1 // Copyright 2009 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 // _rt0_arm is common startup code for most ARM systems when using
11 // internal linking. This is the entry point for the program from the
12 // kernel for an ordinary -buildmode=exe program. The stack holds the
13 // number of arguments and the C-style argv.
14 TEXT _rt0_arm(SB),NOSPLIT|NOFRAME,$0
15 MOVW (R13), R0 // argc
16 MOVW $4(R13), R1 // argv
19 // main is common startup code for most ARM systems when using
20 // external linking. The C startup code will call the symbol "main"
21 // passing argc and argv in the usual C ABI registers R0 and R1.
22 TEXT main(SB),NOSPLIT|NOFRAME,$0
25 // _rt0_arm_lib is common startup code for most ARM systems when
26 // using -buildmode=c-archive or -buildmode=c-shared. The linker will
27 // arrange to invoke this function as a global constructor (for
28 // c-archive) or when the shared library is loaded (for c-shared).
29 // We expect argc and argv to be passed in the usual C ABI registers
31 TEXT _rt0_arm_lib(SB),NOSPLIT,$104
32 // Preserve callee-save registers. Raspberry Pi's dlopen(), for example,
33 // actually cares that R11 is preserved.
42 // Skip floating point registers on GOARM < 6.
43 MOVB runtime·goarm(SB), R11
46 MOVD F8, (40+8*0)(R13)
47 MOVD F9, (40+8*1)(R13)
48 MOVD F10, (40+8*2)(R13)
49 MOVD F11, (40+8*3)(R13)
50 MOVD F12, (40+8*4)(R13)
51 MOVD F13, (40+8*5)(R13)
52 MOVD F14, (40+8*6)(R13)
53 MOVD F15, (40+8*7)(R13)
56 MOVW R0, _rt0_arm_lib_argc<>(SB)
57 MOVW R1, _rt0_arm_lib_argv<>(SB)
59 MOVW $0, g // Initialize g.
61 // Synchronous initialization.
62 CALL runtime·libpreinit(SB)
64 // Create a new thread to do the runtime initialization.
65 MOVW _cgo_sys_thread_create(SB), R2
68 MOVW $_rt0_arm_lib_go<>(SB), R0
73 MOVW $0x800000, R0 // stacksize = 8192KB
74 MOVW $_rt0_arm_lib_go<>(SB), R1 // fn
77 BL runtime·newosproc0(SB)
79 // Restore callee-save registers and return.
80 MOVB runtime·goarm(SB), R11
83 MOVD (40+8*0)(R13), F8
84 MOVD (40+8*1)(R13), F9
85 MOVD (40+8*2)(R13), F10
86 MOVD (40+8*3)(R13), F11
87 MOVD (40+8*4)(R13), F12
88 MOVD (40+8*5)(R13), F13
89 MOVD (40+8*6)(R13), F14
90 MOVD (40+8*7)(R13), F15
101 // _rt0_arm_lib_go initializes the Go runtime.
102 // This is started in a separate thread by _rt0_arm_lib.
103 TEXT _rt0_arm_lib_go<>(SB),NOSPLIT,$8
104 MOVW _rt0_arm_lib_argc<>(SB), R0
105 MOVW _rt0_arm_lib_argv<>(SB), R1
108 DATA _rt0_arm_lib_argc<>(SB)/4,$0
109 GLOBL _rt0_arm_lib_argc<>(SB),NOPTR,$4
110 DATA _rt0_arm_lib_argv<>(SB)/4,$0
111 GLOBL _rt0_arm_lib_argv<>(SB),NOPTR,$4
113 // using NOFRAME means do not save LR on stack.
114 // argc is in R0, argv is in R1.
115 TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
116 MOVW $0xcafebabe, R12
118 // copy arguments forward on an even stack
119 // use R13 instead of SP to avoid linker rewriting the offsets
120 SUB $64, R13 // plenty of scratch
122 MOVW R0, 60(R13) // save argc, argv away
127 MOVW $runtime·g0(SB), g
128 MOVW $runtime·m0(SB), R8
135 // create istack out of the OS stack
136 // (1MB of system stack is available on iOS and Android)
137 MOVW $(-64*1024+104)(R13), R0
138 MOVW R0, g_stackguard0(g)
139 MOVW R0, g_stackguard1(g)
140 MOVW R0, (g_stack+stack_lo)(g)
141 MOVW R13, (g_stack+stack_hi)(g)
143 BL runtime·emptyfunc(SB) // fault if stack check is wrong
146 // Save g to TLS so that it is available from signal trampoline.
147 BL runtime·save_g(SB)
150 BL runtime·_initcgo(SB) // will clobber R0-R3
152 // update stackguard after _cgo_init
153 MOVW (g_stack+stack_lo)(g), R0
154 ADD $const__StackGuard, R0
155 MOVW R0, g_stackguard0(g)
156 MOVW R0, g_stackguard1(g)
166 BL runtime·checkgoarm(SB)
167 BL runtime·osinit(SB)
168 BL runtime·schedinit(SB)
170 // create a new goroutine to start program
172 MOVW $runtime·mainPC(SB), R0
173 MOVW R0, 4(R13) // arg 1: fn
175 MOVW R0, 0(R13) // dummy LR
176 BL runtime·newproc(SB)
177 ADD $8, R13 // pop args and LR
180 BL runtime·mstart(SB)
184 MOVW R0, (R1) // fail hard
186 DATA runtime·mainPC+0(SB)/4,$runtime·main(SB)
187 GLOBL runtime·mainPC(SB),RODATA,$4
189 TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
190 // gdb won't skip this breakpoint instruction automatically,
191 // so you must manually "set $pc+=4" to skip it and continue.
193 WORD $0xD1200070 // undefined instruction used as armv5 breakpoint in Plan 9
195 WORD $0xe7f001f0 // undefined instruction that gdb understands is a software breakpoint
199 TEXT runtime·asminit(SB),NOSPLIT,$0-0
200 // disable runfast (flush-to-zero) mode of vfp if runtime.goarm > 5
201 MOVB runtime·goarm(SB), R11
204 WORD $0xeef1ba10 // vmrs r11, fpscr
206 WORD $0xeee1ba10 // vmsr fpscr, r11
209 TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
210 BL runtime·mstart0(SB)
218 // restore state from Gobuf; longjmp
219 TEXT runtime·gogo(SB),NOSPLIT|NOFRAME,$0-4
222 MOVW 0(R0), R2 // make sure g != nil
225 TEXT gogo<>(SB),NOSPLIT|NOFRAME,$0
227 MOVW gobuf_sp(R1), R13 // restore SP==R13
228 MOVW gobuf_lr(R1), LR
229 MOVW gobuf_ret(R1), R0
230 MOVW gobuf_ctxt(R1), R7
232 MOVW R11, gobuf_sp(R1) // clear to help garbage collector
233 MOVW R11, gobuf_ret(R1)
234 MOVW R11, gobuf_lr(R1)
235 MOVW R11, gobuf_ctxt(R1)
236 MOVW gobuf_pc(R1), R11
237 CMP R11, R11 // set condition codes for == test, needed by stack split
240 // func mcall(fn func(*g))
241 // Switch to m->g0's stack, call fn(g).
242 // Fn must never return. It should gogo(&g->sched)
243 // to keep running g.
244 TEXT runtime·mcall(SB),NOSPLIT|NOFRAME,$0-4
245 // Save caller state in g->sched.
246 MOVW R13, (g_sched+gobuf_sp)(g)
247 MOVW LR, (g_sched+gobuf_pc)(g)
249 MOVW R11, (g_sched+gobuf_lr)(g)
251 // Switch to m->g0 & its stack, call fn.
258 B runtime·badmcall(SB)
260 MOVW (g_sched+gobuf_sp)(g), R13
266 B runtime·badmcall2(SB)
269 // systemstack_switch is a dummy routine that systemstack leaves at the bottom
270 // of the G stack. We need to distinguish the routine that
271 // lives at the bottom of the G stack from the one that lives
272 // at the top of the system stack because the one at the top of
273 // the system stack terminates the stack walk (see topofstack()).
274 TEXT runtime·systemstack_switch(SB),NOSPLIT,$0-0
276 BL (R0) // clobber lr to ensure push {lr} is kept
279 // func systemstack(fn func())
280 TEXT runtime·systemstack(SB),NOSPLIT,$0-4
281 MOVW fn+0(FP), R0 // R0 = fn
282 MOVW g_m(g), R1 // R1 = m
284 MOVW m_gsignal(R1), R2 // R2 = gsignal
288 MOVW m_g0(R1), R2 // R2 = g0
296 // Bad: g is not gsignal, not g0, not curg. What is it?
297 // Hide call from linker nosplit analysis.
298 MOVW $runtime·badsystemstack(SB), R0
303 // save our state in g->sched. Pretend to
304 // be systemstack_switch if the G stack is scanned.
305 BL gosave_systemstack_switch<>(SB)
312 MOVW (g_sched+gobuf_sp)(R2), R13
314 // call target function
323 MOVW (g_sched+gobuf_sp)(g), R13
325 MOVW R3, (g_sched+gobuf_sp)(g)
329 // Using a tail call here cleans up tracebacks since we won't stop
330 // at an intermediate systemstack.
333 MOVW.P 4(R13), R14 // restore LR
337 * support for morestack
340 // Called during function prolog when more stack is needed.
342 // using NOFRAME means do not save LR on stack.
344 // The traceback routines see morestack on a g0 as being
345 // the top of a stack (for example, morestack calling newstack
346 // calling the scheduler calling newm calling gc), so we must
347 // record an argument size. For that purpose, it has no arguments.
348 TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
349 // Cannot grow scheduler stack (m->g0).
354 BL runtime·badmorestackg0(SB)
357 // Cannot grow signal stack (m->gsignal).
358 MOVW m_gsignal(R8), R4
361 BL runtime·badmorestackgsignal(SB)
365 // Set g->sched to context in f.
366 MOVW R13, (g_sched+gobuf_sp)(g)
367 MOVW LR, (g_sched+gobuf_pc)(g)
368 MOVW R3, (g_sched+gobuf_lr)(g)
369 MOVW R7, (g_sched+gobuf_ctxt)(g)
372 // Set m->morebuf to f's caller.
373 MOVW R3, (m_morebuf+gobuf_pc)(R8) // f's caller's PC
374 MOVW R13, (m_morebuf+gobuf_sp)(R8) // f's caller's SP
375 MOVW g, (m_morebuf+gobuf_g)(R8)
377 // Call newstack on m->g0's stack.
380 MOVW (g_sched+gobuf_sp)(g), R13
382 MOVW.W R0, -4(R13) // create a call frame on g0 (saved LR)
383 BL runtime·newstack(SB)
385 // Not reached, but make sure the return PC from the call to newstack
386 // is still in this function, and not the beginning of the next.
389 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
390 // Force SPWRITE. This function doesn't actually write SP,
391 // but it is called with a special calling convention where
392 // the caller doesn't save LR on stack but passes it as a
393 // register (R3), and the unwinder currently doesn't understand.
394 // Make it SPWRITE to stop unwinding. (See issue 54332)
398 B runtime·morestack(SB)
400 // reflectcall: call a function with the given argument list
401 // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
402 // we don't have variable-sized frames, so we use a small number
403 // of constant-sized-frame functions to encode a few bits of size in the pc.
404 // Caution: ugly multiline assembly macros in your future!
406 #define DISPATCH(NAME,MAXSIZE) \
409 MOVW $NAME(SB), R1; \
412 TEXT ·reflectcall(SB),NOSPLIT|NOFRAME,$0-28
413 MOVW frameSize+20(FP), R0
414 DISPATCH(runtime·call16, 16)
415 DISPATCH(runtime·call32, 32)
416 DISPATCH(runtime·call64, 64)
417 DISPATCH(runtime·call128, 128)
418 DISPATCH(runtime·call256, 256)
419 DISPATCH(runtime·call512, 512)
420 DISPATCH(runtime·call1024, 1024)
421 DISPATCH(runtime·call2048, 2048)
422 DISPATCH(runtime·call4096, 4096)
423 DISPATCH(runtime·call8192, 8192)
424 DISPATCH(runtime·call16384, 16384)
425 DISPATCH(runtime·call32768, 32768)
426 DISPATCH(runtime·call65536, 65536)
427 DISPATCH(runtime·call131072, 131072)
428 DISPATCH(runtime·call262144, 262144)
429 DISPATCH(runtime·call524288, 524288)
430 DISPATCH(runtime·call1048576, 1048576)
431 DISPATCH(runtime·call2097152, 2097152)
432 DISPATCH(runtime·call4194304, 4194304)
433 DISPATCH(runtime·call8388608, 8388608)
434 DISPATCH(runtime·call16777216, 16777216)
435 DISPATCH(runtime·call33554432, 33554432)
436 DISPATCH(runtime·call67108864, 67108864)
437 DISPATCH(runtime·call134217728, 134217728)
438 DISPATCH(runtime·call268435456, 268435456)
439 DISPATCH(runtime·call536870912, 536870912)
440 DISPATCH(runtime·call1073741824, 1073741824)
441 MOVW $runtime·badreflectcall(SB), R1
444 #define CALLFN(NAME,MAXSIZE) \
445 TEXT NAME(SB), WRAPPER, $MAXSIZE-28; \
447 /* copy arguments to stack */ \
448 MOVW stackArgs+8(FP), R0; \
449 MOVW stackArgsSize+12(FP), R2; \
457 /* call function */ \
460 PCDATA $PCDATA_StackMapIndex, $0; \
462 /* copy return values back */ \
463 MOVW stackArgsType+0(FP), R4; \
464 MOVW stackArgs+8(FP), R0; \
465 MOVW stackArgsSize+12(FP), R2; \
466 MOVW stackArgsRetOffset+16(FP), R3; \
474 // callRet copies return values back at the end of call*. This is a
475 // separate function so it can allocate stack space for the arguments
476 // to reflectcallmove. It does not follow the Go ABI; it expects its
477 // arguments in registers.
478 TEXT callRet<>(SB), NOSPLIT, $20-0
485 BL runtime·reflectcallmove(SB)
491 CALLFN(·call128, 128)
492 CALLFN(·call256, 256)
493 CALLFN(·call512, 512)
494 CALLFN(·call1024, 1024)
495 CALLFN(·call2048, 2048)
496 CALLFN(·call4096, 4096)
497 CALLFN(·call8192, 8192)
498 CALLFN(·call16384, 16384)
499 CALLFN(·call32768, 32768)
500 CALLFN(·call65536, 65536)
501 CALLFN(·call131072, 131072)
502 CALLFN(·call262144, 262144)
503 CALLFN(·call524288, 524288)
504 CALLFN(·call1048576, 1048576)
505 CALLFN(·call2097152, 2097152)
506 CALLFN(·call4194304, 4194304)
507 CALLFN(·call8388608, 8388608)
508 CALLFN(·call16777216, 16777216)
509 CALLFN(·call33554432, 33554432)
510 CALLFN(·call67108864, 67108864)
511 CALLFN(·call134217728, 134217728)
512 CALLFN(·call268435456, 268435456)
513 CALLFN(·call536870912, 536870912)
514 CALLFN(·call1073741824, 1073741824)
516 // Save state of caller into g->sched,
517 // but using fake PC from systemstack_switch.
518 // Must only be called from functions with no locals ($0)
519 // or else unwinding from systemstack_switch is incorrect.
521 TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
522 MOVW $runtime·systemstack_switch(SB), R11
523 ADD $4, R11 // get past push {lr}
524 MOVW R11, (g_sched+gobuf_pc)(g)
525 MOVW R13, (g_sched+gobuf_sp)(g)
527 MOVW R11, (g_sched+gobuf_lr)(g)
528 MOVW R11, (g_sched+gobuf_ret)(g)
529 // Assert ctxt is zero. See func save.
530 MOVW (g_sched+gobuf_ctxt)(g), R11
536 // func asmcgocall_no_g(fn, arg unsafe.Pointer)
537 // Call fn(arg) aligned appropriately for the gcc ABI.
538 // Called on a system stack, and there may be no g yet (during needm).
539 TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-8
544 BIC $0x7, R13 // alignment for gcc ABI
551 // func asmcgocall(fn, arg unsafe.Pointer) int32
552 // Call fn(arg) on the scheduler stack,
553 // aligned appropriately for the gcc ABI.
554 // See cgocall.go for more details.
555 TEXT ·asmcgocall(SB),NOSPLIT,$0-12
564 // Figure out if we need to switch to m->g0 stack.
565 // We get called to create new OS threads too, and those
566 // come in on the m->g0 stack already. Or we might already
567 // be on the m->gsignal stack.
569 MOVW m_gsignal(R8), R3
575 BL gosave_systemstack_switch<>(SB)
580 MOVW (g_sched+gobuf_sp)(g), R13
582 // Now on a scheduling stack (a pthread-created stack).
584 BIC $0x7, R13 // alignment for gcc ABI
585 MOVW R4, 20(R13) // save old g
586 MOVW (g_stack+stack_hi)(R4), R4
588 MOVW R4, 16(R13) // save depth in stack (can't just save SP, as stack might be copied during a callback)
591 // Restore registers, g, stack pointer.
595 MOVW (g_stack+stack_hi)(g), R1
605 // Running on a system stack, perhaps even without a g.
606 // Having no g can happen during thread creation or thread teardown
607 // (see needm/dropm on Solaris, for example).
608 // This code is like the above sequence but without saving/restoring g
609 // and without worrying about the stack moving out from under us
610 // (because we're on a system stack, not a goroutine stack).
611 // The above code could be used directly if already on a system stack,
612 // but then the only path through this code would be a rare case on Solaris.
613 // Using this code for all "already on system stack" calls exercises it more,
614 // which should help keep it correct.
616 BIC $0x7, R13 // alignment for gcc ABI
617 // save null g in case someone looks during debugging.
620 MOVW R2, 16(R13) // Save old stack pointer.
622 // Restore stack pointer.
628 // cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
629 // See cgocall.go for more details.
630 TEXT ·cgocallback(SB),NOSPLIT,$12-12
633 // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
634 // It is used to dropm while thread is exiting.
637 // Restore the g from frame.
642 // Load m and g from thread-local storage.
644 BL runtime·load_g(SB)
646 MOVB runtime·iscgo(SB), R0
648 BL.NE runtime·load_g(SB)
651 // If g is nil, Go did not create the current thread,
652 // or if this thread never called into Go on pthread platforms.
653 // Call needm to obtain one for temporary use.
654 // In this case, we're running on the thread stack, so there's
655 // lots of space, but the linker doesn't know. Hide the call from
656 // the linker analysis by using an indirect call.
661 MOVW R8, savedm-4(SP)
665 MOVW g, savedm-4(SP) // g is zero, so is m.
666 MOVW $runtime·needAndBindM(SB), R0
669 // Set m->g0->sched.sp = SP, so that if a panic happens
670 // during the function we are about to execute, it will
671 // have a valid SP to run on the g0 stack.
672 // The next few lines (after the havem label)
673 // will save this SP onto the stack and then write
674 // the same SP back to m->sched.sp. That seems redundant,
675 // but if an unrecovered panic happens, unwindm will
676 // restore the g->sched.sp from the stack location
677 // and then systemstack will try to use it. If we don't set it here,
678 // that restored SP will be uninitialized (typically 0) and
679 // will not be usable.
682 MOVW R13, (g_sched+gobuf_sp)(R3)
685 // Now there's a valid m, and we're running on its m->g0.
686 // Save current m->g0->sched.sp on stack and then set it to SP.
687 // Save current sp in m->g0->sched.sp in preparation for
688 // switch back to m->curg stack.
689 // NOTE: unwindm knows that the saved g->sched.sp is at 4(R13) aka savedsp-12(SP).
691 MOVW (g_sched+gobuf_sp)(R3), R4
692 MOVW R4, savedsp-12(SP) // must match frame size
693 MOVW R13, (g_sched+gobuf_sp)(R3)
695 // Switch to m->curg stack and call runtime.cgocallbackg.
696 // Because we are taking over the execution of m->curg
697 // but *not* resuming what had been running, we need to
698 // save that information (m->curg->sched) so we can restore it.
699 // We can restore m->curg->sched.sp easily, because calling
700 // runtime.cgocallbackg leaves SP unchanged upon return.
701 // To save m->curg->sched.pc, we push it onto the curg stack and
702 // open a frame the same size as cgocallback's g0 frame.
703 // Once we switch to the curg stack, the pushed PC will appear
704 // to be the return PC of cgocallback, so that the traceback
705 // will seamlessly trace back into the earlier calls.
708 MOVW (g_sched+gobuf_sp)(g), R4 // prepare stack as R4
709 MOVW (g_sched+gobuf_pc)(g), R5
710 MOVW R5, -(12+4)(R4) // "saved LR"; must match frame size
711 // Gather our arguments into registers.
715 MOVW $-(12+4)(R4), R13 // switch stack; must match frame size
719 BL runtime·cgocallbackg(SB)
721 // Restore g->sched (== m->curg->sched) from saved values.
723 MOVW R5, (g_sched+gobuf_pc)(g)
724 MOVW $(12+4)(R13), R4 // must match frame size
725 MOVW R4, (g_sched+gobuf_sp)(g)
727 // Switch back to m->g0's stack and restore m->g0->sched.sp.
728 // (Unlike m->curg, the g0 goroutine never uses sched.pc,
729 // so we do not have to restore it.)
733 MOVW (g_sched+gobuf_sp)(g), R13
734 MOVW savedsp-12(SP), R4 // must match frame size
735 MOVW R4, (g_sched+gobuf_sp)(g)
737 // If the m on entry was nil, we called needm above to borrow an m,
738 // 1. for the duration of the call on non-pthread platforms,
739 // 2. or the duration of the C thread alive on pthread platforms.
740 // If the m on entry wasn't nil,
741 // 1. the thread might be a Go thread,
742 // 2. or it's wasn't the first call from a C thread on pthread platforms,
743 // since the we skip dropm to resue the m in the first call.
744 MOVW savedm-4(SP), R6
748 // Skip dropm to reuse it in the next call, when a pthread key has been created.
749 MOVW _cgo_pthread_key_created(SB), R6
750 // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
758 MOVW $runtime·dropm(SB), R0
765 // void setg(G*); set g. for use by needm.
766 TEXT runtime·setg(SB),NOSPLIT|NOFRAME,$0-4
770 TEXT setg<>(SB),NOSPLIT|NOFRAME,$0-0
773 // Save g to thread-local storage.
780 MOVB runtime·iscgo(SB), R0
790 TEXT runtime·emptyfunc(SB),0,$0-0
793 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
797 // armPublicationBarrier is a native store/store barrier for ARMv7+.
798 // On earlier ARM revisions, armPublicationBarrier is a no-op.
799 // This will not work on SMP ARMv6 machines, if any are in use.
800 // To implement publicationBarrier in sys_$GOOS_arm.s using the native
801 // instructions, use:
803 // TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
804 // B runtime·armPublicationBarrier(SB)
806 TEXT runtime·armPublicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
807 MOVB runtime·goarm(SB), R11
813 // AES hashing not implemented for ARM
814 TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-16
815 JMP runtime·memhashFallback(SB)
816 TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-12
817 JMP runtime·strhashFallback(SB)
818 TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-12
819 JMP runtime·memhash32Fallback(SB)
820 TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-12
821 JMP runtime·memhash64Fallback(SB)
823 TEXT runtime·return0(SB),NOSPLIT,$0
827 TEXT runtime·procyield(SB),NOSPLIT|NOFRAME,$0
828 MOVW cycles+0(FP), R1
831 WORD $0xe320f001 // YIELD (NOP pre-ARMv6K)
838 // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
839 // Must obey the gcc calling convention.
840 TEXT _cgo_topofstack(SB),NOSPLIT,$8
841 // R11 and g register are clobbered by load_g. They are
842 // callee-save in the gcc calling convention, so save them here.
843 MOVW R11, saveR11-4(SP)
846 BL runtime·load_g(SB)
849 MOVW (g_stack+stack_hi)(R0), R0
852 MOVW saveR11-4(SP), R11
855 // The top-most function running on a goroutine
856 // returns to goexit+PCQuantum.
857 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
859 BL runtime·goexit1(SB) // does not return
860 // traceback from goexit1 must hit code range of goexit
863 // x -> x/1000000, x%1000000, called from Go with args, results on stack.
864 TEXT runtime·usplit(SB),NOSPLIT,$0-12
866 CALL runtime·usplitR0(SB)
871 // R0, R1 = R0/1000000, R0%1000000
872 TEXT runtime·usplitR0(SB),NOSPLIT,$0
873 // magic multiply to avoid software divide without available m.
874 // see output of go tool compile -S for x/1000000.
877 MULLU R1, R0, (R0, R1)
884 // This is called from .init_array and follows the platform, not Go, ABI.
885 TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
886 MOVW R9, saver9-4(SP) // The access to global variables below implicitly uses R9, which is callee-save
887 MOVW R11, saver11-8(SP) // Likewise, R11 is the temp register, but callee-save in C ABI
888 MOVW runtime·lastmoduledatap(SB), R1
889 MOVW R0, moduledata_next(R1)
890 MOVW R0, runtime·lastmoduledatap(SB)
891 MOVW saver11-8(SP), R11
892 MOVW saver9-4(SP), R9
895 TEXT ·checkASM(SB),NOSPLIT,$0-1
900 // gcWriteBarrier informs the GC about heap pointer writes.
902 // gcWriteBarrier does NOT follow the Go ABI. It accepts the
903 // number of bytes of buffer needed in R8, and returns a pointer
904 // to the buffer space in R8.
905 // It clobbers condition codes.
906 // It does not clobber any other general-purpose registers,
907 // but may clobber others (e.g., floating point registers).
908 // The act of CALLing gcWriteBarrier will clobber R14 (LR).
909 TEXT gcWriteBarrier<>(SB),NOSPLIT|NOFRAME,$0
910 // Save the registers clobbered by the fast path.
911 MOVM.DB.W [R0,R1], (R13)
915 MOVW (p_wbBuf+wbBuf_next)(R0), R1
916 MOVW (p_wbBuf+wbBuf_end)(R0), R11
917 // Increment wbBuf.next position.
919 // Is the buffer full?
922 // Commit to the larger buffer.
923 MOVW R1, (p_wbBuf+wbBuf_next)(R0)
924 // Make return value (the original next position)
926 // Restore registers.
927 MOVM.IA.W (R13), [R0,R1]
931 // Save all general purpose registers since these could be
932 // clobbered by wbBufFlush and were not saved by the caller.
934 // R0 and R1 were saved at entry.
935 // R10 is g, so preserved.
936 // R11 is linker temp, so no need to save.
937 // R13 is stack pointer.
939 MOVM.DB.W [R2-R9,R12], (R13)
940 // Save R14 (LR) because the fast path above doesn't save it,
941 // but needs it to RET.
942 MOVM.DB.W [R14], (R13)
944 CALL runtime·wbBufFlush(SB)
946 MOVM.IA.W (R13), [R14]
947 MOVM.IA.W (R13), [R2-R9,R12]
950 TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
952 JMP gcWriteBarrier<>(SB)
953 TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
955 JMP gcWriteBarrier<>(SB)
956 TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
958 JMP gcWriteBarrier<>(SB)
959 TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
961 JMP gcWriteBarrier<>(SB)
962 TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
964 JMP gcWriteBarrier<>(SB)
965 TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
967 JMP gcWriteBarrier<>(SB)
968 TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
970 JMP gcWriteBarrier<>(SB)
971 TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
973 JMP gcWriteBarrier<>(SB)
975 // Note: these functions use a special calling convention to save generated code space.
976 // Arguments are passed in registers, but the space for those arguments are allocated
977 // in the caller's stack frame. These stubs write the args into that stack space and
978 // then tail call to the corresponding runtime handler.
979 // The tail call makes these stubs disappear in backtraces.
980 TEXT runtime·panicIndex(SB),NOSPLIT,$0-8
983 JMP runtime·goPanicIndex(SB)
984 TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8
987 JMP runtime·goPanicIndexU(SB)
988 TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8
991 JMP runtime·goPanicSliceAlen(SB)
992 TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8
995 JMP runtime·goPanicSliceAlenU(SB)
996 TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8
999 JMP runtime·goPanicSliceAcap(SB)
1000 TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8
1003 JMP runtime·goPanicSliceAcapU(SB)
1004 TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8
1007 JMP runtime·goPanicSliceB(SB)
1008 TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8
1011 JMP runtime·goPanicSliceBU(SB)
1012 TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8
1015 JMP runtime·goPanicSlice3Alen(SB)
1016 TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8
1019 JMP runtime·goPanicSlice3AlenU(SB)
1020 TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8
1023 JMP runtime·goPanicSlice3Acap(SB)
1024 TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8
1027 JMP runtime·goPanicSlice3AcapU(SB)
1028 TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8
1031 JMP runtime·goPanicSlice3B(SB)
1032 TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8
1035 JMP runtime·goPanicSlice3BU(SB)
1036 TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8
1039 JMP runtime·goPanicSlice3C(SB)
1040 TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8
1043 JMP runtime·goPanicSlice3CU(SB)
1044 TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-8
1047 JMP runtime·goPanicSliceConvert(SB)
1049 // Extended versions for 64-bit indexes.
1050 TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12
1054 JMP runtime·goPanicExtendIndex(SB)
1055 TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12
1059 JMP runtime·goPanicExtendIndexU(SB)
1060 TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12
1064 JMP runtime·goPanicExtendSliceAlen(SB)
1065 TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12
1069 JMP runtime·goPanicExtendSliceAlenU(SB)
1070 TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12
1074 JMP runtime·goPanicExtendSliceAcap(SB)
1075 TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12
1079 JMP runtime·goPanicExtendSliceAcapU(SB)
1080 TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12
1084 JMP runtime·goPanicExtendSliceB(SB)
1085 TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12
1089 JMP runtime·goPanicExtendSliceBU(SB)
1090 TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12
1094 JMP runtime·goPanicExtendSlice3Alen(SB)
1095 TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12
1099 JMP runtime·goPanicExtendSlice3AlenU(SB)
1100 TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12
1104 JMP runtime·goPanicExtendSlice3Acap(SB)
1105 TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12
1109 JMP runtime·goPanicExtendSlice3AcapU(SB)
1110 TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12
1114 JMP runtime·goPanicExtendSlice3B(SB)
1115 TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12
1119 JMP runtime·goPanicExtendSlice3BU(SB)
1120 TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12
1124 JMP runtime·goPanicExtendSlice3C(SB)
1125 TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12
1129 JMP runtime·goPanicExtendSlice3CU(SB)