MOVV R1, (g_stack+stack_lo)(g)
MOVV R29, (g_stack+stack_hi)(g)
- // no cgo yet
+ // if there is a _cgo_init, call it using the gcc ABI.
+ MOVV _cgo_init(SB), R25
+ BEQ R25, nocgo
+
+ MOVV R0, R7 // arg 3: not used
+ MOVV R0, R6 // arg 2: not used
+ MOVV $setg_gcc<>(SB), R5 // arg 1: setg
+ MOVV g, R4 // arg 0: G
+ JAL (R25)
nocgo:
// update stackguard after _cgo_init
RET
TEXT _cgo_reginit(SB),NOSPLIT,$-8-0
- // crosscall_ppc64 and crosscall2 need to reginit, but can't
+ // crosscall1 needs to reginit, but can't
// get at the 'runtime.reginit' symbol.
JMP runtime·reginit(SB)
// aligned appropriately for the gcc ABI.
// See cgocall.go for more details.
TEXT ·asmcgocall(SB),NOSPLIT,$0-20
- UNDEF // no cgo yet
+ MOVV fn+0(FP), R25
+ MOVV arg+8(FP), R4
+
+ MOVV R29, R3 // save original stack pointer
+ MOVV g, R2
+
+ // Figure out if we need to switch to m->g0 stack.
+ // We get called to create new OS threads too, and those
+ // come in on the m->g0 stack already.
+ MOVV g_m(g), R5
+ MOVV m_g0(R5), R6
+ BEQ R6, g, g0
+
+ JAL gosave<>(SB)
+ MOVV R6, g
+ JAL runtime·save_g(SB)
+ MOVV (g_sched+gobuf_sp)(g), R29
+
+ // Now on a scheduling stack (a pthread-created stack).
+g0:
+ // Save room for two of our pointers.
+ ADDV $-16, R29
+ MOVV R2, 0(R29) // save old g on stack
+ MOVV (g_stack+stack_hi)(R2), R2
+ SUBVU R3, R2
+ MOVV R2, 8(R29) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
+ JAL (R25)
+
+ // Restore g, stack pointer. R2 is return value.
+ MOVV 0(R29), g
+ JAL runtime·save_g(SB)
+ MOVV (g_stack+stack_hi)(g), R5
+ MOVV 8(R29), R6
+ SUBVU R6, R5
+ MOVV R5, R29
+
+ MOVW R2, ret+16(FP)
RET
-// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
+// cgocallback(void (*fn)(void*), void *frame, uintptr framesize, uintptr ctxt)
// Turn the fn into a Go func (by taking its address) and call
// cgocallback_gofunc.
-TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
+TEXT runtime·cgocallback(SB),NOSPLIT,$32-32
MOVV $fn+0(FP), R1
MOVV R1, 8(R29)
MOVV frame+8(FP), R1
MOVV R1, 16(R29)
MOVV framesize+16(FP), R1
MOVV R1, 24(R29)
+ MOVV ctxt+24(FP), R1
+ MOVV R1, 32(R29)
MOVV $runtime·cgocallback_gofunc(SB), R1
JAL (R1)
RET
-// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
+// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize, uintptr ctxt)
// See cgocall.go for more details.
-TEXT ·cgocallback_gofunc(SB),NOSPLIT,$16-24
+TEXT ·cgocallback_gofunc(SB),NOSPLIT,$16-32
NO_LOCAL_POINTERS
// Load m and g from thread-local storage.
// and then systemstack will try to use it. If we don't set it here,
// that restored SP will be uninitialized (typically 0) and
// will not be usable.
- MOVV g_m(g), R1
- MOVV m_g0(R1), R1
+ MOVV g_m(g), R3
+ MOVV m_g0(R3), R1
MOVV R29, (g_sched+gobuf_sp)(R1)
havem:
// so that the traceback will seamlessly trace back into
// the earlier calls.
//
- // In the new goroutine, -16(SP) and -8(SP) are unused.
+ // In the new goroutine, -8(SP) is unused (where SP refers to
+ // m->curg's SP while we're setting it up, before we've adjusted it).
MOVV m_curg(R3), g
JAL runtime·save_g(SB)
MOVV (g_sched+gobuf_sp)(g), R2 // prepare stack as R2
- MOVV (g_sched+gobuf_pc)(g), R3
- MOVV R3, -24(R2)
+ MOVV (g_sched+gobuf_pc)(g), R4
+ MOVV R4, -24(R2)
+ MOVV ctxt+24(FP), R1
+ MOVV R1, -16(R2)
MOVV $-24(R2), R29
JAL runtime·cgocallbackg(SB)
// Restore g->sched (== m->curg->sched) from saved values.
- MOVV 0(R29), R3
- MOVV R3, (g_sched+gobuf_pc)(g)
+ MOVV 0(R29), R4
+ MOVV R4, (g_sched+gobuf_pc)(g)
MOVV $24(R29), R2
MOVV R2, (g_sched+gobuf_sp)(g)
JAL runtime·save_g(SB)
RET
-// void setg_gcc(G*); set g in C TLS.
-// Must obey the gcc calling convention.
-TEXT setg_gcc<>(SB),NOSPLIT,$-8-0
- UNDEF // no cgo yet
+// void setg_gcc(G*); set g called from gcc with g in R1
+TEXT setg_gcc<>(SB),NOSPLIT,$0-0
+ MOVV R1, g
+ JAL runtime·save_g(SB)
RET
TEXT runtime·getcallerpc(SB),NOSPLIT,$8-16
// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
// Must obey the gcc calling convention.
-TEXT _cgo_topofstack(SB),NOSPLIT,$-8
- UNDEF // no cgo yet
+TEXT _cgo_topofstack(SB),NOSPLIT,$16
+ // g (R30) and REGTMP (R23) might be clobbered by load_g. They
+ // are callee-save in the gcc calling convention, so save them.
+ MOVV R23, savedR23-16(SP)
+ MOVV g, savedG-8(SP)
+
+ JAL runtime·load_g(SB)
+ MOVV g_m(g), R1
+ MOVV m_curg(R1), R1
+ MOVV (g_stack+stack_hi)(R1), R2 // return value in R2
+
+ MOVV savedG-8(SP), g
+ MOVV savedR23-16(SP), R23
RET
// The top-most function running on a goroutine