| // 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 |