1 // Copyright 2014 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.
5 //go:build ppc64 || ppc64le
8 #include "asm_ppc64x.h"
10 // Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
11 // It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2
12 TEXT ·set_crosscall2(SB),NOSPLIT,$0-0
13 MOVD _crosscall2_ptr(SB), R5
15 MOVD $_crosscall2<>(SB), R6
17 MOVD $crosscall2(SB), R6
22 #ifdef GO_PPC64X_HAS_FUNCDESC
23 // _crosscall2<> is a function descriptor to the real crosscall2.
24 DATA _crosscall2<>+0(SB)/8, $crosscall2(SB)
25 DATA _crosscall2<>+8(SB)/8, $TOC(SB)
26 DATA _crosscall2<>+16(SB)/8, $0
27 GLOBL _crosscall2<>(SB), NOPTR, $24
30 // Called by C code generated by cmd/cgo.
31 // func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
32 // Saves C callee-saved registers and calls cgocallback with three arguments.
33 // fn is the PC of a func(a unsafe.Pointer) function.
34 // The value of R2 is saved on the new stack frame, and not
35 // the caller's frame due to issue #43228.
36 TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
37 // Start with standard C stack frame layout and linkage
39 MOVD R0, 16(R1) // Save LR in caller's frame
40 MOVW CR, R0 // Save CR in caller's frame
45 MOVDU R1, (-288-3*8-FIXED_FRAME)(R1)
46 // Save the caller's R2
49 // Initialize Go ABI environment
50 BL runtime·reginit(SB)
53 #ifdef GO_PPC64X_HAS_FUNCDESC
54 // Load the real entry address from the first slot of the function descriptor.
55 // The first argument fn might be null, that means dropm in pthread key destructor.
62 MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer
63 MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer
65 MOVD R6, FIXED_FRAME+16(R1) // ctxt uintptr
66 BL runtime·cgocallback(SB)
68 // Restore the caller's R2
70 ADD $(288+3*8+FIXED_FRAME), R1
80 TEXT saveregs2<>(SB),NOSPLIT|NOFRAME,$0
81 // O=-288; for R in R{14..31}; do echo "\tMOVD\t$R, $O(R1)"|sed s/R30/g/; ((O+=8)); done; for F in F{14..31}; do echo "\tFMOVD\t$F, $O(R1)"; ((O+=8)); done
121 TEXT restoreregs2<>(SB),NOSPLIT|NOFRAME,$0
122 // O=-288; for R in R{14..31}; do echo "\tMOVD\t$O(R1), $R"|sed s/R30/g/; ((O+=8)); done; for F in F{14..31}; do echo "\tFMOVD\t$O(R1), $F"; ((O+=8)); done