...

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	// update stackguard after _cgo_init
    41	MOVV	(g_stack+stack_lo)(g), R19
    42	ADDV	$const_stackGuard, R19
    43	MOVV	R19, g_stackguard0(g)
    44	MOVV	R19, g_stackguard1(g)
    45
    46	// set the per-goroutine and per-mach "registers"
    47	MOVV	$runtime·m0(SB), R19
    48
    49	// save m->g0 = g0
    50	MOVV	g, m_g0(R19)
    51	// save m0 to g0->m
    52	MOVV	R19, g_m(g)
    53
    54	JAL	runtime·check(SB)
    55
    56	// args are already prepared
    57	JAL	runtime·args(SB)
    58	JAL	runtime·osinit(SB)
    59	JAL	runtime·schedinit(SB)
    60
    61	// create a new goroutine to start program
    62	MOVV	$runtime·mainPC(SB), R19		// entry
    63	ADDV	$-16, R3
    64	MOVV	R19, 8(R3)
    65	MOVV	R0, 0(R3)
    66	JAL	runtime·newproc(SB)
    67	ADDV	$16, R3
    68
    69	// start this M
    70	JAL	runtime·mstart(SB)
    71
    72	// Prevent dead-code elimination of debugCallV2, which is
    73	// intended to be called by debuggers.
    74	MOVV	$runtime·debugCallV2<ABIInternal>(SB), R0
    75
    76	MOVV	R0, 1(R0)
    77	RET
    78
    79DATA	runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
    80GLOBL	runtime·mainPC(SB),RODATA,$8
    81
    82TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
    83	BREAK
    84	RET
    85
    86TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
    87	RET
    88
    89TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
    90	JAL     runtime·mstart0(SB)
    91	RET // not reached
    92
    93// func cputicks() int64
    94TEXT runtime·cputicks<ABIInternal>(SB),NOSPLIT,$0-8
    95	RDTIMED	R0, R4
    96	RET
    97
    98/*
    99 *  go-routine
   100 */
   101
   102// void gogo(Gobuf*)
   103// restore state from Gobuf; longjmp
   104TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
   105	MOVV	buf+0(FP), R4
   106	MOVV	gobuf_g(R4), R5
   107	MOVV	0(R5), R0	// make sure g != nil
   108	JMP	gogo<>(SB)
   109
   110TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
   111	MOVV	R5, g
   112	JAL	runtime·save_g(SB)
   113
   114	MOVV	gobuf_sp(R4), R3
   115	MOVV	gobuf_lr(R4), R1
   116	MOVV	gobuf_ret(R4), R19
   117	MOVV	gobuf_ctxt(R4), REGCTXT
   118	MOVV	R0, gobuf_sp(R4)
   119	MOVV	R0, gobuf_ret(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.
   129TEXT 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()).
   156TEXT 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())
   162TEXT 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
   182switch:
   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
   205noswitch:
   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())
   215TEXT 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.
   249TEXT 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
   289TEXT 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
   314TEXT ·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)			\
   346TEXT 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;		\
   358loop16:;					\
   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;				\
   366copy16_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;		\
   375check8:;					\
   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.
   419TEXT 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
   429CALLFN(·call16, 16)
   430CALLFN(·call32, 32)
   431CALLFN(·call64, 64)
   432CALLFN(·call128, 128)
   433CALLFN(·call256, 256)
   434CALLFN(·call512, 512)
   435CALLFN(·call1024, 1024)
   436CALLFN(·call2048, 2048)
   437CALLFN(·call4096, 4096)
   438CALLFN(·call8192, 8192)
   439CALLFN(·call16384, 16384)
   440CALLFN(·call32768, 32768)
   441CALLFN(·call65536, 65536)
   442CALLFN(·call131072, 131072)
   443CALLFN(·call262144, 262144)
   444CALLFN(·call524288, 524288)
   445CALLFN(·call1048576, 1048576)
   446CALLFN(·call2097152, 2097152)
   447CALLFN(·call4194304, 4194304)
   448CALLFN(·call8388608, 8388608)
   449CALLFN(·call16777216, 16777216)
   450CALLFN(·call33554432, 33554432)
   451CALLFN(·call67108864, 67108864)
   452CALLFN(·call134217728, 134217728)
   453CALLFN(·call268435456, 268435456)
   454CALLFN(·call536870912, 536870912)
   455CALLFN(·call1073741824, 1073741824)
   456
   457TEXT 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.
   465TEXT 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	MOVV	R0, (g_sched+gobuf_ret)(g)
   472	// Assert ctxt is zero. See func save.
   473	MOVV	(g_sched+gobuf_ctxt)(g), R19
   474	BEQ	R19, 2(PC)
   475	JAL	runtime·abort(SB)
   476	RET
   477
   478// func asmcgocall(fn, arg unsafe.Pointer) int32
   479// Call fn(arg) on the scheduler stack,
   480// aligned appropriately for the gcc ABI.
   481// See cgocall.go for more details.
   482TEXT ·asmcgocall(SB),NOSPLIT,$0-20
   483	MOVV	fn+0(FP), R25
   484	MOVV	arg+8(FP), R4
   485
   486	MOVV	R3, R12	// save original stack pointer
   487	MOVV	g, R13
   488
   489	// Figure out if we need to switch to m->g0 stack.
   490	// We get called to create new OS threads too, and those
   491	// come in on the m->g0 stack already.
   492	MOVV	g_m(g), R5
   493	MOVV	m_gsignal(R5), R6
   494	BEQ	R6, g, g0
   495	MOVV	m_g0(R5), R6
   496	BEQ	R6, g, g0
   497
   498	JAL	gosave_systemstack_switch<>(SB)
   499	MOVV	R6, g
   500	JAL	runtime·save_g(SB)
   501	MOVV	(g_sched+gobuf_sp)(g), R3
   502
   503	// Now on a scheduling stack (a pthread-created stack).
   504g0:
   505	// Save room for two of our pointers.
   506	ADDV	$-16, R3
   507	MOVV	R13, 0(R3)	// save old g on stack
   508	MOVV	(g_stack+stack_hi)(R13), R13
   509	SUBVU	R12, R13
   510	MOVV	R13, 8(R3)	// save depth in old g stack (can't just save SP, as stack might be copied during a callback)
   511	JAL	(R25)
   512
   513	// Restore g, stack pointer. R4 is return value.
   514	MOVV	0(R3), g
   515	JAL	runtime·save_g(SB)
   516	MOVV	(g_stack+stack_hi)(g), R5
   517	MOVV	8(R3), R6
   518	SUBVU	R6, R5
   519	MOVV	R5, R3
   520
   521	MOVW	R4, ret+16(FP)
   522	RET
   523
   524// func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
   525// See cgocall.go for more details.
   526TEXT ·cgocallback(SB),NOSPLIT,$24-24
   527	NO_LOCAL_POINTERS
   528
   529	// Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
   530	// It is used to dropm while thread is exiting.
   531	MOVV    fn+0(FP), R5
   532	BNE	R5, loadg
   533	// Restore the g from frame.
   534	MOVV    frame+8(FP), g
   535	JMP	dropm
   536
   537loadg:
   538	// Load m and g from thread-local storage.
   539	MOVB	runtime·iscgo(SB), R19
   540	BEQ	R19, nocgo
   541	JAL	runtime·load_g(SB)
   542nocgo:
   543
   544	// If g is nil, Go did not create the current thread,
   545	// or if this thread never called into Go on pthread platforms.
   546	// Call needm to obtain one for temporary use.
   547	// In this case, we're running on the thread stack, so there's
   548	// lots of space, but the linker doesn't know. Hide the call from
   549	// the linker analysis by using an indirect call.
   550	BEQ	g, needm
   551
   552	MOVV	g_m(g), R12
   553	MOVV	R12, savedm-8(SP)
   554	JMP	havem
   555
   556needm:
   557	MOVV	g, savedm-8(SP) // g is zero, so is m.
   558	MOVV	$runtime·needAndBindM(SB), R4
   559	JAL	(R4)
   560
   561	// Set m->sched.sp = SP, so that if a panic happens
   562	// during the function we are about to execute, it will
   563	// have a valid SP to run on the g0 stack.
   564	// The next few lines (after the havem label)
   565	// will save this SP onto the stack and then write
   566	// the same SP back to m->sched.sp. That seems redundant,
   567	// but if an unrecovered panic happens, unwindm will
   568	// restore the g->sched.sp from the stack location
   569	// and then systemstack will try to use it. If we don't set it here,
   570	// that restored SP will be uninitialized (typically 0) and
   571	// will not be usable.
   572	MOVV	g_m(g), R12
   573	MOVV	m_g0(R12), R19
   574	MOVV	R3, (g_sched+gobuf_sp)(R19)
   575
   576havem:
   577	// Now there's a valid m, and we're running on its m->g0.
   578	// Save current m->g0->sched.sp on stack and then set it to SP.
   579	// Save current sp in m->g0->sched.sp in preparation for
   580	// switch back to m->curg stack.
   581	// NOTE: unwindm knows that the saved g->sched.sp is at 8(R29) aka savedsp-16(SP).
   582	MOVV	m_g0(R12), R19
   583	MOVV	(g_sched+gobuf_sp)(R19), R13
   584	MOVV	R13, savedsp-24(SP) // must match frame size
   585	MOVV	R3, (g_sched+gobuf_sp)(R19)
   586
   587	// Switch to m->curg stack and call runtime.cgocallbackg.
   588	// Because we are taking over the execution of m->curg
   589	// but *not* resuming what had been running, we need to
   590	// save that information (m->curg->sched) so we can restore it.
   591	// We can restore m->curg->sched.sp easily, because calling
   592	// runtime.cgocallbackg leaves SP unchanged upon return.
   593	// To save m->curg->sched.pc, we push it onto the stack.
   594	// This has the added benefit that it looks to the traceback
   595	// routine like cgocallbackg is going to return to that
   596	// PC (because the frame we allocate below has the same
   597	// size as cgocallback_gofunc's frame declared above)
   598	// so that the traceback will seamlessly trace back into
   599	// the earlier calls.
   600	MOVV	m_curg(R12), g
   601	JAL	runtime·save_g(SB)
   602	MOVV	(g_sched+gobuf_sp)(g), R13 // prepare stack as R13
   603	MOVV	(g_sched+gobuf_pc)(g), R4
   604	MOVV	R4, -(24+8)(R13) // "saved LR"; must match frame size
   605	MOVV    fn+0(FP), R5
   606	MOVV    frame+8(FP), R6
   607	MOVV    ctxt+16(FP), R7
   608	MOVV	$-(24+8)(R13), R3
   609	MOVV    R5, 8(R3)
   610	MOVV    R6, 16(R3)
   611	MOVV    R7, 24(R3)
   612	JAL	runtime·cgocallbackg(SB)
   613
   614	// Restore g->sched (== m->curg->sched) from saved values.
   615	MOVV	0(R3), R4
   616	MOVV	R4, (g_sched+gobuf_pc)(g)
   617	MOVV	$(24+8)(R3), R13 // must match frame size
   618	MOVV	R13, (g_sched+gobuf_sp)(g)
   619
   620	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   621	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   622	// so we do not have to restore it.)
   623	MOVV	g_m(g), R12
   624	MOVV	m_g0(R12), g
   625	JAL	runtime·save_g(SB)
   626	MOVV	(g_sched+gobuf_sp)(g), R3
   627	MOVV	savedsp-24(SP), R13 // must match frame size
   628	MOVV	R13, (g_sched+gobuf_sp)(g)
   629
   630	// If the m on entry was nil, we called needm above to borrow an m,
   631	// 1. for the duration of the call on non-pthread platforms,
   632	// 2. or the duration of the C thread alive on pthread platforms.
   633	// If the m on entry wasn't nil,
   634	// 1. the thread might be a Go thread,
   635	// 2. or it wasn't the first call from a C thread on pthread platforms,
   636	//    since then we skip dropm to resue the m in the first call.
   637	MOVV	savedm-8(SP), R12
   638	BNE	R12, droppedm
   639
   640	// Skip dropm to reuse it in the next call, when a pthread key has been created.
   641	MOVV	_cgo_pthread_key_created(SB), R12
   642	// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
   643	BEQ	R12, dropm
   644	MOVV    (R12), R12
   645	BNE	R12, droppedm
   646
   647dropm:
   648	MOVV	$runtime·dropm(SB), R4
   649	JAL	(R4)
   650droppedm:
   651
   652	// Done!
   653	RET
   654
   655// void setg(G*); set g. for use by needm.
   656TEXT runtime·setg(SB), NOSPLIT, $0-8
   657	MOVV	gg+0(FP), g
   658	// This only happens if iscgo, so jump straight to save_g
   659	JAL	runtime·save_g(SB)
   660	RET
   661
   662// void setg_gcc(G*); set g called from gcc with g in R19
   663TEXT setg_gcc<>(SB),NOSPLIT,$0-0
   664	MOVV	R19, g
   665	JAL	runtime·save_g(SB)
   666	RET
   667
   668TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   669	MOVW	(R0), R0
   670	UNDEF
   671
   672// AES hashing not implemented for loong64
   673TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
   674	JMP	runtime·memhashFallback<ABIInternal>(SB)
   675TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
   676	JMP	runtime·strhashFallback<ABIInternal>(SB)
   677TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
   678	JMP	runtime·memhash32Fallback<ABIInternal>(SB)
   679TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
   680	JMP	runtime·memhash64Fallback<ABIInternal>(SB)
   681
   682TEXT runtime·return0(SB), NOSPLIT, $0
   683	MOVW	$0, R19
   684	RET
   685
   686// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
   687// Must obey the gcc calling convention.
   688TEXT _cgo_topofstack(SB),NOSPLIT,$16
   689	// g (R22) and REGTMP (R30)  might be clobbered by load_g. They
   690	// are callee-save in the gcc calling convention, so save them.
   691	MOVV	R30, savedREGTMP-16(SP)
   692	MOVV	g, savedG-8(SP)
   693
   694	JAL	runtime·load_g(SB)
   695	MOVV	g_m(g), R19
   696	MOVV	m_curg(R19), R19
   697	MOVV	(g_stack+stack_hi)(R19), R4 // return value in R4
   698
   699	MOVV	savedG-8(SP), g
   700	MOVV	savedREGTMP-16(SP), R30
   701	RET
   702
   703// The top-most function running on a goroutine
   704// returns to goexit+PCQuantum.
   705TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
   706	NOOP
   707	JAL	runtime·goexit1(SB)	// does not return
   708	// traceback from goexit1 must hit code range of goexit
   709	NOOP
   710
   711// This is called from .init_array and follows the platform, not Go, ABI.
   712TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
   713	ADDV	$-0x10, R3
   714	MOVV	R30, 8(R3) // The access to global variables below implicitly uses R30, which is callee-save
   715	MOVV	runtime·lastmoduledatap(SB), R12
   716	MOVV	R4, moduledata_next(R12)
   717	MOVV	R4, runtime·lastmoduledatap(SB)
   718	MOVV	8(R3), R30
   719	ADDV	$0x10, R3
   720	RET
   721
   722TEXT ·checkASM(SB),NOSPLIT,$0-1
   723	MOVW	$1, R19
   724	MOVB	R19, ret+0(FP)
   725	RET
   726
   727// spillArgs stores return values from registers to a *internal/abi.RegArgs in R25.
   728TEXT ·spillArgs(SB),NOSPLIT,$0-0
   729	MOVV	R4, (0*8)(R25)
   730	MOVV	R5, (1*8)(R25)
   731	MOVV	R6, (2*8)(R25)
   732	MOVV	R7, (3*8)(R25)
   733	MOVV	R8, (4*8)(R25)
   734	MOVV	R9, (5*8)(R25)
   735	MOVV	R10, (6*8)(R25)
   736	MOVV	R11, (7*8)(R25)
   737	MOVV	R12, (8*8)(R25)
   738	MOVV	R13, (9*8)(R25)
   739	MOVV	R14, (10*8)(R25)
   740	MOVV	R15, (11*8)(R25)
   741	MOVV	R16, (12*8)(R25)
   742	MOVV	R17, (13*8)(R25)
   743	MOVV	R18, (14*8)(R25)
   744	MOVV	R19, (15*8)(R25)
   745	MOVD	F0, (16*8)(R25)
   746	MOVD	F1, (17*8)(R25)
   747	MOVD	F2, (18*8)(R25)
   748	MOVD	F3, (19*8)(R25)
   749	MOVD	F4, (20*8)(R25)
   750	MOVD	F5, (21*8)(R25)
   751	MOVD	F6, (22*8)(R25)
   752	MOVD	F7, (23*8)(R25)
   753	MOVD	F8, (24*8)(R25)
   754	MOVD	F9, (25*8)(R25)
   755	MOVD	F10, (26*8)(R25)
   756	MOVD	F11, (27*8)(R25)
   757	MOVD	F12, (28*8)(R25)
   758	MOVD	F13, (29*8)(R25)
   759	MOVD	F14, (30*8)(R25)
   760	MOVD	F15, (31*8)(R25)
   761	RET
   762
   763// unspillArgs loads args into registers from a *internal/abi.RegArgs in R25.
   764TEXT ·unspillArgs(SB),NOSPLIT,$0-0
   765	MOVV	(0*8)(R25), R4
   766	MOVV	(1*8)(R25), R5
   767	MOVV	(2*8)(R25), R6
   768	MOVV	(3*8)(R25), R7
   769	MOVV	(4*8)(R25), R8
   770	MOVV	(5*8)(R25), R9
   771	MOVV	(6*8)(R25), R10
   772	MOVV	(7*8)(R25), R11
   773	MOVV	(8*8)(R25), R12
   774	MOVV	(9*8)(R25), R13
   775	MOVV	(10*8)(R25), R14
   776	MOVV	(11*8)(R25), R15
   777	MOVV	(12*8)(R25), R16
   778	MOVV	(13*8)(R25), R17
   779	MOVV	(14*8)(R25), R18
   780	MOVV	(15*8)(R25), R19
   781	MOVD	(16*8)(R25), F0
   782	MOVD	(17*8)(R25), F1
   783	MOVD	(18*8)(R25), F2
   784	MOVD	(19*8)(R25), F3
   785	MOVD	(20*8)(R25), F4
   786	MOVD	(21*8)(R25), F5
   787	MOVD	(22*8)(R25), F6
   788	MOVD	(23*8)(R25), F7
   789	MOVD	(24*8)(R25), F8
   790	MOVD	(25*8)(R25), F9
   791	MOVD	(26*8)(R25), F10
   792	MOVD	(27*8)(R25), F11
   793	MOVD	(28*8)(R25), F12
   794	MOVD	(29*8)(R25), F13
   795	MOVD	(30*8)(R25), F14
   796	MOVD	(31*8)(R25), F15
   797	RET
   798
   799// gcWriteBarrier informs the GC about heap pointer writes.
   800//
   801// gcWriteBarrier does NOT follow the Go ABI. It accepts the
   802// number of bytes of buffer needed in R29, and returns a pointer
   803// to the buffer space in R29.
   804// It clobbers R30 (the linker temp register).
   805// The act of CALLing gcWriteBarrier will clobber R1 (LR).
   806// It does not clobber any other general-purpose registers,
   807// but may clobber others (e.g., floating point registers).
   808TEXT gcWriteBarrier<>(SB),NOSPLIT,$216
   809	// Save the registers clobbered by the fast path.
   810	MOVV	R19, 208(R3)
   811	MOVV	R13, 216(R3)
   812retry:
   813	MOVV	g_m(g), R19
   814	MOVV	m_p(R19), R19
   815	MOVV	(p_wbBuf+wbBuf_next)(R19), R13
   816	MOVV	(p_wbBuf+wbBuf_end)(R19), R30 // R30 is linker temp register
   817	// Increment wbBuf.next position.
   818	ADDV	R29, R13
   819	// Is the buffer full?
   820	BLTU	R30, R13, flush
   821	// Commit to the larger buffer.
   822	MOVV	R13, (p_wbBuf+wbBuf_next)(R19)
   823	// Make return value (the original next position)
   824	SUBV	R29, R13, R29
   825	// Restore registers.
   826	MOVV	208(R3), R19
   827	MOVV	216(R3), R13
   828	RET
   829
   830flush:
   831	// Save all general purpose registers since these could be
   832	// clobbered by wbBufFlush and were not saved by the caller.
   833	MOVV	R27, 8(R3)
   834	MOVV	R28, 16(R3)
   835	// R1 is LR, which was saved by the prologue.
   836	MOVV	R2, 24(R3)
   837	// R3 is SP.
   838	MOVV	R4, 32(R3)
   839	MOVV	R5, 40(R3)
   840	MOVV	R6, 48(R3)
   841	MOVV	R7, 56(R3)
   842	MOVV	R8, 64(R3)
   843	MOVV	R9, 72(R3)
   844	MOVV	R10, 80(R3)
   845	MOVV	R11, 88(R3)
   846	MOVV	R12, 96(R3)
   847	// R13 already saved
   848	MOVV	R14, 104(R3)
   849	MOVV	R15, 112(R3)
   850	MOVV	R16, 120(R3)
   851	MOVV	R17, 128(R3)
   852	MOVV	R18, 136(R3)
   853	// R19 already saved
   854	MOVV	R20, 144(R3)
   855	MOVV	R21, 152(R3)
   856	// R22 is g.
   857	MOVV	R23, 160(R3)
   858	MOVV	R24, 168(R3)
   859	MOVV	R25, 176(R3)
   860	MOVV	R26, 184(R3)
   861	// R27 already saved
   862	// R28 already saved.
   863	MOVV	R29, 192(R3)
   864	// R30 is tmp register.
   865	MOVV	R31, 200(R3)
   866
   867	CALL	runtime·wbBufFlush(SB)
   868
   869	MOVV	8(R3), R27
   870	MOVV	16(R3), R28
   871	MOVV	24(R3), R2
   872	MOVV	32(R3), R4
   873	MOVV	40(R3), R5
   874	MOVV	48(R3), R6
   875	MOVV	56(R3), R7
   876	MOVV	64(R3), R8
   877	MOVV	72(R3), R9
   878	MOVV	80(R3), R10
   879	MOVV	88(R3), R11
   880	MOVV	96(R3), R12
   881	MOVV	104(R3), R14
   882	MOVV	112(R3), R15
   883	MOVV	120(R3), R16
   884	MOVV	128(R3), R17
   885	MOVV	136(R3), R18
   886	MOVV	144(R3), R20
   887	MOVV	152(R3), R21
   888	MOVV	160(R3), R23
   889	MOVV	168(R3), R24
   890	MOVV	176(R3), R25
   891	MOVV	184(R3), R26
   892	MOVV	192(R3), R29
   893	MOVV	200(R3), R31
   894	JMP	retry
   895
   896TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
   897	MOVV	$8, R29
   898	JMP	gcWriteBarrier<>(SB)
   899TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
   900	MOVV	$16, R29
   901	JMP	gcWriteBarrier<>(SB)
   902TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
   903	MOVV	$24, R29
   904	JMP	gcWriteBarrier<>(SB)
   905TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
   906	MOVV	$32, R29
   907	JMP	gcWriteBarrier<>(SB)
   908TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
   909	MOVV	$40, R29
   910	JMP	gcWriteBarrier<>(SB)
   911TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
   912	MOVV	$48, R29
   913	JMP	gcWriteBarrier<>(SB)
   914TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
   915	MOVV	$56, R29
   916	JMP	gcWriteBarrier<>(SB)
   917TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
   918	MOVV	$64, R29
   919	JMP	gcWriteBarrier<>(SB)
   920
   921DATA	debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
   922GLOBL	debugCallFrameTooLarge<>(SB), RODATA, $20	// Size duplicated below
   923
   924// debugCallV2 is the entry point for debugger-injected function
   925// calls on running goroutines. It informs the runtime that a
   926// debug call has been injected and creates a call frame for the
   927// debugger to fill in.
   928//
   929// To inject a function call, a debugger should:
   930// 1. Check that the goroutine is in state _Grunning and that
   931//    there are at least 280 bytes free on the stack.
   932// 2. Set SP as SP-8.
   933// 3. Store the current LR in (SP) (using the SP after step 2).
   934// 4. Store the current PC in the LR register.
   935// 5. Write the desired argument frame size at SP-8
   936// 6. Save all machine registers so they can be restored later by the debugger.
   937// 7. Set the PC to debugCallV2 and resume execution.
   938//
   939// If the goroutine is in state _Grunnable, then it's not generally
   940// safe to inject a call because it may return out via other runtime
   941// operations. Instead, the debugger should unwind the stack to find
   942// the return to non-runtime code, add a temporary breakpoint there,
   943// and inject the call once that breakpoint is hit.
   944//
   945// If the goroutine is in any other state, it's not safe to inject a call.
   946//
   947// This function communicates back to the debugger by setting R19 and
   948// invoking BREAK to raise a breakpoint signal. Note that the signal PC of
   949// the signal triggered by the BREAK instruction is the PC where the signal
   950// is trapped, not the next PC, so to resume execution, the debugger needs
   951// to set the signal PC to PC+4. See the comments in the implementation for
   952// the protocol the debugger is expected to follow. InjectDebugCall in the
   953// runtime tests demonstrates this protocol.
   954//
   955// The debugger must ensure that any pointers passed to the function
   956// obey escape analysis requirements. Specifically, it must not pass
   957// a stack pointer to an escaping argument. debugCallV2 cannot check
   958// this invariant.
   959//
   960// This is ABIInternal because Go code injects its PC directly into new
   961// goroutine stacks.
   962TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
   963	MOVV    R1, -272(R3)
   964	ADDV    $-272, R3
   965
   966	// We can't do anything that might clobber any of these
   967	// registers before this.
   968	MOVV    R2, (4*8)(R3)
   969	MOVV    R4, (5*8)(R3)
   970	MOVV    R5, (6*8)(R3)
   971	MOVV    R6, (7*8)(R3)
   972	MOVV    R7, (8*8)(R3)
   973	MOVV    R8, (9*8)(R3)
   974	MOVV    R9, (10*8)(R3)
   975	MOVV    R10, (11*8)(R3)
   976	MOVV    R11, (12*8)(R3)
   977	MOVV    R12, (13*8)(R3)
   978	MOVV    R13, (14*8)(R3)
   979	MOVV    R14, (15*8)(R3)
   980	MOVV    R15, (16*8)(R3)
   981	MOVV    R16, (17*8)(R3)
   982	MOVV    R17, (18*8)(R3)
   983	MOVV    R18, (19*8)(R3)
   984	MOVV    R19, (20*8)(R3)
   985	MOVV    R20, (21*8)(R3)
   986	MOVV    R21, (22*8)(R3)
   987	MOVV    g, (23*8)(R3)
   988	MOVV    R23, (24*8)(R3)
   989	MOVV    R24, (25*8)(R3)
   990	MOVV    R25, (26*8)(R3)
   991	MOVV    R26, (27*8)(R3)
   992	MOVV    R27, (28*8)(R3)
   993	MOVV    R28, (29*8)(R3)
   994	MOVV    R29, (30*8)(R3)
   995	MOVV    R30, (31*8)(R3)
   996	MOVV    R31, (32*8)(R3)
   997
   998	// Perform a safe-point check.
   999	MOVV    R1, 8(R3)
  1000	CALL    runtime·debugCallCheck(SB)
  1001	MOVV    16(R3), R30
  1002	BEQ R30, good
  1003
  1004	// The safety check failed. Put the reason string at the top
  1005	// of the stack.
  1006	MOVV    R30, 8(R3)
  1007
  1008	MOVV    24(R3), R30
  1009	MOVV    R30, 16(R3)
  1010
  1011	MOVV    $8, R19
  1012	BREAK
  1013	JMP restore
  1014
  1015good:
  1016	// Registers are saved and it's safe to make a call.
  1017	// Open up a call frame, moving the stack if necessary.
  1018	//
  1019	// Once the frame is allocated, this will set R19 to 0 and
  1020	// invoke BREAK. The debugger should write the argument
  1021	// frame for the call at SP+8, set up argument registers,
  1022	// set the LR as the signal PC + 4, set the PC to the function
  1023	// to call, set R29 to point to the closure (if a closure call),
  1024	// and resume execution.
  1025	//
  1026	// If the function returns, this will set R19 to 1 and invoke
  1027	// BREAK. The debugger can then inspect any return value saved
  1028	// on the stack at SP+8 and in registers. To resume execution,
  1029	// the debugger should restore the LR from (SP).
  1030	//
  1031	// If the function panics, this will set R19 to 2 and invoke BREAK.
  1032	// The interface{} value of the panic will be at SP+8. The debugger
  1033	// can inspect the panic value and resume execution again.
  1034#define DEBUG_CALL_DISPATCH(NAME,MAXSIZE)	\
  1035	MOVV    $MAXSIZE, R27;         \
  1036	BLT R27, R30, 5(PC);            \
  1037	MOVV    $NAME(SB), R28;			\
  1038	MOVV    R28, 8(R3);			\
  1039	CALL    runtime·debugCallWrap(SB);	\
  1040	JMP restore
  1041
  1042	MOVV    264(R3), R30 // the argument frame size
  1043	DEBUG_CALL_DISPATCH(debugCall32<>, 32)
  1044	DEBUG_CALL_DISPATCH(debugCall64<>, 64)
  1045	DEBUG_CALL_DISPATCH(debugCall128<>, 128)
  1046	DEBUG_CALL_DISPATCH(debugCall256<>, 256)
  1047	DEBUG_CALL_DISPATCH(debugCall512<>, 512)
  1048	DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
  1049	DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
  1050	DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
  1051	DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
  1052	DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
  1053	DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
  1054	DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
  1055	// The frame size is too large. Report the error.
  1056	MOVV    $debugCallFrameTooLarge<>(SB), R30
  1057	MOVV    R30, 8(R3)
  1058	MOVV    $20, R30
  1059	MOVV    R30, 16(R3) // length of debugCallFrameTooLarge string
  1060	MOVV    $8, R19
  1061	BREAK
  1062	JMP restore
  1063
  1064restore:
  1065	// Calls and failures resume here.
  1066	//
  1067	// Set R19 to 16 and invoke BREAK. The debugger should restore
  1068	// all registers except for PC and SP and resume execution.
  1069	MOVV    $16, R19
  1070	BREAK
  1071	// We must not modify flags after this point.
  1072
  1073	// Restore pointer-containing registers, which may have been
  1074	// modified from the debugger's copy by stack copying.
  1075	MOVV    (4*8)(R3), R2
  1076	MOVV    (5*8)(R3), R4
  1077	MOVV    (6*8)(R3), R5
  1078	MOVV    (7*8)(R3), R6
  1079	MOVV    (8*8)(R3), R7
  1080	MOVV    (9*8)(R3), R8
  1081	MOVV    (10*8)(R3), R9
  1082	MOVV    (11*8)(R3), R10
  1083	MOVV    (12*8)(R3), R11
  1084	MOVV    (13*8)(R3), R12
  1085	MOVV    (14*8)(R3), R13
  1086	MOVV    (15*8)(R3), R14
  1087	MOVV    (16*8)(R3), R15
  1088	MOVV    (17*8)(R3), R16
  1089	MOVV    (18*8)(R3), R17
  1090	MOVV    (19*8)(R3), R18
  1091	MOVV    (20*8)(R3), R19
  1092	MOVV    (21*8)(R3), R20
  1093	MOVV    (22*8)(R3), R21
  1094	MOVV    (23*8)(R3), g
  1095	MOVV    (24*8)(R3), R23
  1096	MOVV    (25*8)(R3), R24
  1097	MOVV    (26*8)(R3), R25
  1098	MOVV    (27*8)(R3), R26
  1099	MOVV    (28*8)(R3), R27
  1100	MOVV    (29*8)(R3), R28
  1101	MOVV    (30*8)(R3), R29
  1102	MOVV    (31*8)(R3), R30
  1103	MOVV    (32*8)(R3), R31
  1104
  1105	MOVV    0(R3), R30
  1106	ADDV    $280, R3 // Add 8 more bytes, see saveSigContext
  1107	MOVV    -8(R3), R1
  1108	JMP (R30)
  1109
  1110// runtime.debugCallCheck assumes that functions defined with the
  1111// DEBUG_CALL_FN macro are safe points to inject calls.
  1112#define DEBUG_CALL_FN(NAME,MAXSIZE)		\
  1113TEXT NAME(SB),WRAPPER,$MAXSIZE-0;		\
  1114	NO_LOCAL_POINTERS;		\
  1115	MOVV    $0, R19;		\
  1116	BREAK;		\
  1117	MOVV    $1, R19;		\
  1118	BREAK;		\
  1119	RET
  1120DEBUG_CALL_FN(debugCall32<>, 32)
  1121DEBUG_CALL_FN(debugCall64<>, 64)
  1122DEBUG_CALL_FN(debugCall128<>, 128)
  1123DEBUG_CALL_FN(debugCall256<>, 256)
  1124DEBUG_CALL_FN(debugCall512<>, 512)
  1125DEBUG_CALL_FN(debugCall1024<>, 1024)
  1126DEBUG_CALL_FN(debugCall2048<>, 2048)
  1127DEBUG_CALL_FN(debugCall4096<>, 4096)
  1128DEBUG_CALL_FN(debugCall8192<>, 8192)
  1129DEBUG_CALL_FN(debugCall16384<>, 16384)
  1130DEBUG_CALL_FN(debugCall32768<>, 32768)
  1131DEBUG_CALL_FN(debugCall65536<>, 65536)
  1132
  1133// func debugCallPanicked(val interface{})
  1134TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
  1135	// Copy the panic value to the top of stack at SP+8.
  1136	MOVV    val_type+0(FP), R30
  1137	MOVV    R30, 8(R3)
  1138	MOVV    val_data+8(FP), R30
  1139	MOVV    R30, 16(R3)
  1140	MOVV    $2, R19
  1141	BREAK
  1142	RET
  1143
  1144// Note: these functions use a special calling convention to save generated code space.
  1145// Arguments are passed in registers, but the space for those arguments are allocated
  1146// in the caller's stack frame. These stubs write the args into that stack space and
  1147// then tail call to the corresponding runtime handler.
  1148// The tail call makes these stubs disappear in backtraces.
  1149TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
  1150	MOVV	R20, R4
  1151	MOVV	R21, R5
  1152	JMP	runtime·goPanicIndex<ABIInternal>(SB)
  1153TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
  1154	MOVV	R20, R4
  1155	MOVV	R21, R5
  1156	JMP	runtime·goPanicIndexU<ABIInternal>(SB)
  1157TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
  1158	MOVV	R21, R4
  1159	MOVV	R23, R5
  1160	JMP	runtime·goPanicSliceAlen<ABIInternal>(SB)
  1161TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
  1162	MOVV	R21, R4
  1163	MOVV	R23, R5
  1164	JMP	runtime·goPanicSliceAlenU<ABIInternal>(SB)
  1165TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
  1166	MOVV	R21, R4
  1167	MOVV	R23, R5
  1168	JMP	runtime·goPanicSliceAcap<ABIInternal>(SB)
  1169TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
  1170	MOVV	R21, R4
  1171	MOVV	R23, R5
  1172	JMP	runtime·goPanicSliceAcapU<ABIInternal>(SB)
  1173TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
  1174	MOVV	R20, R4
  1175	MOVV	R21, R5
  1176	JMP	runtime·goPanicSliceB<ABIInternal>(SB)
  1177TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
  1178	MOVV	R20, R4
  1179	MOVV	R21, R5
  1180	JMP	runtime·goPanicSliceBU<ABIInternal>(SB)
  1181TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
  1182	MOVV	R23, R4
  1183	MOVV	R24, R5
  1184	JMP	runtime·goPanicSlice3Alen<ABIInternal>(SB)
  1185TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
  1186	MOVV	R23, R4
  1187	MOVV	R24, R5
  1188	JMP	runtime·goPanicSlice3AlenU<ABIInternal>(SB)
  1189TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
  1190	MOVV	R23, R4
  1191	MOVV	R24, R5
  1192	JMP	runtime·goPanicSlice3Acap<ABIInternal>(SB)
  1193TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
  1194	MOVV	R23, R4
  1195	MOVV	R24, R5
  1196	JMP	runtime·goPanicSlice3AcapU<ABIInternal>(SB)
  1197TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
  1198	MOVV	R21, R4
  1199	MOVV	R23, R5
  1200	JMP	runtime·goPanicSlice3B<ABIInternal>(SB)
  1201TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
  1202	MOVV	R21, R4
  1203	MOVV	R23, R5
  1204	JMP	runtime·goPanicSlice3BU<ABIInternal>(SB)
  1205TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
  1206	MOVV	R20, R4
  1207	MOVV	R21, R5
  1208	JMP	runtime·goPanicSlice3C<ABIInternal>(SB)
  1209TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
  1210	MOVV	R20, R4
  1211	MOVV	R21, R5
  1212	JMP	runtime·goPanicSlice3CU<ABIInternal>(SB)
  1213TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
  1214	MOVV	R23, R4
  1215	MOVV	R24, R5
  1216	JMP	runtime·goPanicSliceConvert<ABIInternal>(SB)

View as plain text