1 /* Assembler macros for x86-64.
2    Copyright (C) 2001-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #ifndef _X86_64_SYSDEP_H
20 #define _X86_64_SYSDEP_H 1
21 
22 #include <sysdeps/x86/sysdep.h>
23 
24 #ifdef	__ASSEMBLER__
25 
26 /* Syntactic details of assembler.  */
27 
28 /* This macro is for setting proper CFI with DW_CFA_expression describing
29    the register as saved relative to %rsp instead of relative to the CFA.
30    Expression is DW_OP_drop, DW_OP_breg7 (%rsp is register 7), sleb128 offset
31    from %rsp.  */
32 #define cfi_offset_rel_rsp(regn, off)	.cfi_escape 0x10, regn, 0x4, 0x13, \
33 					0x77, off & 0x7F | 0x80, off >> 7
34 
35 /* If compiled for profiling, call `mcount' at the start of each function.  */
36 #ifdef	PROF
37 /* The mcount code relies on a normal frame pointer being on the stack
38    to locate our caller, so push one just for its benefit.  */
39 #define CALL_MCOUNT                                                          \
40   pushq %rbp;                                                                \
41   cfi_adjust_cfa_offset(8);                                                  \
42   movq %rsp, %rbp;                                                           \
43   cfi_def_cfa_register(%rbp);                                                \
44   call JUMPTARGET(mcount);                                                   \
45   popq %rbp;                                                                 \
46   cfi_def_cfa(rsp,8);
47 #else
48 #define CALL_MCOUNT		/* Do nothing.  */
49 #endif
50 
51 #define	PSEUDO(name, syscall_name, args)				      \
52 lose:									      \
53   jmp JUMPTARGET(syscall_error)						      \
54   .globl syscall_error;							      \
55   ENTRY (name)								      \
56   DO_CALL (syscall_name, args);						      \
57   jb lose
58 
59 #undef JUMPTARGET
60 #ifdef SHARED
61 # ifdef BIND_NOW
62 #  define JUMPTARGET(name)	*name##@GOTPCREL(%rip)
63 # else
64 #  define JUMPTARGET(name)	name##@PLT
65 # endif
66 #else
67 /* For static archives, branch to target directly.  */
68 # define JUMPTARGET(name)	name
69 #endif
70 
71 /* Long and pointer size in bytes.  */
72 #define LP_SIZE	8
73 
74 /* Instruction to operate on long and pointer.  */
75 #define LP_OP(insn) insn##q
76 
77 /* Assembler address directive. */
78 #define ASM_ADDR .quad
79 
80 /* Registers to hold long and pointer.  */
81 #define RAX_LP	rax
82 #define RBP_LP	rbp
83 #define RBX_LP	rbx
84 #define RCX_LP	rcx
85 #define RDI_LP	rdi
86 #define RDX_LP	rdx
87 #define RSI_LP	rsi
88 #define RSP_LP	rsp
89 #define R8_LP	r8
90 #define R9_LP	r9
91 #define R10_LP	r10
92 #define R11_LP	r11
93 #define R12_LP	r12
94 #define R13_LP	r13
95 #define R14_LP	r14
96 #define R15_LP	r15
97 
98 /* Zero upper vector registers and return with xtest.  NB: Use VZEROALL
99    to avoid RTM abort triggered by VZEROUPPER inside transactionally.  */
100 #define ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST \
101 	xtest;							\
102 	jnz	1f;						\
103 	vzeroupper;						\
104 	ret;							\
105 1:								\
106 	vzeroall;						\
107 	ret
108 
109 /* Can be used to replace vzeroupper that is not directly before a
110    return.  This is useful when hoisting a vzeroupper from multiple
111    return paths to decrease the total number of vzerouppers and code
112    size.  */
113 #define COND_VZEROUPPER_XTEST							\
114     xtest;							\
115     jz 1f;							\
116     vzeroall;							\
117     jmp 2f;							\
118 1:							\
119     vzeroupper;							\
120 2:
121 
122 /* In RTM define this as COND_VZEROUPPER_XTEST.  */
123 #ifndef COND_VZEROUPPER
124 # define COND_VZEROUPPER vzeroupper
125 #endif
126 
127 /* Zero upper vector registers and return.  */
128 #ifndef ZERO_UPPER_VEC_REGISTERS_RETURN
129 # define ZERO_UPPER_VEC_REGISTERS_RETURN \
130 	VZEROUPPER;						\
131 	ret
132 #endif
133 
134 #ifndef VZEROUPPER_RETURN
135 # define VZEROUPPER_RETURN	VZEROUPPER; ret
136 #endif
137 
138 #else	/* __ASSEMBLER__ */
139 
140 /* Long and pointer size in bytes.  */
141 #define LP_SIZE "8"
142 
143 /* Instruction to operate on long and pointer.  */
144 #define LP_OP(insn) #insn "q"
145 
146 /* Assembler address directive. */
147 #define ASM_ADDR ".quad"
148 
149 /* Registers to hold long and pointer.  */
150 #define RAX_LP	"rax"
151 #define RBP_LP	"rbp"
152 #define RBX_LP	"rbx"
153 #define RCX_LP	"rcx"
154 #define RDI_LP	"rdi"
155 #define RDX_LP	"rdx"
156 #define RSI_LP	"rsi"
157 #define RSP_LP	"rsp"
158 #define R8_LP	"r8"
159 #define R9_LP	"r9"
160 #define R10_LP	"r10"
161 #define R11_LP	"r11"
162 #define R12_LP	"r12"
163 #define R13_LP	"r13"
164 #define R14_LP	"r14"
165 #define R15_LP	"r15"
166 
167 #endif	/* __ASSEMBLER__ */
168 
169 #endif	/* _X86_64_SYSDEP_H */
170