100 lines
2.7 KiB
C
100 lines
2.7 KiB
C
|
// Copyright 2021 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.
|
||
|
|
||
|
// Macros for transitioning from the host ABI to Go ABI0.
|
||
|
//
|
||
|
// These save the frame pointer, so in general, functions that use
|
||
|
// these should have zero frame size to suppress the automatic frame
|
||
|
// pointer, though it's harmless to not do this.
|
||
|
|
||
|
#ifdef GOOS_windows
|
||
|
|
||
|
// REGS_HOST_TO_ABI0_STACK is the stack bytes used by
|
||
|
// PUSH_REGS_HOST_TO_ABI0.
|
||
|
#define REGS_HOST_TO_ABI0_STACK (28*8 + 8)
|
||
|
|
||
|
// PUSH_REGS_HOST_TO_ABI0 prepares for transitioning from
|
||
|
// the host ABI to Go ABI0 code. It saves all registers that are
|
||
|
// callee-save in the host ABI and caller-save in Go ABI0 and prepares
|
||
|
// for entry to Go.
|
||
|
//
|
||
|
// Save DI SI BP BX R12 R13 R14 R15 X6-X15 registers and the DF flag.
|
||
|
// Clear the DF flag for the Go ABI.
|
||
|
// MXCSR matches the Go ABI, so we don't have to set that,
|
||
|
// and Go doesn't modify it, so we don't have to save it.
|
||
|
#define PUSH_REGS_HOST_TO_ABI0() \
|
||
|
PUSHFQ \
|
||
|
CLD \
|
||
|
ADJSP $(REGS_HOST_TO_ABI0_STACK - 8) \
|
||
|
MOVQ DI, (0*0)(SP) \
|
||
|
MOVQ SI, (1*8)(SP) \
|
||
|
MOVQ BP, (2*8)(SP) \
|
||
|
MOVQ BX, (3*8)(SP) \
|
||
|
MOVQ R12, (4*8)(SP) \
|
||
|
MOVQ R13, (5*8)(SP) \
|
||
|
MOVQ R14, (6*8)(SP) \
|
||
|
MOVQ R15, (7*8)(SP) \
|
||
|
MOVUPS X6, (8*8)(SP) \
|
||
|
MOVUPS X7, (10*8)(SP) \
|
||
|
MOVUPS X8, (12*8)(SP) \
|
||
|
MOVUPS X9, (14*8)(SP) \
|
||
|
MOVUPS X10, (16*8)(SP) \
|
||
|
MOVUPS X11, (18*8)(SP) \
|
||
|
MOVUPS X12, (20*8)(SP) \
|
||
|
MOVUPS X13, (22*8)(SP) \
|
||
|
MOVUPS X14, (24*8)(SP) \
|
||
|
MOVUPS X15, (26*8)(SP)
|
||
|
|
||
|
#define POP_REGS_HOST_TO_ABI0() \
|
||
|
MOVQ (0*0)(SP), DI \
|
||
|
MOVQ (1*8)(SP), SI \
|
||
|
MOVQ (2*8)(SP), BP \
|
||
|
MOVQ (3*8)(SP), BX \
|
||
|
MOVQ (4*8)(SP), R12 \
|
||
|
MOVQ (5*8)(SP), R13 \
|
||
|
MOVQ (6*8)(SP), R14 \
|
||
|
MOVQ (7*8)(SP), R15 \
|
||
|
MOVUPS (8*8)(SP), X6 \
|
||
|
MOVUPS (10*8)(SP), X7 \
|
||
|
MOVUPS (12*8)(SP), X8 \
|
||
|
MOVUPS (14*8)(SP), X9 \
|
||
|
MOVUPS (16*8)(SP), X10 \
|
||
|
MOVUPS (18*8)(SP), X11 \
|
||
|
MOVUPS (20*8)(SP), X12 \
|
||
|
MOVUPS (22*8)(SP), X13 \
|
||
|
MOVUPS (24*8)(SP), X14 \
|
||
|
MOVUPS (26*8)(SP), X15 \
|
||
|
ADJSP $-(REGS_HOST_TO_ABI0_STACK - 8) \
|
||
|
POPFQ
|
||
|
|
||
|
#else
|
||
|
// SysV ABI
|
||
|
|
||
|
#define REGS_HOST_TO_ABI0_STACK (6*8)
|
||
|
|
||
|
// SysV MXCSR matches the Go ABI, so we don't have to set that,
|
||
|
// and Go doesn't modify it, so we don't have to save it.
|
||
|
// Both SysV and Go require DF to be cleared, so that's already clear.
|
||
|
// The SysV and Go frame pointer conventions are compatible.
|
||
|
#define PUSH_REGS_HOST_TO_ABI0() \
|
||
|
ADJSP $(REGS_HOST_TO_ABI0_STACK) \
|
||
|
MOVQ BP, (5*8)(SP) \
|
||
|
LEAQ (5*8)(SP), BP \
|
||
|
MOVQ BX, (0*8)(SP) \
|
||
|
MOVQ R12, (1*8)(SP) \
|
||
|
MOVQ R13, (2*8)(SP) \
|
||
|
MOVQ R14, (3*8)(SP) \
|
||
|
MOVQ R15, (4*8)(SP)
|
||
|
|
||
|
#define POP_REGS_HOST_TO_ABI0() \
|
||
|
MOVQ (0*8)(SP), BX \
|
||
|
MOVQ (1*8)(SP), R12 \
|
||
|
MOVQ (2*8)(SP), R13 \
|
||
|
MOVQ (3*8)(SP), R14 \
|
||
|
MOVQ (4*8)(SP), R15 \
|
||
|
MOVQ (5*8)(SP), BP \
|
||
|
ADJSP $-(REGS_HOST_TO_ABI0_STACK)
|
||
|
|
||
|
#endif
|