#include "textflag.h"
#include "asm_ppc64x.h"
+// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
+// It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2
+TEXT ·set_crosscall2(SB),NOSPLIT,$0-0
+ MOVD _crosscall2_ptr(SB), R5
+#ifdef GOARCH_ppc64
+ MOVD $_crosscall2<>(SB), R6
+#else
+ MOVD $crosscall2(SB), R6
+#endif
+ MOVD R6, (R5)
+ RET
+
+#ifdef GO_PPC64X_HAS_FUNCDESC
+// _crosscall2<> is a function descriptor to the real crosscall2.
+DATA _crosscall2<>+0(SB)/8, $crosscall2(SB)
+DATA _crosscall2<>+8(SB)/8, $TOC(SB)
+DATA _crosscall2<>+16(SB)/8, $0
+GLOBL _crosscall2<>(SB), NOPTR, $24
+#endif
+
// Called by C code generated by cmd/cgo.
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
// Saves C callee-saved registers and calls cgocallback with three arguments.
#ifdef GO_PPC64X_HAS_FUNCDESC
// Load the real entry address from the first slot of the function descriptor.
+ // The first argument fn might be null, that means dropm in pthread key destructor.
+ CMP R3, $0
+ BEQ nil_fn
MOVD 8(R3), R2
MOVD (R3), R3
+nil_fn:
#endif
MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer
MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer