xref: /linux/arch/x86/include/asm/inst.h (revision e2be04c7f9958dde770eeb8b30e829ca969b37bb)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Generate .byte code for some instructions not supported by old
4  * binutils.
5  */
6 #ifndef X86_ASM_INST_H
7 #define X86_ASM_INST_H
8 
9 #ifdef __ASSEMBLY__
10 
11 #define REG_NUM_INVALID		100
12 
13 #define REG_TYPE_R32		0
14 #define REG_TYPE_R64		1
15 #define REG_TYPE_XMM		2
16 #define REG_TYPE_INVALID	100
17 
18 	.macro R32_NUM opd r32
19 	\opd = REG_NUM_INVALID
20 	.ifc \r32,%eax
21 	\opd = 0
22 	.endif
23 	.ifc \r32,%ecx
24 	\opd = 1
25 	.endif
26 	.ifc \r32,%edx
27 	\opd = 2
28 	.endif
29 	.ifc \r32,%ebx
30 	\opd = 3
31 	.endif
32 	.ifc \r32,%esp
33 	\opd = 4
34 	.endif
35 	.ifc \r32,%ebp
36 	\opd = 5
37 	.endif
38 	.ifc \r32,%esi
39 	\opd = 6
40 	.endif
41 	.ifc \r32,%edi
42 	\opd = 7
43 	.endif
44 #ifdef CONFIG_X86_64
45 	.ifc \r32,%r8d
46 	\opd = 8
47 	.endif
48 	.ifc \r32,%r9d
49 	\opd = 9
50 	.endif
51 	.ifc \r32,%r10d
52 	\opd = 10
53 	.endif
54 	.ifc \r32,%r11d
55 	\opd = 11
56 	.endif
57 	.ifc \r32,%r12d
58 	\opd = 12
59 	.endif
60 	.ifc \r32,%r13d
61 	\opd = 13
62 	.endif
63 	.ifc \r32,%r14d
64 	\opd = 14
65 	.endif
66 	.ifc \r32,%r15d
67 	\opd = 15
68 	.endif
69 #endif
70 	.endm
71 
72 	.macro R64_NUM opd r64
73 	\opd = REG_NUM_INVALID
74 #ifdef CONFIG_X86_64
75 	.ifc \r64,%rax
76 	\opd = 0
77 	.endif
78 	.ifc \r64,%rcx
79 	\opd = 1
80 	.endif
81 	.ifc \r64,%rdx
82 	\opd = 2
83 	.endif
84 	.ifc \r64,%rbx
85 	\opd = 3
86 	.endif
87 	.ifc \r64,%rsp
88 	\opd = 4
89 	.endif
90 	.ifc \r64,%rbp
91 	\opd = 5
92 	.endif
93 	.ifc \r64,%rsi
94 	\opd = 6
95 	.endif
96 	.ifc \r64,%rdi
97 	\opd = 7
98 	.endif
99 	.ifc \r64,%r8
100 	\opd = 8
101 	.endif
102 	.ifc \r64,%r9
103 	\opd = 9
104 	.endif
105 	.ifc \r64,%r10
106 	\opd = 10
107 	.endif
108 	.ifc \r64,%r11
109 	\opd = 11
110 	.endif
111 	.ifc \r64,%r12
112 	\opd = 12
113 	.endif
114 	.ifc \r64,%r13
115 	\opd = 13
116 	.endif
117 	.ifc \r64,%r14
118 	\opd = 14
119 	.endif
120 	.ifc \r64,%r15
121 	\opd = 15
122 	.endif
123 #endif
124 	.endm
125 
126 	.macro XMM_NUM opd xmm
127 	\opd = REG_NUM_INVALID
128 	.ifc \xmm,%xmm0
129 	\opd = 0
130 	.endif
131 	.ifc \xmm,%xmm1
132 	\opd = 1
133 	.endif
134 	.ifc \xmm,%xmm2
135 	\opd = 2
136 	.endif
137 	.ifc \xmm,%xmm3
138 	\opd = 3
139 	.endif
140 	.ifc \xmm,%xmm4
141 	\opd = 4
142 	.endif
143 	.ifc \xmm,%xmm5
144 	\opd = 5
145 	.endif
146 	.ifc \xmm,%xmm6
147 	\opd = 6
148 	.endif
149 	.ifc \xmm,%xmm7
150 	\opd = 7
151 	.endif
152 	.ifc \xmm,%xmm8
153 	\opd = 8
154 	.endif
155 	.ifc \xmm,%xmm9
156 	\opd = 9
157 	.endif
158 	.ifc \xmm,%xmm10
159 	\opd = 10
160 	.endif
161 	.ifc \xmm,%xmm11
162 	\opd = 11
163 	.endif
164 	.ifc \xmm,%xmm12
165 	\opd = 12
166 	.endif
167 	.ifc \xmm,%xmm13
168 	\opd = 13
169 	.endif
170 	.ifc \xmm,%xmm14
171 	\opd = 14
172 	.endif
173 	.ifc \xmm,%xmm15
174 	\opd = 15
175 	.endif
176 	.endm
177 
178 	.macro REG_TYPE type reg
179 	R32_NUM reg_type_r32 \reg
180 	R64_NUM reg_type_r64 \reg
181 	XMM_NUM reg_type_xmm \reg
182 	.if reg_type_r64 <> REG_NUM_INVALID
183 	\type = REG_TYPE_R64
184 	.elseif reg_type_r32 <> REG_NUM_INVALID
185 	\type = REG_TYPE_R32
186 	.elseif reg_type_xmm <> REG_NUM_INVALID
187 	\type = REG_TYPE_XMM
188 	.else
189 	\type = REG_TYPE_INVALID
190 	.endif
191 	.endm
192 
193 	.macro PFX_OPD_SIZE
194 	.byte 0x66
195 	.endm
196 
197 	.macro PFX_REX opd1 opd2 W=0
198 	.if ((\opd1 | \opd2) & 8) || \W
199 	.byte 0x40 | ((\opd1 & 8) >> 3) | ((\opd2 & 8) >> 1) | (\W << 3)
200 	.endif
201 	.endm
202 
203 	.macro MODRM mod opd1 opd2
204 	.byte \mod | (\opd1 & 7) | ((\opd2 & 7) << 3)
205 	.endm
206 
207 	.macro PSHUFB_XMM xmm1 xmm2
208 	XMM_NUM pshufb_opd1 \xmm1
209 	XMM_NUM pshufb_opd2 \xmm2
210 	PFX_OPD_SIZE
211 	PFX_REX pshufb_opd1 pshufb_opd2
212 	.byte 0x0f, 0x38, 0x00
213 	MODRM 0xc0 pshufb_opd1 pshufb_opd2
214 	.endm
215 
216 	.macro PCLMULQDQ imm8 xmm1 xmm2
217 	XMM_NUM clmul_opd1 \xmm1
218 	XMM_NUM clmul_opd2 \xmm2
219 	PFX_OPD_SIZE
220 	PFX_REX clmul_opd1 clmul_opd2
221 	.byte 0x0f, 0x3a, 0x44
222 	MODRM 0xc0 clmul_opd1 clmul_opd2
223 	.byte \imm8
224 	.endm
225 
226 	.macro PEXTRD imm8 xmm gpr
227 	R32_NUM extrd_opd1 \gpr
228 	XMM_NUM extrd_opd2 \xmm
229 	PFX_OPD_SIZE
230 	PFX_REX extrd_opd1 extrd_opd2
231 	.byte 0x0f, 0x3a, 0x16
232 	MODRM 0xc0 extrd_opd1 extrd_opd2
233 	.byte \imm8
234 	.endm
235 
236 	.macro AESKEYGENASSIST rcon xmm1 xmm2
237 	XMM_NUM aeskeygen_opd1 \xmm1
238 	XMM_NUM aeskeygen_opd2 \xmm2
239 	PFX_OPD_SIZE
240 	PFX_REX aeskeygen_opd1 aeskeygen_opd2
241 	.byte 0x0f, 0x3a, 0xdf
242 	MODRM 0xc0 aeskeygen_opd1 aeskeygen_opd2
243 	.byte \rcon
244 	.endm
245 
246 	.macro AESIMC xmm1 xmm2
247 	XMM_NUM aesimc_opd1 \xmm1
248 	XMM_NUM aesimc_opd2 \xmm2
249 	PFX_OPD_SIZE
250 	PFX_REX aesimc_opd1 aesimc_opd2
251 	.byte 0x0f, 0x38, 0xdb
252 	MODRM 0xc0 aesimc_opd1 aesimc_opd2
253 	.endm
254 
255 	.macro AESENC xmm1 xmm2
256 	XMM_NUM aesenc_opd1 \xmm1
257 	XMM_NUM aesenc_opd2 \xmm2
258 	PFX_OPD_SIZE
259 	PFX_REX aesenc_opd1 aesenc_opd2
260 	.byte 0x0f, 0x38, 0xdc
261 	MODRM 0xc0 aesenc_opd1 aesenc_opd2
262 	.endm
263 
264 	.macro AESENCLAST xmm1 xmm2
265 	XMM_NUM aesenclast_opd1 \xmm1
266 	XMM_NUM aesenclast_opd2 \xmm2
267 	PFX_OPD_SIZE
268 	PFX_REX aesenclast_opd1 aesenclast_opd2
269 	.byte 0x0f, 0x38, 0xdd
270 	MODRM 0xc0 aesenclast_opd1 aesenclast_opd2
271 	.endm
272 
273 	.macro AESDEC xmm1 xmm2
274 	XMM_NUM aesdec_opd1 \xmm1
275 	XMM_NUM aesdec_opd2 \xmm2
276 	PFX_OPD_SIZE
277 	PFX_REX aesdec_opd1 aesdec_opd2
278 	.byte 0x0f, 0x38, 0xde
279 	MODRM 0xc0 aesdec_opd1 aesdec_opd2
280 	.endm
281 
282 	.macro AESDECLAST xmm1 xmm2
283 	XMM_NUM aesdeclast_opd1 \xmm1
284 	XMM_NUM aesdeclast_opd2 \xmm2
285 	PFX_OPD_SIZE
286 	PFX_REX aesdeclast_opd1 aesdeclast_opd2
287 	.byte 0x0f, 0x38, 0xdf
288 	MODRM 0xc0 aesdeclast_opd1 aesdeclast_opd2
289 	.endm
290 
291 	.macro MOVQ_R64_XMM opd1 opd2
292 	REG_TYPE movq_r64_xmm_opd1_type \opd1
293 	.if movq_r64_xmm_opd1_type == REG_TYPE_XMM
294 	XMM_NUM movq_r64_xmm_opd1 \opd1
295 	R64_NUM movq_r64_xmm_opd2 \opd2
296 	.else
297 	R64_NUM movq_r64_xmm_opd1 \opd1
298 	XMM_NUM movq_r64_xmm_opd2 \opd2
299 	.endif
300 	PFX_OPD_SIZE
301 	PFX_REX movq_r64_xmm_opd1 movq_r64_xmm_opd2 1
302 	.if movq_r64_xmm_opd1_type == REG_TYPE_XMM
303 	.byte 0x0f, 0x7e
304 	.else
305 	.byte 0x0f, 0x6e
306 	.endif
307 	MODRM 0xc0 movq_r64_xmm_opd1 movq_r64_xmm_opd2
308 	.endm
309 #endif
310 
311 #endif
312