aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/cgo/abi_amd64.h
blob: 9949435fe9e0ae05468a0ae07d673f81ba9f291c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// 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