1 // Copyright 2017 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.
10 TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
11 // X2 = stack; A0 = argc; A1 = argv
14 MOV A1, 16(X2) // argv
16 // create istack out of the given (operating system) stack.
17 // _cgo_init may update stackguard.
18 MOV $runtime·g0(SB), g
21 MOV T1, g_stackguard0(g)
22 MOV T1, g_stackguard1(g)
23 MOV T1, (g_stack+stack_lo)(g)
24 MOV X2, (g_stack+stack_hi)(g)
26 // if there is a _cgo_init, call it using the gcc ABI.
30 MOV ZERO, A3 // arg 3: not used
31 MOV ZERO, A2 // arg 2: not used
32 MOV $setg_gcc<>(SB), A1 // arg 1: setg
37 // update stackguard after _cgo_init
38 MOV (g_stack+stack_lo)(g), T0
39 ADD $const_stackGuard, T0
40 MOV T0, g_stackguard0(g)
41 MOV T0, g_stackguard1(g)
43 // set the per-goroutine and per-mach "registers"
44 MOV $runtime·m0(SB), T0
51 CALL runtime·check(SB)
53 // args are already prepared
55 CALL runtime·osinit(SB)
56 CALL runtime·schedinit(SB)
58 // create a new goroutine to start program
59 MOV $runtime·mainPC(SB), T0 // entry
63 CALL runtime·newproc(SB)
67 CALL runtime·mstart(SB)
69 WORD $0 // crash if reached
72 TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
73 CALL runtime·mstart0(SB)
76 // void setg_gcc(G*); set g called from gcc with g in A0
77 TEXT setg_gcc<>(SB),NOSPLIT,$0-0
79 CALL runtime·save_g(SB)
82 // func cputicks() int64
83 TEXT runtime·cputicks(SB),NOSPLIT,$0-8
84 // RDTIME to emulate cpu ticks
85 // RDCYCLE reads counter that is per HART(core) based
86 // according to the riscv manual, see issue 46737
91 // systemstack_switch is a dummy routine that systemstack leaves at the bottom
92 // of the G stack. We need to distinguish the routine that
93 // lives at the bottom of the G stack from the one that lives
94 // at the top of the system stack because the one at the top of
95 // the system stack terminates the stack walk (see topofstack()).
96 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
98 JALR RA, ZERO // make sure this function is not leaf
101 // func systemstack(fn func())
102 TEXT runtime·systemstack(SB), NOSPLIT, $0-8
103 MOV fn+0(FP), CTXT // CTXT = fn
104 MOV g_m(g), T0 // T0 = m
106 MOV m_gsignal(T0), T1 // T1 = gsignal
109 MOV m_g0(T0), T1 // T1 = g0
115 // Bad: g is not gsignal, not g0, not curg. What is it?
116 // Hide call from linker nosplit analysis.
117 MOV $runtime·badsystemstack(SB), T1
121 // save our state in g->sched. Pretend to
122 // be systemstack_switch if the G stack is scanned.
123 CALL gosave_systemstack_switch<>(SB)
127 CALL runtime·save_g(SB)
128 MOV (g_sched+gobuf_sp)(g), T0
131 // call target function
132 MOV 0(CTXT), T1 // code pointer
138 CALL runtime·save_g(SB)
139 MOV (g_sched+gobuf_sp)(g), X2
140 MOV ZERO, (g_sched+gobuf_sp)(g)
144 // already on m stack, just call directly
145 // Using a tail call here cleans up tracebacks since we won't stop
146 // at an intermediate systemstack.
147 MOV 0(CTXT), T1 // code pointer
151 // func switchToCrashStack0(fn func())
152 TEXT runtime·switchToCrashStack0<ABIInternal>(SB), NOSPLIT, $0-8
153 MOV X10, CTXT // context register
154 MOV g_m(g), X11 // curm
157 MOV $runtime·gcrash(SB), g // g = &gcrash
158 CALL runtime·save_g(SB) // clobbers X31
159 MOV X11, g_m(g) // g.m = curm
160 MOV g, m_g0(X11) // curm.g0 = g
162 // switch to crashstack
163 MOV (g_stack+stack_hi)(g), X11
167 // call target function
171 // should never return
172 CALL runtime·abort(SB)
176 * support for morestack
179 // Called during function prolog when more stack is needed.
180 // Called with return address (i.e. caller's PC) in X5 (aka T0),
181 // and the LR register contains the caller's LR.
183 // The traceback routines see morestack on a g0 as being
184 // the top of a stack (for example, morestack calling newstack
185 // calling the scheduler calling newm calling gc), so we must
186 // record an argument size. For that purpose, it has no arguments.
189 TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
191 // Set g->sched to context in f.
192 MOV X2, (g_sched+gobuf_sp)(g)
193 MOV T0, (g_sched+gobuf_pc)(g)
194 MOV RA, (g_sched+gobuf_lr)(g)
195 MOV CTXT, (g_sched+gobuf_ctxt)(g)
197 // Cannot grow scheduler stack (m->g0).
201 CALL runtime·badmorestackg0(SB)
202 CALL runtime·abort(SB)
204 // Cannot grow signal stack (m->gsignal).
205 MOV m_gsignal(A0), A1
207 CALL runtime·badmorestackgsignal(SB)
208 CALL runtime·abort(SB)
211 // Set m->morebuf to f's caller.
212 MOV RA, (m_morebuf+gobuf_pc)(A0) // f's caller's PC
213 MOV X2, (m_morebuf+gobuf_sp)(A0) // f's caller's SP
214 MOV g, (m_morebuf+gobuf_g)(A0)
216 // Call newstack on m->g0's stack.
218 CALL runtime·save_g(SB)
219 MOV (g_sched+gobuf_sp)(g), X2
220 // Create a stack frame on g0 to call newstack.
221 MOV ZERO, -8(X2) // Zero saved LR in frame
223 CALL runtime·newstack(SB)
225 // Not reached, but make sure the return PC from the call to newstack
226 // is still in this function, and not the beginning of the next.
229 // func morestack_noctxt()
230 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
231 // Force SPWRITE. This function doesn't actually write SP,
232 // but it is called with a special calling convention where
233 // the caller doesn't save LR on stack but passes it as a
234 // register, and the unwinder currently doesn't understand.
235 // Make it SPWRITE to stop unwinding. (See issue 54332)
239 JMP runtime·morestack(SB)
241 // AES hashing not implemented for riscv64
242 TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
243 JMP runtime·memhashFallback<ABIInternal>(SB)
244 TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
245 JMP runtime·strhashFallback<ABIInternal>(SB)
246 TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
247 JMP runtime·memhash32Fallback<ABIInternal>(SB)
248 TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
249 JMP runtime·memhash64Fallback<ABIInternal>(SB)
252 TEXT runtime·return0(SB), NOSPLIT, $0
256 // restore state from Gobuf; longjmp
258 // func gogo(buf *gobuf)
259 TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
262 MOV 0(T1), ZERO // make sure g != nil
265 TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
267 CALL runtime·save_g(SB)
271 MOV gobuf_ret(T0), A0
272 MOV gobuf_ctxt(T0), CTXT
273 MOV ZERO, gobuf_sp(T0)
274 MOV ZERO, gobuf_ret(T0)
275 MOV ZERO, gobuf_lr(T0)
276 MOV ZERO, gobuf_ctxt(T0)
280 // func procyield(cycles uint32)
281 TEXT runtime·procyield(SB),NOSPLIT,$0-0
284 // Switch to m->g0's stack, call fn(g).
285 // Fn must never return. It should gogo(&g->sched)
286 // to keep running g.
288 // func mcall(fn func(*g))
289 TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
292 // Save caller state in g->sched
293 MOV X2, (g_sched+gobuf_sp)(g)
294 MOV RA, (g_sched+gobuf_pc)(g)
295 MOV ZERO, (g_sched+gobuf_lr)(g)
297 // Switch to m->g0 & its stack, call fn.
301 CALL runtime·save_g(SB)
303 JMP runtime·badmcall(SB)
304 MOV 0(CTXT), T1 // code pointer
305 MOV (g_sched+gobuf_sp)(g), X2 // sp = m->g0->sched.sp
306 // we don't need special macro for regabi since arg0(X10) = g
308 MOV X10, 8(X2) // setup g
309 MOV ZERO, 0(X2) // clear return address
311 JMP runtime·badmcall2(SB)
313 // Save state of caller into g->sched,
314 // but using fake PC from systemstack_switch.
315 // Must only be called from functions with no locals ($0)
316 // or else unwinding from systemstack_switch is incorrect.
318 TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
319 MOV $runtime·systemstack_switch(SB), X31
320 ADD $8, X31 // get past prologue
321 MOV X31, (g_sched+gobuf_pc)(g)
322 MOV X2, (g_sched+gobuf_sp)(g)
323 MOV ZERO, (g_sched+gobuf_lr)(g)
324 MOV ZERO, (g_sched+gobuf_ret)(g)
325 // Assert ctxt is zero. See func save.
326 MOV (g_sched+gobuf_ctxt)(g), X31
328 CALL runtime·abort(SB)
331 // func asmcgocall_no_g(fn, arg unsafe.Pointer)
332 // Call fn(arg) aligned appropriately for the gcc ABI.
333 // Called on a system stack, and there may be no g yet (during needm).
334 TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
340 // func asmcgocall(fn, arg unsafe.Pointer) int32
341 // Call fn(arg) on the scheduler stack,
342 // aligned appropriately for the gcc ABI.
343 // See cgocall.go for more details.
344 TEXT ·asmcgocall(SB),NOSPLIT,$0-20
348 MOV X2, X8 // save original stack pointer
351 // Figure out if we need to switch to m->g0 stack.
352 // We get called to create new OS threads too, and those
353 // come in on the m->g0 stack already. Or we might already
354 // be on the m->gsignal stack.
356 MOV m_gsignal(X6), X7
361 CALL gosave_systemstack_switch<>(SB)
363 CALL runtime·save_g(SB)
364 MOV (g_sched+gobuf_sp)(g), X2
366 // Now on a scheduling stack (a pthread-created stack).
368 // Save room for two of our pointers.
370 MOV X9, 0(X2) // save old g on stack
371 MOV (g_stack+stack_hi)(X9), X9
373 MOV X8, 8(X2) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
377 // Restore g, stack pointer. X10 is return value.
379 CALL runtime·save_g(SB)
380 MOV (g_stack+stack_hi)(g), X5
389 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
392 // reflectcall: call a function with the given argument list
393 // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
394 // we don't have variable-sized frames, so we use a small number
395 // of constant-sized-frame functions to encode a few bits of size in the pc.
396 // Caution: ugly multiline assembly macros in your future!
398 #define DISPATCH(NAME,MAXSIZE) \
403 // Note: can't just "BR NAME(SB)" - bad inlining results.
405 // func call(stackArgsType *rtype, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
406 TEXT reflect·call(SB), NOSPLIT, $0-0
409 // func call(stackArgsType *_type, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
410 TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
411 MOVWU frameSize+32(FP), T0
412 DISPATCH(runtime·call16, 16)
413 DISPATCH(runtime·call32, 32)
414 DISPATCH(runtime·call64, 64)
415 DISPATCH(runtime·call128, 128)
416 DISPATCH(runtime·call256, 256)
417 DISPATCH(runtime·call512, 512)
418 DISPATCH(runtime·call1024, 1024)
419 DISPATCH(runtime·call2048, 2048)
420 DISPATCH(runtime·call4096, 4096)
421 DISPATCH(runtime·call8192, 8192)
422 DISPATCH(runtime·call16384, 16384)
423 DISPATCH(runtime·call32768, 32768)
424 DISPATCH(runtime·call65536, 65536)
425 DISPATCH(runtime·call131072, 131072)
426 DISPATCH(runtime·call262144, 262144)
427 DISPATCH(runtime·call524288, 524288)
428 DISPATCH(runtime·call1048576, 1048576)
429 DISPATCH(runtime·call2097152, 2097152)
430 DISPATCH(runtime·call4194304, 4194304)
431 DISPATCH(runtime·call8388608, 8388608)
432 DISPATCH(runtime·call16777216, 16777216)
433 DISPATCH(runtime·call33554432, 33554432)
434 DISPATCH(runtime·call67108864, 67108864)
435 DISPATCH(runtime·call134217728, 134217728)
436 DISPATCH(runtime·call268435456, 268435456)
437 DISPATCH(runtime·call536870912, 536870912)
438 DISPATCH(runtime·call1073741824, 1073741824)
439 MOV $runtime·badreflectcall(SB), T2
442 #define CALLFN(NAME,MAXSIZE) \
443 TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \
445 /* copy arguments to stack */ \
446 MOV stackArgs+16(FP), A1; \
447 MOVWU stackArgsSize+24(FP), A2; \
457 /* set up argument registers */ \
458 MOV regArgs+40(FP), X25; \
459 CALL ·unspillArgs(SB); \
460 /* call function */ \
463 PCDATA $PCDATA_StackMapIndex, $0; \
465 /* copy return values back */ \
466 MOV regArgs+40(FP), X25; \
467 CALL ·spillArgs(SB); \
468 MOV stackArgsType+0(FP), A5; \
469 MOV stackArgs+16(FP), A1; \
470 MOVWU stackArgsSize+24(FP), A2; \
471 MOVWU stackRetOffset+28(FP), A4; \
476 CALL callRet<>(SB); \
479 // callRet copies return values back at the end of call*. This is a
480 // separate function so it can allocate stack space for the arguments
481 // to reflectcallmove. It does not follow the Go ABI; it expects its
482 // arguments in registers.
483 TEXT callRet<>(SB), NOSPLIT, $40-0
490 CALL runtime·reflectcallmove(SB)
496 CALLFN(·call128, 128)
497 CALLFN(·call256, 256)
498 CALLFN(·call512, 512)
499 CALLFN(·call1024, 1024)
500 CALLFN(·call2048, 2048)
501 CALLFN(·call4096, 4096)
502 CALLFN(·call8192, 8192)
503 CALLFN(·call16384, 16384)
504 CALLFN(·call32768, 32768)
505 CALLFN(·call65536, 65536)
506 CALLFN(·call131072, 131072)
507 CALLFN(·call262144, 262144)
508 CALLFN(·call524288, 524288)
509 CALLFN(·call1048576, 1048576)
510 CALLFN(·call2097152, 2097152)
511 CALLFN(·call4194304, 4194304)
512 CALLFN(·call8388608, 8388608)
513 CALLFN(·call16777216, 16777216)
514 CALLFN(·call33554432, 33554432)
515 CALLFN(·call67108864, 67108864)
516 CALLFN(·call134217728, 134217728)
517 CALLFN(·call268435456, 268435456)
518 CALLFN(·call536870912, 536870912)
519 CALLFN(·call1073741824, 1073741824)
521 // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
522 // Must obey the gcc calling convention.
523 TEXT _cgo_topofstack(SB),NOSPLIT,$8
524 // g (X27) and REG_TMP (X31) might be clobbered by load_g.
525 // X27 is callee-save in the gcc calling convention, so save it.
526 MOV g, savedX27-8(SP)
528 CALL runtime·load_g(SB)
531 MOV (g_stack+stack_hi)(X5), X10 // return value in X10
533 MOV savedX27-8(SP), g
536 // func goexit(neverCallThisFunction)
537 // The top-most function running on a goroutine
538 // returns to goexit+PCQuantum.
539 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
540 MOV ZERO, ZERO // NOP
541 JMP runtime·goexit1(SB) // does not return
542 // traceback from goexit1 must hit code range of goexit
543 MOV ZERO, ZERO // NOP
545 // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
546 // See cgocall.go for more details.
547 TEXT ·cgocallback(SB),NOSPLIT,$24-24
550 // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
551 // It is used to dropm while thread is exiting.
554 // Restore the g from frame.
559 // Load m and g from thread-local storage.
560 MOVBU runtime·iscgo(SB), X5
562 CALL runtime·load_g(SB)
565 // If g is nil, Go did not create the current thread,
566 // or if this thread never called into Go on pthread platforms.
567 // Call needm to obtain one for temporary use.
568 // In this case, we're running on the thread stack, so there's
569 // lots of space, but the linker doesn't know. Hide the call from
570 // the linker analysis by using an indirect call.
578 MOV g, savedm-8(SP) // g is zero, so is m.
579 MOV $runtime·needAndBindM(SB), X6
582 // Set m->sched.sp = SP, so that if a panic happens
583 // during the function we are about to execute, it will
584 // have a valid SP to run on the g0 stack.
585 // The next few lines (after the havem label)
586 // will save this SP onto the stack and then write
587 // the same SP back to m->sched.sp. That seems redundant,
588 // but if an unrecovered panic happens, unwindm will
589 // restore the g->sched.sp from the stack location
590 // and then systemstack will try to use it. If we don't set it here,
591 // that restored SP will be uninitialized (typically 0) and
592 // will not be usable.
595 MOV X2, (g_sched+gobuf_sp)(X6)
598 // Now there's a valid m, and we're running on its m->g0.
599 // Save current m->g0->sched.sp on stack and then set it to SP.
600 // Save current sp in m->g0->sched.sp in preparation for
601 // switch back to m->curg stack.
602 // NOTE: unwindm knows that the saved g->sched.sp is at 8(X2) aka savedsp-24(SP).
604 MOV (g_sched+gobuf_sp)(X6), X7
605 MOV X7, savedsp-24(SP) // must match frame size
606 MOV X2, (g_sched+gobuf_sp)(X6)
608 // Switch to m->curg stack and call runtime.cgocallbackg.
609 // Because we are taking over the execution of m->curg
610 // but *not* resuming what had been running, we need to
611 // save that information (m->curg->sched) so we can restore it.
612 // We can restore m->curg->sched.sp easily, because calling
613 // runtime.cgocallbackg leaves SP unchanged upon return.
614 // To save m->curg->sched.pc, we push it onto the curg stack and
615 // open a frame the same size as cgocallback's g0 frame.
616 // Once we switch to the curg stack, the pushed PC will appear
617 // to be the return PC of cgocallback, so that the traceback
618 // will seamlessly trace back into the earlier calls.
620 CALL runtime·save_g(SB)
621 MOV (g_sched+gobuf_sp)(g), X6 // prepare stack as X6
622 MOV (g_sched+gobuf_pc)(g), X7
623 MOV X7, -(24+8)(X6) // "saved LR"; must match frame size
624 // Gather our arguments into registers.
628 MOV $-(24+8)(X6), X2 // switch stack; must match frame size
632 CALL runtime·cgocallbackg(SB)
634 // Restore g->sched (== m->curg->sched) from saved values.
636 MOV X7, (g_sched+gobuf_pc)(g)
637 MOV $(24+8)(X2), X6 // must match frame size
638 MOV X6, (g_sched+gobuf_sp)(g)
640 // Switch back to m->g0's stack and restore m->g0->sched.sp.
641 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
642 // so we do not have to restore it.)
645 CALL runtime·save_g(SB)
646 MOV (g_sched+gobuf_sp)(g), X2
647 MOV savedsp-24(SP), X6 // must match frame size
648 MOV X6, (g_sched+gobuf_sp)(g)
650 // If the m on entry was nil, we called needm above to borrow an m,
651 // 1. for the duration of the call on non-pthread platforms,
652 // 2. or the duration of the C thread alive on pthread platforms.
653 // If the m on entry wasn't nil,
654 // 1. the thread might be a Go thread,
655 // 2. or it wasn't the first call from a C thread on pthread platforms,
656 // since then we skip dropm to reuse the m in the first call.
658 BNE ZERO, X5, droppedm
660 // Skip dropm to reuse it in the next call, when a pthread key has been created.
661 MOV _cgo_pthread_key_created(SB), X5
662 // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
665 BNE ZERO, X5, droppedm
668 MOV $runtime·dropm(SB), X6
675 TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
679 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
683 // void setg(G*); set g. for use by needm.
684 TEXT runtime·setg(SB), NOSPLIT, $0-8
686 // This only happens if iscgo, so jump straight to save_g
687 CALL runtime·save_g(SB)
690 TEXT ·checkASM(SB),NOSPLIT,$0-1
695 // spillArgs stores return values from registers to a *internal/abi.RegArgs in X25.
696 TEXT ·spillArgs(SB),NOSPLIT,$0-0
713 MOVD F10, (16*8)(X25)
714 MOVD F11, (17*8)(X25)
715 MOVD F12, (18*8)(X25)
716 MOVD F13, (19*8)(X25)
717 MOVD F14, (20*8)(X25)
718 MOVD F15, (21*8)(X25)
719 MOVD F16, (22*8)(X25)
720 MOVD F17, (23*8)(X25)
723 MOVD F18, (26*8)(X25)
724 MOVD F19, (27*8)(X25)
725 MOVD F20, (28*8)(X25)
726 MOVD F21, (29*8)(X25)
727 MOVD F22, (30*8)(X25)
728 MOVD F23, (31*8)(X25)
731 // unspillArgs loads args into registers from a *internal/abi.RegArgs in X25.
732 TEXT ·unspillArgs(SB),NOSPLIT,$0-0
749 MOVD (16*8)(X25), F10
750 MOVD (17*8)(X25), F11
751 MOVD (18*8)(X25), F12
752 MOVD (19*8)(X25), F13
753 MOVD (20*8)(X25), F14
754 MOVD (21*8)(X25), F15
755 MOVD (22*8)(X25), F16
756 MOVD (23*8)(X25), F17
759 MOVD (26*8)(X25), F18
760 MOVD (27*8)(X25), F19
761 MOVD (28*8)(X25), F20
762 MOVD (29*8)(X25), F21
763 MOVD (30*8)(X25), F22
764 MOVD (31*8)(X25), F23
767 // gcWriteBarrier informs the GC about heap pointer writes.
769 // gcWriteBarrier does NOT follow the Go ABI. It accepts the
770 // number of bytes of buffer needed in X24, and returns a pointer
771 // to the buffer space in X24.
772 // It clobbers X31 aka T6 (the linker temp register - REG_TMP).
773 // The act of CALLing gcWriteBarrier will clobber RA (LR).
774 // It does not clobber any other general-purpose registers,
775 // but may clobber others (e.g., floating point registers).
776 TEXT gcWriteBarrier<>(SB),NOSPLIT,$208
777 // Save the registers clobbered by the fast path.
783 MOV (p_wbBuf+wbBuf_next)(A0), A1
784 MOV (p_wbBuf+wbBuf_end)(A0), T6 // T6 is linker temp register (REG_TMP)
785 // Increment wbBuf.next position.
787 // Is the buffer full?
789 // Commit to the larger buffer.
790 MOV A1, (p_wbBuf+wbBuf_next)(A0)
791 // Make the return value (the original next position)
793 // Restore registers.
799 // Save all general purpose registers since these could be
800 // clobbered by wbBufFlush and were not saved by the caller.
803 // X0 is zero register
804 // X1 is LR, saved by prologue
811 // X10 already saved (A0)
812 // X11 already saved (A1)
832 // X31 is tmp register.
834 CALL runtime·wbBufFlush(SB)
862 TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
864 JMP gcWriteBarrier<>(SB)
865 TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
867 JMP gcWriteBarrier<>(SB)
868 TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
870 JMP gcWriteBarrier<>(SB)
871 TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
873 JMP gcWriteBarrier<>(SB)
874 TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
876 JMP gcWriteBarrier<>(SB)
877 TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
879 JMP gcWriteBarrier<>(SB)
880 TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
882 JMP gcWriteBarrier<>(SB)
883 TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
885 JMP gcWriteBarrier<>(SB)
887 // Note: these functions use a special calling convention to save generated code space.
888 // Arguments are passed in registers (ssa/gen/RISCV64Ops.go), but the space for those
889 // arguments are allocated in the caller's stack frame.
890 // These stubs write the args into that stack space and then tail call to the
891 // corresponding runtime handler.
892 // The tail call makes these stubs disappear in backtraces.
893 TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
896 JMP runtime·goPanicIndex<ABIInternal>(SB)
897 TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
900 JMP runtime·goPanicIndexU<ABIInternal>(SB)
901 TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
904 JMP runtime·goPanicSliceAlen<ABIInternal>(SB)
905 TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
908 JMP runtime·goPanicSliceAlenU<ABIInternal>(SB)
909 TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
912 JMP runtime·goPanicSliceAcap<ABIInternal>(SB)
913 TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
916 JMP runtime·goPanicSliceAcapU<ABIInternal>(SB)
917 TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
920 JMP runtime·goPanicSliceB<ABIInternal>(SB)
921 TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
924 JMP runtime·goPanicSliceBU<ABIInternal>(SB)
925 TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
928 JMP runtime·goPanicSlice3Alen<ABIInternal>(SB)
929 TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
932 JMP runtime·goPanicSlice3AlenU<ABIInternal>(SB)
933 TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
936 JMP runtime·goPanicSlice3Acap<ABIInternal>(SB)
937 TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
940 JMP runtime·goPanicSlice3AcapU<ABIInternal>(SB)
941 TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
944 JMP runtime·goPanicSlice3B<ABIInternal>(SB)
945 TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
948 JMP runtime·goPanicSlice3BU<ABIInternal>(SB)
949 TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
952 JMP runtime·goPanicSlice3C<ABIInternal>(SB)
953 TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
956 JMP runtime·goPanicSlice3CU<ABIInternal>(SB)
957 TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
960 JMP runtime·goPanicSliceConvert<ABIInternal>(SB)
962 DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
963 GLOBL runtime·mainPC(SB),RODATA,$8