diff options
Diffstat (limited to 'src/runtime/cgo/asm_ppc64x.s')
-rw-r--r-- | src/runtime/cgo/asm_ppc64x.s | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/runtime/cgo/asm_ppc64x.s b/src/runtime/cgo/asm_ppc64x.s new file mode 100644 index 0000000..f4efc1e --- /dev/null +++ b/src/runtime/cgo/asm_ppc64x.s @@ -0,0 +1,134 @@ +// 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. + +// +build ppc64 ppc64le + +#include "textflag.h" +#include "asm_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. +TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0 + // Start with standard C stack frame layout and linkage + MOVD LR, R0 + MOVD R0, 16(R1) // Save LR in caller's frame + MOVW CR, R0 // Save CR in caller's frame + MOVD R0, 8(R1) + MOVD R2, 24(R1) // Save TOC in caller's frame + + BL saveregs2<>(SB) + + MOVDU R1, (-288-3*8-FIXED_FRAME)(R1) + + // Initialize Go ABI environment + BL runtime·reginit(SB) + BL runtime·load_g(SB) + +#ifdef GOARCH_ppc64 + // ppc64 use elf ABI v1. we must get the real entry address from + // first slot of the function descriptor before call. + // Same for AIX. + MOVD 8(R3), R2 + MOVD (R3), R3 +#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) + + ADD $(288+3*8+FIXED_FRAME), R1 + + BL restoreregs2<>(SB) + + MOVD 24(R1), R2 + MOVD 8(R1), R0 + MOVFL R0, $0xff + MOVD 16(R1), R0 + MOVD R0, LR + RET + +TEXT saveregs2<>(SB),NOSPLIT|NOFRAME,$0 + // 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 + MOVD R14, -288(R1) + MOVD R15, -280(R1) + MOVD R16, -272(R1) + MOVD R17, -264(R1) + MOVD R18, -256(R1) + MOVD R19, -248(R1) + MOVD R20, -240(R1) + MOVD R21, -232(R1) + MOVD R22, -224(R1) + MOVD R23, -216(R1) + MOVD R24, -208(R1) + MOVD R25, -200(R1) + MOVD R26, -192(R1) + MOVD R27, -184(R1) + MOVD R28, -176(R1) + MOVD R29, -168(R1) + MOVD g, -160(R1) + MOVD R31, -152(R1) + FMOVD F14, -144(R1) + FMOVD F15, -136(R1) + FMOVD F16, -128(R1) + FMOVD F17, -120(R1) + FMOVD F18, -112(R1) + FMOVD F19, -104(R1) + FMOVD F20, -96(R1) + FMOVD F21, -88(R1) + FMOVD F22, -80(R1) + FMOVD F23, -72(R1) + FMOVD F24, -64(R1) + FMOVD F25, -56(R1) + FMOVD F26, -48(R1) + FMOVD F27, -40(R1) + FMOVD F28, -32(R1) + FMOVD F29, -24(R1) + FMOVD F30, -16(R1) + FMOVD F31, -8(R1) + + RET + +TEXT restoreregs2<>(SB),NOSPLIT|NOFRAME,$0 + // 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 + MOVD -288(R1), R14 + MOVD -280(R1), R15 + MOVD -272(R1), R16 + MOVD -264(R1), R17 + MOVD -256(R1), R18 + MOVD -248(R1), R19 + MOVD -240(R1), R20 + MOVD -232(R1), R21 + MOVD -224(R1), R22 + MOVD -216(R1), R23 + MOVD -208(R1), R24 + MOVD -200(R1), R25 + MOVD -192(R1), R26 + MOVD -184(R1), R27 + MOVD -176(R1), R28 + MOVD -168(R1), R29 + MOVD -160(R1), g + MOVD -152(R1), R31 + FMOVD -144(R1), F14 + FMOVD -136(R1), F15 + FMOVD -128(R1), F16 + FMOVD -120(R1), F17 + FMOVD -112(R1), F18 + FMOVD -104(R1), F19 + FMOVD -96(R1), F20 + FMOVD -88(R1), F21 + FMOVD -80(R1), F22 + FMOVD -72(R1), F23 + FMOVD -64(R1), F24 + FMOVD -56(R1), F25 + FMOVD -48(R1), F26 + FMOVD -40(R1), F27 + FMOVD -32(R1), F28 + FMOVD -24(R1), F29 + FMOVD -16(R1), F30 + FMOVD -8(R1), F31 + + RET |