...
▽

Text file src/runtime/asm_loong64.s

Documentation: runtime

     1// Copyright 2022 The Go Authors. All rights reserved.
     2// Use of this source code is governed by a BSD-style
     3// license that can be found in the LICENSE file.
     4
     5#include "go_asm.h"
     6#include "go_tls.h"
     7#include "funcdata.h"
     8#include "textflag.h"
     9#include "cgo/abi_loong64.h"
    10
    11// When building with -buildmode=c-shared, this symbol is called when the shared
    12// library is loaded.
    13TEXT _rt0_loong64_lib(SB),NOSPLIT,$168
    14	// Preserve callee-save registers.
    15	SAVE_R22_TO_R31(3*8)
    16	SAVE_F24_TO_F31(13*8)
    17
    18	// Initialize g as nil in case of using g later e.g. sigaction in cgo_sigaction.go
    19	MOVV	R0, g
    20
    21	MOVV	R4, _rt0_loong64_lib_argc<>(SB)
    22	MOVV	R5, _rt0_loong64_lib_argv<>(SB)
    23
    24	MOVV	$runtime·libInit(SB), R19
    25	JAL	(R19)
    26
    27	// Restore callee-save registers.
    28	RESTORE_R22_TO_R31(3*8)
    29	RESTORE_F24_TO_F31(13*8)
    30	RET
    31
    32TEXT runtime·rt0_lib_go<ABIInternal>(SB),NOSPLIT,$0
    33	MOVV	_rt0_loong64_lib_argc<>(SB), R4
    34	MOVV	_rt0_loong64_lib_argv<>(SB), R5
    35	MOVV	$runtime·rt0_go(SB),R19
    36	JMP	(R19)
    37
    38DATA _rt0_loong64_lib_argc<>(SB)/8, $0
    39GLOBL _rt0_loong64_lib_argc<>(SB),NOPTR, $8
    40DATA _rt0_loong64_lib_argv<>(SB)/8, $0
    41GLOBL _rt0_loong64_lib_argv<>(SB),NOPTR, $8
    42
    43#define	REGCTXT	R29
    44
    45TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
    46	// R3 = stack; R4 = argc; R5 = argv
    47
    48	ADDV	$-24, R3
    49	MOVW	R4, 8(R3) // argc
    50	MOVV	R5, 16(R3) // argv
    51
    52	// create istack out of the given (operating system) stack.
    53	// _cgo_init may update stackguard.
    54	MOVV	$runtime·g0(SB), g
    55	MOVV	$(-64*1024), R30
    56	ADDV	R30, R3, R19
    57	MOVV	R19, g_stackguard0(g)
    58	MOVV	R19, g_stackguard1(g)
    59	MOVV	R19, (g_stack+stack_lo)(g)
    60	MOVV	R3, (g_stack+stack_hi)(g)
    61
    62	// if there is a _cgo_init, call it using the gcc ABI.
    63	MOVV	_cgo_init(SB), R25
    64	BEQ	R25, nocgo
    65
    66	MOVV	R0, R7	// arg 3: not used
    67	MOVV	R0, R6	// arg 2: not used
    68	MOVV	$setg_gcc<>(SB), R5	// arg 1: setg
    69	MOVV	g, R4	// arg 0: G
    70	JAL	(R25)
    71
    72nocgo:
    73	JAL	runtime·save_g(SB)
    74	// update stackguard after _cgo_init
    75	MOVV	(g_stack+stack_lo)(g), R19
    76	ADDV	$const_stackGuard, R19
    77	MOVV	R19, g_stackguard0(g)
    78	MOVV	R19, g_stackguard1(g)
    79
    80	// set the per-goroutine and per-mach "registers"
    81	MOVV	$runtime·m0(SB), R19
    82
    83	// save m->g0 = g0
    84	MOVV	g, m_g0(R19)
    85	// save m0 to g0->m
    86	MOVV	R19, g_m(g)
    87
    88	JAL	runtime·check(SB)
    89
    90	// args are already prepared
    91	JAL	runtime·args(SB)
    92	JAL	runtime·osinit(SB)
    93	JAL	runtime·schedinit(SB)
    94
    95	// create a new goroutine to start program
    96	MOVV	$runtime·mainPC(SB), R19		// entry
    97	ADDV	$-16, R3
    98	MOVV	R19, 8(R3)
    99	MOVV	R0, 0(R3)
   100	JAL	runtime·newproc(SB)
   101	ADDV	$16, R3
   102
   103	// start this M
   104	JAL	runtime·mstart(SB)
   105
   106	// Prevent dead-code elimination of debugCallV2 and debugPinnerV1, which are
   107	// intended to be called by debuggers.
   108	MOVV	$runtime·debugPinnerV1<ABIInternal>(SB), R0
   109	MOVV	$runtime·debugCallV2<ABIInternal>(SB), R0
   110
   111	MOVV	R0, 1(R0)
   112	RET
   113
   114DATA	runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
   115GLOBL	runtime·mainPC(SB),RODATA,$8
   116
   117TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
   118	BREAK
   119	RET
   120
   121TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
   122	RET
   123
   124TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
   125	JAL     runtime·mstart0(SB)
   126	RET // not reached
   127
   128// func cputicks() int64
   129TEXT runtime·cputicks<ABIInternal>(SB),NOSPLIT,$0-8
   130	RDTIMED	R0, R4
   131	RET
   132
   133/*
   134 *  go-routine
   135 */
   136
   137// void gogo(Gobuf*)
   138// restore state from Gobuf; longjmp
   139TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
   140	MOVV	buf+0(FP), R4
   141	MOVV	gobuf_g(R4), R5
   142	MOVV	0(R5), R0	// make sure g != nil
   143	JMP	gogo<>(SB)
   144
   145TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
   146	MOVV	R5, g
   147	JAL	runtime·save_g(SB)
   148
   149	MOVV	gobuf_sp(R4), R3
   150	MOVV	gobuf_lr(R4), R1
   151	MOVV	gobuf_ctxt(R4), REGCTXT
   152	MOVV	R0, gobuf_sp(R4)
   153	MOVV	R0, gobuf_lr(R4)
   154	MOVV	R0, gobuf_ctxt(R4)
   155	MOVV	gobuf_pc(R4), R6
   156	JMP	(R6)
   157
   158// void mcall(fn func(*g))
   159// Switch to m->g0's stack, call fn(g).
   160// Fn must never return. It should gogo(&g->sched)
   161// to keep running g.
   162TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
   163	MOVV	R4, REGCTXT
   164	// Save caller state in g->sched
   165	MOVV	R3, (g_sched+gobuf_sp)(g)
   166	MOVV	R1, (g_sched+gobuf_pc)(g)
   167	MOVV	R0, (g_sched+gobuf_lr)(g)
   168
   169	// Switch to m->g0 & its stack, call fn.
   170	MOVV	g, R4		// arg = g
   171	MOVV	g_m(g), R20
   172	MOVV	m_g0(R20), g
   173	JAL	runtime·save_g(SB)
   174	BNE	g, R4, 2(PC)
   175	JMP	runtime·badmcall(SB)
   176	MOVV	0(REGCTXT), R20			// code pointer
   177	MOVV	(g_sched+gobuf_sp)(g), R3	// sp = m->g0->sched.sp
   178	ADDV	$-16, R3
   179	MOVV	R4, 8(R3)
   180	MOVV	R0, 0(R3)
   181	JAL	(R20)
   182	JMP	runtime·badmcall2(SB)
   183
   184// systemstack_switch is a dummy routine that systemstack leaves at the bottom
   185// of the G stack. We need to distinguish the routine that
   186// lives at the bottom of the G stack from the one that lives
   187// at the top of the system stack because the one at the top of
   188// the system stack terminates the stack walk (see topofstack()).
   189TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
   190	UNDEF
   191	JAL	(R1)	// make sure this function is not leaf
   192	RET
   193
   194// func systemstack(fn func())
   195TEXT runtime·systemstack(SB), NOSPLIT, $0-8
   196	MOVV	fn+0(FP), R19	// R19 = fn
   197	MOVV	R19, REGCTXT		// context
   198	MOVV	g_m(g), R4	// R4 = m
   199
   200	MOVV	m_gsignal(R4), R5	// R5 = gsignal
   201	BEQ	g, R5, noswitch
   202
   203	MOVV	m_g0(R4), R5	// R5 = g0
   204	BEQ	g, R5, noswitch
   205
   206	MOVV	m_curg(R4), R6
   207	BEQ	g, R6, switch
   208
   209	// Bad: g is not gsignal, not g0, not curg. What is it?
   210	// Hide call from linker nosplit analysis.
   211	MOVV	$runtime·badsystemstack(SB), R7
   212	JAL	(R7)
   213	JAL	runtime·abort(SB)
   214
   215switch:
   216	// save our state in g->sched. Pretend to
   217	// be systemstack_switch if the G stack is scanned.
   218	JAL	gosave_systemstack_switch<>(SB)
   219
   220	// switch to g0
   221	MOVV	R5, g
   222	JAL	runtime·save_g(SB)
   223	MOVV	(g_sched+gobuf_sp)(g), R19
   224	MOVV	R19, R3
   225
   226	// call target function
   227	MOVV	0(REGCTXT), R6	// code pointer
   228	JAL	(R6)
   229
   230	// switch back to g
   231	MOVV	g_m(g), R4
   232	MOVV	m_curg(R4), g
   233	JAL	runtime·save_g(SB)
   234	MOVV	(g_sched+gobuf_sp)(g), R3
   235	MOVV	R0, (g_sched+gobuf_sp)(g)
   236	RET
   237
   238noswitch:
   239	// already on m stack, just call directly
   240	// Using a tail call here cleans up tracebacks since we won't stop
   241	// at an intermediate systemstack.
   242	MOVV	0(REGCTXT), R4	// code pointer
   243	MOVV	0(R3), R1	// restore LR
   244	ADDV	$8, R3
   245	JMP	(R4)
   246
   247// func switchToCrashStack0(fn func())
   248TEXT runtime·switchToCrashStack0<ABIInternal>(SB),NOSPLIT,$0-8
   249	MOVV	R4, REGCTXT	// context register
   250	MOVV	g_m(g), R5	// curm
   251
   252	// set g to gcrash
   253	MOVV	$runtime·gcrash(SB), g	// g = &gcrash
   254	JAL	runtime·save_g(SB)
   255	MOVV	R5, g_m(g)	// g.m = curm
   256	MOVV	g, m_g0(R5)	// curm.g0 = g
   257
   258	// switch to crashstack
   259	MOVV	(g_stack+stack_hi)(g), R5
   260	ADDV	$(-4*8), R5, R3
   261
   262	// call target function
   263	MOVV	0(REGCTXT), R6
   264	JAL	(R6)
   265
   266	// should never return
   267	JAL	runtime·abort(SB)
   268	UNDEF
   269
   270/*
   271 * support for morestack
   272 */
   273
   274// Called during function prolog when more stack is needed.
   275// Caller has already loaded:
   276// loong64: R31: LR
   277//
   278// The traceback routines see morestack on a g0 as being
   279// the top of a stack (for example, morestack calling newstack
   280// calling the scheduler calling newm calling gc), so we must
   281// record an argument size. For that purpose, it has no arguments.
   282TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
   283	// Called from f.
   284	// Set g->sched to context in f.
   285	MOVV	R3, (g_sched+gobuf_sp)(g)
   286	MOVV	R1, (g_sched+gobuf_pc)(g)
   287	MOVV	R31, (g_sched+gobuf_lr)(g)
   288	MOVV	REGCTXT, (g_sched+gobuf_ctxt)(g)
   289
   290	// Cannot grow scheduler stack (m->g0).
   291	MOVV	g_m(g), R7
   292	MOVV	m_g0(R7), R8
   293	BNE	g, R8, 3(PC)
   294	JAL	runtime·badmorestackg0(SB)
   295	JAL	runtime·abort(SB)
   296
   297	// Cannot grow signal stack (m->gsignal).
   298	MOVV	m_gsignal(R7), R8
   299	BNE	g, R8, 3(PC)
   300	JAL	runtime·badmorestackgsignal(SB)
   301	JAL	runtime·abort(SB)
   302
   303	// Called from f.
   304	// Set m->morebuf to f's caller.
   305	MOVV	R31, (m_morebuf+gobuf_pc)(R7)	// f's caller's PC
   306	MOVV	R3, (m_morebuf+gobuf_sp)(R7)	// f's caller's SP
   307	MOVV	g, (m_morebuf+gobuf_g)(R7)
   308
   309	// Call newstack on m->g0's stack.
   310	MOVV	m_g0(R7), g
   311	JAL	runtime·save_g(SB)
   312	MOVV	(g_sched+gobuf_sp)(g), R3
   313	// Create a stack frame on g0 to call newstack.
   314	MOVV	R0, -8(R3)	// Zero saved LR in frame
   315	ADDV	$-8, R3
   316	JAL	runtime·newstack(SB)
   317
   318	// Not reached, but make sure the return PC from the call to newstack
   319	// is still in this function, and not the beginning of the next.
   320	UNDEF
   321
   322TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
   323	// Force SPWRITE. This function doesn't actually write SP,
   324	// but it is called with a special calling convention where
   325	// the caller doesn't save LR on stack but passes it as a
   326	// register (R5), and the unwinder currently doesn't understand.
   327	// Make it SPWRITE to stop unwinding. (See issue 54332)
   328	MOVV    R3, R3
   329
   330	MOVV	R0, REGCTXT
   331	JMP	runtime·morestack(SB)
   332
   333// reflectcall: call a function with the given argument list
   334// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
   335// we don't have variable-sized frames, so we use a small number
   336// of constant-sized-frame functions to encode a few bits of size in the pc.
   337// Caution: ugly multiline assembly macros in your future!
   338
   339#define DISPATCH(NAME,MAXSIZE)		\
   340	MOVV	$MAXSIZE, R30;		\
   341	SGTU	R19, R30, R30;		\
   342	BNE	R30, 3(PC);			\
   343	MOVV	$NAME(SB), R4;	\
   344	JMP	(R4)
   345// Note: can't just "BR NAME(SB)" - bad inlining results.
   346
   347TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
   348	MOVWU frameSize+32(FP), R19
   349	DISPATCH(runtime·call32, 32)
   350	DISPATCH(runtime·call64, 64)
   351	DISPATCH(runtime·call128, 128)
   352	DISPATCH(runtime·call256, 256)
   353	DISPATCH(runtime·call512, 512)
   354	DISPATCH(runtime·call1024, 1024)
   355	DISPATCH(runtime·call2048, 2048)
   356	DISPATCH(runtime·call4096, 4096)
   357	DISPATCH(runtime·call8192, 8192)
   358	DISPATCH(runtime·call16384, 16384)
   359	DISPATCH(runtime·call32768, 32768)
   360	DISPATCH(runtime·call65536, 65536)
   361	DISPATCH(runtime·call131072, 131072)
   362	DISPATCH(runtime·call262144, 262144)
   363	DISPATCH(runtime·call524288, 524288)
   364	DISPATCH(runtime·call1048576, 1048576)
   365	DISPATCH(runtime·call2097152, 2097152)
   366	DISPATCH(runtime·call4194304, 4194304)
   367	DISPATCH(runtime·call8388608, 8388608)
   368	DISPATCH(runtime·call16777216, 16777216)
   369	DISPATCH(runtime·call33554432, 33554432)
   370	DISPATCH(runtime·call67108864, 67108864)
   371	DISPATCH(runtime·call134217728, 134217728)
   372	DISPATCH(runtime·call268435456, 268435456)
   373	DISPATCH(runtime·call536870912, 536870912)
   374	DISPATCH(runtime·call1073741824, 1073741824)
   375	MOVV	$runtime·badreflectcall(SB), R4
   376	JMP	(R4)
   377
   378#define CALLFN(NAME,MAXSIZE)			\
   379TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
   380	NO_LOCAL_POINTERS;			\
   381	/* copy arguments to stack */		\
   382	MOVV	arg+16(FP), R4;			\
   383	MOVWU	argsize+24(FP), R5;		\
   384	MOVV	R3, R12;			\
   385	MOVV	$16, R13;			\
   386	ADDV	$8, R12;			\
   387	BLT	R5, R13, check8;		\
   388	/* copy 16 bytes a time */		\
   389	MOVBU	internal∕cpu·Loong64+const_offsetLOONG64HasLSX(SB), R16;	\
   390	BEQ	R16, copy16_again;		\
   391loop16:;					\
   392	VMOVQ	(R4), V0;			\
   393	ADDV	$16, R4;			\
   394	ADDV	$-16, R5;			\
   395	VMOVQ	V0, (R12);			\
   396	ADDV	$16, R12;			\
   397	BGE	R5, R13, loop16;		\
   398	JMP	check8;				\
   399copy16_again:;					\
   400	MOVV	(R4), R14;			\
   401	MOVV	8(R4), R15;			\
   402	ADDV	$16, R4;			\
   403	ADDV	$-16, R5;			\
   404	MOVV	R14, (R12);			\
   405	MOVV	R15, 8(R12);			\
   406	ADDV	$16, R12;			\
   407	BGE	R5, R13, copy16_again;		\
   408check8:;					\
   409	/* R13 = 8 */;				\
   410	SRLV	$1, R13;			\
   411	BLT	R5, R13, 6(PC);			\
   412	/* copy 8 bytes a time */		\
   413	MOVV	(R4), R14;			\
   414	ADDV	$8, R4;				\
   415	ADDV	$-8, R5;			\
   416	MOVV	R14, (R12);			\
   417	ADDV	$8, R12;			\
   418	BEQ     R5, R0, 7(PC);  		\
   419	/* copy 1 byte a time for the rest */	\
   420	MOVBU   (R4), R14;      		\
   421	ADDV    $1, R4;         		\
   422	ADDV    $-1, R5;        		\
   423	MOVBU   R14, (R12);     		\
   424	ADDV    $1, R12;        		\
   425	JMP     -6(PC);         		\
   426	/* set up argument registers */		\
   427	MOVV	regArgs+40(FP), R25;		\
   428	JAL	·unspillArgs(SB);		\
   429	/* call function */			\
   430	MOVV	f+8(FP), REGCTXT;		\
   431	MOVV	(REGCTXT), R25;			\
   432	PCDATA  $PCDATA_StackMapIndex, $0;	\
   433	JAL	(R25);				\
   434	/* copy return values back */		\
   435	MOVV	regArgs+40(FP), R25;		\
   436	JAL	·spillArgs(SB);			\
   437	MOVV	argtype+0(FP), R7;		\
   438	MOVV	arg+16(FP), R4;			\
   439	MOVWU	n+24(FP), R5;			\
   440	MOVWU	retoffset+28(FP), R6;		\
   441	ADDV	$8, R3, R12;			\
   442	ADDV	R6, R12; 			\
   443	ADDV	R6, R4;				\
   444	SUBVU	R6, R5;				\
   445	JAL	callRet<>(SB);			\
   446	RET
   447
   448// callRet copies return values back at the end of call*. This is a
   449// separate function so it can allocate stack space for the arguments
   450// to reflectcallmove. It does not follow the Go ABI; it expects its
   451// arguments in registers.
   452TEXT callRet<>(SB), NOSPLIT, $40-0
   453	NO_LOCAL_POINTERS
   454	MOVV	R7, 8(R3)
   455	MOVV	R4, 16(R3)
   456	MOVV	R12, 24(R3)
   457	MOVV	R5, 32(R3)
   458	MOVV	R25, 40(R3)
   459	JAL	runtime·reflectcallmove(SB)
   460	RET
   461
   462CALLFN(·call16, 16)
   463CALLFN(·call32, 32)
   464CALLFN(·call64, 64)
   465CALLFN(·call128, 128)
   466CALLFN(·call256, 256)
   467CALLFN(·call512, 512)
   468CALLFN(·call1024, 1024)
   469CALLFN(·call2048, 2048)
   470CALLFN(·call4096, 4096)
   471CALLFN(·call8192, 8192)
   472CALLFN(·call16384, 16384)
   473CALLFN(·call32768, 32768)
   474CALLFN(·call65536, 65536)
   475CALLFN(·call131072, 131072)
   476CALLFN(·call262144, 262144)
   477CALLFN(·call524288, 524288)
   478CALLFN(·call1048576, 1048576)
   479CALLFN(·call2097152, 2097152)
   480CALLFN(·call4194304, 4194304)
   481CALLFN(·call8388608, 8388608)
   482CALLFN(·call16777216, 16777216)
   483CALLFN(·call33554432, 33554432)
   484CALLFN(·call67108864, 67108864)
   485CALLFN(·call134217728, 134217728)
   486CALLFN(·call268435456, 268435456)
   487CALLFN(·call536870912, 536870912)
   488CALLFN(·call1073741824, 1073741824)
   489
   490TEXT runtime·procyieldAsm(SB),NOSPLIT,$0-0
   491	RET
   492
   493// Save state of caller into g->sched.
   494// but using fake PC from systemstack_switch.
   495// Must only be called from functions with no locals ($0)
   496// or else unwinding from systemstack_switch is incorrect.
   497// Smashes R19.
   498TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
   499	MOVV    $runtime·systemstack_switch(SB), R19
   500	ADDV	$8, R19
   501	MOVV	R19, (g_sched+gobuf_pc)(g)
   502	MOVV	R3, (g_sched+gobuf_sp)(g)
   503	MOVV	R0, (g_sched+gobuf_lr)(g)
   504	// Assert ctxt is zero. See func save.
   505	MOVV	(g_sched+gobuf_ctxt)(g), R19
   506	BEQ	R19, 2(PC)
   507	JAL	runtime·abort(SB)
   508	RET
   509
   510// func asmcgocall(fn, arg unsafe.Pointer) int32
   511// Call fn(arg) on the scheduler stack,
   512// aligned appropriately for the gcc ABI.
   513// See cgocall.go for more details.
   514TEXT ·asmcgocall(SB),NOSPLIT,$0-20
   515	MOVV	fn+0(FP), R25
   516	MOVV	arg+8(FP), R4
   517
   518	MOVV	R3, R12	// save original stack pointer
   519	MOVV	g, R13
   520
   521	// Figure out if we need to switch to m->g0 stack.
   522	// We get called to create new OS threads too, and those
   523	// come in on the m->g0 stack already.
   524	BEQ	g, R0, nosave
   525	MOVV	g_m(g), R5
   526	MOVV	m_gsignal(R5), R6
   527	BEQ	R6, g, g0
   528	MOVV	m_g0(R5), R6
   529	BEQ	R6, g, g0
   530
   531	JAL	gosave_systemstack_switch<>(SB)
   532	MOVV	R6, g
   533	JAL	runtime·save_g(SB)
   534	MOVV	(g_sched+gobuf_sp)(g), R3
   535
   536	// Now on a scheduling stack (a pthread-created stack).
   537g0:
   538	// Save room for two of our pointers.
   539	ADDV	$-16, R3
   540	MOVV	R13, 0(R3)	// save old g on stack
   541	MOVV	(g_stack+stack_hi)(R13), R13
   542	SUBVU	R12, R13
   543	MOVV	R13, 8(R3)	// save depth in old g stack (can't just save SP, as stack might be copied during a callback)
   544	JAL	(R25)
   545
   546	// Restore g, stack pointer. R4 is return value.
   547	MOVV	0(R3), g
   548	JAL	runtime·save_g(SB)
   549	MOVV	(g_stack+stack_hi)(g), R5
   550	MOVV	8(R3), R6
   551	SUBVU	R6, R5
   552	MOVV	R5, R3
   553
   554	MOVW	R4, ret+16(FP)
   555	RET
   556
   557nosave:
   558	// Running on a system stack, perhaps even without a g.
   559	// Having no g can happen during thread creation or thread teardown.
   560	MOVV	fn+0(FP), R25
   561	MOVV	arg+8(FP), R4
   562	MOVV	R3, R12
   563	ADDV	$-16, R3
   564	MOVV	R0, 0(R3)	// Where above code stores g, in case someone looks during debugging.
   565	MOVV	R12, 8(R3)	// Save original stack pointer.
   566	JAL	(R25)
   567	MOVV	8(R3), R3	// Restore stack pointer.
   568	MOVW	R4, ret+16(FP)
   569	RET
   570
   571// func asmcgocall_no_g(fn, arg unsafe.Pointer)
   572// Call fn(arg) aligned appropriately for the gcc ABI.
   573// Called on a system stack, and there may be no g yet.
   574TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
   575	MOVV	fn+0(FP), R25
   576	MOVV	arg+8(FP), R4
   577	JAL	(R25)
   578	RET
   579
   580// func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
   581// See cgocall.go for more details.
   582TEXT ·cgocallback(SB),NOSPLIT,$24-24
   583	NO_LOCAL_POINTERS
   584
   585	// Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
   586	// It is used to dropm while thread is exiting.
   587	MOVV    fn+0(FP), R5
   588	BNE	R5, loadg
   589	// Restore the g from frame.
   590	MOVV    frame+8(FP), g
   591	JMP	dropm
   592
   593loadg:
   594	// Load m and g from thread-local storage.
   595	MOVB	runtime·iscgo(SB), R19
   596	BEQ	R19, nocgo
   597	JAL	runtime·load_g(SB)
   598nocgo:
   599
   600	// If g is nil, Go did not create the current thread,
   601	// or if this thread never called into Go on pthread platforms.
   602	// Call needm to obtain one for temporary use.
   603	// In this case, we're running on the thread stack, so there's
   604	// lots of space, but the linker doesn't know. Hide the call from
   605	// the linker analysis by using an indirect call.
   606	BEQ	g, needm
   607
   608	MOVV	g_m(g), R12
   609	MOVV	R12, savedm-8(SP)
   610	JMP	havem
   611
   612needm:
   613	MOVV	g, savedm-8(SP) // g is zero, so is m.
   614	MOVV	$runtime·needAndBindM(SB), R4
   615	JAL	(R4)
   616
   617	// Set m->sched.sp = SP, so that if a panic happens
   618	// during the function we are about to execute, it will
   619	// have a valid SP to run on the g0 stack.
   620	// The next few lines (after the havem label)
   621	// will save this SP onto the stack and then write
   622	// the same SP back to m->sched.sp. That seems redundant,
   623	// but if an unrecovered panic happens, unwindm will
   624	// restore the g->sched.sp from the stack location
   625	// and then systemstack will try to use it. If we don't set it here,
   626	// that restored SP will be uninitialized (typically 0) and
   627	// will not be usable.
   628	MOVV	g_m(g), R12
   629	MOVV	m_g0(R12), R19
   630	MOVV	R3, (g_sched+gobuf_sp)(R19)
   631
   632havem:
   633	// Now there's a valid m, and we're running on its m->g0.
   634	// Save current m->g0->sched.sp on stack and then set it to SP.
   635	// Save current sp in m->g0->sched.sp in preparation for
   636	// switch back to m->curg stack.
   637	// NOTE: unwindm knows that the saved g->sched.sp is at 8(R29) aka savedsp-16(SP).
   638	MOVV	m_g0(R12), R19
   639	MOVV	(g_sched+gobuf_sp)(R19), R13
   640	MOVV	R13, savedsp-24(SP) // must match frame size
   641	MOVV	R3, (g_sched+gobuf_sp)(R19)
   642
   643	// Switch to m->curg stack and call runtime.cgocallbackg.
   644	// Because we are taking over the execution of m->curg
   645	// but *not* resuming what had been running, we need to
   646	// save that information (m->curg->sched) so we can restore it.
   647	// We can restore m->curg->sched.sp easily, because calling
   648	// runtime.cgocallbackg leaves SP unchanged upon return.
   649	// To save m->curg->sched.pc, we push it onto the stack.
   650	// This has the added benefit that it looks to the traceback
   651	// routine like cgocallbackg is going to return to that
   652	// PC (because the frame we allocate below has the same
   653	// size as cgocallback_gofunc's frame declared above)
   654	// so that the traceback will seamlessly trace back into
   655	// the earlier calls.
   656	MOVV	m_curg(R12), g
   657	JAL	runtime·save_g(SB)
   658	MOVV	(g_sched+gobuf_sp)(g), R13 // prepare stack as R13
   659	MOVV	(g_sched+gobuf_pc)(g), R7
   660	MOVV	R7, -(24+8)(R13) // "saved LR"; must match frame size
   661
   662	MOVV    fn+0(FP), R4
   663	MOVV    frame+8(FP), R5
   664	MOVV    ctxt+16(FP), R6
   665	SUBV	$(24+8), R13	// Allocate the same frame size on the g stack
   666	MOVV	R13, R3		// switch stack
   667	JAL	runtime·cgocallbackg<ABIInternal>(SB)
   668
   669	// Restore g->sched (== m->curg->sched) from saved values.
   670	MOVV	0(R3), R7
   671	MOVV	R7, (g_sched+gobuf_pc)(g)
   672	MOVV	$(24+8)(R3), R13 // must match frame size
   673	MOVV	R13, (g_sched+gobuf_sp)(g)
   674
   675	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   676	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   677	// so we do not have to restore it.)
   678	MOVV	g_m(g), R12
   679	MOVV	m_g0(R12), g
   680	JAL	runtime·save_g(SB)
   681	MOVV	(g_sched+gobuf_sp)(g), R3
   682	MOVV	savedsp-24(SP), R13 // must match frame size
   683	MOVV	R13, (g_sched+gobuf_sp)(g)
   684
   685	// If the m on entry was nil, we called needm above to borrow an m,
   686	// 1. for the duration of the call on non-pthread platforms,
   687	// 2. or the duration of the C thread alive on pthread platforms.
   688	// If the m on entry wasn't nil,
   689	// 1. the thread might be a Go thread,
   690	// 2. or it wasn't the first call from a C thread on pthread platforms,
   691	//    since then we skip dropm to resue the m in the first call.
   692	MOVV	savedm-8(SP), R12
   693	BNE	R12, droppedm
   694
   695	// Skip dropm to reuse it in the next call, when a pthread key has been created.
   696	MOVV	_cgo_pthread_key_created(SB), R12
   697	// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
   698	BEQ	R12, dropm
   699	MOVV    (R12), R12
   700	BNE	R12, droppedm
   701
   702dropm:
   703	MOVV	$runtime·dropm(SB), R4
   704	JAL	(R4)
   705droppedm:
   706
   707	// Done!
   708	RET
   709
   710// void setg(G*); set g. for use by needm.
   711TEXT runtime·setg(SB), NOSPLIT, $0-8
   712	MOVV	gg+0(FP), g
   713	// This only happens if iscgo, so jump straight to save_g
   714	JAL	runtime·save_g(SB)
   715	RET
   716
   717// void setg_gcc(G*); set g called from gcc with g in R4
   718TEXT setg_gcc<>(SB),NOSPLIT,$0-0
   719	MOVV	R4, g
   720	JAL	runtime·save_g(SB)
   721	RET
   722
   723TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   724	MOVW	(R0), R0
   725	UNDEF
   726
   727// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
   728// Must obey the gcc calling convention.
   729TEXT _cgo_topofstack(SB),NOSPLIT,$16
   730	// g (R22) and REGTMP (R30)  might be clobbered by load_g. They
   731	// are callee-save in the gcc calling convention, so save them.
   732	MOVV	R30, savedREGTMP-16(SP)
   733	MOVV	g, savedG-8(SP)
   734
   735	JAL	runtime·load_g(SB)
   736	MOVV	g_m(g), R19
   737	MOVV	m_curg(R19), R19
   738	MOVV	(g_stack+stack_hi)(R19), R4 // return value in R4
   739
   740	MOVV	savedG-8(SP), g
   741	MOVV	savedREGTMP-16(SP), R30
   742	RET
   743
   744// The top-most function running on a goroutine
   745// returns to goexit+PCQuantum.
   746TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
   747	NOOP
   748	JAL	runtime·goexit1(SB)	// does not return
   749	// traceback from goexit1 must hit code range of goexit
   750	NOOP
   751
   752// This is called from .init_array and follows the platform, not Go, ABI.
   753TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
   754	ADDV	$-0x10, R3
   755	MOVV	R30, 8(R3) // The access to global variables below implicitly uses R30, which is callee-save
   756	MOVV	runtime·lastmoduledatap(SB), R12
   757	MOVV	R4, moduledata_next(R12)
   758	MOVV	R4, runtime·lastmoduledatap(SB)
   759	MOVV	8(R3), R30
   760	ADDV	$0x10, R3
   761	RET
   762
   763// spillArgs stores return values from registers to a *internal/abi.RegArgs in R25.
   764TEXT ·spillArgs(SB),NOSPLIT,$0-0
   765	MOVV	R4, (0*8)(R25)
   766	MOVV	R5, (1*8)(R25)
   767	MOVV	R6, (2*8)(R25)
   768	MOVV	R7, (3*8)(R25)
   769	MOVV	R8, (4*8)(R25)
   770	MOVV	R9, (5*8)(R25)
   771	MOVV	R10, (6*8)(R25)
   772	MOVV	R11, (7*8)(R25)
   773	MOVV	R12, (8*8)(R25)
   774	MOVV	R13, (9*8)(R25)
   775	MOVV	R14, (10*8)(R25)
   776	MOVV	R15, (11*8)(R25)
   777	MOVV	R16, (12*8)(R25)
   778	MOVV	R17, (13*8)(R25)
   779	MOVV	R18, (14*8)(R25)
   780	MOVV	R19, (15*8)(R25)
   781	MOVD	F0, (16*8)(R25)
   782	MOVD	F1, (17*8)(R25)
   783	MOVD	F2, (18*8)(R25)
   784	MOVD	F3, (19*8)(R25)
   785	MOVD	F4, (20*8)(R25)
   786	MOVD	F5, (21*8)(R25)
   787	MOVD	F6, (22*8)(R25)
   788	MOVD	F7, (23*8)(R25)
   789	MOVD	F8, (24*8)(R25)
   790	MOVD	F9, (25*8)(R25)
   791	MOVD	F10, (26*8)(R25)
   792	MOVD	F11, (27*8)(R25)
   793	MOVD	F12, (28*8)(R25)
   794	MOVD	F13, (29*8)(R25)
   795	MOVD	F14, (30*8)(R25)
   796	MOVD	F15, (31*8)(R25)
   797	RET
   798
   799// unspillArgs loads args into registers from a *internal/abi.RegArgs in R25.
   800TEXT ·unspillArgs(SB),NOSPLIT,$0-0
   801	MOVV	(0*8)(R25), R4
   802	MOVV	(1*8)(R25), R5
   803	MOVV	(2*8)(R25), R6
   804	MOVV	(3*8)(R25), R7
   805	MOVV	(4*8)(R25), R8
   806	MOVV	(5*8)(R25), R9
   807	MOVV	(6*8)(R25), R10
   808	MOVV	(7*8)(R25), R11
   809	MOVV	(8*8)(R25), R12
   810	MOVV	(9*8)(R25), R13
   811	MOVV	(10*8)(R25), R14
   812	MOVV	(11*8)(R25), R15
   813	MOVV	(12*8)(R25), R16
   814	MOVV	(13*8)(R25), R17
   815	MOVV	(14*8)(R25), R18
   816	MOVV	(15*8)(R25), R19
   817	MOVD	(16*8)(R25), F0
   818	MOVD	(17*8)(R25), F1
   819	MOVD	(18*8)(R25), F2
   820	MOVD	(19*8)(R25), F3
   821	MOVD	(20*8)(R25), F4
   822	MOVD	(21*8)(R25), F5
   823	MOVD	(22*8)(R25), F6
   824	MOVD	(23*8)(R25), F7
   825	MOVD	(24*8)(R25), F8
   826	MOVD	(25*8)(R25), F9
   827	MOVD	(26*8)(R25), F10
   828	MOVD	(27*8)(R25), F11
   829	MOVD	(28*8)(R25), F12
   830	MOVD	(29*8)(R25), F13
   831	MOVD	(30*8)(R25), F14
   832	MOVD	(31*8)(R25), F15
   833	RET
   834
   835// gcWriteBarrier informs the GC about heap pointer writes.
   836//
   837// gcWriteBarrier does NOT follow the Go ABI. It accepts the
   838// number of bytes of buffer needed in R29, and returns a pointer
   839// to the buffer space in R29.
   840// It clobbers R30 (the linker temp register).
   841// The act of CALLing gcWriteBarrier will clobber R1 (LR).
   842// It does not clobber any other general-purpose registers,
   843// but may clobber others (e.g., floating point registers).
   844TEXT gcWriteBarrier<>(SB),NOSPLIT,$216
   845	// Save the registers clobbered by the fast path.
   846	MOVV	R19, 208(R3)
   847	MOVV	R13, 216(R3)
   848retry:
   849	MOVV	g_m(g), R19
   850	MOVV	m_p(R19), R19
   851	MOVV	(p_wbBuf+wbBuf_next)(R19), R13
   852	MOVV	(p_wbBuf+wbBuf_end)(R19), R30 // R30 is linker temp register
   853	// Increment wbBuf.next position.
   854	ADDV	R29, R13
   855	// Is the buffer full?
   856	BLTU	R30, R13, flush
   857	// Commit to the larger buffer.
   858	MOVV	R13, (p_wbBuf+wbBuf_next)(R19)
   859	// Make return value (the original next position)
   860	SUBV	R29, R13, R29
   861	// Restore registers.
   862	MOVV	208(R3), R19
   863	MOVV	216(R3), R13
   864	RET
   865
   866flush:
   867	// Save all general purpose registers since these could be
   868	// clobbered by wbBufFlush and were not saved by the caller.
   869	MOVV	R27, 8(R3)
   870	MOVV	R28, 16(R3)
   871	// R1 is LR, which was saved by the prologue.
   872	MOVV	R2, 24(R3)
   873	// R3 is SP.
   874	MOVV	R4, 32(R3)
   875	MOVV	R5, 40(R3)
   876	MOVV	R6, 48(R3)
   877	MOVV	R7, 56(R3)
   878	MOVV	R8, 64(R3)
   879	MOVV	R9, 72(R3)
   880	MOVV	R10, 80(R3)
   881	MOVV	R11, 88(R3)
   882	MOVV	R12, 96(R3)
   883	// R13 already saved
   884	MOVV	R14, 104(R3)
   885	MOVV	R15, 112(R3)
   886	MOVV	R16, 120(R3)
   887	MOVV	R17, 128(R3)
   888	MOVV	R18, 136(R3)
   889	// R19 already saved
   890	MOVV	R20, 144(R3)
   891	MOVV	R21, 152(R3)
   892	// R22 is g.
   893	MOVV	R23, 160(R3)
   894	MOVV	R24, 168(R3)
   895	MOVV	R25, 176(R3)
   896	MOVV	R26, 184(R3)
   897	// R27 already saved
   898	// R28 already saved.
   899	MOVV	R29, 192(R3)
   900	// R30 is tmp register.
   901	MOVV	R31, 200(R3)
   902
   903	CALL	runtime·wbBufFlush(SB)
   904
   905	MOVV	8(R3), R27
   906	MOVV	16(R3), R28
   907	MOVV	24(R3), R2
   908	MOVV	32(R3), R4
   909	MOVV	40(R3), R5
   910	MOVV	48(R3), R6
   911	MOVV	56(R3), R7
   912	MOVV	64(R3), R8
   913	MOVV	72(R3), R9
   914	MOVV	80(R3), R10
   915	MOVV	88(R3), R11
   916	MOVV	96(R3), R12
   917	MOVV	104(R3), R14
   918	MOVV	112(R3), R15
   919	MOVV	120(R3), R16
   920	MOVV	128(R3), R17
   921	MOVV	136(R3), R18
   922	MOVV	144(R3), R20
   923	MOVV	152(R3), R21
   924	MOVV	160(R3), R23
   925	MOVV	168(R3), R24
   926	MOVV	176(R3), R25
   927	MOVV	184(R3), R26
   928	MOVV	192(R3), R29
   929	MOVV	200(R3), R31
   930	JMP	retry
   931
   932TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
   933	MOVV	$8, R29
   934	JMP	gcWriteBarrier<>(SB)
   935TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
   936	MOVV	$16, R29
   937	JMP	gcWriteBarrier<>(SB)
   938TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
   939	MOVV	$24, R29
   940	JMP	gcWriteBarrier<>(SB)
   941TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
   942	MOVV	$32, R29
   943	JMP	gcWriteBarrier<>(SB)
   944TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
   945	MOVV	$40, R29
   946	JMP	gcWriteBarrier<>(SB)
   947TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
   948	MOVV	$48, R29
   949	JMP	gcWriteBarrier<>(SB)
   950TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
   951	MOVV	$56, R29
   952	JMP	gcWriteBarrier<>(SB)
   953TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
   954	MOVV	$64, R29
   955	JMP	gcWriteBarrier<>(SB)
   956
   957DATA	debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
   958GLOBL	debugCallFrameTooLarge<>(SB), RODATA, $20	// Size duplicated below
   959
   960// debugCallV2 is the entry point for debugger-injected function
   961// calls on running goroutines. It informs the runtime that a
   962// debug call has been injected and creates a call frame for the
   963// debugger to fill in.
   964//
   965// To inject a function call, a debugger should:
   966// 1. Check that the goroutine is in state _Grunning and that
   967//    there are at least 280 bytes free on the stack.
   968// 2. Set SP as SP-8.
   969// 3. Store the current LR in (SP) (using the SP after step 2).
   970// 4. Store the current PC in the LR register.
   971// 5. Write the desired argument frame size at SP-8
   972// 6. Save all machine registers so they can be restored later by the debugger.
   973// 7. Set the PC to debugCallV2 and resume execution.
   974//
   975// If the goroutine is in state _Grunnable, then it's not generally
   976// safe to inject a call because it may return out via other runtime
   977// operations. Instead, the debugger should unwind the stack to find
   978// the return to non-runtime code, add a temporary breakpoint there,
   979// and inject the call once that breakpoint is hit.
   980//
   981// If the goroutine is in any other state, it's not safe to inject a call.
   982//
   983// This function communicates back to the debugger by setting R19 and
   984// invoking BREAK to raise a breakpoint signal. Note that the signal PC of
   985// the signal triggered by the BREAK instruction is the PC where the signal
   986// is trapped, not the next PC, so to resume execution, the debugger needs
   987// to set the signal PC to PC+4. See the comments in the implementation for
   988// the protocol the debugger is expected to follow. InjectDebugCall in the
   989// runtime tests demonstrates this protocol.
   990//
   991// The debugger must ensure that any pointers passed to the function
   992// obey escape analysis requirements. Specifically, it must not pass
   993// a stack pointer to an escaping argument. debugCallV2 cannot check
   994// this invariant.
   995//
   996// This is ABIInternal because Go code injects its PC directly into new
   997// goroutine stacks.
   998TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
   999	MOVV    R1, -272(R3)
  1000	ADDV    $-272, R3
  1001
  1002	// We can't do anything that might clobber any of these
  1003	// registers before this.
  1004	MOVV    R2, (4*8)(R3)
  1005	MOVV    R4, (5*8)(R3)
  1006	MOVV    R5, (6*8)(R3)
  1007	MOVV    R6, (7*8)(R3)
  1008	MOVV    R7, (8*8)(R3)
  1009	MOVV    R8, (9*8)(R3)
  1010	MOVV    R9, (10*8)(R3)
  1011	MOVV    R10, (11*8)(R3)
  1012	MOVV    R11, (12*8)(R3)
  1013	MOVV    R12, (13*8)(R3)
  1014	MOVV    R13, (14*8)(R3)
  1015	MOVV    R14, (15*8)(R3)
  1016	MOVV    R15, (16*8)(R3)
  1017	MOVV    R16, (17*8)(R3)
  1018	MOVV    R17, (18*8)(R3)
  1019	MOVV    R18, (19*8)(R3)
  1020	MOVV    R19, (20*8)(R3)
  1021	MOVV    R20, (21*8)(R3)
  1022	MOVV    R21, (22*8)(R3)
  1023	MOVV    g, (23*8)(R3)
  1024	MOVV    R23, (24*8)(R3)
  1025	MOVV    R24, (25*8)(R3)
  1026	MOVV    R25, (26*8)(R3)
  1027	MOVV    R26, (27*8)(R3)
  1028	MOVV    R27, (28*8)(R3)
  1029	MOVV    R28, (29*8)(R3)
  1030	MOVV    R29, (30*8)(R3)
  1031	MOVV    R30, (31*8)(R3)
  1032	MOVV    R31, (32*8)(R3)
  1033
  1034	// Perform a safe-point check.
  1035	MOVV    R1, 8(R3)
  1036	CALL    runtime·debugCallCheck(SB)
  1037	MOVV    16(R3), R30
  1038	BEQ R30, good
  1039
  1040	// The safety check failed. Put the reason string at the top
  1041	// of the stack.
  1042	MOVV    R30, 8(R3)
  1043
  1044	MOVV    24(R3), R30
  1045	MOVV    R30, 16(R3)
  1046
  1047	MOVV    $8, R19
  1048	BREAK
  1049	JMP restore
  1050
  1051good:
  1052	// Registers are saved and it's safe to make a call.
  1053	// Open up a call frame, moving the stack if necessary.
  1054	//
  1055	// Once the frame is allocated, this will set R19 to 0 and
  1056	// invoke BREAK. The debugger should write the argument
  1057	// frame for the call at SP+8, set up argument registers,
  1058	// set the LR as the signal PC + 4, set the PC to the function
  1059	// to call, set R29 to point to the closure (if a closure call),
  1060	// and resume execution.
  1061	//
  1062	// If the function returns, this will set R19 to 1 and invoke
  1063	// BREAK. The debugger can then inspect any return value saved
  1064	// on the stack at SP+8 and in registers. To resume execution,
  1065	// the debugger should restore the LR from (SP).
  1066	//
  1067	// If the function panics, this will set R19 to 2 and invoke BREAK.
  1068	// The interface{} value of the panic will be at SP+8. The debugger
  1069	// can inspect the panic value and resume execution again.
  1070#define DEBUG_CALL_DISPATCH(NAME,MAXSIZE)	\
  1071	MOVV    $MAXSIZE, R27;         \
  1072	BLT R27, R30, 5(PC);            \
  1073	MOVV    $NAME(SB), R28;			\
  1074	MOVV    R28, 8(R3);			\
  1075	CALL    runtime·debugCallWrap(SB);	\
  1076	JMP restore
  1077
  1078	MOVV    264(R3), R30 // the argument frame size
  1079	DEBUG_CALL_DISPATCH(debugCall32<>, 32)
  1080	DEBUG_CALL_DISPATCH(debugCall64<>, 64)
  1081	DEBUG_CALL_DISPATCH(debugCall128<>, 128)
  1082	DEBUG_CALL_DISPATCH(debugCall256<>, 256)
  1083	DEBUG_CALL_DISPATCH(debugCall512<>, 512)
  1084	DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
  1085	DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
  1086	DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
  1087	DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
  1088	DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
  1089	DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
  1090	DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
  1091	// The frame size is too large. Report the error.
  1092	MOVV    $debugCallFrameTooLarge<>(SB), R30
  1093	MOVV    R30, 8(R3)
  1094	MOVV    $20, R30
  1095	MOVV    R30, 16(R3) // length of debugCallFrameTooLarge string
  1096	MOVV    $8, R19
  1097	BREAK
  1098	JMP restore
  1099
  1100restore:
  1101	// Calls and failures resume here.
  1102	//
  1103	// Set R19 to 16 and invoke BREAK. The debugger should restore
  1104	// all registers except for PC and SP and resume execution.
  1105	MOVV    $16, R19
  1106	BREAK
  1107	// We must not modify flags after this point.
  1108
  1109	// Restore pointer-containing registers, which may have been
  1110	// modified from the debugger's copy by stack copying.
  1111	MOVV    (4*8)(R3), R2
  1112	MOVV    (5*8)(R3), R4
  1113	MOVV    (6*8)(R3), R5
  1114	MOVV    (7*8)(R3), R6
  1115	MOVV    (8*8)(R3), R7
  1116	MOVV    (9*8)(R3), R8
  1117	MOVV    (10*8)(R3), R9
  1118	MOVV    (11*8)(R3), R10
  1119	MOVV    (12*8)(R3), R11
  1120	MOVV    (13*8)(R3), R12
  1121	MOVV    (14*8)(R3), R13
  1122	MOVV    (15*8)(R3), R14
  1123	MOVV    (16*8)(R3), R15
  1124	MOVV    (17*8)(R3), R16
  1125	MOVV    (18*8)(R3), R17
  1126	MOVV    (19*8)(R3), R18
  1127	MOVV    (20*8)(R3), R19
  1128	MOVV    (21*8)(R3), R20
  1129	MOVV    (22*8)(R3), R21
  1130	MOVV    (23*8)(R3), g
  1131	MOVV    (24*8)(R3), R23
  1132	MOVV    (25*8)(R3), R24
  1133	MOVV    (26*8)(R3), R25
  1134	MOVV    (27*8)(R3), R26
  1135	MOVV    (28*8)(R3), R27
  1136	MOVV    (29*8)(R3), R28
  1137	MOVV    (30*8)(R3), R29
  1138	MOVV    (31*8)(R3), R30
  1139	MOVV    (32*8)(R3), R31
  1140
  1141	MOVV    0(R3), R30
  1142	ADDV    $280, R3 // Add 8 more bytes, see saveSigContext
  1143	MOVV    -8(R3), R1
  1144	JMP (R30)
  1145
  1146// runtime.debugCallCheck assumes that functions defined with the
  1147// DEBUG_CALL_FN macro are safe points to inject calls.
  1148#define DEBUG_CALL_FN(NAME,MAXSIZE)		\
  1149TEXT NAME(SB),WRAPPER,$MAXSIZE-0;		\
  1150	NO_LOCAL_POINTERS;		\
  1151	MOVV    $0, R19;		\
  1152	BREAK;		\
  1153	MOVV    $1, R19;		\
  1154	BREAK;		\
  1155	RET
  1156DEBUG_CALL_FN(debugCall32<>, 32)
  1157DEBUG_CALL_FN(debugCall64<>, 64)
  1158DEBUG_CALL_FN(debugCall128<>, 128)
  1159DEBUG_CALL_FN(debugCall256<>, 256)
  1160DEBUG_CALL_FN(debugCall512<>, 512)
  1161DEBUG_CALL_FN(debugCall1024<>, 1024)
  1162DEBUG_CALL_FN(debugCall2048<>, 2048)
  1163DEBUG_CALL_FN(debugCall4096<>, 4096)
  1164DEBUG_CALL_FN(debugCall8192<>, 8192)
  1165DEBUG_CALL_FN(debugCall16384<>, 16384)
  1166DEBUG_CALL_FN(debugCall32768<>, 32768)
  1167DEBUG_CALL_FN(debugCall65536<>, 65536)
  1168
  1169// func debugCallPanicked(val interface{})
  1170TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
  1171	// Copy the panic value to the top of stack at SP+8.
  1172	MOVV    val_type+0(FP), R30
  1173	MOVV    R30, 8(R3)
  1174	MOVV    val_data+8(FP), R30
  1175	MOVV    R30, 16(R3)
  1176	MOVV    $2, R19
  1177	BREAK
  1178	RET
  1179
  1180TEXT runtime·panicBounds<ABIInternal>(SB),NOSPLIT,$144-0
  1181	NO_LOCAL_POINTERS
  1182	// Save all 16 int registers that could have an index in them.
  1183	// They may be pointers, but if they are they are dead.
  1184	// Skip R0 aka ZERO, R1 aka LR, R2 aka thread pointer, R3 aka SP.
  1185	MOVV	R4, 24(R3)
  1186	MOVV	R5, 32(R3)
  1187	MOVV	R6, 40(R3)
  1188	MOVV	R7, 48(R3)
  1189	MOVV	R8, 56(R3)
  1190	MOVV	R9, 64(R3)
  1191	MOVV	R10, 72(R3)
  1192	MOVV	R11, 80(R3)
  1193	MOVV	R12, 88(R3)
  1194	MOVV	R13, 96(R3)
  1195	MOVV	R14, 104(R3)
  1196	MOVV	R15, 112(R3)
  1197	MOVV	R16, 120(R3)
  1198	MOVV	R17, 128(R3)
  1199	MOVV	R18, 136(R3)
  1200	MOVV	R19, 144(R3)
  1201
  1202	MOVV	R1, R4		// PC immediately after call to panicBounds
  1203	ADDV	$24, R3, R5	// pointer to save area
  1204	CALL	runtime·panicBounds64<ABIInternal>(SB)
  1205	RET

View as plain text