| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- // Copyright 2014 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- #include "textflag.h"
- #include "abi_ppc64x.h"
- // 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.
- // fn is the PC of a func(a unsafe.Pointer) function.
- //
- // This is a simplified version that only saves GPR and FPR registers,
- // not vector registers. This keeps the stack frame smaller to avoid
- // exceeding the nosplit stack limit.
- //
- // On PPC64LE ELFv2, callee-save registers are:
- // R14-R31 (18 GPRs = 144 bytes)
- // F14-F31 (18 FPRs = 144 bytes)
- // CR2-CR4 (saved in CR field)
- //
- // Stack layout (must be 16-byte aligned):
- // 32 (FIXED_FRAME) + 24 (args) + 144 (GPR) + 144 (FPR) = 344
- // Rounded to 352 for 16-byte alignment.
- #define FIXED_FRAME 32
- #define SAVE_SIZE 352
- #define GPR_OFFSET (FIXED_FRAME+24)
- #define FPR_OFFSET (GPR_OFFSET+SAVE_GPR_SIZE)
- TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
- // Save LR and CR in caller's frame per ELFv2 ABI
- MOVD LR, R0
- MOVD R0, 16(R1)
- MOVW CR, R0
- MOVD R0, 8(R1)
- // Allocate our stack frame
- MOVDU R1, -SAVE_SIZE(R1)
- // Save TOC (R2) in case needed
- MOVD R2, 24(R1)
- // Save callee-save GPRs
- SAVE_GPR(GPR_OFFSET)
- // Save callee-save FPRs
- SAVE_FPR(FPR_OFFSET)
- // Initialize R0 to 0 as expected by Go
- MOVD $0, R0
- // Load the current g.
- BL runtime·load_g(SB)
- // Set up arguments for cgocallback
- MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer
- MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer
- // Skip R5 = n uint32
- MOVD R6, FIXED_FRAME+16(R1) // ctxt uintptr
- BL runtime·cgocallback(SB)
- // Restore callee-save FPRs
- RESTORE_FPR(FPR_OFFSET)
- // Restore callee-save GPRs
- RESTORE_GPR(GPR_OFFSET)
- // Restore TOC
- MOVD 24(R1), R2
- // Deallocate stack frame
- ADD $SAVE_SIZE, R1
- // Restore LR and CR from caller's frame
- MOVD 16(R1), R0
- MOVD R0, LR
- MOVD 8(R1), R0
- MOVW R0, CR
- RET
|