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  	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()).
   189  TEXT 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())
   195  TEXT 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  
   215  switch:
   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  
   238  noswitch:
   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())
   248  TEXT 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.
   282  TEXT 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  
   322  TEXT 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  
   347  TEXT ·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)			\
   379  TEXT 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;		\
   391  loop16:;					\
   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;				\
   399  copy16_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;		\
   408  check8:;					\
   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.
   452  TEXT 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  
   462  CALLFN(·call16, 16)
   463  CALLFN(·call32, 32)
   464  CALLFN(·call64, 64)
   465  CALLFN(·call128, 128)
   466  CALLFN(·call256, 256)
   467  CALLFN(·call512, 512)
   468  CALLFN(·call1024, 1024)
   469  CALLFN(·call2048, 2048)
   470  CALLFN(·call4096, 4096)
   471  CALLFN(·call8192, 8192)
   472  CALLFN(·call16384, 16384)
   473  CALLFN(·call32768, 32768)
   474  CALLFN(·call65536, 65536)
   475  CALLFN(·call131072, 131072)
   476  CALLFN(·call262144, 262144)
   477  CALLFN(·call524288, 524288)
   478  CALLFN(·call1048576, 1048576)
   479  CALLFN(·call2097152, 2097152)
   480  CALLFN(·call4194304, 4194304)
   481  CALLFN(·call8388608, 8388608)
   482  CALLFN(·call16777216, 16777216)
   483  CALLFN(·call33554432, 33554432)
   484  CALLFN(·call67108864, 67108864)
   485  CALLFN(·call134217728, 134217728)
   486  CALLFN(·call268435456, 268435456)
   487  CALLFN(·call536870912, 536870912)
   488  CALLFN(·call1073741824, 1073741824)
   489  
   490  TEXT 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.
   498  TEXT 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.
   514  TEXT ·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).
   537  g0:
   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  
   557  nosave:
   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.
   574  TEXT ·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.
   582  TEXT ·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  
   593  loadg:
   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)
   598  nocgo:
   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  
   612  needm:
   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  
   632  havem:
   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), R4
   660  	MOVV	R4, -(24+8)(R13) // "saved LR"; must match frame size
   661  	MOVV    fn+0(FP), R5
   662  	MOVV    frame+8(FP), R6
   663  	MOVV    ctxt+16(FP), R7
   664  	MOVV	$-(24+8)(R13), R3
   665  	MOVV    R5, 8(R3)
   666  	MOVV    R6, 16(R3)
   667  	MOVV    R7, 24(R3)
   668  	JAL	runtime·cgocallbackg(SB)
   669  
   670  	// Restore g->sched (== m->curg->sched) from saved values.
   671  	MOVV	0(R3), R4
   672  	MOVV	R4, (g_sched+gobuf_pc)(g)
   673  	MOVV	$(24+8)(R3), R13 // must match frame size
   674  	MOVV	R13, (g_sched+gobuf_sp)(g)
   675  
   676  	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   677  	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   678  	// so we do not have to restore it.)
   679  	MOVV	g_m(g), R12
   680  	MOVV	m_g0(R12), g
   681  	JAL	runtime·save_g(SB)
   682  	MOVV	(g_sched+gobuf_sp)(g), R3
   683  	MOVV	savedsp-24(SP), R13 // must match frame size
   684  	MOVV	R13, (g_sched+gobuf_sp)(g)
   685  
   686  	// If the m on entry was nil, we called needm above to borrow an m,
   687  	// 1. for the duration of the call on non-pthread platforms,
   688  	// 2. or the duration of the C thread alive on pthread platforms.
   689  	// If the m on entry wasn't nil,
   690  	// 1. the thread might be a Go thread,
   691  	// 2. or it wasn't the first call from a C thread on pthread platforms,
   692  	//    since then we skip dropm to resue the m in the first call.
   693  	MOVV	savedm-8(SP), R12
   694  	BNE	R12, droppedm
   695  
   696  	// Skip dropm to reuse it in the next call, when a pthread key has been created.
   697  	MOVV	_cgo_pthread_key_created(SB), R12
   698  	// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
   699  	BEQ	R12, dropm
   700  	MOVV    (R12), R12
   701  	BNE	R12, droppedm
   702  
   703  dropm:
   704  	MOVV	$runtime·dropm(SB), R4
   705  	JAL	(R4)
   706  droppedm:
   707  
   708  	// Done!
   709  	RET
   710  
   711  // void setg(G*); set g. for use by needm.
   712  TEXT runtime·setg(SB), NOSPLIT, $0-8
   713  	MOVV	gg+0(FP), g
   714  	// This only happens if iscgo, so jump straight to save_g
   715  	JAL	runtime·save_g(SB)
   716  	RET
   717  
   718  // void setg_gcc(G*); set g called from gcc with g in R4
   719  TEXT setg_gcc<>(SB),NOSPLIT,$0-0
   720  	MOVV	R4, g
   721  	JAL	runtime·save_g(SB)
   722  	RET
   723  
   724  TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   725  	MOVW	(R0), R0
   726  	UNDEF
   727  
   728  // AES hashing not implemented for loong64
   729  TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
   730  	JMP	runtime·memhashFallback<ABIInternal>(SB)
   731  TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
   732  	JMP	runtime·strhashFallback<ABIInternal>(SB)
   733  TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
   734  	JMP	runtime·memhash32Fallback<ABIInternal>(SB)
   735  TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
   736  	JMP	runtime·memhash64Fallback<ABIInternal>(SB)
   737  
   738  // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
   739  // Must obey the gcc calling convention.
   740  TEXT _cgo_topofstack(SB),NOSPLIT,$16
   741  	// g (R22) and REGTMP (R30)  might be clobbered by load_g. They
   742  	// are callee-save in the gcc calling convention, so save them.
   743  	MOVV	R30, savedREGTMP-16(SP)
   744  	MOVV	g, savedG-8(SP)
   745  
   746  	JAL	runtime·load_g(SB)
   747  	MOVV	g_m(g), R19
   748  	MOVV	m_curg(R19), R19
   749  	MOVV	(g_stack+stack_hi)(R19), R4 // return value in R4
   750  
   751  	MOVV	savedG-8(SP), g
   752  	MOVV	savedREGTMP-16(SP), R30
   753  	RET
   754  
   755  // The top-most function running on a goroutine
   756  // returns to goexit+PCQuantum.
   757  TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
   758  	NOOP
   759  	JAL	runtime·goexit1(SB)	// does not return
   760  	// traceback from goexit1 must hit code range of goexit
   761  	NOOP
   762  
   763  // This is called from .init_array and follows the platform, not Go, ABI.
   764  TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
   765  	ADDV	$-0x10, R3
   766  	MOVV	R30, 8(R3) // The access to global variables below implicitly uses R30, which is callee-save
   767  	MOVV	runtime·lastmoduledatap(SB), R12
   768  	MOVV	R4, moduledata_next(R12)
   769  	MOVV	R4, runtime·lastmoduledatap(SB)
   770  	MOVV	8(R3), R30
   771  	ADDV	$0x10, R3
   772  	RET
   773  
   774  TEXT ·checkASM(SB),NOSPLIT,$0-1
   775  	MOVW	$1, R19
   776  	MOVB	R19, ret+0(FP)
   777  	RET
   778  
   779  // spillArgs stores return values from registers to a *internal/abi.RegArgs in R25.
   780  TEXT ·spillArgs(SB),NOSPLIT,$0-0
   781  	MOVV	R4, (0*8)(R25)
   782  	MOVV	R5, (1*8)(R25)
   783  	MOVV	R6, (2*8)(R25)
   784  	MOVV	R7, (3*8)(R25)
   785  	MOVV	R8, (4*8)(R25)
   786  	MOVV	R9, (5*8)(R25)
   787  	MOVV	R10, (6*8)(R25)
   788  	MOVV	R11, (7*8)(R25)
   789  	MOVV	R12, (8*8)(R25)
   790  	MOVV	R13, (9*8)(R25)
   791  	MOVV	R14, (10*8)(R25)
   792  	MOVV	R15, (11*8)(R25)
   793  	MOVV	R16, (12*8)(R25)
   794  	MOVV	R17, (13*8)(R25)
   795  	MOVV	R18, (14*8)(R25)
   796  	MOVV	R19, (15*8)(R25)
   797  	MOVD	F0, (16*8)(R25)
   798  	MOVD	F1, (17*8)(R25)
   799  	MOVD	F2, (18*8)(R25)
   800  	MOVD	F3, (19*8)(R25)
   801  	MOVD	F4, (20*8)(R25)
   802  	MOVD	F5, (21*8)(R25)
   803  	MOVD	F6, (22*8)(R25)
   804  	MOVD	F7, (23*8)(R25)
   805  	MOVD	F8, (24*8)(R25)
   806  	MOVD	F9, (25*8)(R25)
   807  	MOVD	F10, (26*8)(R25)
   808  	MOVD	F11, (27*8)(R25)
   809  	MOVD	F12, (28*8)(R25)
   810  	MOVD	F13, (29*8)(R25)
   811  	MOVD	F14, (30*8)(R25)
   812  	MOVD	F15, (31*8)(R25)
   813  	RET
   814  
   815  // unspillArgs loads args into registers from a *internal/abi.RegArgs in R25.
   816  TEXT ·unspillArgs(SB),NOSPLIT,$0-0
   817  	MOVV	(0*8)(R25), R4
   818  	MOVV	(1*8)(R25), R5
   819  	MOVV	(2*8)(R25), R6
   820  	MOVV	(3*8)(R25), R7
   821  	MOVV	(4*8)(R25), R8
   822  	MOVV	(5*8)(R25), R9
   823  	MOVV	(6*8)(R25), R10
   824  	MOVV	(7*8)(R25), R11
   825  	MOVV	(8*8)(R25), R12
   826  	MOVV	(9*8)(R25), R13
   827  	MOVV	(10*8)(R25), R14
   828  	MOVV	(11*8)(R25), R15
   829  	MOVV	(12*8)(R25), R16
   830  	MOVV	(13*8)(R25), R17
   831  	MOVV	(14*8)(R25), R18
   832  	MOVV	(15*8)(R25), R19
   833  	MOVD	(16*8)(R25), F0
   834  	MOVD	(17*8)(R25), F1
   835  	MOVD	(18*8)(R25), F2
   836  	MOVD	(19*8)(R25), F3
   837  	MOVD	(20*8)(R25), F4
   838  	MOVD	(21*8)(R25), F5
   839  	MOVD	(22*8)(R25), F6
   840  	MOVD	(23*8)(R25), F7
   841  	MOVD	(24*8)(R25), F8
   842  	MOVD	(25*8)(R25), F9
   843  	MOVD	(26*8)(R25), F10
   844  	MOVD	(27*8)(R25), F11
   845  	MOVD	(28*8)(R25), F12
   846  	MOVD	(29*8)(R25), F13
   847  	MOVD	(30*8)(R25), F14
   848  	MOVD	(31*8)(R25), F15
   849  	RET
   850  
   851  // gcWriteBarrier informs the GC about heap pointer writes.
   852  //
   853  // gcWriteBarrier does NOT follow the Go ABI. It accepts the
   854  // number of bytes of buffer needed in R29, and returns a pointer
   855  // to the buffer space in R29.
   856  // It clobbers R30 (the linker temp register).
   857  // The act of CALLing gcWriteBarrier will clobber R1 (LR).
   858  // It does not clobber any other general-purpose registers,
   859  // but may clobber others (e.g., floating point registers).
   860  TEXT gcWriteBarrier<>(SB),NOSPLIT,$216
   861  	// Save the registers clobbered by the fast path.
   862  	MOVV	R19, 208(R3)
   863  	MOVV	R13, 216(R3)
   864  retry:
   865  	MOVV	g_m(g), R19
   866  	MOVV	m_p(R19), R19
   867  	MOVV	(p_wbBuf+wbBuf_next)(R19), R13
   868  	MOVV	(p_wbBuf+wbBuf_end)(R19), R30 // R30 is linker temp register
   869  	// Increment wbBuf.next position.
   870  	ADDV	R29, R13
   871  	// Is the buffer full?
   872  	BLTU	R30, R13, flush
   873  	// Commit to the larger buffer.
   874  	MOVV	R13, (p_wbBuf+wbBuf_next)(R19)
   875  	// Make return value (the original next position)
   876  	SUBV	R29, R13, R29
   877  	// Restore registers.
   878  	MOVV	208(R3), R19
   879  	MOVV	216(R3), R13
   880  	RET
   881  
   882  flush:
   883  	// Save all general purpose registers since these could be
   884  	// clobbered by wbBufFlush and were not saved by the caller.
   885  	MOVV	R27, 8(R3)
   886  	MOVV	R28, 16(R3)
   887  	// R1 is LR, which was saved by the prologue.
   888  	MOVV	R2, 24(R3)
   889  	// R3 is SP.
   890  	MOVV	R4, 32(R3)
   891  	MOVV	R5, 40(R3)
   892  	MOVV	R6, 48(R3)
   893  	MOVV	R7, 56(R3)
   894  	MOVV	R8, 64(R3)
   895  	MOVV	R9, 72(R3)
   896  	MOVV	R10, 80(R3)
   897  	MOVV	R11, 88(R3)
   898  	MOVV	R12, 96(R3)
   899  	// R13 already saved
   900  	MOVV	R14, 104(R3)
   901  	MOVV	R15, 112(R3)
   902  	MOVV	R16, 120(R3)
   903  	MOVV	R17, 128(R3)
   904  	MOVV	R18, 136(R3)
   905  	// R19 already saved
   906  	MOVV	R20, 144(R3)
   907  	MOVV	R21, 152(R3)
   908  	// R22 is g.
   909  	MOVV	R23, 160(R3)
   910  	MOVV	R24, 168(R3)
   911  	MOVV	R25, 176(R3)
   912  	MOVV	R26, 184(R3)
   913  	// R27 already saved
   914  	// R28 already saved.
   915  	MOVV	R29, 192(R3)
   916  	// R30 is tmp register.
   917  	MOVV	R31, 200(R3)
   918  
   919  	CALL	runtime·wbBufFlush(SB)
   920  
   921  	MOVV	8(R3), R27
   922  	MOVV	16(R3), R28
   923  	MOVV	24(R3), R2
   924  	MOVV	32(R3), R4
   925  	MOVV	40(R3), R5
   926  	MOVV	48(R3), R6
   927  	MOVV	56(R3), R7
   928  	MOVV	64(R3), R8
   929  	MOVV	72(R3), R9
   930  	MOVV	80(R3), R10
   931  	MOVV	88(R3), R11
   932  	MOVV	96(R3), R12
   933  	MOVV	104(R3), R14
   934  	MOVV	112(R3), R15
   935  	MOVV	120(R3), R16
   936  	MOVV	128(R3), R17
   937  	MOVV	136(R3), R18
   938  	MOVV	144(R3), R20
   939  	MOVV	152(R3), R21
   940  	MOVV	160(R3), R23
   941  	MOVV	168(R3), R24
   942  	MOVV	176(R3), R25
   943  	MOVV	184(R3), R26
   944  	MOVV	192(R3), R29
   945  	MOVV	200(R3), R31
   946  	JMP	retry
   947  
   948  TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
   949  	MOVV	$8, R29
   950  	JMP	gcWriteBarrier<>(SB)
   951  TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
   952  	MOVV	$16, R29
   953  	JMP	gcWriteBarrier<>(SB)
   954  TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
   955  	MOVV	$24, R29
   956  	JMP	gcWriteBarrier<>(SB)
   957  TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
   958  	MOVV	$32, R29
   959  	JMP	gcWriteBarrier<>(SB)
   960  TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
   961  	MOVV	$40, R29
   962  	JMP	gcWriteBarrier<>(SB)
   963  TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
   964  	MOVV	$48, R29
   965  	JMP	gcWriteBarrier<>(SB)
   966  TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
   967  	MOVV	$56, R29
   968  	JMP	gcWriteBarrier<>(SB)
   969  TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
   970  	MOVV	$64, R29
   971  	JMP	gcWriteBarrier<>(SB)
   972  
   973  DATA	debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
   974  GLOBL	debugCallFrameTooLarge<>(SB), RODATA, $20	// Size duplicated below
   975  
   976  // debugCallV2 is the entry point for debugger-injected function
   977  // calls on running goroutines. It informs the runtime that a
   978  // debug call has been injected and creates a call frame for the
   979  // debugger to fill in.
   980  //
   981  // To inject a function call, a debugger should:
   982  // 1. Check that the goroutine is in state _Grunning and that
   983  //    there are at least 280 bytes free on the stack.
   984  // 2. Set SP as SP-8.
   985  // 3. Store the current LR in (SP) (using the SP after step 2).
   986  // 4. Store the current PC in the LR register.
   987  // 5. Write the desired argument frame size at SP-8
   988  // 6. Save all machine registers so they can be restored later by the debugger.
   989  // 7. Set the PC to debugCallV2 and resume execution.
   990  //
   991  // If the goroutine is in state _Grunnable, then it's not generally
   992  // safe to inject a call because it may return out via other runtime
   993  // operations. Instead, the debugger should unwind the stack to find
   994  // the return to non-runtime code, add a temporary breakpoint there,
   995  // and inject the call once that breakpoint is hit.
   996  //
   997  // If the goroutine is in any other state, it's not safe to inject a call.
   998  //
   999  // This function communicates back to the debugger by setting R19 and
  1000  // invoking BREAK to raise a breakpoint signal. Note that the signal PC of
  1001  // the signal triggered by the BREAK instruction is the PC where the signal
  1002  // is trapped, not the next PC, so to resume execution, the debugger needs
  1003  // to set the signal PC to PC+4. See the comments in the implementation for
  1004  // the protocol the debugger is expected to follow. InjectDebugCall in the
  1005  // runtime tests demonstrates this protocol.
  1006  //
  1007  // The debugger must ensure that any pointers passed to the function
  1008  // obey escape analysis requirements. Specifically, it must not pass
  1009  // a stack pointer to an escaping argument. debugCallV2 cannot check
  1010  // this invariant.
  1011  //
  1012  // This is ABIInternal because Go code injects its PC directly into new
  1013  // goroutine stacks.
  1014  TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
  1015  	MOVV    R1, -272(R3)
  1016  	ADDV    $-272, R3
  1017  
  1018  	// We can't do anything that might clobber any of these
  1019  	// registers before this.
  1020  	MOVV    R2, (4*8)(R3)
  1021  	MOVV    R4, (5*8)(R3)
  1022  	MOVV    R5, (6*8)(R3)
  1023  	MOVV    R6, (7*8)(R3)
  1024  	MOVV    R7, (8*8)(R3)
  1025  	MOVV    R8, (9*8)(R3)
  1026  	MOVV    R9, (10*8)(R3)
  1027  	MOVV    R10, (11*8)(R3)
  1028  	MOVV    R11, (12*8)(R3)
  1029  	MOVV    R12, (13*8)(R3)
  1030  	MOVV    R13, (14*8)(R3)
  1031  	MOVV    R14, (15*8)(R3)
  1032  	MOVV    R15, (16*8)(R3)
  1033  	MOVV    R16, (17*8)(R3)
  1034  	MOVV    R17, (18*8)(R3)
  1035  	MOVV    R18, (19*8)(R3)
  1036  	MOVV    R19, (20*8)(R3)
  1037  	MOVV    R20, (21*8)(R3)
  1038  	MOVV    R21, (22*8)(R3)
  1039  	MOVV    g, (23*8)(R3)
  1040  	MOVV    R23, (24*8)(R3)
  1041  	MOVV    R24, (25*8)(R3)
  1042  	MOVV    R25, (26*8)(R3)
  1043  	MOVV    R26, (27*8)(R3)
  1044  	MOVV    R27, (28*8)(R3)
  1045  	MOVV    R28, (29*8)(R3)
  1046  	MOVV    R29, (30*8)(R3)
  1047  	MOVV    R30, (31*8)(R3)
  1048  	MOVV    R31, (32*8)(R3)
  1049  
  1050  	// Perform a safe-point check.
  1051  	MOVV    R1, 8(R3)
  1052  	CALL    runtime·debugCallCheck(SB)
  1053  	MOVV    16(R3), R30
  1054  	BEQ R30, good
  1055  
  1056  	// The safety check failed. Put the reason string at the top
  1057  	// of the stack.
  1058  	MOVV    R30, 8(R3)
  1059  
  1060  	MOVV    24(R3), R30
  1061  	MOVV    R30, 16(R3)
  1062  
  1063  	MOVV    $8, R19
  1064  	BREAK
  1065  	JMP restore
  1066  
  1067  good:
  1068  	// Registers are saved and it's safe to make a call.
  1069  	// Open up a call frame, moving the stack if necessary.
  1070  	//
  1071  	// Once the frame is allocated, this will set R19 to 0 and
  1072  	// invoke BREAK. The debugger should write the argument
  1073  	// frame for the call at SP+8, set up argument registers,
  1074  	// set the LR as the signal PC + 4, set the PC to the function
  1075  	// to call, set R29 to point to the closure (if a closure call),
  1076  	// and resume execution.
  1077  	//
  1078  	// If the function returns, this will set R19 to 1 and invoke
  1079  	// BREAK. The debugger can then inspect any return value saved
  1080  	// on the stack at SP+8 and in registers. To resume execution,
  1081  	// the debugger should restore the LR from (SP).
  1082  	//
  1083  	// If the function panics, this will set R19 to 2 and invoke BREAK.
  1084  	// The interface{} value of the panic will be at SP+8. The debugger
  1085  	// can inspect the panic value and resume execution again.
  1086  #define DEBUG_CALL_DISPATCH(NAME,MAXSIZE)	\
  1087  	MOVV    $MAXSIZE, R27;         \
  1088  	BLT R27, R30, 5(PC);            \
  1089  	MOVV    $NAME(SB), R28;			\
  1090  	MOVV    R28, 8(R3);			\
  1091  	CALL    runtime·debugCallWrap(SB);	\
  1092  	JMP restore
  1093  
  1094  	MOVV    264(R3), R30 // the argument frame size
  1095  	DEBUG_CALL_DISPATCH(debugCall32<>, 32)
  1096  	DEBUG_CALL_DISPATCH(debugCall64<>, 64)
  1097  	DEBUG_CALL_DISPATCH(debugCall128<>, 128)
  1098  	DEBUG_CALL_DISPATCH(debugCall256<>, 256)
  1099  	DEBUG_CALL_DISPATCH(debugCall512<>, 512)
  1100  	DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
  1101  	DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
  1102  	DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
  1103  	DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
  1104  	DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
  1105  	DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
  1106  	DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
  1107  	// The frame size is too large. Report the error.
  1108  	MOVV    $debugCallFrameTooLarge<>(SB), R30
  1109  	MOVV    R30, 8(R3)
  1110  	MOVV    $20, R30
  1111  	MOVV    R30, 16(R3) // length of debugCallFrameTooLarge string
  1112  	MOVV    $8, R19
  1113  	BREAK
  1114  	JMP restore
  1115  
  1116  restore:
  1117  	// Calls and failures resume here.
  1118  	//
  1119  	// Set R19 to 16 and invoke BREAK. The debugger should restore
  1120  	// all registers except for PC and SP and resume execution.
  1121  	MOVV    $16, R19
  1122  	BREAK
  1123  	// We must not modify flags after this point.
  1124  
  1125  	// Restore pointer-containing registers, which may have been
  1126  	// modified from the debugger's copy by stack copying.
  1127  	MOVV    (4*8)(R3), R2
  1128  	MOVV    (5*8)(R3), R4
  1129  	MOVV    (6*8)(R3), R5
  1130  	MOVV    (7*8)(R3), R6
  1131  	MOVV    (8*8)(R3), R7
  1132  	MOVV    (9*8)(R3), R8
  1133  	MOVV    (10*8)(R3), R9
  1134  	MOVV    (11*8)(R3), R10
  1135  	MOVV    (12*8)(R3), R11
  1136  	MOVV    (13*8)(R3), R12
  1137  	MOVV    (14*8)(R3), R13
  1138  	MOVV    (15*8)(R3), R14
  1139  	MOVV    (16*8)(R3), R15
  1140  	MOVV    (17*8)(R3), R16
  1141  	MOVV    (18*8)(R3), R17
  1142  	MOVV    (19*8)(R3), R18
  1143  	MOVV    (20*8)(R3), R19
  1144  	MOVV    (21*8)(R3), R20
  1145  	MOVV    (22*8)(R3), R21
  1146  	MOVV    (23*8)(R3), g
  1147  	MOVV    (24*8)(R3), R23
  1148  	MOVV    (25*8)(R3), R24
  1149  	MOVV    (26*8)(R3), R25
  1150  	MOVV    (27*8)(R3), R26
  1151  	MOVV    (28*8)(R3), R27
  1152  	MOVV    (29*8)(R3), R28
  1153  	MOVV    (30*8)(R3), R29
  1154  	MOVV    (31*8)(R3), R30
  1155  	MOVV    (32*8)(R3), R31
  1156  
  1157  	MOVV    0(R3), R30
  1158  	ADDV    $280, R3 // Add 8 more bytes, see saveSigContext
  1159  	MOVV    -8(R3), R1
  1160  	JMP (R30)
  1161  
  1162  // runtime.debugCallCheck assumes that functions defined with the
  1163  // DEBUG_CALL_FN macro are safe points to inject calls.
  1164  #define DEBUG_CALL_FN(NAME,MAXSIZE)		\
  1165  TEXT NAME(SB),WRAPPER,$MAXSIZE-0;		\
  1166  	NO_LOCAL_POINTERS;		\
  1167  	MOVV    $0, R19;		\
  1168  	BREAK;		\
  1169  	MOVV    $1, R19;		\
  1170  	BREAK;		\
  1171  	RET
  1172  DEBUG_CALL_FN(debugCall32<>, 32)
  1173  DEBUG_CALL_FN(debugCall64<>, 64)
  1174  DEBUG_CALL_FN(debugCall128<>, 128)
  1175  DEBUG_CALL_FN(debugCall256<>, 256)
  1176  DEBUG_CALL_FN(debugCall512<>, 512)
  1177  DEBUG_CALL_FN(debugCall1024<>, 1024)
  1178  DEBUG_CALL_FN(debugCall2048<>, 2048)
  1179  DEBUG_CALL_FN(debugCall4096<>, 4096)
  1180  DEBUG_CALL_FN(debugCall8192<>, 8192)
  1181  DEBUG_CALL_FN(debugCall16384<>, 16384)
  1182  DEBUG_CALL_FN(debugCall32768<>, 32768)
  1183  DEBUG_CALL_FN(debugCall65536<>, 65536)
  1184  
  1185  // func debugCallPanicked(val interface{})
  1186  TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
  1187  	// Copy the panic value to the top of stack at SP+8.
  1188  	MOVV    val_type+0(FP), R30
  1189  	MOVV    R30, 8(R3)
  1190  	MOVV    val_data+8(FP), R30
  1191  	MOVV    R30, 16(R3)
  1192  	MOVV    $2, R19
  1193  	BREAK
  1194  	RET
  1195  
  1196  TEXT runtime·panicBounds<ABIInternal>(SB),NOSPLIT,$144-0
  1197  	NO_LOCAL_POINTERS
  1198  	// Save all 16 int registers that could have an index in them.
  1199  	// They may be pointers, but if they are they are dead.
  1200  	// Skip R0 aka ZERO, R1 aka LR, R2 aka thread pointer, R3 aka SP.
  1201  	MOVV	R4, 24(R3)
  1202  	MOVV	R5, 32(R3)
  1203  	MOVV	R6, 40(R3)
  1204  	MOVV	R7, 48(R3)
  1205  	MOVV	R8, 56(R3)
  1206  	MOVV	R9, 64(R3)
  1207  	MOVV	R10, 72(R3)
  1208  	MOVV	R11, 80(R3)
  1209  	MOVV	R12, 88(R3)
  1210  	MOVV	R13, 96(R3)
  1211  	MOVV	R14, 104(R3)
  1212  	MOVV	R15, 112(R3)
  1213  	MOVV	R16, 120(R3)
  1214  	MOVV	R17, 128(R3)
  1215  	MOVV	R18, 136(R3)
  1216  	MOVV	R19, 144(R3)
  1217  
  1218  	MOVV	R1, R4		// PC immediately after call to panicBounds
  1219  	ADDV	$24, R3, R5	// pointer to save area
  1220  	CALL	runtime·panicBounds64<ABIInternal>(SB)
  1221  	RET
  1222  

View as plain text