| // 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. |
| |
| //go:build ppc64 || ppc64le |
| |
| #include "textflag.h" |
| #include "asm_ppc64x.h" |
| #include "abi_ppc64x.h" |
| |
| #ifdef GO_PPC64X_HAS_FUNCDESC |
| // crosscall2 is marked with go:cgo_export_static. On AIX, this creates and exports |
| // the symbol name and descriptor as the AIX linker expects, but does not work if |
| // referenced from within Go. Create and use an aliased descriptor of crosscall2 |
| // to workaround this. |
| DEFINE_PPC64X_FUNCDESC(_crosscall2<>, crosscall2) |
| #define CROSSCALL2_FPTR $_crosscall2<>(SB) |
| #else |
| // Use a local trampoline, to avoid taking the address of a dynamically exported |
| // function. |
| #define CROSSCALL2_FPTR $crosscall2_trampoline<>(SB) |
| #endif |
| |
| // 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 |
| MOVD CROSSCALL2_FPTR, R6 |
| MOVD R6, (R5) |
| RET |
| |
| TEXT crosscall2_trampoline<>(SB),NOSPLIT,$0-0 |
| JMP crosscall2(SB) |
| |
| // 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. |
| // The value of R2 is saved on the new stack frame, and not |
| // the caller's frame due to issue #43228. |
| TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0 |
| // Start with standard C stack frame layout and linkage, allocate |
| // 32 bytes of argument space, save callee-save regs, and set R0 to $0. |
| STACK_AND_SAVE_HOST_TO_GO_ABI(32) |
| // The above will not preserve R2 (TOC). Save it in case Go is |
| // compiled without a TOC pointer (e.g -buildmode=default). |
| MOVD R2, 24(R1) |
| |
| // Load the current g. |
| BL runtime·load_g(SB) |
| |
| #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 |
| // Skip R5 = n uint32 |
| MOVD R6, FIXED_FRAME+16(R1) // ctxt uintptr |
| BL runtime·cgocallback(SB) |
| |
| // Restore the old frame, and R2. |
| MOVD 24(R1), R2 |
| UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(32) |
| RET |