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