mirror of https://go.googlesource.com/go
87 lines
2.0 KiB
ArmAsm
87 lines
2.0 KiB
ArmAsm
// 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 linux && (ppc64 || ppc64le)
|
|
|
|
.file "gcc_linux_ppc64x.S"
|
|
|
|
// Define a frame which has no argument space, but is compatible with
|
|
// a call into a Go ABI. We allocate 32B to match FIXED_FRAME with
|
|
// similar semantics, except we store the backchain pointer, not the
|
|
// LR at offset 0. R2 is stored in the Go TOC save slot (offset 24).
|
|
.set GPR_OFFSET, 32
|
|
.set FPR_OFFSET, GPR_OFFSET + 18*8
|
|
.set VR_OFFSET, FPR_OFFSET + 18*8
|
|
.set FRAME_SIZE, VR_OFFSET + 12*16
|
|
|
|
.macro FOR_EACH_GPR opcode r=14
|
|
.ifge 31 - \r
|
|
\opcode \r, GPR_OFFSET + 8*(\r-14)(1)
|
|
FOR_EACH_GPR \opcode "(\r+1)"
|
|
.endif
|
|
.endm
|
|
|
|
.macro FOR_EACH_FPR opcode fr=14
|
|
.ifge 31 - \fr
|
|
\opcode \fr, FPR_OFFSET + 8*(\fr-14)(1)
|
|
FOR_EACH_FPR \opcode "(\fr+1)"
|
|
.endif
|
|
.endm
|
|
|
|
.macro FOR_EACH_VR opcode vr=20
|
|
.ifge 31 - \vr
|
|
li 0, VR_OFFSET + 16*(\vr-20)
|
|
\opcode \vr, 1, 0
|
|
FOR_EACH_VR \opcode "(\vr+1)"
|
|
.endif
|
|
.endm
|
|
|
|
/*
|
|
* void crosscall_ppc64(void (*fn)(void), void *g)
|
|
*
|
|
* Calling into the gc tool chain, where all registers are caller save.
|
|
* Called from standard ppc64 C ABI, where r2, r14-r31, f14-f31 are
|
|
* callee-save, so they must be saved explicitly.
|
|
*/
|
|
.globl crosscall_ppc64
|
|
crosscall_ppc64:
|
|
// Start with standard C stack frame layout and linkage
|
|
mflr %r0
|
|
std %r0, 16(%r1) // Save LR in caller's frame
|
|
mfcr %r0
|
|
std %r0, 8(%r1) // Save CR in caller's frame
|
|
stdu %r1, -FRAME_SIZE(%r1)
|
|
std %r2, 24(%r1)
|
|
|
|
FOR_EACH_GPR std
|
|
FOR_EACH_FPR stfd
|
|
FOR_EACH_VR stvx
|
|
|
|
// Set up Go ABI constant registers
|
|
li %r0, 0
|
|
|
|
// Restore g pointer (r30 in Go ABI, which may have been clobbered by C)
|
|
mr %r30, %r4
|
|
|
|
// Call fn
|
|
mr %r12, %r3
|
|
mtctr %r3
|
|
bctrl
|
|
|
|
FOR_EACH_GPR ld
|
|
FOR_EACH_FPR lfd
|
|
FOR_EACH_VR lvx
|
|
|
|
ld %r2, 24(%r1)
|
|
addi %r1, %r1, FRAME_SIZE
|
|
ld %r0, 16(%r1)
|
|
mtlr %r0
|
|
ld %r0, 8(%r1)
|
|
mtcr %r0
|
|
blr
|
|
|
|
#ifdef __ELF__
|
|
.section .note.GNU-stack,"",%progbits
|
|
#endif
|