1 // Copyright 2021 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 
5 // Macros for transitioning from the host ABI to Go ABI0.
6 //
7 // These save the frame pointer, so in general, functions that use
8 // these should have zero frame size to suppress the automatic frame
9 // pointer, though it's harmless to not do this.
10 
11 #ifdef GOOS_windows
12 
13 // REGS_HOST_TO_ABI0_STACK is the stack bytes used by
14 // PUSH_REGS_HOST_TO_ABI0.
15 #define REGS_HOST_TO_ABI0_STACK (28*8 + 8)
16 
17 // PUSH_REGS_HOST_TO_ABI0 prepares for transitioning from
18 // the host ABI to Go ABI0 code. It saves all registers that are
19 // callee-save in the host ABI and caller-save in Go ABI0 and prepares
20 // for entry to Go.
21 //
22 // Save DI SI BP BX R12 R13 R14 R15 X6-X15 registers and the DF flag.
23 // Clear the DF flag for the Go ABI.
24 // MXCSR matches the Go ABI, so we don't have to set that,
25 // and Go doesn't modify it, so we don't have to save it.
26 #define PUSH_REGS_HOST_TO_ABI0()	\
27 	PUSHFQ			\
28 	CLD			\
29 	ADJSP	$(REGS_HOST_TO_ABI0_STACK - 8)	\
30 	MOVQ	DI, (0*0)(SP)	\
31 	MOVQ	SI, (1*8)(SP)	\
32 	MOVQ	BP, (2*8)(SP)	\
33 	MOVQ	BX, (3*8)(SP)	\
34 	MOVQ	R12, (4*8)(SP)	\
35 	MOVQ	R13, (5*8)(SP)	\
36 	MOVQ	R14, (6*8)(SP)	\
37 	MOVQ	R15, (7*8)(SP)	\
38 	MOVUPS	X6, (8*8)(SP)	\
39 	MOVUPS	X7, (10*8)(SP)	\
40 	MOVUPS	X8, (12*8)(SP)	\
41 	MOVUPS	X9, (14*8)(SP)	\
42 	MOVUPS	X10, (16*8)(SP)	\
43 	MOVUPS	X11, (18*8)(SP)	\
44 	MOVUPS	X12, (20*8)(SP)	\
45 	MOVUPS	X13, (22*8)(SP)	\
46 	MOVUPS	X14, (24*8)(SP)	\
47 	MOVUPS	X15, (26*8)(SP)
48 
49 #define POP_REGS_HOST_TO_ABI0()	\
50 	MOVQ	(0*0)(SP), DI	\
51 	MOVQ	(1*8)(SP), SI	\
52 	MOVQ	(2*8)(SP), BP	\
53 	MOVQ	(3*8)(SP), BX	\
54 	MOVQ	(4*8)(SP), R12	\
55 	MOVQ	(5*8)(SP), R13	\
56 	MOVQ	(6*8)(SP), R14	\
57 	MOVQ	(7*8)(SP), R15	\
58 	MOVUPS	(8*8)(SP), X6	\
59 	MOVUPS	(10*8)(SP), X7	\
60 	MOVUPS	(12*8)(SP), X8	\
61 	MOVUPS	(14*8)(SP), X9	\
62 	MOVUPS	(16*8)(SP), X10	\
63 	MOVUPS	(18*8)(SP), X11	\
64 	MOVUPS	(20*8)(SP), X12	\
65 	MOVUPS	(22*8)(SP), X13	\
66 	MOVUPS	(24*8)(SP), X14	\
67 	MOVUPS	(26*8)(SP), X15	\
68 	ADJSP	$-(REGS_HOST_TO_ABI0_STACK - 8)	\
69 	POPFQ
70 
71 #else
72 // SysV ABI
73 
74 #define REGS_HOST_TO_ABI0_STACK (6*8)
75 
76 // SysV MXCSR matches the Go ABI, so we don't have to set that,
77 // and Go doesn't modify it, so we don't have to save it.
78 // Both SysV and Go require DF to be cleared, so that's already clear.
79 // The SysV and Go frame pointer conventions are compatible.
80 #define PUSH_REGS_HOST_TO_ABI0()	\
81 	ADJSP	$(REGS_HOST_TO_ABI0_STACK)	\
82 	MOVQ	BP, (5*8)(SP)	\
83 	LEAQ	(5*8)(SP), BP	\
84 	MOVQ	BX, (0*8)(SP)	\
85 	MOVQ	R12, (1*8)(SP)	\
86 	MOVQ	R13, (2*8)(SP)	\
87 	MOVQ	R14, (3*8)(SP)	\
88 	MOVQ	R15, (4*8)(SP)
89 
90 #define POP_REGS_HOST_TO_ABI0()	\
91 	MOVQ	(0*8)(SP), BX	\
92 	MOVQ	(1*8)(SP), R12	\
93 	MOVQ	(2*8)(SP), R13	\
94 	MOVQ	(3*8)(SP), R14	\
95 	MOVQ	(4*8)(SP), R15	\
96 	MOVQ	(5*8)(SP), BP	\
97 	ADJSP	$-(REGS_HOST_TO_ABI0_STACK)
98 
99 #endif
100