1 /* Assembler macros for x86-64.
2    Copyright (C) 2001-2021 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 	jz	1f;						\
103 	vzeroall;						\
104 	ret;							\
105 1:								\
106 	vzeroupper;						\
107 	ret
108 
109 /* Zero upper vector registers and return.  */
110 #ifndef ZERO_UPPER_VEC_REGISTERS_RETURN
111 # define ZERO_UPPER_VEC_REGISTERS_RETURN \
112 	VZEROUPPER;						\
113 	ret
114 #endif
115 
116 #ifndef VZEROUPPER_RETURN
117 # define VZEROUPPER_RETURN	VZEROUPPER; ret
118 #endif
119 
120 #else	/* __ASSEMBLER__ */
121 
122 /* Long and pointer size in bytes.  */
123 #define LP_SIZE "8"
124 
125 /* Instruction to operate on long and pointer.  */
126 #define LP_OP(insn) #insn "q"
127 
128 /* Assembler address directive. */
129 #define ASM_ADDR ".quad"
130 
131 /* Registers to hold long and pointer.  */
132 #define RAX_LP	"rax"
133 #define RBP_LP	"rbp"
134 #define RBX_LP	"rbx"
135 #define RCX_LP	"rcx"
136 #define RDI_LP	"rdi"
137 #define RDX_LP	"rdx"
138 #define RSI_LP	"rsi"
139 #define RSP_LP	"rsp"
140 #define R8_LP	"r8"
141 #define R9_LP	"r9"
142 #define R10_LP	"r10"
143 #define R11_LP	"r11"
144 #define R12_LP	"r12"
145 #define R13_LP	"r13"
146 #define R14_LP	"r14"
147 #define R15_LP	"r15"
148 
149 #endif	/* __ASSEMBLER__ */
150 
151 #endif	/* _X86_64_SYSDEP_H */
152