...

Text file src/runtime/asm_loong64.s

Documentation: runtime

     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
    12TEXT 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
    39nocgo:
    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
    80DATA	runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
    81GLOBL	runtime·mainPC(SB),RODATA,$8
    82
    83TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
    84	BREAK
    85	RET
    86
    87TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
    88	RET
    89
    90TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
    91	JAL     runtime·mstart0(SB)
    92	RET // not reached
    93
    94// func cputicks() int64
    95TEXT 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
   105TEXT 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
   111TEXT 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.
   128TEXT 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()).
   155TEXT 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())
   161TEXT 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
   181switch:
   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
   204noswitch:
   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())
   214TEXT 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.
   248TEXT 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
   288TEXT 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
   313TEXT ·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)			\
   345TEXT 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;		\
   357loop16:;					\
   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;				\
   365copy16_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;		\
   374check8:;					\
   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.
   418TEXT 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
   428CALLFN(·call16, 16)
   429CALLFN(·call32, 32)
   430CALLFN(·call64, 64)
   431CALLFN(·call128, 128)
   432CALLFN(·call256, 256)
   433CALLFN(·call512, 512)
   434CALLFN(·call1024, 1024)
   435CALLFN(·call2048, 2048)
   436CALLFN(·call4096, 4096)
   437CALLFN(·call8192, 8192)
   438CALLFN(·call16384, 16384)
   439CALLFN(·call32768, 32768)
   440CALLFN(·call65536, 65536)
   441CALLFN(·call131072, 131072)
   442CALLFN(·call262144, 262144)
   443CALLFN(·call524288, 524288)
   444CALLFN(·call1048576, 1048576)
   445CALLFN(·call2097152, 2097152)
   446CALLFN(·call4194304, 4194304)
   447CALLFN(·call8388608, 8388608)
   448CALLFN(·call16777216, 16777216)
   449CALLFN(·call33554432, 33554432)
   450CALLFN(·call67108864, 67108864)
   451CALLFN(·call134217728, 134217728)
   452CALLFN(·call268435456, 268435456)
   453CALLFN(·call536870912, 536870912)
   454CALLFN(·call1073741824, 1073741824)
   455
   456TEXT 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.
   464TEXT 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.
   480TEXT ·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).
   502g0:
   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.
   524TEXT ·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
   535loadg:
   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)
   540nocgo:
   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
   554needm:
   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
   574havem:
   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
   645dropm:
   646	MOVV	$runtime·dropm(SB), R4
   647	JAL	(R4)
   648droppedm:
   649
   650	// Done!
   651	RET
   652
   653// void setg(G*); set g. for use by needm.
   654TEXT 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
   661TEXT setg_gcc<>(SB),NOSPLIT,$0-0
   662	MOVV	R4, g
   663	JAL	runtime·save_g(SB)
   664	RET
   665
   666TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   667	MOVW	(R0), R0
   668	UNDEF
   669
   670// AES hashing not implemented for loong64
   671TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
   672	JMP	runtime·memhashFallback<ABIInternal>(SB)
   673TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
   674	JMP	runtime·strhashFallback<ABIInternal>(SB)
   675TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
   676	JMP	runtime·memhash32Fallback<ABIInternal>(SB)
   677TEXT 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.
   682TEXT _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.
   699TEXT 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.
   706TEXT 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
   716TEXT ·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.
   722TEXT ·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.
   758TEXT ·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).
   802TEXT gcWriteBarrier<>(SB),NOSPLIT,$216
   803	// Save the registers clobbered by the fast path.
   804	MOVV	R19, 208(R3)
   805	MOVV	R13, 216(R3)
   806retry:
   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
   824flush:
   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
   890TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
   891	MOVV	$8, R29
   892	JMP	gcWriteBarrier<>(SB)
   893TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
   894	MOVV	$16, R29
   895	JMP	gcWriteBarrier<>(SB)
   896TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
   897	MOVV	$24, R29
   898	JMP	gcWriteBarrier<>(SB)
   899TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
   900	MOVV	$32, R29
   901	JMP	gcWriteBarrier<>(SB)
   902TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
   903	MOVV	$40, R29
   904	JMP	gcWriteBarrier<>(SB)
   905TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
   906	MOVV	$48, R29
   907	JMP	gcWriteBarrier<>(SB)
   908TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
   909	MOVV	$56, R29
   910	JMP	gcWriteBarrier<>(SB)
   911TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
   912	MOVV	$64, R29
   913	JMP	gcWriteBarrier<>(SB)
   914
   915DATA	debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
   916GLOBL	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.
   956TEXT 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
  1009good:
  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
  1058restore:
  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)		\
  1107TEXT NAME(SB),WRAPPER,$MAXSIZE-0;		\
  1108	NO_LOCAL_POINTERS;		\
  1109	MOVV    $0, R19;		\
  1110	BREAK;		\
  1111	MOVV    $1, R19;		\
  1112	BREAK;		\
  1113	RET
  1114DEBUG_CALL_FN(debugCall32<>, 32)
  1115DEBUG_CALL_FN(debugCall64<>, 64)
  1116DEBUG_CALL_FN(debugCall128<>, 128)
  1117DEBUG_CALL_FN(debugCall256<>, 256)
  1118DEBUG_CALL_FN(debugCall512<>, 512)
  1119DEBUG_CALL_FN(debugCall1024<>, 1024)
  1120DEBUG_CALL_FN(debugCall2048<>, 2048)
  1121DEBUG_CALL_FN(debugCall4096<>, 4096)
  1122DEBUG_CALL_FN(debugCall8192<>, 8192)
  1123DEBUG_CALL_FN(debugCall16384<>, 16384)
  1124DEBUG_CALL_FN(debugCall32768<>, 32768)
  1125DEBUG_CALL_FN(debugCall65536<>, 65536)
  1126
  1127// func debugCallPanicked(val interface{})
  1128TEXT 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.
  1143TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
  1144	MOVV	R20, R4
  1145	MOVV	R21, R5
  1146	JMP	runtime·goPanicIndex<ABIInternal>(SB)
  1147TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
  1148	MOVV	R20, R4
  1149	MOVV	R21, R5
  1150	JMP	runtime·goPanicIndexU<ABIInternal>(SB)
  1151TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
  1152	MOVV	R21, R4
  1153	MOVV	R23, R5
  1154	JMP	runtime·goPanicSliceAlen<ABIInternal>(SB)
  1155TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
  1156	MOVV	R21, R4
  1157	MOVV	R23, R5
  1158	JMP	runtime·goPanicSliceAlenU<ABIInternal>(SB)
  1159TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
  1160	MOVV	R21, R4
  1161	MOVV	R23, R5
  1162	JMP	runtime·goPanicSliceAcap<ABIInternal>(SB)
  1163TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
  1164	MOVV	R21, R4
  1165	MOVV	R23, R5
  1166	JMP	runtime·goPanicSliceAcapU<ABIInternal>(SB)
  1167TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
  1168	MOVV	R20, R4
  1169	MOVV	R21, R5
  1170	JMP	runtime·goPanicSliceB<ABIInternal>(SB)
  1171TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
  1172	MOVV	R20, R4
  1173	MOVV	R21, R5
  1174	JMP	runtime·goPanicSliceBU<ABIInternal>(SB)
  1175TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
  1176	MOVV	R23, R4
  1177	MOVV	R24, R5
  1178	JMP	runtime·goPanicSlice3Alen<ABIInternal>(SB)
  1179TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
  1180	MOVV	R23, R4
  1181	MOVV	R24, R5
  1182	JMP	runtime·goPanicSlice3AlenU<ABIInternal>(SB)
  1183TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
  1184	MOVV	R23, R4
  1185	MOVV	R24, R5
  1186	JMP	runtime·goPanicSlice3Acap<ABIInternal>(SB)
  1187TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
  1188	MOVV	R23, R4
  1189	MOVV	R24, R5
  1190	JMP	runtime·goPanicSlice3AcapU<ABIInternal>(SB)
  1191TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
  1192	MOVV	R21, R4
  1193	MOVV	R23, R5
  1194	JMP	runtime·goPanicSlice3B<ABIInternal>(SB)
  1195TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
  1196	MOVV	R21, R4
  1197	MOVV	R23, R5
  1198	JMP	runtime·goPanicSlice3BU<ABIInternal>(SB)
  1199TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
  1200	MOVV	R20, R4
  1201	MOVV	R21, R5
  1202	JMP	runtime·goPanicSlice3C<ABIInternal>(SB)
  1203TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
  1204	MOVV	R20, R4
  1205	MOVV	R21, R5
  1206	JMP	runtime·goPanicSlice3CU<ABIInternal>(SB)
  1207TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
  1208	MOVV	R23, R4
  1209	MOVV	R24, R5
  1210	JMP	runtime·goPanicSliceConvert<ABIInternal>(SB)

View as plain text