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

View as plain text