Text file src/runtime/asm_loong64.s

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

View as plain text