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

View as plain text