asm_ppc64le.s raw
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.
4
5 #include "textflag.h"
6 #include "abi_ppc64x.h"
7
8 // Called by C code generated by cmd/cgo.
9 // func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
10 // Saves C callee-saved registers and calls cgocallback with three arguments.
11 // fn is the PC of a func(a unsafe.Pointer) function.
12 //
13 // This is a simplified version that only saves GPR and FPR registers,
14 // not vector registers. This keeps the stack frame smaller to avoid
15 // exceeding the nosplit stack limit.
16 //
17 // On PPC64LE ELFv2, callee-save registers are:
18 // R14-R31 (18 GPRs = 144 bytes)
19 // F14-F31 (18 FPRs = 144 bytes)
20 // CR2-CR4 (saved in CR field)
21 //
22 // Stack layout (must be 16-byte aligned):
23 // 32 (FIXED_FRAME) + 24 (args) + 144 (GPR) + 144 (FPR) = 344
24 // Rounded to 352 for 16-byte alignment.
25
26 #define FIXED_FRAME 32
27 #define SAVE_SIZE 352
28 #define GPR_OFFSET (FIXED_FRAME+24)
29 #define FPR_OFFSET (GPR_OFFSET+SAVE_GPR_SIZE)
30
31 TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
32 // Save LR and CR in caller's frame per ELFv2 ABI
33 MOVD LR, R0
34 MOVD R0, 16(R1)
35 MOVW CR, R0
36 MOVD R0, 8(R1)
37
38 // Allocate our stack frame
39 MOVDU R1, -SAVE_SIZE(R1)
40
41 // Save TOC (R2) in case needed
42 MOVD R2, 24(R1)
43
44 // Save callee-save GPRs
45 SAVE_GPR(GPR_OFFSET)
46
47 // Save callee-save FPRs
48 SAVE_FPR(FPR_OFFSET)
49
50 // Initialize R0 to 0 as expected by Go
51 MOVD $0, R0
52
53 // Load the current g.
54 BL runtimeĀ·load_g(SB)
55
56 // Set up arguments for cgocallback
57 MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer
58 MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer
59
60 // Skip R5 = n uint32
61 MOVD R6, FIXED_FRAME+16(R1) // ctxt uintptr
62 BL runtimeĀ·cgocallback(SB)
63
64 // Restore callee-save FPRs
65 RESTORE_FPR(FPR_OFFSET)
66
67 // Restore callee-save GPRs
68 RESTORE_GPR(GPR_OFFSET)
69
70 // Restore TOC
71 MOVD 24(R1), R2
72
73 // Deallocate stack frame
74 ADD $SAVE_SIZE, R1
75
76 // Restore LR and CR from caller's frame
77 MOVD 16(R1), R0
78 MOVD R0, LR
79 MOVD 8(R1), R0
80 MOVW R0, CR
81
82 RET
83