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

View as plain text