MOVD arg+8(FP), R4
MOVD R1, R7 // save original stack pointer
+ CMP $0, g
+ BEQ nosave
MOVD g, R5
// Figure out if we need to switch to m->g0 stack.
MOVD g_m(g), R8
MOVD m_gsignal(R8), R6
CMP R6, g
- BEQ g0
+ BEQ nosave
MOVD m_g0(R8), R6
CMP R6, g
- BEQ g0
+ BEQ nosave
+
BL gosave_systemstack_switch<>(SB)
MOVD R6, g
BL runtime·save_g(SB)
MOVD (g_sched+gobuf_sp)(g), R1
// Now on a scheduling stack (a pthread-created stack).
-g0:
#ifdef GOOS_aix
// Create a fake LR to improve backtrace.
MOVD $runtime·asmcgocall(SB), R6
MOVD R6, 16(R1)
- // AIX also save one argument on the stack.
- SUB $8, R1
+ // AIX also saves one argument on the stack.
+ SUB $8, R1
#endif
// Save room for two of our pointers, plus the callee
// save area that lives on the caller stack.
SUB $(asmcgocallSaveOffset+16), R1
RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI
- MOVD R5, (asmcgocallSaveOffset+8)(R1)// save old g on stack
+ MOVD R5, (asmcgocallSaveOffset+8)(R1) // save old g on stack
MOVD (g_stack+stack_hi)(R5), R5
SUB R7, R5
MOVD R5, asmcgocallSaveOffset(R1) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
MOVD R12, CTR
MOVD R4, R3 // arg in r3
BL (CTR)
- // C code can clobber R0, so set it back to 0. F27-F31 are
- // callee save, so we don't need to recover those.
+
+ // Reinitialise zero value register.
XOR R0, R0
+
// Restore g, stack pointer, toc pointer.
// R3 is errno, so don't touch it
MOVD (asmcgocallSaveOffset+8)(R1), g
MOVW R3, ret+16(FP)
RET
+nosave:
+ // Running on a system stack, perhaps even without a g.
+ // Having no g can happen during thread creation or thread teardown.
+ // This code is like the above sequence but without saving/restoring g
+ // and without worrying about the stack moving out from under us
+ // (because we're on a system stack, not a goroutine stack).
+ // The above code could be used directly if already on a system stack,
+ // but then the only path through this code would be a rare case.
+ // Using this code for all "already on system stack" calls exercises it more,
+ // which should help keep it correct.
+
+ SUB $(asmcgocallSaveOffset+8), R1
+ RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI
+ MOVD R7, asmcgocallSaveOffset(R1) // Save original stack pointer.
+
+ MOVD R3, R12 // fn
+#ifdef GO_PPC64X_HAS_FUNCDESC
+ // Load the real entry address from the first slot of the function descriptor.
+ MOVD 8(R12), R2
+ MOVD (R12), R12
+#endif
+ MOVD R12, CTR
+ MOVD R4, R3 // arg
+ BL (CTR)
+
+ // Reinitialise zero value register.
+ XOR R0, R0
+
+ MOVD asmcgocallSaveOffset(R1), R1 // Restore stack pointer.
+#ifndef GOOS_aix
+ MOVD 24(R1), R2
+#endif
+ MOVW R3, ret+16(FP)
+ RET
+
// func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
// See cgocall.go for more details.
TEXT ·cgocallback(SB),NOSPLIT,$24-24