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