]>
Commit | Line | Data |
---|---|---|
f9f354fc | 1 | use super::{InlineAsmArch, InlineAsmType}; |
5e7ed085 | 2 | use crate::spec::{RelocModel, Target}; |
5099ac24 | 3 | use rustc_data_structures::stable_set::FxHashSet; |
f9f354fc | 4 | use rustc_macros::HashStable_Generic; |
5099ac24 | 5 | use rustc_span::Symbol; |
f9f354fc XL |
6 | use std::fmt; |
7 | ||
8 | def_reg_class! { | |
9 | X86 X86InlineAsmRegClass { | |
10 | reg, | |
11 | reg_abcd, | |
12 | reg_byte, | |
13 | xmm_reg, | |
14 | ymm_reg, | |
15 | zmm_reg, | |
16 | kreg, | |
04454e1e | 17 | kreg0, |
136023e0 XL |
18 | mmx_reg, |
19 | x87_reg, | |
923072b8 | 20 | tmm_reg, |
f9f354fc XL |
21 | } |
22 | } | |
23 | ||
24 | impl X86InlineAsmRegClass { | |
25 | pub fn valid_modifiers(self, arch: super::InlineAsmArch) -> &'static [char] { | |
26 | match self { | |
27 | Self::reg => { | |
28 | if arch == InlineAsmArch::X86_64 { | |
29 | &['l', 'x', 'e', 'r'] | |
30 | } else { | |
31 | &['x', 'e'] | |
32 | } | |
33 | } | |
34 | Self::reg_abcd => { | |
35 | if arch == InlineAsmArch::X86_64 { | |
36 | &['l', 'h', 'x', 'e', 'r'] | |
37 | } else { | |
38 | &['l', 'h', 'x', 'e'] | |
39 | } | |
40 | } | |
41 | Self::reg_byte => &[], | |
42 | Self::xmm_reg | Self::ymm_reg | Self::zmm_reg => &['x', 'y', 'z'], | |
04454e1e | 43 | Self::kreg | Self::kreg0 => &[], |
136023e0 | 44 | Self::mmx_reg | Self::x87_reg => &[], |
923072b8 | 45 | Self::tmm_reg => &[], |
f9f354fc XL |
46 | } |
47 | } | |
48 | ||
49 | pub fn suggest_class(self, _arch: InlineAsmArch, ty: InlineAsmType) -> Option<Self> { | |
50 | match self { | |
51 | Self::reg | Self::reg_abcd if ty.size().bits() == 8 => Some(Self::reg_byte), | |
52 | _ => None, | |
53 | } | |
54 | } | |
55 | ||
56 | pub fn suggest_modifier( | |
57 | self, | |
58 | arch: InlineAsmArch, | |
59 | ty: InlineAsmType, | |
60 | ) -> Option<(char, &'static str)> { | |
61 | match self { | |
62 | Self::reg => match ty.size().bits() { | |
63 | 16 => Some(('x', "ax")), | |
64 | 32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax")), | |
65 | _ => None, | |
66 | }, | |
67 | Self::reg_abcd => match ty.size().bits() { | |
68 | 16 => Some(('x', "ax")), | |
69 | 32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax")), | |
70 | _ => None, | |
71 | }, | |
72 | Self::reg_byte => None, | |
73 | Self::xmm_reg => None, | |
74 | Self::ymm_reg => match ty.size().bits() { | |
75 | 256 => None, | |
76 | _ => Some(('x', "xmm0")), | |
77 | }, | |
78 | Self::zmm_reg => match ty.size().bits() { | |
79 | 512 => None, | |
80 | 256 => Some(('y', "ymm0")), | |
81 | _ => Some(('x', "xmm0")), | |
82 | }, | |
04454e1e | 83 | Self::kreg | Self::kreg0 => None, |
136023e0 | 84 | Self::mmx_reg | Self::x87_reg => None, |
923072b8 | 85 | Self::tmm_reg => None, |
f9f354fc XL |
86 | } |
87 | } | |
88 | ||
89 | pub fn default_modifier(self, arch: InlineAsmArch) -> Option<(char, &'static str)> { | |
90 | match self { | |
91 | Self::reg | Self::reg_abcd => { | |
92 | if arch == InlineAsmArch::X86_64 { | |
93 | Some(('r', "rax")) | |
94 | } else { | |
95 | Some(('e', "eax")) | |
96 | } | |
97 | } | |
98 | Self::reg_byte => None, | |
99 | Self::xmm_reg => Some(('x', "xmm0")), | |
100 | Self::ymm_reg => Some(('y', "ymm0")), | |
101 | Self::zmm_reg => Some(('z', "zmm0")), | |
04454e1e | 102 | Self::kreg | Self::kreg0 => None, |
136023e0 | 103 | Self::mmx_reg | Self::x87_reg => None, |
923072b8 | 104 | Self::tmm_reg => None, |
f9f354fc XL |
105 | } |
106 | } | |
107 | ||
108 | pub fn supported_types( | |
109 | self, | |
110 | arch: InlineAsmArch, | |
5099ac24 | 111 | ) -> &'static [(InlineAsmType, Option<Symbol>)] { |
f9f354fc XL |
112 | match self { |
113 | Self::reg | Self::reg_abcd => { | |
114 | if arch == InlineAsmArch::X86_64 { | |
115 | types! { _: I16, I32, I64, F32, F64; } | |
116 | } else { | |
117 | types! { _: I16, I32, F32; } | |
118 | } | |
119 | } | |
120 | Self::reg_byte => types! { _: I8; }, | |
121 | Self::xmm_reg => types! { | |
5099ac24 | 122 | sse: I32, I64, F32, F64, |
f9f354fc XL |
123 | VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2); |
124 | }, | |
125 | Self::ymm_reg => types! { | |
5099ac24 | 126 | avx: I32, I64, F32, F64, |
f9f354fc XL |
127 | VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2), |
128 | VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF32(8), VecF64(4); | |
129 | }, | |
130 | Self::zmm_reg => types! { | |
5099ac24 | 131 | avx512f: I32, I64, F32, F64, |
f9f354fc XL |
132 | VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2), |
133 | VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF32(8), VecF64(4), | |
134 | VecI8(64), VecI16(32), VecI32(16), VecI64(8), VecF32(16), VecF64(8); | |
135 | }, | |
136 | Self::kreg => types! { | |
5099ac24 FG |
137 | avx512f: I8, I16; |
138 | avx512bw: I32, I64; | |
f9f354fc | 139 | }, |
04454e1e | 140 | Self::kreg0 => &[], |
136023e0 | 141 | Self::mmx_reg | Self::x87_reg => &[], |
923072b8 | 142 | Self::tmm_reg => &[], |
f9f354fc XL |
143 | } |
144 | } | |
145 | } | |
146 | ||
147 | fn x86_64_only( | |
148 | arch: InlineAsmArch, | |
5e7ed085 | 149 | _reloc_model: RelocModel, |
5099ac24 | 150 | _target_features: &FxHashSet<Symbol>, |
f035d41b | 151 | _target: &Target, |
5099ac24 | 152 | _is_clobber: bool, |
f9f354fc XL |
153 | ) -> Result<(), &'static str> { |
154 | match arch { | |
155 | InlineAsmArch::X86 => Err("register is only available on x86_64"), | |
156 | InlineAsmArch::X86_64 => Ok(()), | |
157 | _ => unreachable!(), | |
158 | } | |
159 | } | |
160 | ||
161 | fn high_byte( | |
162 | arch: InlineAsmArch, | |
5e7ed085 | 163 | _reloc_model: RelocModel, |
5099ac24 | 164 | _target_features: &FxHashSet<Symbol>, |
f035d41b | 165 | _target: &Target, |
5099ac24 | 166 | _is_clobber: bool, |
f9f354fc XL |
167 | ) -> Result<(), &'static str> { |
168 | match arch { | |
cdc7bbd5 | 169 | InlineAsmArch::X86_64 => Err("high byte registers cannot be used as an operand on x86_64"), |
f9f354fc XL |
170 | _ => Ok(()), |
171 | } | |
172 | } | |
173 | ||
17df50a5 XL |
174 | fn rbx_reserved( |
175 | arch: InlineAsmArch, | |
5e7ed085 | 176 | _reloc_model: RelocModel, |
5099ac24 | 177 | _target_features: &FxHashSet<Symbol>, |
17df50a5 | 178 | _target: &Target, |
5099ac24 | 179 | _is_clobber: bool, |
17df50a5 XL |
180 | ) -> Result<(), &'static str> { |
181 | match arch { | |
182 | InlineAsmArch::X86 => Ok(()), | |
183 | InlineAsmArch::X86_64 => { | |
184 | Err("rbx is used internally by LLVM and cannot be used as an operand for inline asm") | |
185 | } | |
186 | _ => unreachable!(), | |
187 | } | |
188 | } | |
189 | ||
190 | fn esi_reserved( | |
191 | arch: InlineAsmArch, | |
5e7ed085 | 192 | _reloc_model: RelocModel, |
5099ac24 | 193 | _target_features: &FxHashSet<Symbol>, |
17df50a5 | 194 | _target: &Target, |
5099ac24 | 195 | _is_clobber: bool, |
17df50a5 XL |
196 | ) -> Result<(), &'static str> { |
197 | match arch { | |
198 | InlineAsmArch::X86 => { | |
199 | Err("esi is used internally by LLVM and cannot be used as an operand for inline asm") | |
200 | } | |
201 | InlineAsmArch::X86_64 => Ok(()), | |
202 | _ => unreachable!(), | |
203 | } | |
204 | } | |
205 | ||
f9f354fc XL |
206 | def_regs! { |
207 | X86 X86InlineAsmReg X86InlineAsmRegClass { | |
208 | ax: reg, reg_abcd = ["ax", "eax", "rax"], | |
17df50a5 | 209 | bx: reg, reg_abcd = ["bx", "ebx", "rbx"] % rbx_reserved, |
f9f354fc XL |
210 | cx: reg, reg_abcd = ["cx", "ecx", "rcx"], |
211 | dx: reg, reg_abcd = ["dx", "edx", "rdx"], | |
17df50a5 | 212 | si: reg = ["si", "esi", "rsi"] % esi_reserved, |
f9f354fc XL |
213 | di: reg = ["di", "edi", "rdi"], |
214 | r8: reg = ["r8", "r8w", "r8d"] % x86_64_only, | |
215 | r9: reg = ["r9", "r9w", "r9d"] % x86_64_only, | |
216 | r10: reg = ["r10", "r10w", "r10d"] % x86_64_only, | |
217 | r11: reg = ["r11", "r11w", "r11d"] % x86_64_only, | |
218 | r12: reg = ["r12", "r12w", "r12d"] % x86_64_only, | |
219 | r13: reg = ["r13", "r13w", "r13d"] % x86_64_only, | |
220 | r14: reg = ["r14", "r14w", "r14d"] % x86_64_only, | |
221 | r15: reg = ["r15", "r15w", "r15d"] % x86_64_only, | |
222 | al: reg_byte = ["al"], | |
223 | ah: reg_byte = ["ah"] % high_byte, | |
224 | bl: reg_byte = ["bl"], | |
225 | bh: reg_byte = ["bh"] % high_byte, | |
226 | cl: reg_byte = ["cl"], | |
227 | ch: reg_byte = ["ch"] % high_byte, | |
228 | dl: reg_byte = ["dl"], | |
229 | dh: reg_byte = ["dh"] % high_byte, | |
230 | sil: reg_byte = ["sil"] % x86_64_only, | |
231 | dil: reg_byte = ["dil"] % x86_64_only, | |
232 | r8b: reg_byte = ["r8b"] % x86_64_only, | |
233 | r9b: reg_byte = ["r9b"] % x86_64_only, | |
234 | r10b: reg_byte = ["r10b"] % x86_64_only, | |
235 | r11b: reg_byte = ["r11b"] % x86_64_only, | |
236 | r12b: reg_byte = ["r12b"] % x86_64_only, | |
237 | r13b: reg_byte = ["r13b"] % x86_64_only, | |
238 | r14b: reg_byte = ["r14b"] % x86_64_only, | |
239 | r15b: reg_byte = ["r15b"] % x86_64_only, | |
240 | xmm0: xmm_reg = ["xmm0"], | |
241 | xmm1: xmm_reg = ["xmm1"], | |
242 | xmm2: xmm_reg = ["xmm2"], | |
243 | xmm3: xmm_reg = ["xmm3"], | |
244 | xmm4: xmm_reg = ["xmm4"], | |
245 | xmm5: xmm_reg = ["xmm5"], | |
246 | xmm6: xmm_reg = ["xmm6"], | |
247 | xmm7: xmm_reg = ["xmm7"], | |
248 | xmm8: xmm_reg = ["xmm8"] % x86_64_only, | |
249 | xmm9: xmm_reg = ["xmm9"] % x86_64_only, | |
250 | xmm10: xmm_reg = ["xmm10"] % x86_64_only, | |
251 | xmm11: xmm_reg = ["xmm11"] % x86_64_only, | |
252 | xmm12: xmm_reg = ["xmm12"] % x86_64_only, | |
253 | xmm13: xmm_reg = ["xmm13"] % x86_64_only, | |
254 | xmm14: xmm_reg = ["xmm14"] % x86_64_only, | |
255 | xmm15: xmm_reg = ["xmm15"] % x86_64_only, | |
256 | ymm0: ymm_reg = ["ymm0"], | |
257 | ymm1: ymm_reg = ["ymm1"], | |
258 | ymm2: ymm_reg = ["ymm2"], | |
259 | ymm3: ymm_reg = ["ymm3"], | |
260 | ymm4: ymm_reg = ["ymm4"], | |
261 | ymm5: ymm_reg = ["ymm5"], | |
262 | ymm6: ymm_reg = ["ymm6"], | |
263 | ymm7: ymm_reg = ["ymm7"], | |
264 | ymm8: ymm_reg = ["ymm8"] % x86_64_only, | |
265 | ymm9: ymm_reg = ["ymm9"] % x86_64_only, | |
266 | ymm10: ymm_reg = ["ymm10"] % x86_64_only, | |
267 | ymm11: ymm_reg = ["ymm11"] % x86_64_only, | |
268 | ymm12: ymm_reg = ["ymm12"] % x86_64_only, | |
269 | ymm13: ymm_reg = ["ymm13"] % x86_64_only, | |
270 | ymm14: ymm_reg = ["ymm14"] % x86_64_only, | |
271 | ymm15: ymm_reg = ["ymm15"] % x86_64_only, | |
272 | zmm0: zmm_reg = ["zmm0"], | |
273 | zmm1: zmm_reg = ["zmm1"], | |
274 | zmm2: zmm_reg = ["zmm2"], | |
275 | zmm3: zmm_reg = ["zmm3"], | |
276 | zmm4: zmm_reg = ["zmm4"], | |
277 | zmm5: zmm_reg = ["zmm5"], | |
278 | zmm6: zmm_reg = ["zmm6"], | |
279 | zmm7: zmm_reg = ["zmm7"], | |
280 | zmm8: zmm_reg = ["zmm8"] % x86_64_only, | |
281 | zmm9: zmm_reg = ["zmm9"] % x86_64_only, | |
282 | zmm10: zmm_reg = ["zmm10"] % x86_64_only, | |
283 | zmm11: zmm_reg = ["zmm11"] % x86_64_only, | |
284 | zmm12: zmm_reg = ["zmm12"] % x86_64_only, | |
285 | zmm13: zmm_reg = ["zmm13"] % x86_64_only, | |
286 | zmm14: zmm_reg = ["zmm14"] % x86_64_only, | |
287 | zmm15: zmm_reg = ["zmm15"] % x86_64_only, | |
288 | zmm16: zmm_reg = ["zmm16", "xmm16", "ymm16"] % x86_64_only, | |
289 | zmm17: zmm_reg = ["zmm17", "xmm17", "ymm17"] % x86_64_only, | |
290 | zmm18: zmm_reg = ["zmm18", "xmm18", "ymm18"] % x86_64_only, | |
291 | zmm19: zmm_reg = ["zmm19", "xmm19", "ymm19"] % x86_64_only, | |
292 | zmm20: zmm_reg = ["zmm20", "xmm20", "ymm20"] % x86_64_only, | |
293 | zmm21: zmm_reg = ["zmm21", "xmm21", "ymm21"] % x86_64_only, | |
294 | zmm22: zmm_reg = ["zmm22", "xmm22", "ymm22"] % x86_64_only, | |
295 | zmm23: zmm_reg = ["zmm23", "xmm23", "ymm23"] % x86_64_only, | |
296 | zmm24: zmm_reg = ["zmm24", "xmm24", "ymm24"] % x86_64_only, | |
297 | zmm25: zmm_reg = ["zmm25", "xmm25", "ymm25"] % x86_64_only, | |
298 | zmm26: zmm_reg = ["zmm26", "xmm26", "ymm26"] % x86_64_only, | |
299 | zmm27: zmm_reg = ["zmm27", "xmm27", "ymm27"] % x86_64_only, | |
300 | zmm28: zmm_reg = ["zmm28", "xmm28", "ymm28"] % x86_64_only, | |
301 | zmm29: zmm_reg = ["zmm29", "xmm29", "ymm29"] % x86_64_only, | |
302 | zmm30: zmm_reg = ["zmm30", "xmm30", "ymm30"] % x86_64_only, | |
303 | zmm31: zmm_reg = ["zmm31", "xmm31", "ymm31"] % x86_64_only, | |
04454e1e | 304 | k0: kreg0 = ["k0"], |
f9f354fc XL |
305 | k1: kreg = ["k1"], |
306 | k2: kreg = ["k2"], | |
307 | k3: kreg = ["k3"], | |
308 | k4: kreg = ["k4"], | |
309 | k5: kreg = ["k5"], | |
310 | k6: kreg = ["k6"], | |
311 | k7: kreg = ["k7"], | |
136023e0 XL |
312 | mm0: mmx_reg = ["mm0"], |
313 | mm1: mmx_reg = ["mm1"], | |
314 | mm2: mmx_reg = ["mm2"], | |
315 | mm3: mmx_reg = ["mm3"], | |
316 | mm4: mmx_reg = ["mm4"], | |
317 | mm5: mmx_reg = ["mm5"], | |
318 | mm6: mmx_reg = ["mm6"], | |
319 | mm7: mmx_reg = ["mm7"], | |
320 | st0: x87_reg = ["st(0)", "st"], | |
321 | st1: x87_reg = ["st(1)"], | |
322 | st2: x87_reg = ["st(2)"], | |
323 | st3: x87_reg = ["st(3)"], | |
324 | st4: x87_reg = ["st(4)"], | |
325 | st5: x87_reg = ["st(5)"], | |
326 | st6: x87_reg = ["st(6)"], | |
327 | st7: x87_reg = ["st(7)"], | |
923072b8 FG |
328 | tmm0: tmm_reg = ["tmm0"] % x86_64_only, |
329 | tmm1: tmm_reg = ["tmm1"] % x86_64_only, | |
330 | tmm2: tmm_reg = ["tmm2"] % x86_64_only, | |
331 | tmm3: tmm_reg = ["tmm3"] % x86_64_only, | |
332 | tmm4: tmm_reg = ["tmm4"] % x86_64_only, | |
333 | tmm5: tmm_reg = ["tmm5"] % x86_64_only, | |
334 | tmm6: tmm_reg = ["tmm6"] % x86_64_only, | |
335 | tmm7: tmm_reg = ["tmm7"] % x86_64_only, | |
f9f354fc XL |
336 | #error = ["bp", "bpl", "ebp", "rbp"] => |
337 | "the frame pointer cannot be used as an operand for inline asm", | |
338 | #error = ["sp", "spl", "esp", "rsp"] => | |
339 | "the stack pointer cannot be used as an operand for inline asm", | |
340 | #error = ["ip", "eip", "rip"] => | |
341 | "the instruction pointer cannot be used as an operand for inline asm", | |
f9f354fc XL |
342 | } |
343 | } | |
344 | ||
345 | impl X86InlineAsmReg { | |
346 | pub fn emit( | |
347 | self, | |
348 | out: &mut dyn fmt::Write, | |
349 | arch: InlineAsmArch, | |
350 | modifier: Option<char>, | |
351 | ) -> fmt::Result { | |
352 | let reg_default_modifier = match arch { | |
353 | InlineAsmArch::X86 => 'e', | |
354 | InlineAsmArch::X86_64 => 'r', | |
355 | _ => unreachable!(), | |
356 | }; | |
357 | if self as u32 <= Self::dx as u32 { | |
358 | let root = ['a', 'b', 'c', 'd'][self as usize - Self::ax as usize]; | |
359 | match modifier.unwrap_or(reg_default_modifier) { | |
360 | 'l' => write!(out, "{}l", root), | |
361 | 'h' => write!(out, "{}h", root), | |
362 | 'x' => write!(out, "{}x", root), | |
363 | 'e' => write!(out, "e{}x", root), | |
364 | 'r' => write!(out, "r{}x", root), | |
365 | _ => unreachable!(), | |
366 | } | |
367 | } else if self as u32 <= Self::di as u32 { | |
368 | let root = self.name(); | |
369 | match modifier.unwrap_or(reg_default_modifier) { | |
370 | 'l' => write!(out, "{}l", root), | |
371 | 'x' => write!(out, "{}", root), | |
372 | 'e' => write!(out, "e{}", root), | |
373 | 'r' => write!(out, "r{}", root), | |
374 | _ => unreachable!(), | |
375 | } | |
376 | } else if self as u32 <= Self::r15 as u32 { | |
377 | let root = self.name(); | |
378 | match modifier.unwrap_or(reg_default_modifier) { | |
379 | 'l' => write!(out, "{}b", root), | |
380 | 'x' => write!(out, "{}w", root), | |
381 | 'e' => write!(out, "{}d", root), | |
382 | 'r' => out.write_str(root), | |
383 | _ => unreachable!(), | |
384 | } | |
385 | } else if self as u32 <= Self::r15b as u32 { | |
386 | out.write_str(self.name()) | |
387 | } else if self as u32 <= Self::xmm15 as u32 { | |
388 | let prefix = modifier.unwrap_or('x'); | |
389 | let index = self as u32 - Self::xmm0 as u32; | |
390 | write!(out, "{}{}", prefix, index) | |
391 | } else if self as u32 <= Self::ymm15 as u32 { | |
392 | let prefix = modifier.unwrap_or('y'); | |
393 | let index = self as u32 - Self::ymm0 as u32; | |
394 | write!(out, "{}{}", prefix, index) | |
395 | } else if self as u32 <= Self::zmm31 as u32 { | |
396 | let prefix = modifier.unwrap_or('z'); | |
397 | let index = self as u32 - Self::zmm0 as u32; | |
398 | write!(out, "{}{}", prefix, index) | |
399 | } else { | |
400 | out.write_str(self.name()) | |
401 | } | |
402 | } | |
403 | ||
404 | pub fn overlapping_regs(self, mut cb: impl FnMut(X86InlineAsmReg)) { | |
405 | macro_rules! reg_conflicts { | |
406 | ( | |
407 | $( | |
408 | $w:ident : $l:ident $h:ident | |
409 | ),*; | |
410 | $( | |
411 | $w2:ident : $l2:ident | |
412 | ),*; | |
413 | $( | |
414 | $x:ident : $y:ident : $z:ident | |
415 | ),*; | |
416 | ) => { | |
417 | match self { | |
418 | $( | |
419 | Self::$w => { | |
420 | cb(Self::$w); | |
421 | cb(Self::$l); | |
422 | cb(Self::$h); | |
423 | } | |
424 | Self::$l => { | |
425 | cb(Self::$w); | |
426 | cb(Self::$l); | |
427 | } | |
428 | Self::$h => { | |
429 | cb(Self::$w); | |
430 | cb(Self::$h); | |
431 | } | |
432 | )* | |
433 | $( | |
434 | Self::$w2 | Self::$l2 => { | |
435 | cb(Self::$w2); | |
436 | cb(Self::$l2); | |
437 | } | |
438 | )* | |
439 | $( | |
440 | Self::$x | Self::$y | Self::$z => { | |
441 | cb(Self::$x); | |
442 | cb(Self::$y); | |
443 | cb(Self::$z); | |
444 | } | |
445 | )* | |
446 | r => cb(r), | |
447 | } | |
448 | }; | |
449 | } | |
450 | ||
451 | // XMM*, YMM* and ZMM* are all different views of the same register. | |
452 | // | |
453 | // See section 15.5 of the combined Intel® 64 and IA-32 Architectures | |
454 | // Software Developer’s Manual for more details. | |
455 | // | |
456 | // We don't need to specify conflicts for [x,y,z]mm[16-31] since these | |
457 | // registers are only available with AVX-512, so we just specify them | |
458 | // as aliases directly. | |
459 | reg_conflicts! { | |
460 | ax : al ah, | |
461 | bx : bl bh, | |
462 | cx : cl ch, | |
463 | dx : dl dh; | |
464 | si : sil, | |
465 | di : dil, | |
466 | r8 : r8b, | |
467 | r9 : r9b, | |
468 | r10 : r10b, | |
469 | r11 : r11b, | |
470 | r12 : r12b, | |
471 | r13 : r13b, | |
472 | r14 : r14b, | |
473 | r15 : r15b; | |
474 | xmm0 : ymm0 : zmm0, | |
475 | xmm1 : ymm1 : zmm1, | |
476 | xmm2 : ymm2 : zmm2, | |
477 | xmm3 : ymm3 : zmm3, | |
478 | xmm4 : ymm4 : zmm4, | |
479 | xmm5 : ymm5 : zmm5, | |
480 | xmm6 : ymm6 : zmm6, | |
481 | xmm7 : ymm7 : zmm7, | |
482 | xmm8 : ymm8 : zmm8, | |
483 | xmm9 : ymm9 : zmm9, | |
484 | xmm10 : ymm10 : zmm10, | |
485 | xmm11 : ymm11 : zmm11, | |
486 | xmm12 : ymm12 : zmm12, | |
487 | xmm13 : ymm13 : zmm13, | |
488 | xmm14 : ymm14 : zmm14, | |
489 | xmm15 : ymm15 : zmm15; | |
490 | } | |
491 | } | |
492 | } |