Text file
src/runtime/asm_loong64.s
1 // Copyright 2022 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "go_asm.h"
6 #include "go_tls.h"
7 #include "funcdata.h"
8 #include "textflag.h"
9
10 #define REGCTXT R29
11
12 TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
13 // R3 = stack; R4 = argc; R5 = argv
14
15 ADDV $-24, R3
16 MOVW R4, 8(R3) // argc
17 MOVV R5, 16(R3) // argv
18
19 // create istack out of the given (operating system) stack.
20 // _cgo_init may update stackguard.
21 MOVV $runtime·g0(SB), g
22 MOVV $(-64*1024), R30
23 ADDV R30, R3, R19
24 MOVV R19, g_stackguard0(g)
25 MOVV R19, g_stackguard1(g)
26 MOVV R19, (g_stack+stack_lo)(g)
27 MOVV R3, (g_stack+stack_hi)(g)
28
29 // if there is a _cgo_init, call it using the gcc ABI.
30 MOVV _cgo_init(SB), R25
31 BEQ R25, nocgo
32
33 MOVV R0, R7 // arg 3: not used
34 MOVV R0, R6 // arg 2: not used
35 MOVV $setg_gcc<>(SB), R5 // arg 1: setg
36 MOVV g, R4 // arg 0: G
37 JAL (R25)
38
39 nocgo:
40 JAL runtime·save_g(SB)
41 // update stackguard after _cgo_init
42 MOVV (g_stack+stack_lo)(g), R19
43 ADDV $const_stackGuard, R19
44 MOVV R19, g_stackguard0(g)
45 MOVV R19, g_stackguard1(g)
46
47 // set the per-goroutine and per-mach "registers"
48 MOVV $runtime·m0(SB), R19
49
50 // save m->g0 = g0
51 MOVV g, m_g0(R19)
52 // save m0 to g0->m
53 MOVV R19, g_m(g)
54
55 JAL runtime·check(SB)
56
57 // args are already prepared
58 JAL runtime·args(SB)
59 JAL runtime·osinit(SB)
60 JAL runtime·schedinit(SB)
61
62 // create a new goroutine to start program
63 MOVV $runtime·mainPC(SB), R19 // entry
64 ADDV $-16, R3
65 MOVV R19, 8(R3)
66 MOVV R0, 0(R3)
67 JAL runtime·newproc(SB)
68 ADDV $16, R3
69
70 // start this M
71 JAL runtime·mstart(SB)
72
73 // Prevent dead-code elimination of debugCallV2, 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
80 DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
81 GLOBL runtime·mainPC(SB),RODATA,$8
82
83 TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
84 BREAK
85 RET
86
87 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
88 RET
89
90 TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
91 JAL runtime·mstart0(SB)
92 RET // not reached
93
94 // func cputicks() int64
95 TEXT 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
105 TEXT 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
111 TEXT 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.
128 TEXT 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()).
155 TEXT 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())
161 TEXT 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
181 switch:
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
204 noswitch:
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())
214 TEXT 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.
248 TEXT 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
288 TEXT 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
313 TEXT ·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) \
345 TEXT 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; \
357 loop16:; \
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; \
365 copy16_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; \
374 check8:; \
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.
418 TEXT 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
428 CALLFN(·call16, 16)
429 CALLFN(·call32, 32)
430 CALLFN(·call64, 64)
431 CALLFN(·call128, 128)
432 CALLFN(·call256, 256)
433 CALLFN(·call512, 512)
434 CALLFN(·call1024, 1024)
435 CALLFN(·call2048, 2048)
436 CALLFN(·call4096, 4096)
437 CALLFN(·call8192, 8192)
438 CALLFN(·call16384, 16384)
439 CALLFN(·call32768, 32768)
440 CALLFN(·call65536, 65536)
441 CALLFN(·call131072, 131072)
442 CALLFN(·call262144, 262144)
443 CALLFN(·call524288, 524288)
444 CALLFN(·call1048576, 1048576)
445 CALLFN(·call2097152, 2097152)
446 CALLFN(·call4194304, 4194304)
447 CALLFN(·call8388608, 8388608)
448 CALLFN(·call16777216, 16777216)
449 CALLFN(·call33554432, 33554432)
450 CALLFN(·call67108864, 67108864)
451 CALLFN(·call134217728, 134217728)
452 CALLFN(·call268435456, 268435456)
453 CALLFN(·call536870912, 536870912)
454 CALLFN(·call1073741824, 1073741824)
455
456 TEXT 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.
464 TEXT 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.
480 TEXT ·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).
502 g0:
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.
524 TEXT ·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
535 loadg:
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)
540 nocgo:
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
554 needm:
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
574 havem:
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
645 dropm:
646 MOVV $runtime·dropm(SB), R4
647 JAL (R4)
648 droppedm:
649
650 // Done!
651 RET
652
653 // void setg(G*); set g. for use by needm.
654 TEXT 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
661 TEXT setg_gcc<>(SB),NOSPLIT,$0-0
662 MOVV R4, g
663 JAL runtime·save_g(SB)
664 RET
665
666 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
667 MOVW (R0), R0
668 UNDEF
669
670 // AES hashing not implemented for loong64
671 TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
672 JMP runtime·memhashFallback<ABIInternal>(SB)
673 TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
674 JMP runtime·strhashFallback<ABIInternal>(SB)
675 TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
676 JMP runtime·memhash32Fallback<ABIInternal>(SB)
677 TEXT 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.
682 TEXT _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.
699 TEXT 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.
706 TEXT 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
716 TEXT ·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.
722 TEXT ·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.
758 TEXT ·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).
802 TEXT gcWriteBarrier<>(SB),NOSPLIT,$216
803 // Save the registers clobbered by the fast path.
804 MOVV R19, 208(R3)
805 MOVV R13, 216(R3)
806 retry:
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
824 flush:
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
890 TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
891 MOVV $8, R29
892 JMP gcWriteBarrier<>(SB)
893 TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
894 MOVV $16, R29
895 JMP gcWriteBarrier<>(SB)
896 TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
897 MOVV $24, R29
898 JMP gcWriteBarrier<>(SB)
899 TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
900 MOVV $32, R29
901 JMP gcWriteBarrier<>(SB)
902 TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
903 MOVV $40, R29
904 JMP gcWriteBarrier<>(SB)
905 TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
906 MOVV $48, R29
907 JMP gcWriteBarrier<>(SB)
908 TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
909 MOVV $56, R29
910 JMP gcWriteBarrier<>(SB)
911 TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
912 MOVV $64, R29
913 JMP gcWriteBarrier<>(SB)
914
915 DATA debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
916 GLOBL 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.
956 TEXT 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
1009 good:
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
1058 restore:
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) \
1107 TEXT NAME(SB),WRAPPER,$MAXSIZE-0; \
1108 NO_LOCAL_POINTERS; \
1109 MOVV $0, R19; \
1110 BREAK; \
1111 MOVV $1, R19; \
1112 BREAK; \
1113 RET
1114 DEBUG_CALL_FN(debugCall32<>, 32)
1115 DEBUG_CALL_FN(debugCall64<>, 64)
1116 DEBUG_CALL_FN(debugCall128<>, 128)
1117 DEBUG_CALL_FN(debugCall256<>, 256)
1118 DEBUG_CALL_FN(debugCall512<>, 512)
1119 DEBUG_CALL_FN(debugCall1024<>, 1024)
1120 DEBUG_CALL_FN(debugCall2048<>, 2048)
1121 DEBUG_CALL_FN(debugCall4096<>, 4096)
1122 DEBUG_CALL_FN(debugCall8192<>, 8192)
1123 DEBUG_CALL_FN(debugCall16384<>, 16384)
1124 DEBUG_CALL_FN(debugCall32768<>, 32768)
1125 DEBUG_CALL_FN(debugCall65536<>, 65536)
1126
1127 // func debugCallPanicked(val interface{})
1128 TEXT 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.
1143 TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
1144 MOVV R20, R4
1145 MOVV R21, R5
1146 JMP runtime·goPanicIndex<ABIInternal>(SB)
1147 TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
1148 MOVV R20, R4
1149 MOVV R21, R5
1150 JMP runtime·goPanicIndexU<ABIInternal>(SB)
1151 TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
1152 MOVV R21, R4
1153 MOVV R23, R5
1154 JMP runtime·goPanicSliceAlen<ABIInternal>(SB)
1155 TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
1156 MOVV R21, R4
1157 MOVV R23, R5
1158 JMP runtime·goPanicSliceAlenU<ABIInternal>(SB)
1159 TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
1160 MOVV R21, R4
1161 MOVV R23, R5
1162 JMP runtime·goPanicSliceAcap<ABIInternal>(SB)
1163 TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
1164 MOVV R21, R4
1165 MOVV R23, R5
1166 JMP runtime·goPanicSliceAcapU<ABIInternal>(SB)
1167 TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
1168 MOVV R20, R4
1169 MOVV R21, R5
1170 JMP runtime·goPanicSliceB<ABIInternal>(SB)
1171 TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
1172 MOVV R20, R4
1173 MOVV R21, R5
1174 JMP runtime·goPanicSliceBU<ABIInternal>(SB)
1175 TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
1176 MOVV R23, R4
1177 MOVV R24, R5
1178 JMP runtime·goPanicSlice3Alen<ABIInternal>(SB)
1179 TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
1180 MOVV R23, R4
1181 MOVV R24, R5
1182 JMP runtime·goPanicSlice3AlenU<ABIInternal>(SB)
1183 TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
1184 MOVV R23, R4
1185 MOVV R24, R5
1186 JMP runtime·goPanicSlice3Acap<ABIInternal>(SB)
1187 TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
1188 MOVV R23, R4
1189 MOVV R24, R5
1190 JMP runtime·goPanicSlice3AcapU<ABIInternal>(SB)
1191 TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
1192 MOVV R21, R4
1193 MOVV R23, R5
1194 JMP runtime·goPanicSlice3B<ABIInternal>(SB)
1195 TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
1196 MOVV R21, R4
1197 MOVV R23, R5
1198 JMP runtime·goPanicSlice3BU<ABIInternal>(SB)
1199 TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
1200 MOVV R20, R4
1201 MOVV R21, R5
1202 JMP runtime·goPanicSlice3C<ABIInternal>(SB)
1203 TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
1204 MOVV R20, R4
1205 MOVV R21, R5
1206 JMP runtime·goPanicSlice3CU<ABIInternal>(SB)
1207 TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
1208 MOVV R23, R4
1209 MOVV R24, R5
1210 JMP runtime·goPanicSliceConvert<ABIInternal>(SB)
1211
View as plain text