aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/cgo
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2021-04-13 23:30:19 -0400
committerAustin Clements <austin@google.com>2021-04-15 12:38:13 +0000
commit7ad496b6f5300131d6f1fbafe44ac882897889e4 (patch)
tree99f5c84ae8cebe176f35097effee24bc5e93e4bb /src/runtime/cgo
parentdba2eab8267599f5f59f1f586b47f31b6552938c (diff)
downloadgo-7ad496b6f5300131d6f1fbafe44ac882897889e4.tar.gz
go-7ad496b6f5300131d6f1fbafe44ac882897889e4.zip
runtime: unify C->Go ABI transitions
The previous CL introduced macros for transitions from the Windows ABI to the Go ABI. This CL does the same for SysV and uses them in almost all places where we transition from the C ABI to the Go ABI. Compared to Windows, this transition is much simpler and I didn't find any places that were getting it wrong. But this does let us unify a lot of code nicely and introduces some degree of abstraction around these ABI transitions. Change-Id: Ib6bdecafce587ce18fca4c8300fcf401284a2bcd Reviewed-on: https://go-review.googlesource.com/c/go/+/309930 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/cgo')
-rw-r--r--src/runtime/cgo/abi_amd64.h32
-rw-r--r--src/runtime/cgo/asm_amd64.s30
2 files changed, 37 insertions, 25 deletions
diff --git a/src/runtime/cgo/abi_amd64.h b/src/runtime/cgo/abi_amd64.h
index 44cc0969da..9949435fe9 100644
--- a/src/runtime/cgo/abi_amd64.h
+++ b/src/runtime/cgo/abi_amd64.h
@@ -4,7 +4,9 @@
// Macros for transitioning from the host ABI to Go ABI0.
//
-// TODO(austin): Define these for ELF platforms as well.
+// 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
@@ -66,4 +68,32 @@
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
diff --git a/src/runtime/cgo/asm_amd64.s b/src/runtime/cgo/asm_amd64.s
index 447ddb118d..386299c548 100644
--- a/src/runtime/cgo/asm_amd64.s
+++ b/src/runtime/cgo/asm_amd64.s
@@ -10,43 +10,25 @@
// Saves C callee-saved registers and calls cgocallback with three arguments.
// fn is the PC of a func(a unsafe.Pointer) function.
// This signature is known to SWIG, so we can't change it.
-#ifndef GOOS_windows
-TEXT crosscall2(SB),NOSPLIT,$0x50-0 /* keeps stack pointer 32-byte aligned */
- MOVQ BX, 0x18(SP)
- MOVQ R12, 0x28(SP)
- MOVQ R13, 0x30(SP)
- MOVQ R14, 0x38(SP)
- MOVQ R15, 0x40(SP)
+TEXT crosscall2(SB),NOSPLIT,$0-0
+ PUSH_REGS_HOST_TO_ABI0()
+ // Make room for arguments to cgocallback.
+ ADJSP $0x18
+#ifndef GOOS_windows
MOVQ DI, 0x0(SP) /* fn */
MOVQ SI, 0x8(SP) /* arg */
// Skip n in DX.
MOVQ CX, 0x10(SP) /* ctxt */
-
- CALL runtime·cgocallback(SB)
-
- MOVQ 0x18(SP), BX
- MOVQ 0x28(SP), R12
- MOVQ 0x30(SP), R13
- MOVQ 0x38(SP), R14
- MOVQ 0x40(SP), R15
-
- RET
-
#else
-TEXT crosscall2(SB),NOSPLIT,$0-0
- PUSH_REGS_HOST_TO_ABI0()
-
- // Make room for arguments to cgocallback.
- ADJSP $0x18
MOVQ CX, 0x0(SP) /* fn */
MOVQ DX, 0x8(SP) /* arg */
// Skip n in R8.
MOVQ R9, 0x10(SP) /* ctxt */
+#endif
CALL runtime·cgocallback(SB)
ADJSP $-0x18
POP_REGS_HOST_TO_ABI0()
RET
-#endif