/rust/registry/src/index.crates.io-1949cf8c6b5b557f/iced-x86-1.21.0/src/enums.rs
Line | Count | Source |
1 | | // SPDX-License-Identifier: MIT |
2 | | // Copyright (C) 2018-present iced project and contributors |
3 | | |
4 | | use crate::iced_constants::IcedConstants; |
5 | | use crate::iced_error::IcedError; |
6 | | use core::iter::{ExactSizeIterator, FusedIterator, Iterator}; |
7 | | use core::{fmt, mem}; |
8 | | |
9 | | // GENERATOR-BEGIN: CodeSize |
10 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
11 | | /// The code size (16/32/64) that was used when an instruction was decoded |
12 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
13 | | pub enum CodeSize { |
14 | | /// Unknown size |
15 | | Unknown = 0, |
16 | | /// 16-bit code |
17 | | Code16 = 1, |
18 | | /// 32-bit code |
19 | | Code32 = 2, |
20 | | /// 64-bit code |
21 | | Code64 = 3, |
22 | | } |
23 | | #[rustfmt::skip] |
24 | | static GEN_DEBUG_CODE_SIZE: [&str; 4] = [ |
25 | | "Unknown", |
26 | | "Code16", |
27 | | "Code32", |
28 | | "Code64", |
29 | | ]; |
30 | | impl fmt::Debug for CodeSize { |
31 | | #[inline] |
32 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
33 | 0 | write!(f, "{}", GEN_DEBUG_CODE_SIZE[*self as usize]) |
34 | 0 | } |
35 | | } |
36 | | impl Default for CodeSize { |
37 | | #[must_use] |
38 | | #[inline] |
39 | 0 | fn default() -> Self { |
40 | 0 | CodeSize::Unknown |
41 | 0 | } |
42 | | } |
43 | | #[allow(non_camel_case_types)] |
44 | | #[allow(dead_code)] |
45 | | pub(crate) type CodeSizeUnderlyingType = u8; |
46 | | #[rustfmt::skip] |
47 | | impl CodeSize { |
48 | | /// Iterates over all `CodeSize` enum values |
49 | | #[inline] |
50 | 0 | pub fn values() -> impl Iterator<Item = CodeSize> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
51 | | // SAFETY: all values 0-max are valid enum values |
52 | 0 | (0..IcedConstants::CODE_SIZE_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, CodeSize>(x as u8) }) |
53 | 0 | } |
54 | | } |
55 | | #[test] |
56 | | #[rustfmt::skip] |
57 | | fn test_codesize_values() { |
58 | | let mut iter = CodeSize::values(); |
59 | | assert_eq!(iter.size_hint(), (IcedConstants::CODE_SIZE_ENUM_COUNT, Some(IcedConstants::CODE_SIZE_ENUM_COUNT))); |
60 | | assert_eq!(iter.len(), IcedConstants::CODE_SIZE_ENUM_COUNT); |
61 | | assert!(iter.next().is_some()); |
62 | | assert_eq!(iter.size_hint(), (IcedConstants::CODE_SIZE_ENUM_COUNT - 1, Some(IcedConstants::CODE_SIZE_ENUM_COUNT - 1))); |
63 | | assert_eq!(iter.len(), IcedConstants::CODE_SIZE_ENUM_COUNT - 1); |
64 | | |
65 | | let values: Vec<CodeSize> = CodeSize::values().collect(); |
66 | | assert_eq!(values.len(), IcedConstants::CODE_SIZE_ENUM_COUNT); |
67 | | for (i, value) in values.into_iter().enumerate() { |
68 | | assert_eq!(i, value as usize); |
69 | | } |
70 | | |
71 | | let values1: Vec<CodeSize> = CodeSize::values().collect(); |
72 | | let mut values2: Vec<CodeSize> = CodeSize::values().rev().collect(); |
73 | | values2.reverse(); |
74 | | assert_eq!(values1, values2); |
75 | | } |
76 | | #[rustfmt::skip] |
77 | | impl TryFrom<usize> for CodeSize { |
78 | | type Error = IcedError; |
79 | | #[inline] |
80 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
81 | 0 | if value < IcedConstants::CODE_SIZE_ENUM_COUNT { |
82 | | // SAFETY: all values 0-max are valid enum values |
83 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
84 | | } else { |
85 | 0 | Err(IcedError::new("Invalid CodeSize value")) |
86 | | } |
87 | 0 | } |
88 | | } |
89 | | #[test] |
90 | | #[rustfmt::skip] |
91 | | fn test_codesize_try_from_usize() { |
92 | | for value in CodeSize::values() { |
93 | | let converted = <CodeSize as TryFrom<usize>>::try_from(value as usize).unwrap(); |
94 | | assert_eq!(converted, value); |
95 | | } |
96 | | assert!(<CodeSize as TryFrom<usize>>::try_from(IcedConstants::CODE_SIZE_ENUM_COUNT).is_err()); |
97 | | assert!(<CodeSize as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
98 | | } |
99 | | #[cfg(feature = "serde")] |
100 | | #[rustfmt::skip] |
101 | | #[allow(clippy::zero_sized_map_values)] |
102 | | const _: () = { |
103 | | use core::marker::PhantomData; |
104 | | use serde::de; |
105 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
106 | | type EnumType = CodeSize; |
107 | | impl Serialize for EnumType { |
108 | | #[inline] |
109 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
110 | | where |
111 | | S: Serializer, |
112 | | { |
113 | | serializer.serialize_u8(*self as u8) |
114 | | } |
115 | | } |
116 | | impl<'de> Deserialize<'de> for EnumType { |
117 | | #[inline] |
118 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
119 | | where |
120 | | D: Deserializer<'de>, |
121 | | { |
122 | | struct Visitor<'de> { |
123 | | marker: PhantomData<EnumType>, |
124 | | lifetime: PhantomData<&'de ()>, |
125 | | } |
126 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
127 | | type Value = EnumType; |
128 | | #[inline] |
129 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
130 | | formatter.write_str("enum CodeSize") |
131 | | } |
132 | | #[inline] |
133 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
134 | | where |
135 | | E: de::Error, |
136 | | { |
137 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
138 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
139 | | return Ok(value); |
140 | | } |
141 | | } |
142 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid CodeSize variant value")) |
143 | | } |
144 | | } |
145 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
146 | | } |
147 | | } |
148 | | }; |
149 | | // GENERATOR-END: CodeSize |
150 | | |
151 | | // GENERATOR-BEGIN: RoundingControl |
152 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
153 | | /// Rounding control |
154 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
155 | | pub enum RoundingControl { |
156 | | /// No rounding mode |
157 | | None = 0, |
158 | | /// Round to nearest (even) |
159 | | RoundToNearest = 1, |
160 | | /// Round down (toward -inf) |
161 | | RoundDown = 2, |
162 | | /// Round up (toward +inf) |
163 | | RoundUp = 3, |
164 | | /// Round toward zero (truncate) |
165 | | RoundTowardZero = 4, |
166 | | } |
167 | | #[rustfmt::skip] |
168 | | static GEN_DEBUG_ROUNDING_CONTROL: [&str; 5] = [ |
169 | | "None", |
170 | | "RoundToNearest", |
171 | | "RoundDown", |
172 | | "RoundUp", |
173 | | "RoundTowardZero", |
174 | | ]; |
175 | | impl fmt::Debug for RoundingControl { |
176 | | #[inline] |
177 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
178 | 0 | write!(f, "{}", GEN_DEBUG_ROUNDING_CONTROL[*self as usize]) |
179 | 0 | } |
180 | | } |
181 | | impl Default for RoundingControl { |
182 | | #[must_use] |
183 | | #[inline] |
184 | 0 | fn default() -> Self { |
185 | 0 | RoundingControl::None |
186 | 0 | } |
187 | | } |
188 | | #[allow(non_camel_case_types)] |
189 | | #[allow(dead_code)] |
190 | | pub(crate) type RoundingControlUnderlyingType = u8; |
191 | | #[rustfmt::skip] |
192 | | impl RoundingControl { |
193 | | /// Iterates over all `RoundingControl` enum values |
194 | | #[inline] |
195 | 0 | pub fn values() -> impl Iterator<Item = RoundingControl> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
196 | | // SAFETY: all values 0-max are valid enum values |
197 | 0 | (0..IcedConstants::ROUNDING_CONTROL_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, RoundingControl>(x as u8) }) |
198 | 0 | } |
199 | | } |
200 | | #[test] |
201 | | #[rustfmt::skip] |
202 | | fn test_roundingcontrol_values() { |
203 | | let mut iter = RoundingControl::values(); |
204 | | assert_eq!(iter.size_hint(), (IcedConstants::ROUNDING_CONTROL_ENUM_COUNT, Some(IcedConstants::ROUNDING_CONTROL_ENUM_COUNT))); |
205 | | assert_eq!(iter.len(), IcedConstants::ROUNDING_CONTROL_ENUM_COUNT); |
206 | | assert!(iter.next().is_some()); |
207 | | assert_eq!(iter.size_hint(), (IcedConstants::ROUNDING_CONTROL_ENUM_COUNT - 1, Some(IcedConstants::ROUNDING_CONTROL_ENUM_COUNT - 1))); |
208 | | assert_eq!(iter.len(), IcedConstants::ROUNDING_CONTROL_ENUM_COUNT - 1); |
209 | | |
210 | | let values: Vec<RoundingControl> = RoundingControl::values().collect(); |
211 | | assert_eq!(values.len(), IcedConstants::ROUNDING_CONTROL_ENUM_COUNT); |
212 | | for (i, value) in values.into_iter().enumerate() { |
213 | | assert_eq!(i, value as usize); |
214 | | } |
215 | | |
216 | | let values1: Vec<RoundingControl> = RoundingControl::values().collect(); |
217 | | let mut values2: Vec<RoundingControl> = RoundingControl::values().rev().collect(); |
218 | | values2.reverse(); |
219 | | assert_eq!(values1, values2); |
220 | | } |
221 | | #[rustfmt::skip] |
222 | | impl TryFrom<usize> for RoundingControl { |
223 | | type Error = IcedError; |
224 | | #[inline] |
225 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
226 | 0 | if value < IcedConstants::ROUNDING_CONTROL_ENUM_COUNT { |
227 | | // SAFETY: all values 0-max are valid enum values |
228 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
229 | | } else { |
230 | 0 | Err(IcedError::new("Invalid RoundingControl value")) |
231 | | } |
232 | 0 | } |
233 | | } |
234 | | #[test] |
235 | | #[rustfmt::skip] |
236 | | fn test_roundingcontrol_try_from_usize() { |
237 | | for value in RoundingControl::values() { |
238 | | let converted = <RoundingControl as TryFrom<usize>>::try_from(value as usize).unwrap(); |
239 | | assert_eq!(converted, value); |
240 | | } |
241 | | assert!(<RoundingControl as TryFrom<usize>>::try_from(IcedConstants::ROUNDING_CONTROL_ENUM_COUNT).is_err()); |
242 | | assert!(<RoundingControl as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
243 | | } |
244 | | #[cfg(feature = "serde")] |
245 | | #[rustfmt::skip] |
246 | | #[allow(clippy::zero_sized_map_values)] |
247 | | const _: () = { |
248 | | use core::marker::PhantomData; |
249 | | use serde::de; |
250 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
251 | | type EnumType = RoundingControl; |
252 | | impl Serialize for EnumType { |
253 | | #[inline] |
254 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
255 | | where |
256 | | S: Serializer, |
257 | | { |
258 | | serializer.serialize_u8(*self as u8) |
259 | | } |
260 | | } |
261 | | impl<'de> Deserialize<'de> for EnumType { |
262 | | #[inline] |
263 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
264 | | where |
265 | | D: Deserializer<'de>, |
266 | | { |
267 | | struct Visitor<'de> { |
268 | | marker: PhantomData<EnumType>, |
269 | | lifetime: PhantomData<&'de ()>, |
270 | | } |
271 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
272 | | type Value = EnumType; |
273 | | #[inline] |
274 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
275 | | formatter.write_str("enum RoundingControl") |
276 | | } |
277 | | #[inline] |
278 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
279 | | where |
280 | | E: de::Error, |
281 | | { |
282 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
283 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
284 | | return Ok(value); |
285 | | } |
286 | | } |
287 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid RoundingControl variant value")) |
288 | | } |
289 | | } |
290 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
291 | | } |
292 | | } |
293 | | }; |
294 | | // GENERATOR-END: RoundingControl |
295 | | |
296 | | // GENERATOR-BEGIN: OpKind |
297 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
298 | | /// Instruction operand kind |
299 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
300 | | #[allow(non_camel_case_types)] |
301 | | pub enum OpKind { |
302 | | /// A register ([`Register`]). |
303 | | /// |
304 | | /// This operand kind uses [`Instruction::op0_register()`], [`Instruction::op1_register()`], [`Instruction::op2_register()`], [`Instruction::op3_register()`] or [`Instruction::op4_register()`] depending on operand number. See also [`Instruction::op_register()`]. |
305 | | /// |
306 | | /// [`Register`]: enum.Register.html |
307 | | /// [`Instruction::op0_register()`]: struct.Instruction.html#method.op0_register |
308 | | /// [`Instruction::op1_register()`]: struct.Instruction.html#method.op1_register |
309 | | /// [`Instruction::op2_register()`]: struct.Instruction.html#method.op2_register |
310 | | /// [`Instruction::op3_register()`]: struct.Instruction.html#method.op3_register |
311 | | /// [`Instruction::op4_register()`]: struct.Instruction.html#method.op4_register |
312 | | /// [`Instruction::op_register()`]: struct.Instruction.html#method.op_register |
313 | | Register = 0, |
314 | | /// Near 16-bit branch. This operand kind uses [`Instruction::near_branch16()`] |
315 | | /// |
316 | | /// [`Instruction::near_branch16()`]: struct.Instruction.html#method.near_branch16 |
317 | | NearBranch16 = 1, |
318 | | /// Near 32-bit branch. This operand kind uses [`Instruction::near_branch32()`] |
319 | | /// |
320 | | /// [`Instruction::near_branch32()`]: struct.Instruction.html#method.near_branch32 |
321 | | NearBranch32 = 2, |
322 | | /// Near 64-bit branch. This operand kind uses [`Instruction::near_branch64()`] |
323 | | /// |
324 | | /// [`Instruction::near_branch64()`]: struct.Instruction.html#method.near_branch64 |
325 | | NearBranch64 = 3, |
326 | | /// Far 16-bit branch. This operand kind uses [`Instruction::far_branch16()`] and [`Instruction::far_branch_selector()`] |
327 | | /// |
328 | | /// [`Instruction::far_branch16()`]: struct.Instruction.html#method.far_branch16 |
329 | | /// [`Instruction::far_branch_selector()`]: struct.Instruction.html#method.far_branch_selector |
330 | | FarBranch16 = 4, |
331 | | /// Far 32-bit branch. This operand kind uses [`Instruction::far_branch32()`] and [`Instruction::far_branch_selector()`] |
332 | | /// |
333 | | /// [`Instruction::far_branch32()`]: struct.Instruction.html#method.far_branch32 |
334 | | /// [`Instruction::far_branch_selector()`]: struct.Instruction.html#method.far_branch_selector |
335 | | FarBranch32 = 5, |
336 | | /// 8-bit constant. This operand kind uses [`Instruction::immediate8()`] |
337 | | /// |
338 | | /// [`Instruction::immediate8()`]: struct.Instruction.html#method.immediate8 |
339 | | Immediate8 = 6, |
340 | | /// 8-bit constant used by the `ENTER`, `EXTRQ`, `INSERTQ` instructions. This operand kind uses [`Instruction::immediate8_2nd()`] |
341 | | /// |
342 | | /// [`Instruction::immediate8_2nd()`]: struct.Instruction.html#method.immediate8_2nd |
343 | | Immediate8_2nd = 7, |
344 | | /// 16-bit constant. This operand kind uses [`Instruction::immediate16()`] |
345 | | /// |
346 | | /// [`Instruction::immediate16()`]: struct.Instruction.html#method.immediate16 |
347 | | Immediate16 = 8, |
348 | | /// 32-bit constant. This operand kind uses [`Instruction::immediate32()`] |
349 | | /// |
350 | | /// [`Instruction::immediate32()`]: struct.Instruction.html#method.immediate32 |
351 | | Immediate32 = 9, |
352 | | /// 64-bit constant. This operand kind uses [`Instruction::immediate64()`] |
353 | | /// |
354 | | /// [`Instruction::immediate64()`]: struct.Instruction.html#method.immediate64 |
355 | | Immediate64 = 10, |
356 | | /// An 8-bit value sign extended to 16 bits. This operand kind uses [`Instruction::immediate8to16()`] |
357 | | /// |
358 | | /// [`Instruction::immediate8to16()`]: struct.Instruction.html#method.immediate8to16 |
359 | | Immediate8to16 = 11, |
360 | | /// An 8-bit value sign extended to 32 bits. This operand kind uses [`Instruction::immediate8to32()`] |
361 | | /// |
362 | | /// [`Instruction::immediate8to32()`]: struct.Instruction.html#method.immediate8to32 |
363 | | Immediate8to32 = 12, |
364 | | /// An 8-bit value sign extended to 64 bits. This operand kind uses [`Instruction::immediate8to64()`] |
365 | | /// |
366 | | /// [`Instruction::immediate8to64()`]: struct.Instruction.html#method.immediate8to64 |
367 | | Immediate8to64 = 13, |
368 | | /// A 32-bit value sign extended to 64 bits. This operand kind uses [`Instruction::immediate32to64()`] |
369 | | /// |
370 | | /// [`Instruction::immediate32to64()`]: struct.Instruction.html#method.immediate32to64 |
371 | | Immediate32to64 = 14, |
372 | | /// `seg:[SI]`. This operand kind uses [`Instruction::memory_size()`], [`Instruction::memory_segment()`], [`Instruction::segment_prefix()`] |
373 | | /// |
374 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
375 | | /// [`Instruction::memory_segment()`]: struct.Instruction.html#method.memory_segment |
376 | | /// [`Instruction::segment_prefix()`]: struct.Instruction.html#method.segment_prefix |
377 | | MemorySegSI = 15, |
378 | | /// `seg:[ESI]`. This operand kind uses [`Instruction::memory_size()`], [`Instruction::memory_segment()`], [`Instruction::segment_prefix()`] |
379 | | /// |
380 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
381 | | /// [`Instruction::memory_segment()`]: struct.Instruction.html#method.memory_segment |
382 | | /// [`Instruction::segment_prefix()`]: struct.Instruction.html#method.segment_prefix |
383 | | MemorySegESI = 16, |
384 | | /// `seg:[RSI]`. This operand kind uses [`Instruction::memory_size()`], [`Instruction::memory_segment()`], [`Instruction::segment_prefix()`] |
385 | | /// |
386 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
387 | | /// [`Instruction::memory_segment()`]: struct.Instruction.html#method.memory_segment |
388 | | /// [`Instruction::segment_prefix()`]: struct.Instruction.html#method.segment_prefix |
389 | | MemorySegRSI = 17, |
390 | | /// `seg:[DI]`. This operand kind uses [`Instruction::memory_size()`], [`Instruction::memory_segment()`], [`Instruction::segment_prefix()`] |
391 | | /// |
392 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
393 | | /// [`Instruction::memory_segment()`]: struct.Instruction.html#method.memory_segment |
394 | | /// [`Instruction::segment_prefix()`]: struct.Instruction.html#method.segment_prefix |
395 | | MemorySegDI = 18, |
396 | | /// `seg:[EDI]`. This operand kind uses [`Instruction::memory_size()`], [`Instruction::memory_segment()`], [`Instruction::segment_prefix()`] |
397 | | /// |
398 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
399 | | /// [`Instruction::memory_segment()`]: struct.Instruction.html#method.memory_segment |
400 | | /// [`Instruction::segment_prefix()`]: struct.Instruction.html#method.segment_prefix |
401 | | MemorySegEDI = 19, |
402 | | /// `seg:[RDI]`. This operand kind uses [`Instruction::memory_size()`], [`Instruction::memory_segment()`], [`Instruction::segment_prefix()`] |
403 | | /// |
404 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
405 | | /// [`Instruction::memory_segment()`]: struct.Instruction.html#method.memory_segment |
406 | | /// [`Instruction::segment_prefix()`]: struct.Instruction.html#method.segment_prefix |
407 | | MemorySegRDI = 20, |
408 | | /// `ES:[DI]`. This operand kind uses [`Instruction::memory_size()`] |
409 | | /// |
410 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
411 | | MemoryESDI = 21, |
412 | | /// `ES:[EDI]`. This operand kind uses [`Instruction::memory_size()`] |
413 | | /// |
414 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
415 | | MemoryESEDI = 22, |
416 | | /// `ES:[RDI]`. This operand kind uses [`Instruction::memory_size()`] |
417 | | /// |
418 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
419 | | MemoryESRDI = 23, |
420 | | /// Memory operand. |
421 | | /// |
422 | | /// This operand kind uses [`Instruction::memory_displ_size()`], [`Instruction::memory_size()`], [`Instruction::memory_index_scale()`], [`Instruction::memory_displacement64()`], [`Instruction::memory_base()`], [`Instruction::memory_index()`], [`Instruction::memory_segment()`], [`Instruction::segment_prefix()`] |
423 | | /// |
424 | | /// [`Instruction::memory_displ_size()`]: struct.Instruction.html#method.memory_displ_size |
425 | | /// [`Instruction::memory_size()`]: struct.Instruction.html#method.memory_size |
426 | | /// [`Instruction::memory_index_scale()`]: struct.Instruction.html#method.memory_index_scale |
427 | | /// [`Instruction::memory_displacement64()`]: struct.Instruction.html#method.memory_displacement64 |
428 | | /// [`Instruction::memory_base()`]: struct.Instruction.html#method.memory_base |
429 | | /// [`Instruction::memory_index()`]: struct.Instruction.html#method.memory_index |
430 | | /// [`Instruction::memory_segment()`]: struct.Instruction.html#method.memory_segment |
431 | | /// [`Instruction::segment_prefix()`]: struct.Instruction.html#method.segment_prefix |
432 | | Memory = 24, |
433 | | } |
434 | | #[rustfmt::skip] |
435 | | static GEN_DEBUG_OP_KIND: [&str; 25] = [ |
436 | | "Register", |
437 | | "NearBranch16", |
438 | | "NearBranch32", |
439 | | "NearBranch64", |
440 | | "FarBranch16", |
441 | | "FarBranch32", |
442 | | "Immediate8", |
443 | | "Immediate8_2nd", |
444 | | "Immediate16", |
445 | | "Immediate32", |
446 | | "Immediate64", |
447 | | "Immediate8to16", |
448 | | "Immediate8to32", |
449 | | "Immediate8to64", |
450 | | "Immediate32to64", |
451 | | "MemorySegSI", |
452 | | "MemorySegESI", |
453 | | "MemorySegRSI", |
454 | | "MemorySegDI", |
455 | | "MemorySegEDI", |
456 | | "MemorySegRDI", |
457 | | "MemoryESDI", |
458 | | "MemoryESEDI", |
459 | | "MemoryESRDI", |
460 | | "Memory", |
461 | | ]; |
462 | | impl fmt::Debug for OpKind { |
463 | | #[inline] |
464 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
465 | 0 | write!(f, "{}", GEN_DEBUG_OP_KIND[*self as usize]) |
466 | 0 | } Unexecuted instantiation: <iced_x86::enums::OpKind as core::fmt::Debug>::fmt Unexecuted instantiation: <iced_x86::enums::OpKind as core::fmt::Debug>::fmt |
467 | | } |
468 | | impl Default for OpKind { |
469 | | #[must_use] |
470 | | #[inline] |
471 | 17.6k | fn default() -> Self { |
472 | 17.6k | OpKind::Register |
473 | 17.6k | } |
474 | | } |
475 | | #[allow(non_camel_case_types)] |
476 | | #[allow(dead_code)] |
477 | | pub(crate) type OpKindUnderlyingType = u8; |
478 | | #[rustfmt::skip] |
479 | | impl OpKind { |
480 | | /// Iterates over all `OpKind` enum values |
481 | | #[inline] |
482 | 0 | pub fn values() -> impl Iterator<Item = OpKind> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
483 | | // SAFETY: all values 0-max are valid enum values |
484 | 0 | (0..IcedConstants::OP_KIND_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, OpKind>(x as u8) }) |
485 | 0 | } |
486 | | } |
487 | | #[test] |
488 | | #[rustfmt::skip] |
489 | | fn test_opkind_values() { |
490 | | let mut iter = OpKind::values(); |
491 | | assert_eq!(iter.size_hint(), (IcedConstants::OP_KIND_ENUM_COUNT, Some(IcedConstants::OP_KIND_ENUM_COUNT))); |
492 | | assert_eq!(iter.len(), IcedConstants::OP_KIND_ENUM_COUNT); |
493 | | assert!(iter.next().is_some()); |
494 | | assert_eq!(iter.size_hint(), (IcedConstants::OP_KIND_ENUM_COUNT - 1, Some(IcedConstants::OP_KIND_ENUM_COUNT - 1))); |
495 | | assert_eq!(iter.len(), IcedConstants::OP_KIND_ENUM_COUNT - 1); |
496 | | |
497 | | let values: Vec<OpKind> = OpKind::values().collect(); |
498 | | assert_eq!(values.len(), IcedConstants::OP_KIND_ENUM_COUNT); |
499 | | for (i, value) in values.into_iter().enumerate() { |
500 | | assert_eq!(i, value as usize); |
501 | | } |
502 | | |
503 | | let values1: Vec<OpKind> = OpKind::values().collect(); |
504 | | let mut values2: Vec<OpKind> = OpKind::values().rev().collect(); |
505 | | values2.reverse(); |
506 | | assert_eq!(values1, values2); |
507 | | } |
508 | | #[rustfmt::skip] |
509 | | impl TryFrom<usize> for OpKind { |
510 | | type Error = IcedError; |
511 | | #[inline] |
512 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
513 | 0 | if value < IcedConstants::OP_KIND_ENUM_COUNT { |
514 | | // SAFETY: all values 0-max are valid enum values |
515 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
516 | | } else { |
517 | 0 | Err(IcedError::new("Invalid OpKind value")) |
518 | | } |
519 | 0 | } |
520 | | } |
521 | | #[test] |
522 | | #[rustfmt::skip] |
523 | | fn test_opkind_try_from_usize() { |
524 | | for value in OpKind::values() { |
525 | | let converted = <OpKind as TryFrom<usize>>::try_from(value as usize).unwrap(); |
526 | | assert_eq!(converted, value); |
527 | | } |
528 | | assert!(<OpKind as TryFrom<usize>>::try_from(IcedConstants::OP_KIND_ENUM_COUNT).is_err()); |
529 | | assert!(<OpKind as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
530 | | } |
531 | | #[cfg(feature = "serde")] |
532 | | #[rustfmt::skip] |
533 | | #[allow(clippy::zero_sized_map_values)] |
534 | | const _: () = { |
535 | | use core::marker::PhantomData; |
536 | | use serde::de; |
537 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
538 | | type EnumType = OpKind; |
539 | | impl Serialize for EnumType { |
540 | | #[inline] |
541 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
542 | | where |
543 | | S: Serializer, |
544 | | { |
545 | | serializer.serialize_u8(*self as u8) |
546 | | } |
547 | | } |
548 | | impl<'de> Deserialize<'de> for EnumType { |
549 | | #[inline] |
550 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
551 | | where |
552 | | D: Deserializer<'de>, |
553 | | { |
554 | | struct Visitor<'de> { |
555 | | marker: PhantomData<EnumType>, |
556 | | lifetime: PhantomData<&'de ()>, |
557 | | } |
558 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
559 | | type Value = EnumType; |
560 | | #[inline] |
561 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
562 | | formatter.write_str("enum OpKind") |
563 | | } |
564 | | #[inline] |
565 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
566 | | where |
567 | | E: de::Error, |
568 | | { |
569 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
570 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
571 | | return Ok(value); |
572 | | } |
573 | | } |
574 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid OpKind variant value")) |
575 | | } |
576 | | } |
577 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
578 | | } |
579 | | } |
580 | | }; |
581 | | // GENERATOR-END: OpKind |
582 | | |
583 | | // GENERATOR-BEGIN: VectorLength |
584 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
585 | | #[derive(Copy, Clone, Eq, PartialEq)] |
586 | | #[cfg(any(feature = "decoder", feature = "encoder"))] |
587 | | #[repr(u32)] |
588 | | #[allow(dead_code)] |
589 | | pub(crate) enum VectorLength { |
590 | | L128, |
591 | | L256, |
592 | | L512, |
593 | | Unknown, |
594 | | } |
595 | | #[cfg(any(feature = "decoder", feature = "encoder"))] |
596 | | #[rustfmt::skip] |
597 | | static GEN_DEBUG_VECTOR_LENGTH: [&str; 4] = [ |
598 | | "L128", |
599 | | "L256", |
600 | | "L512", |
601 | | "Unknown", |
602 | | ]; |
603 | | #[cfg(any(feature = "decoder", feature = "encoder"))] |
604 | | impl fmt::Debug for VectorLength { |
605 | | #[inline] |
606 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
607 | 0 | write!(f, "{}", GEN_DEBUG_VECTOR_LENGTH[*self as usize]) |
608 | 0 | } |
609 | | } |
610 | | #[cfg(any(feature = "decoder", feature = "encoder"))] |
611 | | impl Default for VectorLength { |
612 | | #[must_use] |
613 | | #[inline] |
614 | 2.09k | fn default() -> Self { |
615 | 2.09k | VectorLength::L128 |
616 | 2.09k | } |
617 | | } |
618 | | // GENERATOR-END: VectorLength |
619 | | |
620 | | // GENERATOR-BEGIN: MandatoryPrefixByte |
621 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
622 | | #[derive(Copy, Clone, Eq, PartialEq)] |
623 | | #[cfg(feature = "encoder")] |
624 | | #[allow(dead_code)] |
625 | | pub(crate) enum MandatoryPrefixByte { |
626 | | None, |
627 | | P66, |
628 | | PF3, |
629 | | PF2, |
630 | | } |
631 | | #[cfg(feature = "encoder")] |
632 | | #[rustfmt::skip] |
633 | | static GEN_DEBUG_MANDATORY_PREFIX_BYTE: [&str; 4] = [ |
634 | | "None", |
635 | | "P66", |
636 | | "PF3", |
637 | | "PF2", |
638 | | ]; |
639 | | #[cfg(feature = "encoder")] |
640 | | impl fmt::Debug for MandatoryPrefixByte { |
641 | | #[inline] |
642 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
643 | 0 | write!(f, "{}", GEN_DEBUG_MANDATORY_PREFIX_BYTE[*self as usize]) |
644 | 0 | } |
645 | | } |
646 | | #[cfg(feature = "encoder")] |
647 | | impl Default for MandatoryPrefixByte { |
648 | | #[must_use] |
649 | | #[inline] |
650 | 0 | fn default() -> Self { |
651 | 0 | MandatoryPrefixByte::None |
652 | 0 | } |
653 | | } |
654 | | // GENERATOR-END: MandatoryPrefixByte |
655 | | |
656 | | // GENERATOR-BEGIN: EncodingKind |
657 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
658 | | /// Instruction encoding |
659 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
660 | | #[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)] |
661 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
662 | | pub enum EncodingKind { |
663 | | /// Legacy encoding |
664 | | Legacy = 0, |
665 | | /// VEX encoding |
666 | | VEX = 1, |
667 | | /// EVEX encoding |
668 | | EVEX = 2, |
669 | | /// XOP encoding |
670 | | XOP = 3, |
671 | | /// 3DNow! encoding |
672 | | D3NOW = 4, |
673 | | /// MVEX encoding |
674 | | MVEX = 5, |
675 | | } |
676 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
677 | | #[rustfmt::skip] |
678 | | static GEN_DEBUG_ENCODING_KIND: [&str; 6] = [ |
679 | | "Legacy", |
680 | | "VEX", |
681 | | "EVEX", |
682 | | "XOP", |
683 | | "D3NOW", |
684 | | "MVEX", |
685 | | ]; |
686 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
687 | | impl fmt::Debug for EncodingKind { |
688 | | #[inline] |
689 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
690 | 0 | write!(f, "{}", GEN_DEBUG_ENCODING_KIND[*self as usize]) |
691 | 0 | } |
692 | | } |
693 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
694 | | impl Default for EncodingKind { |
695 | | #[must_use] |
696 | | #[inline] |
697 | 0 | fn default() -> Self { |
698 | 0 | EncodingKind::Legacy |
699 | 0 | } |
700 | | } |
701 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
702 | | #[allow(non_camel_case_types)] |
703 | | #[allow(dead_code)] |
704 | | pub(crate) type EncodingKindUnderlyingType = u8; |
705 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
706 | | #[rustfmt::skip] |
707 | | impl EncodingKind { |
708 | | /// Iterates over all `EncodingKind` enum values |
709 | | #[inline] |
710 | 0 | pub fn values() -> impl Iterator<Item = EncodingKind> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
711 | | // SAFETY: all values 0-max are valid enum values |
712 | 0 | (0..IcedConstants::ENCODING_KIND_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, EncodingKind>(x as u8) }) |
713 | 0 | } |
714 | | } |
715 | | #[test] |
716 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
717 | | #[rustfmt::skip] |
718 | | fn test_encodingkind_values() { |
719 | | let mut iter = EncodingKind::values(); |
720 | | assert_eq!(iter.size_hint(), (IcedConstants::ENCODING_KIND_ENUM_COUNT, Some(IcedConstants::ENCODING_KIND_ENUM_COUNT))); |
721 | | assert_eq!(iter.len(), IcedConstants::ENCODING_KIND_ENUM_COUNT); |
722 | | assert!(iter.next().is_some()); |
723 | | assert_eq!(iter.size_hint(), (IcedConstants::ENCODING_KIND_ENUM_COUNT - 1, Some(IcedConstants::ENCODING_KIND_ENUM_COUNT - 1))); |
724 | | assert_eq!(iter.len(), IcedConstants::ENCODING_KIND_ENUM_COUNT - 1); |
725 | | |
726 | | let values: Vec<EncodingKind> = EncodingKind::values().collect(); |
727 | | assert_eq!(values.len(), IcedConstants::ENCODING_KIND_ENUM_COUNT); |
728 | | for (i, value) in values.into_iter().enumerate() { |
729 | | assert_eq!(i, value as usize); |
730 | | } |
731 | | |
732 | | let values1: Vec<EncodingKind> = EncodingKind::values().collect(); |
733 | | let mut values2: Vec<EncodingKind> = EncodingKind::values().rev().collect(); |
734 | | values2.reverse(); |
735 | | assert_eq!(values1, values2); |
736 | | } |
737 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
738 | | #[rustfmt::skip] |
739 | | impl TryFrom<usize> for EncodingKind { |
740 | | type Error = IcedError; |
741 | | #[inline] |
742 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
743 | 0 | if value < IcedConstants::ENCODING_KIND_ENUM_COUNT { |
744 | | // SAFETY: all values 0-max are valid enum values |
745 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
746 | | } else { |
747 | 0 | Err(IcedError::new("Invalid EncodingKind value")) |
748 | | } |
749 | 0 | } |
750 | | } |
751 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
752 | | #[test] |
753 | | #[rustfmt::skip] |
754 | | fn test_encodingkind_try_from_usize() { |
755 | | for value in EncodingKind::values() { |
756 | | let converted = <EncodingKind as TryFrom<usize>>::try_from(value as usize).unwrap(); |
757 | | assert_eq!(converted, value); |
758 | | } |
759 | | assert!(<EncodingKind as TryFrom<usize>>::try_from(IcedConstants::ENCODING_KIND_ENUM_COUNT).is_err()); |
760 | | assert!(<EncodingKind as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
761 | | } |
762 | | #[cfg(feature = "serde")] |
763 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "instr_info", feature = "op_code_info"))] |
764 | | #[rustfmt::skip] |
765 | | #[allow(clippy::zero_sized_map_values)] |
766 | | const _: () = { |
767 | | use core::marker::PhantomData; |
768 | | use serde::de; |
769 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
770 | | type EnumType = EncodingKind; |
771 | | impl Serialize for EnumType { |
772 | | #[inline] |
773 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
774 | | where |
775 | | S: Serializer, |
776 | | { |
777 | | serializer.serialize_u8(*self as u8) |
778 | | } |
779 | | } |
780 | | impl<'de> Deserialize<'de> for EnumType { |
781 | | #[inline] |
782 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
783 | | where |
784 | | D: Deserializer<'de>, |
785 | | { |
786 | | struct Visitor<'de> { |
787 | | marker: PhantomData<EnumType>, |
788 | | lifetime: PhantomData<&'de ()>, |
789 | | } |
790 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
791 | | type Value = EnumType; |
792 | | #[inline] |
793 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
794 | | formatter.write_str("enum EncodingKind") |
795 | | } |
796 | | #[inline] |
797 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
798 | | where |
799 | | E: de::Error, |
800 | | { |
801 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
802 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
803 | | return Ok(value); |
804 | | } |
805 | | } |
806 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid EncodingKind variant value")) |
807 | | } |
808 | | } |
809 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
810 | | } |
811 | | } |
812 | | }; |
813 | | // GENERATOR-END: EncodingKind |
814 | | |
815 | | // GENERATOR-BEGIN: TupleType |
816 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
817 | | /// Tuple type (EVEX/MVEX) which can be used to get the disp8 scale factor `N` |
818 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
819 | | #[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)] |
820 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
821 | | #[allow(non_camel_case_types)] |
822 | | pub enum TupleType { |
823 | | /// `N = 1` |
824 | | N1 = 0, |
825 | | /// `N = 2` |
826 | | N2 = 1, |
827 | | /// `N = 4` |
828 | | N4 = 2, |
829 | | /// `N = 8` |
830 | | N8 = 3, |
831 | | /// `N = 16` |
832 | | N16 = 4, |
833 | | /// `N = 32` |
834 | | N32 = 5, |
835 | | /// `N = 64` |
836 | | N64 = 6, |
837 | | /// `N = b ? 4 : 8` |
838 | | N8b4 = 7, |
839 | | /// `N = b ? 4 : 16` |
840 | | N16b4 = 8, |
841 | | /// `N = b ? 4 : 32` |
842 | | N32b4 = 9, |
843 | | /// `N = b ? 4 : 64` |
844 | | N64b4 = 10, |
845 | | /// `N = b ? 8 : 16` |
846 | | N16b8 = 11, |
847 | | /// `N = b ? 8 : 32` |
848 | | N32b8 = 12, |
849 | | /// `N = b ? 8 : 64` |
850 | | N64b8 = 13, |
851 | | /// `N = b ? 2 : 4` |
852 | | N4b2 = 14, |
853 | | /// `N = b ? 2 : 8` |
854 | | N8b2 = 15, |
855 | | /// `N = b ? 2 : 16` |
856 | | N16b2 = 16, |
857 | | /// `N = b ? 2 : 32` |
858 | | N32b2 = 17, |
859 | | /// `N = b ? 2 : 64` |
860 | | N64b2 = 18, |
861 | | } |
862 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
863 | | #[rustfmt::skip] |
864 | | static GEN_DEBUG_TUPLE_TYPE: [&str; 19] = [ |
865 | | "N1", |
866 | | "N2", |
867 | | "N4", |
868 | | "N8", |
869 | | "N16", |
870 | | "N32", |
871 | | "N64", |
872 | | "N8b4", |
873 | | "N16b4", |
874 | | "N32b4", |
875 | | "N64b4", |
876 | | "N16b8", |
877 | | "N32b8", |
878 | | "N64b8", |
879 | | "N4b2", |
880 | | "N8b2", |
881 | | "N16b2", |
882 | | "N32b2", |
883 | | "N64b2", |
884 | | ]; |
885 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
886 | | impl fmt::Debug for TupleType { |
887 | | #[inline] |
888 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
889 | 0 | write!(f, "{}", GEN_DEBUG_TUPLE_TYPE[*self as usize]) |
890 | 0 | } |
891 | | } |
892 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
893 | | impl Default for TupleType { |
894 | | #[must_use] |
895 | | #[inline] |
896 | 0 | fn default() -> Self { |
897 | 0 | TupleType::N1 |
898 | 0 | } |
899 | | } |
900 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
901 | | #[allow(non_camel_case_types)] |
902 | | #[allow(dead_code)] |
903 | | pub(crate) type TupleTypeUnderlyingType = u8; |
904 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
905 | | #[rustfmt::skip] |
906 | | impl TupleType { |
907 | | /// Iterates over all `TupleType` enum values |
908 | | #[inline] |
909 | 0 | pub fn values() -> impl Iterator<Item = TupleType> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
910 | | // SAFETY: all values 0-max are valid enum values |
911 | 0 | (0..IcedConstants::TUPLE_TYPE_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, TupleType>(x as u8) }) |
912 | 0 | } |
913 | | } |
914 | | #[test] |
915 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
916 | | #[rustfmt::skip] |
917 | | fn test_tupletype_values() { |
918 | | let mut iter = TupleType::values(); |
919 | | assert_eq!(iter.size_hint(), (IcedConstants::TUPLE_TYPE_ENUM_COUNT, Some(IcedConstants::TUPLE_TYPE_ENUM_COUNT))); |
920 | | assert_eq!(iter.len(), IcedConstants::TUPLE_TYPE_ENUM_COUNT); |
921 | | assert!(iter.next().is_some()); |
922 | | assert_eq!(iter.size_hint(), (IcedConstants::TUPLE_TYPE_ENUM_COUNT - 1, Some(IcedConstants::TUPLE_TYPE_ENUM_COUNT - 1))); |
923 | | assert_eq!(iter.len(), IcedConstants::TUPLE_TYPE_ENUM_COUNT - 1); |
924 | | |
925 | | let values: Vec<TupleType> = TupleType::values().collect(); |
926 | | assert_eq!(values.len(), IcedConstants::TUPLE_TYPE_ENUM_COUNT); |
927 | | for (i, value) in values.into_iter().enumerate() { |
928 | | assert_eq!(i, value as usize); |
929 | | } |
930 | | |
931 | | let values1: Vec<TupleType> = TupleType::values().collect(); |
932 | | let mut values2: Vec<TupleType> = TupleType::values().rev().collect(); |
933 | | values2.reverse(); |
934 | | assert_eq!(values1, values2); |
935 | | } |
936 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
937 | | #[rustfmt::skip] |
938 | | impl TryFrom<usize> for TupleType { |
939 | | type Error = IcedError; |
940 | | #[inline] |
941 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
942 | 0 | if value < IcedConstants::TUPLE_TYPE_ENUM_COUNT { |
943 | | // SAFETY: all values 0-max are valid enum values |
944 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
945 | | } else { |
946 | 0 | Err(IcedError::new("Invalid TupleType value")) |
947 | | } |
948 | 0 | } |
949 | | } |
950 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
951 | | #[test] |
952 | | #[rustfmt::skip] |
953 | | fn test_tupletype_try_from_usize() { |
954 | | for value in TupleType::values() { |
955 | | let converted = <TupleType as TryFrom<usize>>::try_from(value as usize).unwrap(); |
956 | | assert_eq!(converted, value); |
957 | | } |
958 | | assert!(<TupleType as TryFrom<usize>>::try_from(IcedConstants::TUPLE_TYPE_ENUM_COUNT).is_err()); |
959 | | assert!(<TupleType as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
960 | | } |
961 | | #[cfg(feature = "serde")] |
962 | | #[cfg(any(feature = "decoder", feature = "encoder", feature = "op_code_info"))] |
963 | | #[rustfmt::skip] |
964 | | #[allow(clippy::zero_sized_map_values)] |
965 | | const _: () = { |
966 | | use core::marker::PhantomData; |
967 | | use serde::de; |
968 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
969 | | type EnumType = TupleType; |
970 | | impl Serialize for EnumType { |
971 | | #[inline] |
972 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
973 | | where |
974 | | S: Serializer, |
975 | | { |
976 | | serializer.serialize_u8(*self as u8) |
977 | | } |
978 | | } |
979 | | impl<'de> Deserialize<'de> for EnumType { |
980 | | #[inline] |
981 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
982 | | where |
983 | | D: Deserializer<'de>, |
984 | | { |
985 | | struct Visitor<'de> { |
986 | | marker: PhantomData<EnumType>, |
987 | | lifetime: PhantomData<&'de ()>, |
988 | | } |
989 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
990 | | type Value = EnumType; |
991 | | #[inline] |
992 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
993 | | formatter.write_str("enum TupleType") |
994 | | } |
995 | | #[inline] |
996 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
997 | | where |
998 | | E: de::Error, |
999 | | { |
1000 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
1001 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
1002 | | return Ok(value); |
1003 | | } |
1004 | | } |
1005 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid TupleType variant value")) |
1006 | | } |
1007 | | } |
1008 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
1009 | | } |
1010 | | } |
1011 | | }; |
1012 | | // GENERATOR-END: TupleType |
1013 | | |
1014 | | // GENERATOR-BEGIN: FlowControl |
1015 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
1016 | | /// Control flow |
1017 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
1018 | | #[cfg(feature = "instr_info")] |
1019 | | pub enum FlowControl { |
1020 | | /// The next instruction that will be executed is the next instruction in the instruction stream |
1021 | | Next = 0, |
1022 | | /// It's an unconditional branch instruction: `JMP NEAR`, `JMP FAR` |
1023 | | UnconditionalBranch = 1, |
1024 | | /// It's an unconditional indirect branch: `JMP NEAR reg`, `JMP NEAR [mem]`, `JMP FAR [mem]` |
1025 | | IndirectBranch = 2, |
1026 | | /// It's a conditional branch instruction: `Jcc SHORT`, `Jcc NEAR`, `LOOP`, `LOOPcc`, `JRCXZ`, `JKccD SHORT`, `JKccD NEAR` |
1027 | | ConditionalBranch = 3, |
1028 | | /// It's a return instruction: `RET NEAR`, `RET FAR`, `IRET`, `SYSRET`, `SYSEXIT`, `RSM`, `SKINIT`, `RDM`, `UIRET` |
1029 | | Return = 4, |
1030 | | /// It's a call instruction: `CALL NEAR`, `CALL FAR`, `SYSCALL`, `SYSENTER`, `VMLAUNCH`, `VMRESUME`, `VMCALL`, `VMMCALL`, `VMGEXIT`, `VMRUN`, `TDCALL`, `SEAMCALL`, `SEAMRET` |
1031 | | Call = 5, |
1032 | | /// It's an indirect call instruction: `CALL NEAR reg`, `CALL NEAR [mem]`, `CALL FAR [mem]` |
1033 | | IndirectCall = 6, |
1034 | | /// It's an interrupt instruction: `INT n`, `INT3`, `INT1`, `INTO`, `SMINT`, `DMINT` |
1035 | | Interrupt = 7, |
1036 | | /// It's `XBEGIN` |
1037 | | XbeginXabortXend = 8, |
1038 | | /// It's an invalid instruction, eg. [`Code::INVALID`], `UD0`, `UD1`, `UD2` |
1039 | | /// |
1040 | | /// [`Code::INVALID`]: enum.Code.html#variant.INVALID |
1041 | | Exception = 9, |
1042 | | } |
1043 | | #[cfg(feature = "instr_info")] |
1044 | | #[rustfmt::skip] |
1045 | | static GEN_DEBUG_FLOW_CONTROL: [&str; 10] = [ |
1046 | | "Next", |
1047 | | "UnconditionalBranch", |
1048 | | "IndirectBranch", |
1049 | | "ConditionalBranch", |
1050 | | "Return", |
1051 | | "Call", |
1052 | | "IndirectCall", |
1053 | | "Interrupt", |
1054 | | "XbeginXabortXend", |
1055 | | "Exception", |
1056 | | ]; |
1057 | | #[cfg(feature = "instr_info")] |
1058 | | impl fmt::Debug for FlowControl { |
1059 | | #[inline] |
1060 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1061 | 0 | write!(f, "{}", GEN_DEBUG_FLOW_CONTROL[*self as usize]) |
1062 | 0 | } |
1063 | | } |
1064 | | #[cfg(feature = "instr_info")] |
1065 | | impl Default for FlowControl { |
1066 | | #[must_use] |
1067 | | #[inline] |
1068 | 0 | fn default() -> Self { |
1069 | 0 | FlowControl::Next |
1070 | 0 | } |
1071 | | } |
1072 | | #[cfg(feature = "instr_info")] |
1073 | | #[allow(non_camel_case_types)] |
1074 | | #[allow(dead_code)] |
1075 | | pub(crate) type FlowControlUnderlyingType = u8; |
1076 | | #[cfg(feature = "instr_info")] |
1077 | | #[rustfmt::skip] |
1078 | | impl FlowControl { |
1079 | | /// Iterates over all `FlowControl` enum values |
1080 | | #[inline] |
1081 | 0 | pub fn values() -> impl Iterator<Item = FlowControl> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
1082 | | // SAFETY: all values 0-max are valid enum values |
1083 | 0 | (0..IcedConstants::FLOW_CONTROL_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, FlowControl>(x as u8) }) |
1084 | 0 | } |
1085 | | } |
1086 | | #[test] |
1087 | | #[cfg(feature = "instr_info")] |
1088 | | #[rustfmt::skip] |
1089 | | fn test_flowcontrol_values() { |
1090 | | let mut iter = FlowControl::values(); |
1091 | | assert_eq!(iter.size_hint(), (IcedConstants::FLOW_CONTROL_ENUM_COUNT, Some(IcedConstants::FLOW_CONTROL_ENUM_COUNT))); |
1092 | | assert_eq!(iter.len(), IcedConstants::FLOW_CONTROL_ENUM_COUNT); |
1093 | | assert!(iter.next().is_some()); |
1094 | | assert_eq!(iter.size_hint(), (IcedConstants::FLOW_CONTROL_ENUM_COUNT - 1, Some(IcedConstants::FLOW_CONTROL_ENUM_COUNT - 1))); |
1095 | | assert_eq!(iter.len(), IcedConstants::FLOW_CONTROL_ENUM_COUNT - 1); |
1096 | | |
1097 | | let values: Vec<FlowControl> = FlowControl::values().collect(); |
1098 | | assert_eq!(values.len(), IcedConstants::FLOW_CONTROL_ENUM_COUNT); |
1099 | | for (i, value) in values.into_iter().enumerate() { |
1100 | | assert_eq!(i, value as usize); |
1101 | | } |
1102 | | |
1103 | | let values1: Vec<FlowControl> = FlowControl::values().collect(); |
1104 | | let mut values2: Vec<FlowControl> = FlowControl::values().rev().collect(); |
1105 | | values2.reverse(); |
1106 | | assert_eq!(values1, values2); |
1107 | | } |
1108 | | #[cfg(feature = "instr_info")] |
1109 | | #[rustfmt::skip] |
1110 | | impl TryFrom<usize> for FlowControl { |
1111 | | type Error = IcedError; |
1112 | | #[inline] |
1113 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
1114 | 0 | if value < IcedConstants::FLOW_CONTROL_ENUM_COUNT { |
1115 | | // SAFETY: all values 0-max are valid enum values |
1116 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
1117 | | } else { |
1118 | 0 | Err(IcedError::new("Invalid FlowControl value")) |
1119 | | } |
1120 | 0 | } |
1121 | | } |
1122 | | #[cfg(feature = "instr_info")] |
1123 | | #[test] |
1124 | | #[rustfmt::skip] |
1125 | | fn test_flowcontrol_try_from_usize() { |
1126 | | for value in FlowControl::values() { |
1127 | | let converted = <FlowControl as TryFrom<usize>>::try_from(value as usize).unwrap(); |
1128 | | assert_eq!(converted, value); |
1129 | | } |
1130 | | assert!(<FlowControl as TryFrom<usize>>::try_from(IcedConstants::FLOW_CONTROL_ENUM_COUNT).is_err()); |
1131 | | assert!(<FlowControl as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
1132 | | } |
1133 | | #[cfg(feature = "serde")] |
1134 | | #[cfg(feature = "instr_info")] |
1135 | | #[rustfmt::skip] |
1136 | | #[allow(clippy::zero_sized_map_values)] |
1137 | | const _: () = { |
1138 | | use core::marker::PhantomData; |
1139 | | use serde::de; |
1140 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
1141 | | type EnumType = FlowControl; |
1142 | | impl Serialize for EnumType { |
1143 | | #[inline] |
1144 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
1145 | | where |
1146 | | S: Serializer, |
1147 | | { |
1148 | | serializer.serialize_u8(*self as u8) |
1149 | | } |
1150 | | } |
1151 | | impl<'de> Deserialize<'de> for EnumType { |
1152 | | #[inline] |
1153 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
1154 | | where |
1155 | | D: Deserializer<'de>, |
1156 | | { |
1157 | | struct Visitor<'de> { |
1158 | | marker: PhantomData<EnumType>, |
1159 | | lifetime: PhantomData<&'de ()>, |
1160 | | } |
1161 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
1162 | | type Value = EnumType; |
1163 | | #[inline] |
1164 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
1165 | | formatter.write_str("enum FlowControl") |
1166 | | } |
1167 | | #[inline] |
1168 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
1169 | | where |
1170 | | E: de::Error, |
1171 | | { |
1172 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
1173 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
1174 | | return Ok(value); |
1175 | | } |
1176 | | } |
1177 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid FlowControl variant value")) |
1178 | | } |
1179 | | } |
1180 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
1181 | | } |
1182 | | } |
1183 | | }; |
1184 | | // GENERATOR-END: FlowControl |
1185 | | |
1186 | | // GENERATOR-BEGIN: OpCodeOperandKind |
1187 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
1188 | | /// Operand kind |
1189 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
1190 | | #[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)] |
1191 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1192 | | #[allow(non_camel_case_types)] |
1193 | | pub enum OpCodeOperandKind { |
1194 | | /// No operand |
1195 | | None = 0, |
1196 | | /// Far branch 16-bit offset, 16-bit segment/selector |
1197 | | farbr2_2 = 1, |
1198 | | /// Far branch 32-bit offset, 16-bit segment/selector |
1199 | | farbr4_2 = 2, |
1200 | | /// Memory offset without a modrm byte (eg. `MOV AL,[offset]`) |
1201 | | mem_offs = 3, |
1202 | | /// Memory (modrm) |
1203 | | mem = 4, |
1204 | | /// Memory (modrm), MPX: |
1205 | | /// |
1206 | | /// 16/32-bit mode: must be 32-bit addressing |
1207 | | /// |
1208 | | /// 64-bit mode: 64-bit addressing is forced and must not be RIP relative |
1209 | | mem_mpx = 5, |
1210 | | /// Memory (modrm), MPX: |
1211 | | /// |
1212 | | /// 16/32-bit mode: must be 32-bit addressing |
1213 | | /// |
1214 | | /// 64-bit mode: 64-bit addressing is forced and must not be RIP relative |
1215 | | mem_mib = 6, |
1216 | | /// Memory (modrm), vsib32, `XMM` registers |
1217 | | mem_vsib32x = 7, |
1218 | | /// Memory (modrm), vsib64, `XMM` registers |
1219 | | mem_vsib64x = 8, |
1220 | | /// Memory (modrm), vsib32, `YMM` registers |
1221 | | mem_vsib32y = 9, |
1222 | | /// Memory (modrm), vsib64, `YMM` registers |
1223 | | mem_vsib64y = 10, |
1224 | | /// Memory (modrm), vsib32, `ZMM` registers |
1225 | | mem_vsib32z = 11, |
1226 | | /// Memory (modrm), vsib64, `ZMM` registers |
1227 | | mem_vsib64z = 12, |
1228 | | /// 8-bit GPR or memory |
1229 | | r8_or_mem = 13, |
1230 | | /// 16-bit GPR or memory |
1231 | | r16_or_mem = 14, |
1232 | | /// 32-bit GPR or memory |
1233 | | r32_or_mem = 15, |
1234 | | /// 32-bit GPR or memory, MPX: 16/32-bit mode: must be 32-bit addressing, 64-bit mode: 64-bit addressing is forced |
1235 | | r32_or_mem_mpx = 16, |
1236 | | /// 64-bit GPR or memory |
1237 | | r64_or_mem = 17, |
1238 | | /// 64-bit GPR or memory, MPX: 16/32-bit mode: must be 32-bit addressing, 64-bit mode: 64-bit addressing is forced |
1239 | | r64_or_mem_mpx = 18, |
1240 | | /// `MM` register or memory |
1241 | | mm_or_mem = 19, |
1242 | | /// `XMM` register or memory |
1243 | | xmm_or_mem = 20, |
1244 | | /// `YMM` register or memory |
1245 | | ymm_or_mem = 21, |
1246 | | /// `ZMM` register or memory |
1247 | | zmm_or_mem = 22, |
1248 | | /// `BND` register or memory, MPX: 16/32-bit mode: must be 32-bit addressing, 64-bit mode: 64-bit addressing is forced |
1249 | | bnd_or_mem_mpx = 23, |
1250 | | /// `K` register or memory |
1251 | | k_or_mem = 24, |
1252 | | /// 8-bit GPR encoded in the `reg` field of the modrm byte |
1253 | | r8_reg = 25, |
1254 | | /// 8-bit GPR encoded in the low 3 bits of the opcode |
1255 | | r8_opcode = 26, |
1256 | | /// 16-bit GPR encoded in the `reg` field of the modrm byte |
1257 | | r16_reg = 27, |
1258 | | /// 16-bit GPR encoded in the `reg` field of the modrm byte. This is a memory operand and it uses the address size prefix (`67h`) not the operand size prefix (`66h`). |
1259 | | r16_reg_mem = 28, |
1260 | | /// 16-bit GPR encoded in the `mod + r/m` fields of the modrm byte |
1261 | | r16_rm = 29, |
1262 | | /// 16-bit GPR encoded in the low 3 bits of the opcode |
1263 | | r16_opcode = 30, |
1264 | | /// 32-bit GPR encoded in the `reg` field of the modrm byte |
1265 | | r32_reg = 31, |
1266 | | /// 32-bit GPR encoded in the `reg` field of the modrm byte. This is a memory operand and it uses the address size prefix (`67h`) not the operand size prefix (`66h`). |
1267 | | r32_reg_mem = 32, |
1268 | | /// 32-bit GPR encoded in the `mod + r/m` fields of the modrm byte |
1269 | | r32_rm = 33, |
1270 | | /// 32-bit GPR encoded in the low 3 bits of the opcode |
1271 | | r32_opcode = 34, |
1272 | | /// 32-bit GPR encoded in the the `V'vvvv` field (VEX/EVEX/XOP) |
1273 | | r32_vvvv = 35, |
1274 | | /// 64-bit GPR encoded in the `reg` field of the modrm byte |
1275 | | r64_reg = 36, |
1276 | | /// 64-bit GPR encoded in the `reg` field of the modrm byte. This is a memory operand and it uses the address size prefix (`67h`) not the operand size prefix (`66h`). |
1277 | | r64_reg_mem = 37, |
1278 | | /// 64-bit GPR encoded in the `mod + r/m` fields of the modrm byte |
1279 | | r64_rm = 38, |
1280 | | /// 64-bit GPR encoded in the low 3 bits of the opcode |
1281 | | r64_opcode = 39, |
1282 | | /// 64-bit GPR encoded in the the `V'vvvv` field (VEX/EVEX/XOP) |
1283 | | r64_vvvv = 40, |
1284 | | /// Segment register encoded in the `reg` field of the modrm byte |
1285 | | seg_reg = 41, |
1286 | | /// `K` register encoded in the `reg` field of the modrm byte |
1287 | | k_reg = 42, |
1288 | | /// `K` register (+1) encoded in the `reg` field of the modrm byte |
1289 | | kp1_reg = 43, |
1290 | | /// `K` register encoded in the `mod + r/m` fields of the modrm byte |
1291 | | k_rm = 44, |
1292 | | /// `K` register encoded in the the `V'vvvv` field (VEX/EVEX/MVEX/XOP) |
1293 | | k_vvvv = 45, |
1294 | | /// `MM` register encoded in the `reg` field of the modrm byte |
1295 | | mm_reg = 46, |
1296 | | /// `MM` register encoded in the `mod + r/m` fields of the modrm byte |
1297 | | mm_rm = 47, |
1298 | | /// `XMM` register encoded in the `reg` field of the modrm byte |
1299 | | xmm_reg = 48, |
1300 | | /// `XMM` register encoded in the `mod + r/m` fields of the modrm byte |
1301 | | xmm_rm = 49, |
1302 | | /// `XMM` register encoded in the the `V'vvvv` field (VEX/EVEX/XOP) |
1303 | | xmm_vvvv = 50, |
1304 | | /// `XMM` register (+3) encoded in the the `V'vvvv` field (VEX/EVEX/XOP) |
1305 | | xmmp3_vvvv = 51, |
1306 | | /// `XMM` register encoded in the the high 4 bits of the last 8-bit immediate (VEX/XOP only so only `XMM0`-`XMM15`) |
1307 | | xmm_is4 = 52, |
1308 | | /// `XMM` register encoded in the the high 4 bits of the last 8-bit immediate (VEX/XOP only so only `XMM0`-`XMM15`) |
1309 | | xmm_is5 = 53, |
1310 | | /// `YMM` register encoded in the `reg` field of the modrm byte |
1311 | | ymm_reg = 54, |
1312 | | /// `YMM` register encoded in the `mod + r/m` fields of the modrm byte |
1313 | | ymm_rm = 55, |
1314 | | /// `YMM` register encoded in the the `V'vvvv` field (VEX/EVEX/XOP) |
1315 | | ymm_vvvv = 56, |
1316 | | /// `YMM` register encoded in the the high 4 bits of the last 8-bit immediate (VEX/XOP only so only `YMM0`-`YMM15`) |
1317 | | ymm_is4 = 57, |
1318 | | /// `YMM` register encoded in the the high 4 bits of the last 8-bit immediate (VEX/XOP only so only `YMM0`-`YMM15`) |
1319 | | ymm_is5 = 58, |
1320 | | /// `ZMM` register encoded in the `reg` field of the modrm byte |
1321 | | zmm_reg = 59, |
1322 | | /// `ZMM` register encoded in the `mod + r/m` fields of the modrm byte |
1323 | | zmm_rm = 60, |
1324 | | /// `ZMM` register encoded in the the `V'vvvv` field (VEX/EVEX/MVEX/XOP) |
1325 | | zmm_vvvv = 61, |
1326 | | /// `ZMM` register (+3) encoded in the the `V'vvvv` field (VEX/EVEX/XOP) |
1327 | | zmmp3_vvvv = 62, |
1328 | | /// `CR` register encoded in the `reg` field of the modrm byte |
1329 | | cr_reg = 63, |
1330 | | /// `DR` register encoded in the `reg` field of the modrm byte |
1331 | | dr_reg = 64, |
1332 | | /// `TR` register encoded in the `reg` field of the modrm byte |
1333 | | tr_reg = 65, |
1334 | | /// `BND` register encoded in the `reg` field of the modrm byte |
1335 | | bnd_reg = 66, |
1336 | | /// `ES` register |
1337 | | es = 67, |
1338 | | /// `CS` register |
1339 | | cs = 68, |
1340 | | /// `SS` register |
1341 | | ss = 69, |
1342 | | /// `DS` register |
1343 | | ds = 70, |
1344 | | /// `FS` register |
1345 | | fs = 71, |
1346 | | /// `GS` register |
1347 | | gs = 72, |
1348 | | /// `AL` register |
1349 | | al = 73, |
1350 | | /// `CL` register |
1351 | | cl = 74, |
1352 | | /// `AX` register |
1353 | | ax = 75, |
1354 | | /// `DX` register |
1355 | | dx = 76, |
1356 | | /// `EAX` register |
1357 | | eax = 77, |
1358 | | /// `RAX` register |
1359 | | rax = 78, |
1360 | | /// `ST(0)` register |
1361 | | st0 = 79, |
1362 | | /// `ST(i)` register encoded in the low 3 bits of the opcode |
1363 | | sti_opcode = 80, |
1364 | | /// 4-bit immediate (m2z field, low 4 bits of the /is5 immediate, eg. `VPERMIL2PS`) |
1365 | | imm4_m2z = 81, |
1366 | | /// 8-bit immediate |
1367 | | imm8 = 82, |
1368 | | /// Constant 1 (8-bit immediate) |
1369 | | imm8_const_1 = 83, |
1370 | | /// 8-bit immediate sign extended to 16 bits |
1371 | | imm8sex16 = 84, |
1372 | | /// 8-bit immediate sign extended to 32 bits |
1373 | | imm8sex32 = 85, |
1374 | | /// 8-bit immediate sign extended to 64 bits |
1375 | | imm8sex64 = 86, |
1376 | | /// 16-bit immediate |
1377 | | imm16 = 87, |
1378 | | /// 32-bit immediate |
1379 | | imm32 = 88, |
1380 | | /// 32-bit immediate sign extended to 64 bits |
1381 | | imm32sex64 = 89, |
1382 | | /// 64-bit immediate |
1383 | | imm64 = 90, |
1384 | | /// `seg:[rSI]` memory operand (string instructions) |
1385 | | seg_rSI = 91, |
1386 | | /// `es:[rDI]` memory operand (string instructions) |
1387 | | es_rDI = 92, |
1388 | | /// `seg:[rDI]` memory operand (`(V)MASKMOVQ` instructions) |
1389 | | seg_rDI = 93, |
1390 | | /// `seg:[rBX+al]` memory operand (`XLATB` instruction) |
1391 | | seg_rBX_al = 94, |
1392 | | /// 16-bit branch, 1-byte signed relative offset |
1393 | | br16_1 = 95, |
1394 | | /// 32-bit branch, 1-byte signed relative offset |
1395 | | br32_1 = 96, |
1396 | | /// 64-bit branch, 1-byte signed relative offset |
1397 | | br64_1 = 97, |
1398 | | /// 16-bit branch, 2-byte signed relative offset |
1399 | | br16_2 = 98, |
1400 | | /// 32-bit branch, 4-byte signed relative offset |
1401 | | br32_4 = 99, |
1402 | | /// 64-bit branch, 4-byte signed relative offset |
1403 | | br64_4 = 100, |
1404 | | /// `XBEGIN`, 2-byte signed relative offset |
1405 | | xbegin_2 = 101, |
1406 | | /// `XBEGIN`, 4-byte signed relative offset |
1407 | | xbegin_4 = 102, |
1408 | | /// 2-byte branch offset (`JMPE` instruction) |
1409 | | brdisp_2 = 103, |
1410 | | /// 4-byte branch offset (`JMPE` instruction) |
1411 | | brdisp_4 = 104, |
1412 | | /// Memory (modrm) and the sib byte must be present |
1413 | | sibmem = 105, |
1414 | | /// `TMM` register encoded in the `reg` field of the modrm byte |
1415 | | tmm_reg = 106, |
1416 | | /// `TMM` register encoded in the `mod + r/m` fields of the modrm byte |
1417 | | tmm_rm = 107, |
1418 | | /// `TMM` register encoded in the the `V'vvvv` field (VEX/EVEX/XOP) |
1419 | | tmm_vvvv = 108, |
1420 | | } |
1421 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1422 | | #[rustfmt::skip] |
1423 | | static GEN_DEBUG_OP_CODE_OPERAND_KIND: [&str; 109] = [ |
1424 | | "None", |
1425 | | "farbr2_2", |
1426 | | "farbr4_2", |
1427 | | "mem_offs", |
1428 | | "mem", |
1429 | | "mem_mpx", |
1430 | | "mem_mib", |
1431 | | "mem_vsib32x", |
1432 | | "mem_vsib64x", |
1433 | | "mem_vsib32y", |
1434 | | "mem_vsib64y", |
1435 | | "mem_vsib32z", |
1436 | | "mem_vsib64z", |
1437 | | "r8_or_mem", |
1438 | | "r16_or_mem", |
1439 | | "r32_or_mem", |
1440 | | "r32_or_mem_mpx", |
1441 | | "r64_or_mem", |
1442 | | "r64_or_mem_mpx", |
1443 | | "mm_or_mem", |
1444 | | "xmm_or_mem", |
1445 | | "ymm_or_mem", |
1446 | | "zmm_or_mem", |
1447 | | "bnd_or_mem_mpx", |
1448 | | "k_or_mem", |
1449 | | "r8_reg", |
1450 | | "r8_opcode", |
1451 | | "r16_reg", |
1452 | | "r16_reg_mem", |
1453 | | "r16_rm", |
1454 | | "r16_opcode", |
1455 | | "r32_reg", |
1456 | | "r32_reg_mem", |
1457 | | "r32_rm", |
1458 | | "r32_opcode", |
1459 | | "r32_vvvv", |
1460 | | "r64_reg", |
1461 | | "r64_reg_mem", |
1462 | | "r64_rm", |
1463 | | "r64_opcode", |
1464 | | "r64_vvvv", |
1465 | | "seg_reg", |
1466 | | "k_reg", |
1467 | | "kp1_reg", |
1468 | | "k_rm", |
1469 | | "k_vvvv", |
1470 | | "mm_reg", |
1471 | | "mm_rm", |
1472 | | "xmm_reg", |
1473 | | "xmm_rm", |
1474 | | "xmm_vvvv", |
1475 | | "xmmp3_vvvv", |
1476 | | "xmm_is4", |
1477 | | "xmm_is5", |
1478 | | "ymm_reg", |
1479 | | "ymm_rm", |
1480 | | "ymm_vvvv", |
1481 | | "ymm_is4", |
1482 | | "ymm_is5", |
1483 | | "zmm_reg", |
1484 | | "zmm_rm", |
1485 | | "zmm_vvvv", |
1486 | | "zmmp3_vvvv", |
1487 | | "cr_reg", |
1488 | | "dr_reg", |
1489 | | "tr_reg", |
1490 | | "bnd_reg", |
1491 | | "es", |
1492 | | "cs", |
1493 | | "ss", |
1494 | | "ds", |
1495 | | "fs", |
1496 | | "gs", |
1497 | | "al", |
1498 | | "cl", |
1499 | | "ax", |
1500 | | "dx", |
1501 | | "eax", |
1502 | | "rax", |
1503 | | "st0", |
1504 | | "sti_opcode", |
1505 | | "imm4_m2z", |
1506 | | "imm8", |
1507 | | "imm8_const_1", |
1508 | | "imm8sex16", |
1509 | | "imm8sex32", |
1510 | | "imm8sex64", |
1511 | | "imm16", |
1512 | | "imm32", |
1513 | | "imm32sex64", |
1514 | | "imm64", |
1515 | | "seg_rSI", |
1516 | | "es_rDI", |
1517 | | "seg_rDI", |
1518 | | "seg_rBX_al", |
1519 | | "br16_1", |
1520 | | "br32_1", |
1521 | | "br64_1", |
1522 | | "br16_2", |
1523 | | "br32_4", |
1524 | | "br64_4", |
1525 | | "xbegin_2", |
1526 | | "xbegin_4", |
1527 | | "brdisp_2", |
1528 | | "brdisp_4", |
1529 | | "sibmem", |
1530 | | "tmm_reg", |
1531 | | "tmm_rm", |
1532 | | "tmm_vvvv", |
1533 | | ]; |
1534 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1535 | | impl fmt::Debug for OpCodeOperandKind { |
1536 | | #[inline] |
1537 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1538 | 0 | write!(f, "{}", GEN_DEBUG_OP_CODE_OPERAND_KIND[*self as usize]) |
1539 | 0 | } |
1540 | | } |
1541 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1542 | | impl Default for OpCodeOperandKind { |
1543 | | #[must_use] |
1544 | | #[inline] |
1545 | 0 | fn default() -> Self { |
1546 | 0 | OpCodeOperandKind::None |
1547 | 0 | } |
1548 | | } |
1549 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1550 | | #[allow(non_camel_case_types)] |
1551 | | #[allow(dead_code)] |
1552 | | pub(crate) type OpCodeOperandKindUnderlyingType = u8; |
1553 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1554 | | #[rustfmt::skip] |
1555 | | impl OpCodeOperandKind { |
1556 | | /// Iterates over all `OpCodeOperandKind` enum values |
1557 | | #[inline] |
1558 | 0 | pub fn values() -> impl Iterator<Item = OpCodeOperandKind> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
1559 | | // SAFETY: all values 0-max are valid enum values |
1560 | 0 | (0..IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, OpCodeOperandKind>(x as u8) }) |
1561 | 0 | } |
1562 | | } |
1563 | | #[test] |
1564 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1565 | | #[rustfmt::skip] |
1566 | | fn test_opcodeoperandkind_values() { |
1567 | | let mut iter = OpCodeOperandKind::values(); |
1568 | | assert_eq!(iter.size_hint(), (IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT, Some(IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT))); |
1569 | | assert_eq!(iter.len(), IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT); |
1570 | | assert!(iter.next().is_some()); |
1571 | | assert_eq!(iter.size_hint(), (IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT - 1, Some(IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT - 1))); |
1572 | | assert_eq!(iter.len(), IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT - 1); |
1573 | | |
1574 | | let values: Vec<OpCodeOperandKind> = OpCodeOperandKind::values().collect(); |
1575 | | assert_eq!(values.len(), IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT); |
1576 | | for (i, value) in values.into_iter().enumerate() { |
1577 | | assert_eq!(i, value as usize); |
1578 | | } |
1579 | | |
1580 | | let values1: Vec<OpCodeOperandKind> = OpCodeOperandKind::values().collect(); |
1581 | | let mut values2: Vec<OpCodeOperandKind> = OpCodeOperandKind::values().rev().collect(); |
1582 | | values2.reverse(); |
1583 | | assert_eq!(values1, values2); |
1584 | | } |
1585 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1586 | | #[rustfmt::skip] |
1587 | | impl TryFrom<usize> for OpCodeOperandKind { |
1588 | | type Error = IcedError; |
1589 | | #[inline] |
1590 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
1591 | 0 | if value < IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT { |
1592 | | // SAFETY: all values 0-max are valid enum values |
1593 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
1594 | | } else { |
1595 | 0 | Err(IcedError::new("Invalid OpCodeOperandKind value")) |
1596 | | } |
1597 | 0 | } |
1598 | | } |
1599 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1600 | | #[test] |
1601 | | #[rustfmt::skip] |
1602 | | fn test_opcodeoperandkind_try_from_usize() { |
1603 | | for value in OpCodeOperandKind::values() { |
1604 | | let converted = <OpCodeOperandKind as TryFrom<usize>>::try_from(value as usize).unwrap(); |
1605 | | assert_eq!(converted, value); |
1606 | | } |
1607 | | assert!(<OpCodeOperandKind as TryFrom<usize>>::try_from(IcedConstants::OP_CODE_OPERAND_KIND_ENUM_COUNT).is_err()); |
1608 | | assert!(<OpCodeOperandKind as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
1609 | | } |
1610 | | #[cfg(feature = "serde")] |
1611 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
1612 | | #[rustfmt::skip] |
1613 | | #[allow(clippy::zero_sized_map_values)] |
1614 | | const _: () = { |
1615 | | use core::marker::PhantomData; |
1616 | | use serde::de; |
1617 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
1618 | | type EnumType = OpCodeOperandKind; |
1619 | | impl Serialize for EnumType { |
1620 | | #[inline] |
1621 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
1622 | | where |
1623 | | S: Serializer, |
1624 | | { |
1625 | | serializer.serialize_u8(*self as u8) |
1626 | | } |
1627 | | } |
1628 | | impl<'de> Deserialize<'de> for EnumType { |
1629 | | #[inline] |
1630 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
1631 | | where |
1632 | | D: Deserializer<'de>, |
1633 | | { |
1634 | | struct Visitor<'de> { |
1635 | | marker: PhantomData<EnumType>, |
1636 | | lifetime: PhantomData<&'de ()>, |
1637 | | } |
1638 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
1639 | | type Value = EnumType; |
1640 | | #[inline] |
1641 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
1642 | | formatter.write_str("enum OpCodeOperandKind") |
1643 | | } |
1644 | | #[inline] |
1645 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
1646 | | where |
1647 | | E: de::Error, |
1648 | | { |
1649 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
1650 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
1651 | | return Ok(value); |
1652 | | } |
1653 | | } |
1654 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid OpCodeOperandKind variant value")) |
1655 | | } |
1656 | | } |
1657 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
1658 | | } |
1659 | | } |
1660 | | }; |
1661 | | // GENERATOR-END: OpCodeOperandKind |
1662 | | |
1663 | | // GENERATOR-BEGIN: MvexEHBit |
1664 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
1665 | | /// (MVEX) EH bit value |
1666 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
1667 | | #[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)] |
1668 | | #[cfg(feature = "mvex")] |
1669 | | #[allow(non_camel_case_types)] |
1670 | | pub enum MvexEHBit { |
1671 | | /// Not hard coded to 0 or 1 so can be used for other purposes |
1672 | | None = 0, |
1673 | | /// EH bit must be 0 |
1674 | | EH0 = 1, |
1675 | | /// EH bit must be 1 |
1676 | | EH1 = 2, |
1677 | | } |
1678 | | #[cfg(feature = "mvex")] |
1679 | | #[rustfmt::skip] |
1680 | | static GEN_DEBUG_MVEX_EHBIT: [&str; 3] = [ |
1681 | | "None", |
1682 | | "EH0", |
1683 | | "EH1", |
1684 | | ]; |
1685 | | #[cfg(feature = "mvex")] |
1686 | | impl fmt::Debug for MvexEHBit { |
1687 | | #[inline] |
1688 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1689 | | write!(f, "{}", GEN_DEBUG_MVEX_EHBIT[*self as usize]) |
1690 | | } |
1691 | | } |
1692 | | #[cfg(feature = "mvex")] |
1693 | | impl Default for MvexEHBit { |
1694 | | #[must_use] |
1695 | | #[inline] |
1696 | | fn default() -> Self { |
1697 | | MvexEHBit::None |
1698 | | } |
1699 | | } |
1700 | | #[cfg(feature = "mvex")] |
1701 | | #[allow(non_camel_case_types)] |
1702 | | #[allow(dead_code)] |
1703 | | pub(crate) type MvexEHBitUnderlyingType = u8; |
1704 | | #[cfg(feature = "mvex")] |
1705 | | #[rustfmt::skip] |
1706 | | impl MvexEHBit { |
1707 | | /// Iterates over all `MvexEHBit` enum values |
1708 | | #[inline] |
1709 | | pub fn values() -> impl Iterator<Item = MvexEHBit> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
1710 | | // SAFETY: all values 0-max are valid enum values |
1711 | | (0..IcedConstants::MVEX_EHBIT_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, MvexEHBit>(x as u8) }) |
1712 | | } |
1713 | | } |
1714 | | #[test] |
1715 | | #[cfg(feature = "mvex")] |
1716 | | #[rustfmt::skip] |
1717 | | fn test_mvexehbit_values() { |
1718 | | let mut iter = MvexEHBit::values(); |
1719 | | assert_eq!(iter.size_hint(), (IcedConstants::MVEX_EHBIT_ENUM_COUNT, Some(IcedConstants::MVEX_EHBIT_ENUM_COUNT))); |
1720 | | assert_eq!(iter.len(), IcedConstants::MVEX_EHBIT_ENUM_COUNT); |
1721 | | assert!(iter.next().is_some()); |
1722 | | assert_eq!(iter.size_hint(), (IcedConstants::MVEX_EHBIT_ENUM_COUNT - 1, Some(IcedConstants::MVEX_EHBIT_ENUM_COUNT - 1))); |
1723 | | assert_eq!(iter.len(), IcedConstants::MVEX_EHBIT_ENUM_COUNT - 1); |
1724 | | |
1725 | | let values: Vec<MvexEHBit> = MvexEHBit::values().collect(); |
1726 | | assert_eq!(values.len(), IcedConstants::MVEX_EHBIT_ENUM_COUNT); |
1727 | | for (i, value) in values.into_iter().enumerate() { |
1728 | | assert_eq!(i, value as usize); |
1729 | | } |
1730 | | |
1731 | | let values1: Vec<MvexEHBit> = MvexEHBit::values().collect(); |
1732 | | let mut values2: Vec<MvexEHBit> = MvexEHBit::values().rev().collect(); |
1733 | | values2.reverse(); |
1734 | | assert_eq!(values1, values2); |
1735 | | } |
1736 | | #[cfg(feature = "mvex")] |
1737 | | #[rustfmt::skip] |
1738 | | impl TryFrom<usize> for MvexEHBit { |
1739 | | type Error = IcedError; |
1740 | | #[inline] |
1741 | | fn try_from(value: usize) -> Result<Self, Self::Error> { |
1742 | | if value < IcedConstants::MVEX_EHBIT_ENUM_COUNT { |
1743 | | // SAFETY: all values 0-max are valid enum values |
1744 | | Ok(unsafe { mem::transmute(value as u8) }) |
1745 | | } else { |
1746 | | Err(IcedError::new("Invalid MvexEHBit value")) |
1747 | | } |
1748 | | } |
1749 | | } |
1750 | | #[cfg(feature = "mvex")] |
1751 | | #[test] |
1752 | | #[rustfmt::skip] |
1753 | | fn test_mvexehbit_try_from_usize() { |
1754 | | for value in MvexEHBit::values() { |
1755 | | let converted = <MvexEHBit as TryFrom<usize>>::try_from(value as usize).unwrap(); |
1756 | | assert_eq!(converted, value); |
1757 | | } |
1758 | | assert!(<MvexEHBit as TryFrom<usize>>::try_from(IcedConstants::MVEX_EHBIT_ENUM_COUNT).is_err()); |
1759 | | assert!(<MvexEHBit as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
1760 | | } |
1761 | | #[cfg(feature = "serde")] |
1762 | | #[cfg(feature = "mvex")] |
1763 | | #[rustfmt::skip] |
1764 | | #[allow(clippy::zero_sized_map_values)] |
1765 | | const _: () = { |
1766 | | use core::marker::PhantomData; |
1767 | | use serde::de; |
1768 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
1769 | | type EnumType = MvexEHBit; |
1770 | | impl Serialize for EnumType { |
1771 | | #[inline] |
1772 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
1773 | | where |
1774 | | S: Serializer, |
1775 | | { |
1776 | | serializer.serialize_u8(*self as u8) |
1777 | | } |
1778 | | } |
1779 | | impl<'de> Deserialize<'de> for EnumType { |
1780 | | #[inline] |
1781 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
1782 | | where |
1783 | | D: Deserializer<'de>, |
1784 | | { |
1785 | | struct Visitor<'de> { |
1786 | | marker: PhantomData<EnumType>, |
1787 | | lifetime: PhantomData<&'de ()>, |
1788 | | } |
1789 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
1790 | | type Value = EnumType; |
1791 | | #[inline] |
1792 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
1793 | | formatter.write_str("enum MvexEHBit") |
1794 | | } |
1795 | | #[inline] |
1796 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
1797 | | where |
1798 | | E: de::Error, |
1799 | | { |
1800 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
1801 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
1802 | | return Ok(value); |
1803 | | } |
1804 | | } |
1805 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid MvexEHBit variant value")) |
1806 | | } |
1807 | | } |
1808 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
1809 | | } |
1810 | | } |
1811 | | }; |
1812 | | // GENERATOR-END: MvexEHBit |
1813 | | |
1814 | | // GENERATOR-BEGIN: MvexInfoFlags1 |
1815 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
1816 | | #[cfg(feature = "mvex")] |
1817 | | pub(crate) struct MvexInfoFlags1; |
1818 | | #[cfg(feature = "mvex")] |
1819 | | #[allow(dead_code)] |
1820 | | impl MvexInfoFlags1 { |
1821 | | pub(crate) const NONE: u32 = 0x0000_0000; |
1822 | | pub(crate) const NDD: u32 = 0x0000_0001; |
1823 | | pub(crate) const NDS: u32 = 0x0000_0002; |
1824 | | pub(crate) const EVICTION_HINT: u32 = 0x0000_0004; |
1825 | | pub(crate) const IMM_ROUNDING_CONTROL: u32 = 0x0000_0008; |
1826 | | pub(crate) const ROUNDING_CONTROL: u32 = 0x0000_0010; |
1827 | | pub(crate) const SUPPRESS_ALL_EXCEPTIONS: u32 = 0x0000_0020; |
1828 | | pub(crate) const IGNORES_OP_MASK_REGISTER: u32 = 0x0000_0040; |
1829 | | pub(crate) const REQUIRE_OP_MASK_REGISTER: u32 = 0x0000_0080; |
1830 | | } |
1831 | | // GENERATOR-END: MvexInfoFlags1 |
1832 | | |
1833 | | // GENERATOR-BEGIN: MvexInfoFlags2 |
1834 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
1835 | | #[cfg(feature = "mvex")] |
1836 | | pub(crate) struct MvexInfoFlags2; |
1837 | | #[cfg(feature = "mvex")] |
1838 | | #[allow(dead_code)] |
1839 | | impl MvexInfoFlags2 { |
1840 | | pub(crate) const NONE: u32 = 0x0000_0000; |
1841 | | pub(crate) const NO_SAE_ROUNDING_CONTROL: u32 = 0x0000_0001; |
1842 | | pub(crate) const CONV_FN32: u32 = 0x0000_0002; |
1843 | | pub(crate) const IGNORES_EVICTION_HINT: u32 = 0x0000_0004; |
1844 | | } |
1845 | | // GENERATOR-END: MvexInfoFlags2 |
1846 | | |
1847 | | // GENERATOR-BEGIN: CpuidFeature |
1848 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
1849 | | /// `CPUID` feature flags |
1850 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
1851 | | #[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)] |
1852 | | #[cfg(feature = "instr_info")] |
1853 | | #[allow(non_camel_case_types)] |
1854 | | pub enum CpuidFeature { |
1855 | | /// 8086 or later |
1856 | | INTEL8086 = 0, |
1857 | | /// 8086 only |
1858 | | INTEL8086_ONLY = 1, |
1859 | | /// 80186 or later |
1860 | | INTEL186 = 2, |
1861 | | /// 80286 or later |
1862 | | INTEL286 = 3, |
1863 | | /// 80286 only |
1864 | | INTEL286_ONLY = 4, |
1865 | | /// 80386 or later |
1866 | | INTEL386 = 5, |
1867 | | /// 80386 only |
1868 | | INTEL386_ONLY = 6, |
1869 | | /// 80386 A0-B0 stepping only (`XBTS`, `IBTS` instructions) |
1870 | | INTEL386_A0_ONLY = 7, |
1871 | | /// Intel486 or later |
1872 | | INTEL486 = 8, |
1873 | | /// Intel486 A stepping only (`CMPXCHG`) |
1874 | | INTEL486_A_ONLY = 9, |
1875 | | /// UMOV (80386 and Intel486) |
1876 | | UMOV = 10, |
1877 | | /// IA-64 |
1878 | | IA64 = 11, |
1879 | | /// CPUID.80000001H:EDX.LM\[bit 29\] |
1880 | | X64 = 12, |
1881 | | /// CPUID.(EAX=07H, ECX=0H):EBX.ADX\[bit 19\] |
1882 | | ADX = 13, |
1883 | | /// CPUID.01H:ECX.AES\[bit 25\] |
1884 | | AES = 14, |
1885 | | /// CPUID.01H:ECX.AVX\[bit 28\] |
1886 | | AVX = 15, |
1887 | | /// CPUID.(EAX=07H, ECX=0H):EBX.AVX2\[bit 5\] |
1888 | | AVX2 = 16, |
1889 | | /// CPUID.(EAX=07H, ECX=0H):EDX.AVX512_4FMAPS\[bit 3\] |
1890 | | AVX512_4FMAPS = 17, |
1891 | | /// CPUID.(EAX=07H, ECX=0H):EDX.AVX512_4VNNIW\[bit 2\] |
1892 | | AVX512_4VNNIW = 18, |
1893 | | /// CPUID.(EAX=07H, ECX=1H):EAX.AVX512_BF16\[bit 5\] |
1894 | | AVX512_BF16 = 19, |
1895 | | /// CPUID.(EAX=07H, ECX=0H):ECX.AVX512_BITALG\[bit 12\] |
1896 | | AVX512_BITALG = 20, |
1897 | | /// CPUID.(EAX=07H, ECX=0H):EBX.AVX512_IFMA\[bit 21\] |
1898 | | AVX512_IFMA = 21, |
1899 | | /// CPUID.(EAX=07H, ECX=0H):ECX.AVX512_VBMI\[bit 1\] |
1900 | | AVX512_VBMI = 22, |
1901 | | /// CPUID.(EAX=07H, ECX=0H):ECX.AVX512_VBMI2\[bit 6\] |
1902 | | AVX512_VBMI2 = 23, |
1903 | | /// CPUID.(EAX=07H, ECX=0H):ECX.AVX512_VNNI\[bit 11\] |
1904 | | AVX512_VNNI = 24, |
1905 | | /// CPUID.(EAX=07H, ECX=0H):EDX.AVX512_VP2INTERSECT\[bit 08\] |
1906 | | AVX512_VP2INTERSECT = 25, |
1907 | | /// CPUID.(EAX=07H, ECX=0H):ECX.AVX512_VPOPCNTDQ\[bit 14\] |
1908 | | AVX512_VPOPCNTDQ = 26, |
1909 | | /// CPUID.(EAX=07H, ECX=0H):EBX.AVX512BW\[bit 30\] |
1910 | | AVX512BW = 27, |
1911 | | /// CPUID.(EAX=07H, ECX=0H):EBX.AVX512CD\[bit 28\] |
1912 | | AVX512CD = 28, |
1913 | | /// CPUID.(EAX=07H, ECX=0H):EBX.AVX512DQ\[bit 17\] |
1914 | | AVX512DQ = 29, |
1915 | | /// CPUID.(EAX=07H, ECX=0H):EBX.AVX512ER\[bit 27\] |
1916 | | AVX512ER = 30, |
1917 | | /// CPUID.(EAX=07H, ECX=0H):EBX.AVX512F\[bit 16\] |
1918 | | AVX512F = 31, |
1919 | | /// CPUID.(EAX=07H, ECX=0H):EBX.AVX512PF\[bit 26\] |
1920 | | AVX512PF = 32, |
1921 | | /// CPUID.(EAX=07H, ECX=0H):EBX.AVX512VL\[bit 31\] |
1922 | | AVX512VL = 33, |
1923 | | /// CPUID.(EAX=07H, ECX=0H):EBX.BMI1\[bit 3\] |
1924 | | BMI1 = 34, |
1925 | | /// CPUID.(EAX=07H, ECX=0H):EBX.BMI2\[bit 8\] |
1926 | | BMI2 = 35, |
1927 | | /// CPUID.(EAX=07H, ECX=0H):EDX.CET_IBT\[bit 20\] |
1928 | | CET_IBT = 36, |
1929 | | /// CPUID.(EAX=07H, ECX=0H):ECX.CET_SS\[bit 7\] |
1930 | | CET_SS = 37, |
1931 | | /// `CL1INVMB` instruction (Intel SCC = Single-Chip Computer) |
1932 | | CL1INVMB = 38, |
1933 | | /// CPUID.(EAX=07H, ECX=0H):ECX.CLDEMOTE\[bit 25\] |
1934 | | CLDEMOTE = 39, |
1935 | | /// CPUID.(EAX=07H, ECX=0H):EBX.CLFLUSHOPT\[bit 23\] |
1936 | | CLFLUSHOPT = 40, |
1937 | | /// CPUID.01H:EDX.CLFSH\[bit 19\] |
1938 | | CLFSH = 41, |
1939 | | /// CPUID.(EAX=07H, ECX=0H):EBX.CLWB\[bit 24\] |
1940 | | CLWB = 42, |
1941 | | /// CPUID.80000008H:EBX.CLZERO\[bit 0\] |
1942 | | CLZERO = 43, |
1943 | | /// CPUID.01H:EDX.CMOV\[bit 15\] |
1944 | | CMOV = 44, |
1945 | | /// CPUID.01H:ECX.CMPXCHG16B\[bit 13\] |
1946 | | CMPXCHG16B = 45, |
1947 | | /// `RFLAGS.ID` can be toggled |
1948 | | CPUID = 46, |
1949 | | /// CPUID.01H:EDX.CX8\[bit 8\] |
1950 | | CX8 = 47, |
1951 | | /// CPUID.80000001H:EDX.3DNOW\[bit 31\] |
1952 | | D3NOW = 48, |
1953 | | /// CPUID.80000001H:EDX.3DNOWEXT\[bit 30\] |
1954 | | D3NOWEXT = 49, |
1955 | | /// CPUID.(EAX=12H, ECX=0H):EAX.OSS\[bit 5\] |
1956 | | OSS = 50, |
1957 | | /// CPUID.(EAX=07H, ECX=0H):ECX.ENQCMD\[bit 29\] |
1958 | | ENQCMD = 51, |
1959 | | /// CPUID.01H:ECX.F16C\[bit 29\] |
1960 | | F16C = 52, |
1961 | | /// CPUID.01H:ECX.FMA\[bit 12\] |
1962 | | FMA = 53, |
1963 | | /// CPUID.80000001H:ECX.FMA4\[bit 16\] |
1964 | | FMA4 = 54, |
1965 | | /// 8087 or later (CPUID.01H:EDX.FPU\[bit 0\]) |
1966 | | FPU = 55, |
1967 | | /// 80287 or later |
1968 | | FPU287 = 56, |
1969 | | /// 80287XL only |
1970 | | FPU287XL_ONLY = 57, |
1971 | | /// 80387 or later |
1972 | | FPU387 = 58, |
1973 | | /// 80387SL only |
1974 | | FPU387SL_ONLY = 59, |
1975 | | /// CPUID.(EAX=07H, ECX=0H):EBX.FSGSBASE\[bit 0\] |
1976 | | FSGSBASE = 60, |
1977 | | /// CPUID.01H:EDX.FXSR\[bit 24\] |
1978 | | FXSR = 61, |
1979 | | /// Cyrix (AMD Geode GX/LX) 3DNow! instructions |
1980 | | CYRIX_D3NOW = 62, |
1981 | | /// CPUID.(EAX=07H, ECX=0H):ECX.GFNI\[bit 8\] |
1982 | | GFNI = 63, |
1983 | | /// CPUID.(EAX=07H, ECX=0H):EBX.HLE\[bit 4\] |
1984 | | HLE = 64, |
1985 | | /// [`HLE`] or [`RTM`] |
1986 | | /// |
1987 | | /// [`HLE`]: enum.CpuidFeature.html#variant.HLE |
1988 | | /// [`RTM`]: enum.CpuidFeature.html#variant.RTM |
1989 | | HLE_or_RTM = 65, |
1990 | | /// IA32_VMX_EPT_VPID_CAP\[bit 20\] |
1991 | | INVEPT = 66, |
1992 | | /// CPUID.(EAX=07H, ECX=0H):EBX.INVPCID\[bit 10\] |
1993 | | INVPCID = 67, |
1994 | | /// IA32_VMX_EPT_VPID_CAP\[bit 32\] |
1995 | | INVVPID = 68, |
1996 | | /// CPUID.80000001H:ECX.LWP\[bit 15\] |
1997 | | LWP = 69, |
1998 | | /// CPUID.80000001H:ECX.LZCNT\[bit 5\] |
1999 | | LZCNT = 70, |
2000 | | /// CPUID.80000008H:EBX.MCOMMIT\[bit 8\] |
2001 | | MCOMMIT = 71, |
2002 | | /// CPUID.01H:EDX.MMX\[bit 23\] |
2003 | | MMX = 72, |
2004 | | /// CPUID.01H:ECX.MONITOR\[bit 3\] |
2005 | | MONITOR = 73, |
2006 | | /// CPUID.80000001H:ECX.MONITORX\[bit 29\] |
2007 | | MONITORX = 74, |
2008 | | /// CPUID.01H:ECX.MOVBE\[bit 22\] |
2009 | | MOVBE = 75, |
2010 | | /// CPUID.(EAX=07H, ECX=0H):ECX.MOVDIR64B\[bit 28\] |
2011 | | MOVDIR64B = 76, |
2012 | | /// CPUID.(EAX=07H, ECX=0H):ECX.MOVDIRI\[bit 27\] |
2013 | | MOVDIRI = 77, |
2014 | | /// CPUID.(EAX=07H, ECX=0H):EBX.MPX\[bit 14\] |
2015 | | MPX = 78, |
2016 | | /// CPUID.01H:EDX.MSR\[bit 5\] |
2017 | | MSR = 79, |
2018 | | /// Multi-byte nops (`0F1F /0`): CPUID.01H.EAX\[Bits 11:8\] = 0110B or 1111B |
2019 | | MULTIBYTENOP = 80, |
2020 | | /// CPUID.0C0000000H:EAX >= 0C0000001H AND CPUID.0C0000001H:EDX.ACE\[Bits 7:6\] = 11B (\[6\] = exists, \[7\] = enabled) |
2021 | | PADLOCK_ACE = 81, |
2022 | | /// CPUID.0C0000000H:EAX >= 0C0000001H AND CPUID.0C0000001H:EDX.PHE\[Bits 11:10\] = 11B (\[10\] = exists, \[11\] = enabled) |
2023 | | PADLOCK_PHE = 82, |
2024 | | /// CPUID.0C0000000H:EAX >= 0C0000001H AND CPUID.0C0000001H:EDX.PMM\[Bits 13:12\] = 11B (\[12\] = exists, \[13\] = enabled) |
2025 | | PADLOCK_PMM = 83, |
2026 | | /// CPUID.0C0000000H:EAX >= 0C0000001H AND CPUID.0C0000001H:EDX.RNG\[Bits 3:2\] = 11B (\[2\] = exists, \[3\] = enabled) |
2027 | | PADLOCK_RNG = 84, |
2028 | | /// `PAUSE` instruction (Pentium 4 or later) |
2029 | | PAUSE = 85, |
2030 | | /// CPUID.01H:ECX.PCLMULQDQ\[bit 1\] |
2031 | | PCLMULQDQ = 86, |
2032 | | /// CPUID.(EAX=07H, ECX=0H):EBX.PCOMMIT\[bit 22\] |
2033 | | PCOMMIT = 87, |
2034 | | /// CPUID.(EAX=07H, ECX=0H):EDX.PCONFIG\[bit 18\] |
2035 | | PCONFIG = 88, |
2036 | | /// CPUID.(EAX=07H, ECX=0H):ECX.PKU\[bit 3\] |
2037 | | PKU = 89, |
2038 | | /// CPUID.01H:ECX.POPCNT\[bit 23\] |
2039 | | POPCNT = 90, |
2040 | | /// CPUID.80000001H:ECX.PREFETCHW\[bit 8\] |
2041 | | PREFETCHW = 91, |
2042 | | /// CPUID.(EAX=07H, ECX=0H):ECX.PREFETCHWT1\[bit 0\] |
2043 | | PREFETCHWT1 = 92, |
2044 | | /// CPUID.(EAX=14H, ECX=0H):EBX.PTWRITE\[bit 4\] |
2045 | | PTWRITE = 93, |
2046 | | /// CPUID.(EAX=07H, ECX=0H):ECX.RDPID\[bit 22\] |
2047 | | RDPID = 94, |
2048 | | /// `RDPMC` instruction (Pentium MMX or later, or Pentium Pro or later) |
2049 | | RDPMC = 95, |
2050 | | /// CPUID.80000008H:EBX.RDPRU\[bit 4\] |
2051 | | RDPRU = 96, |
2052 | | /// CPUID.01H:ECX.RDRAND\[bit 30\] |
2053 | | RDRAND = 97, |
2054 | | /// CPUID.(EAX=07H, ECX=0H):EBX.RDSEED\[bit 18\] |
2055 | | RDSEED = 98, |
2056 | | /// CPUID.80000001H:EDX.RDTSCP\[bit 27\] |
2057 | | RDTSCP = 99, |
2058 | | /// CPUID.(EAX=07H, ECX=0H):EBX.RTM\[bit 11\] |
2059 | | RTM = 100, |
2060 | | /// CPUID.01H:EDX.SEP\[bit 11\] |
2061 | | SEP = 101, |
2062 | | /// CPUID.(EAX=12H, ECX=0H):EAX.SGX1\[bit 0\] |
2063 | | SGX1 = 102, |
2064 | | /// CPUID.(EAX=07H, ECX=0H):EBX.SHA\[bit 29\] |
2065 | | SHA = 103, |
2066 | | /// CPUID.80000001H:ECX.SKINIT\[bit 12\] |
2067 | | SKINIT = 104, |
2068 | | /// [`SKINIT`] or [`SVM`] |
2069 | | /// |
2070 | | /// [`SKINIT`]: enum.CpuidFeature.html#variant.SKINIT |
2071 | | /// [`SVM`]: enum.CpuidFeature.html#variant.SVM |
2072 | | SKINIT_or_SVM = 105, |
2073 | | /// CPUID.(EAX=07H, ECX=0H):EBX.SMAP\[bit 20\] |
2074 | | SMAP = 106, |
2075 | | /// CPUID.01H:ECX.SMX\[bit 6\] |
2076 | | SMX = 107, |
2077 | | /// CPUID.01H:EDX.SSE\[bit 25\] |
2078 | | SSE = 108, |
2079 | | /// CPUID.01H:EDX.SSE2\[bit 26\] |
2080 | | SSE2 = 109, |
2081 | | /// CPUID.01H:ECX.SSE3\[bit 0\] |
2082 | | SSE3 = 110, |
2083 | | /// CPUID.01H:ECX.SSE4_1\[bit 19\] |
2084 | | SSE4_1 = 111, |
2085 | | /// CPUID.01H:ECX.SSE4_2\[bit 20\] |
2086 | | SSE4_2 = 112, |
2087 | | /// CPUID.80000001H:ECX.SSE4A\[bit 6\] |
2088 | | SSE4A = 113, |
2089 | | /// CPUID.01H:ECX.SSSE3\[bit 9\] |
2090 | | SSSE3 = 114, |
2091 | | /// CPUID.80000001H:ECX.SVM\[bit 2\] |
2092 | | SVM = 115, |
2093 | | /// CPUID.8000001FH:EAX.SEV-ES\[bit 3\] |
2094 | | SEV_ES = 116, |
2095 | | /// CPUID.80000001H:EDX.SYSCALL\[bit 11\] |
2096 | | SYSCALL = 117, |
2097 | | /// CPUID.80000001H:ECX.TBM\[bit 21\] |
2098 | | TBM = 118, |
2099 | | /// CPUID.01H:EDX.TSC\[bit 4\] |
2100 | | TSC = 119, |
2101 | | /// CPUID.(EAX=07H, ECX=0H):ECX.VAES\[bit 9\] |
2102 | | VAES = 120, |
2103 | | /// CPUID.01H:ECX.VMX\[bit 5\] |
2104 | | VMX = 121, |
2105 | | /// CPUID.(EAX=07H, ECX=0H):ECX.VPCLMULQDQ\[bit 10\] |
2106 | | VPCLMULQDQ = 122, |
2107 | | /// CPUID.(EAX=07H, ECX=0H):ECX.WAITPKG\[bit 5\] |
2108 | | WAITPKG = 123, |
2109 | | /// CPUID.(EAX=80000008H, ECX=0H):EBX.WBNOINVD\[bit 9\] |
2110 | | WBNOINVD = 124, |
2111 | | /// CPUID.80000001H:ECX.XOP\[bit 11\] |
2112 | | XOP = 125, |
2113 | | /// CPUID.01H:ECX.XSAVE\[bit 26\] |
2114 | | XSAVE = 126, |
2115 | | /// CPUID.(EAX=0DH, ECX=1H):EAX.XSAVEC\[bit 1\] |
2116 | | XSAVEC = 127, |
2117 | | /// CPUID.(EAX=0DH, ECX=1H):EAX.XSAVEOPT\[bit 0\] |
2118 | | XSAVEOPT = 128, |
2119 | | /// CPUID.(EAX=0DH, ECX=1H):EAX.XSAVES\[bit 3\] |
2120 | | XSAVES = 129, |
2121 | | /// CPUID.8000001FH:EAX.SEV-SNP\[bit 4\] |
2122 | | SEV_SNP = 130, |
2123 | | /// CPUID.(EAX=07H, ECX=0H):EDX.SERIALIZE\[bit 14\] |
2124 | | SERIALIZE = 131, |
2125 | | /// CPUID.(EAX=07H, ECX=0H):EDX.TSXLDTRK\[bit 16\] |
2126 | | TSXLDTRK = 132, |
2127 | | /// CPUID.80000008H:EBX.INVLPGB\[bit 3\] |
2128 | | INVLPGB = 133, |
2129 | | /// CPUID.(EAX=07H, ECX=0H):EDX.AMX-BF16\[bit 22\] |
2130 | | AMX_BF16 = 134, |
2131 | | /// CPUID.(EAX=07H, ECX=0H):EDX.AMX-TILE\[bit 24\] |
2132 | | AMX_TILE = 135, |
2133 | | /// CPUID.(EAX=07H, ECX=0H):EDX.AMX-INT8\[bit 25\] |
2134 | | AMX_INT8 = 136, |
2135 | | /// Cyrix FPU instructions (Cyrix, AMD Geode GX/LX) |
2136 | | CYRIX_FPU = 137, |
2137 | | /// Cyrix SMM instructions: `SVDC`, `RSDC`, `SVLDT`, `RSLDT`, `SVTS`, `RSTS` (Cyrix, AMD Geode GX/LX) |
2138 | | CYRIX_SMM = 138, |
2139 | | /// Cyrix `SMINT 0F38` (6x86MX and later, AMD Geode GX/LX) |
2140 | | CYRIX_SMINT = 139, |
2141 | | /// Cyrix `SMINT 0F7E` (6x86 or earlier) |
2142 | | CYRIX_SMINT_0F7E = 140, |
2143 | | /// Cyrix SMM instructions: `RDSHR`, `WRSHR` (6x86MX, M II, Cyrix III) |
2144 | | CYRIX_SHR = 141, |
2145 | | /// Cyrix DDI instructions: `BB0_Reset`, `BB1_Reset`, `CPU_READ`, `CPU_WRITE` (MediaGX, GXm, GXLV, GX1) |
2146 | | CYRIX_DDI = 142, |
2147 | | /// Cyrix AND CPUID.80000001H:EDX.EMMI\[bit 24\] |
2148 | | CYRIX_EMMI = 143, |
2149 | | /// Cyrix DMI instructions: `DMINT`, `RDM` (AMD Geode GX/LX) |
2150 | | CYRIX_DMI = 144, |
2151 | | /// CPUID.0C0000000H:EAX >= 0C0000001H AND CPUID.0C0000001H:EDX.AIS\[Bits 1:0\] = 11B (\[0\] = exists, \[1\] = enabled) |
2152 | | CENTAUR_AIS = 145, |
2153 | | /// MOV to/from TR (80386, Intel486, Cyrix, Geode) |
2154 | | MOV_TR = 146, |
2155 | | /// `RSM` instruction (some 386s, some 486s, Pentium and later) |
2156 | | SMM = 147, |
2157 | | /// CPUID.(EAX=??H, ECX=?H):???.????\[bit ??\] |
2158 | | TDX = 148, |
2159 | | /// CPUID.(EAX=07H, ECX=0H):ECX.KL\[bit 23\] |
2160 | | KL = 149, |
2161 | | /// CPUID.19H:EBX.AESKLE\[bit 0\] |
2162 | | AESKLE = 150, |
2163 | | /// CPUID.19H:EBX.WIDE_KL\[bit 2\] |
2164 | | WIDE_KL = 151, |
2165 | | /// CPUID.(EAX=07H, ECX=0H):EDX.UINTR\[bit 5\] |
2166 | | UINTR = 152, |
2167 | | /// CPUID.(EAX=07H, ECX=01H):EAX.HRESET\[bit 22\] |
2168 | | HRESET = 153, |
2169 | | /// CPUID.(EAX=07H, ECX=01H):EAX.AVX-VNNI\[bit 4\] |
2170 | | AVX_VNNI = 154, |
2171 | | /// CPUID.0C0000000H:EAX >= 0C0000001H AND CPUID.0C0000001H:EDX.GMI\[Bits 5:4\] = 11B (\[4\] = exists, \[5\] = enabled) |
2172 | | PADLOCK_GMI = 155, |
2173 | | /// CPUID.(EAX=07H, ECX=01H):EAX.FRED\[bit 17\] |
2174 | | FRED = 156, |
2175 | | /// CPUID.(EAX=07H, ECX=01H):EAX.LKGS\[bit 18\] |
2176 | | LKGS = 157, |
2177 | | /// CPUID.(EAX=07H, ECX=0H):EDX.AVX512-FP16\[bit 23\] |
2178 | | AVX512_FP16 = 158, |
2179 | | /// Undocumented Intel `RDUDBG` and `WRUDBG` instructions |
2180 | | UDBG = 159, |
2181 | | /// Intel Knights Corner |
2182 | | KNC = 160, |
2183 | | /// Undocumented instruction |
2184 | | PADLOCK_UNDOC = 161, |
2185 | | /// CPUID.8000001FH:EAX.RMPQUERY\[bit 6\] |
2186 | | RMPQUERY = 162, |
2187 | | /// CPUID.(EAX=07H, ECX=1H):EAX.RAO-INT\[bit 3\] |
2188 | | RAO_INT = 163, |
2189 | | /// CPUID.(EAX=07H, ECX=1H):EDX.PREFETCHITI\[bit 14\] |
2190 | | PREFETCHITI = 164, |
2191 | | /// CPUID.(EAX=07H, ECX=1H):EAX.AMX-FP16\[bit 21\] |
2192 | | AMX_FP16 = 165, |
2193 | | /// CPUID.(EAX=07H, ECX=1H):EAX.CMPCCXADD\[bit 7\] |
2194 | | CMPCCXADD = 166, |
2195 | | /// CPUID.(EAX=07H, ECX=1H):EAX.AVX-IFMA\[bit 23\] |
2196 | | AVX_IFMA = 167, |
2197 | | /// CPUID.(EAX=07H, ECX=1H):EDX.AVX-NE-CONVERT\[bit 5\] |
2198 | | AVX_NE_CONVERT = 168, |
2199 | | /// CPUID.(EAX=07H, ECX=1H):EDX.AVX-VNNI-INT8\[bit 4\] |
2200 | | AVX_VNNI_INT8 = 169, |
2201 | | /// CPUID.(EAX=07H, ECX=1H):EAX.MSRLIST\[bit 27\] |
2202 | | MSRLIST = 170, |
2203 | | /// CPUID.(EAX=07H, ECX=1H):EAX.WRMSRNS\[bit 19\] |
2204 | | WRMSRNS = 171, |
2205 | | /// CPUID.(EAX=07H, ECX=1H):EDX.AMX-COMPLEX\[bit 8\] |
2206 | | AMX_COMPLEX = 172, |
2207 | | /// CPUID.(EAX=07H, ECX=1H):EAX.SHA512\[bit 0\] |
2208 | | SHA512 = 173, |
2209 | | /// CPUID.(EAX=07H, ECX=1H):EAX.SM3\[bit 1\] |
2210 | | SM3 = 174, |
2211 | | /// CPUID.(EAX=07H, ECX=1H):EAX.SM4\[bit 2\] |
2212 | | SM4 = 175, |
2213 | | /// CPUID.(EAX=07H, ECX=1H):EBX.TSE\[bit 1\] |
2214 | | TSE = 176, |
2215 | | /// CPUID.(EAX=07H, ECX=1H):EDX.AVX-VNNI-INT16\[bit 10\] |
2216 | | AVX_VNNI_INT16 = 177, |
2217 | | } |
2218 | | #[cfg(feature = "instr_info")] |
2219 | | #[rustfmt::skip] |
2220 | | static GEN_DEBUG_CPUID_FEATURE: [&str; 178] = [ |
2221 | | "INTEL8086", |
2222 | | "INTEL8086_ONLY", |
2223 | | "INTEL186", |
2224 | | "INTEL286", |
2225 | | "INTEL286_ONLY", |
2226 | | "INTEL386", |
2227 | | "INTEL386_ONLY", |
2228 | | "INTEL386_A0_ONLY", |
2229 | | "INTEL486", |
2230 | | "INTEL486_A_ONLY", |
2231 | | "UMOV", |
2232 | | "IA64", |
2233 | | "X64", |
2234 | | "ADX", |
2235 | | "AES", |
2236 | | "AVX", |
2237 | | "AVX2", |
2238 | | "AVX512_4FMAPS", |
2239 | | "AVX512_4VNNIW", |
2240 | | "AVX512_BF16", |
2241 | | "AVX512_BITALG", |
2242 | | "AVX512_IFMA", |
2243 | | "AVX512_VBMI", |
2244 | | "AVX512_VBMI2", |
2245 | | "AVX512_VNNI", |
2246 | | "AVX512_VP2INTERSECT", |
2247 | | "AVX512_VPOPCNTDQ", |
2248 | | "AVX512BW", |
2249 | | "AVX512CD", |
2250 | | "AVX512DQ", |
2251 | | "AVX512ER", |
2252 | | "AVX512F", |
2253 | | "AVX512PF", |
2254 | | "AVX512VL", |
2255 | | "BMI1", |
2256 | | "BMI2", |
2257 | | "CET_IBT", |
2258 | | "CET_SS", |
2259 | | "CL1INVMB", |
2260 | | "CLDEMOTE", |
2261 | | "CLFLUSHOPT", |
2262 | | "CLFSH", |
2263 | | "CLWB", |
2264 | | "CLZERO", |
2265 | | "CMOV", |
2266 | | "CMPXCHG16B", |
2267 | | "CPUID", |
2268 | | "CX8", |
2269 | | "D3NOW", |
2270 | | "D3NOWEXT", |
2271 | | "OSS", |
2272 | | "ENQCMD", |
2273 | | "F16C", |
2274 | | "FMA", |
2275 | | "FMA4", |
2276 | | "FPU", |
2277 | | "FPU287", |
2278 | | "FPU287XL_ONLY", |
2279 | | "FPU387", |
2280 | | "FPU387SL_ONLY", |
2281 | | "FSGSBASE", |
2282 | | "FXSR", |
2283 | | "CYRIX_D3NOW", |
2284 | | "GFNI", |
2285 | | "HLE", |
2286 | | "HLE_or_RTM", |
2287 | | "INVEPT", |
2288 | | "INVPCID", |
2289 | | "INVVPID", |
2290 | | "LWP", |
2291 | | "LZCNT", |
2292 | | "MCOMMIT", |
2293 | | "MMX", |
2294 | | "MONITOR", |
2295 | | "MONITORX", |
2296 | | "MOVBE", |
2297 | | "MOVDIR64B", |
2298 | | "MOVDIRI", |
2299 | | "MPX", |
2300 | | "MSR", |
2301 | | "MULTIBYTENOP", |
2302 | | "PADLOCK_ACE", |
2303 | | "PADLOCK_PHE", |
2304 | | "PADLOCK_PMM", |
2305 | | "PADLOCK_RNG", |
2306 | | "PAUSE", |
2307 | | "PCLMULQDQ", |
2308 | | "PCOMMIT", |
2309 | | "PCONFIG", |
2310 | | "PKU", |
2311 | | "POPCNT", |
2312 | | "PREFETCHW", |
2313 | | "PREFETCHWT1", |
2314 | | "PTWRITE", |
2315 | | "RDPID", |
2316 | | "RDPMC", |
2317 | | "RDPRU", |
2318 | | "RDRAND", |
2319 | | "RDSEED", |
2320 | | "RDTSCP", |
2321 | | "RTM", |
2322 | | "SEP", |
2323 | | "SGX1", |
2324 | | "SHA", |
2325 | | "SKINIT", |
2326 | | "SKINIT_or_SVM", |
2327 | | "SMAP", |
2328 | | "SMX", |
2329 | | "SSE", |
2330 | | "SSE2", |
2331 | | "SSE3", |
2332 | | "SSE4_1", |
2333 | | "SSE4_2", |
2334 | | "SSE4A", |
2335 | | "SSSE3", |
2336 | | "SVM", |
2337 | | "SEV_ES", |
2338 | | "SYSCALL", |
2339 | | "TBM", |
2340 | | "TSC", |
2341 | | "VAES", |
2342 | | "VMX", |
2343 | | "VPCLMULQDQ", |
2344 | | "WAITPKG", |
2345 | | "WBNOINVD", |
2346 | | "XOP", |
2347 | | "XSAVE", |
2348 | | "XSAVEC", |
2349 | | "XSAVEOPT", |
2350 | | "XSAVES", |
2351 | | "SEV_SNP", |
2352 | | "SERIALIZE", |
2353 | | "TSXLDTRK", |
2354 | | "INVLPGB", |
2355 | | "AMX_BF16", |
2356 | | "AMX_TILE", |
2357 | | "AMX_INT8", |
2358 | | "CYRIX_FPU", |
2359 | | "CYRIX_SMM", |
2360 | | "CYRIX_SMINT", |
2361 | | "CYRIX_SMINT_0F7E", |
2362 | | "CYRIX_SHR", |
2363 | | "CYRIX_DDI", |
2364 | | "CYRIX_EMMI", |
2365 | | "CYRIX_DMI", |
2366 | | "CENTAUR_AIS", |
2367 | | "MOV_TR", |
2368 | | "SMM", |
2369 | | "TDX", |
2370 | | "KL", |
2371 | | "AESKLE", |
2372 | | "WIDE_KL", |
2373 | | "UINTR", |
2374 | | "HRESET", |
2375 | | "AVX_VNNI", |
2376 | | "PADLOCK_GMI", |
2377 | | "FRED", |
2378 | | "LKGS", |
2379 | | "AVX512_FP16", |
2380 | | "UDBG", |
2381 | | "KNC", |
2382 | | "PADLOCK_UNDOC", |
2383 | | "RMPQUERY", |
2384 | | "RAO_INT", |
2385 | | "PREFETCHITI", |
2386 | | "AMX_FP16", |
2387 | | "CMPCCXADD", |
2388 | | "AVX_IFMA", |
2389 | | "AVX_NE_CONVERT", |
2390 | | "AVX_VNNI_INT8", |
2391 | | "MSRLIST", |
2392 | | "WRMSRNS", |
2393 | | "AMX_COMPLEX", |
2394 | | "SHA512", |
2395 | | "SM3", |
2396 | | "SM4", |
2397 | | "TSE", |
2398 | | "AVX_VNNI_INT16", |
2399 | | ]; |
2400 | | #[cfg(feature = "instr_info")] |
2401 | | impl fmt::Debug for CpuidFeature { |
2402 | | #[inline] |
2403 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
2404 | 0 | write!(f, "{}", GEN_DEBUG_CPUID_FEATURE[*self as usize]) |
2405 | 0 | } |
2406 | | } |
2407 | | #[cfg(feature = "instr_info")] |
2408 | | impl Default for CpuidFeature { |
2409 | | #[must_use] |
2410 | | #[inline] |
2411 | 0 | fn default() -> Self { |
2412 | 0 | CpuidFeature::INTEL8086 |
2413 | 0 | } |
2414 | | } |
2415 | | #[cfg(feature = "instr_info")] |
2416 | | #[allow(non_camel_case_types)] |
2417 | | #[allow(dead_code)] |
2418 | | pub(crate) type CpuidFeatureUnderlyingType = u8; |
2419 | | #[cfg(feature = "instr_info")] |
2420 | | #[rustfmt::skip] |
2421 | | impl CpuidFeature { |
2422 | | /// Iterates over all `CpuidFeature` enum values |
2423 | | #[inline] |
2424 | 0 | pub fn values() -> impl Iterator<Item = CpuidFeature> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
2425 | | // SAFETY: all values 0-max are valid enum values |
2426 | 0 | (0..IcedConstants::CPUID_FEATURE_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, CpuidFeature>(x as u8) }) |
2427 | 0 | } |
2428 | | } |
2429 | | #[test] |
2430 | | #[cfg(feature = "instr_info")] |
2431 | | #[rustfmt::skip] |
2432 | | fn test_cpuidfeature_values() { |
2433 | | let mut iter = CpuidFeature::values(); |
2434 | | assert_eq!(iter.size_hint(), (IcedConstants::CPUID_FEATURE_ENUM_COUNT, Some(IcedConstants::CPUID_FEATURE_ENUM_COUNT))); |
2435 | | assert_eq!(iter.len(), IcedConstants::CPUID_FEATURE_ENUM_COUNT); |
2436 | | assert!(iter.next().is_some()); |
2437 | | assert_eq!(iter.size_hint(), (IcedConstants::CPUID_FEATURE_ENUM_COUNT - 1, Some(IcedConstants::CPUID_FEATURE_ENUM_COUNT - 1))); |
2438 | | assert_eq!(iter.len(), IcedConstants::CPUID_FEATURE_ENUM_COUNT - 1); |
2439 | | |
2440 | | let values: Vec<CpuidFeature> = CpuidFeature::values().collect(); |
2441 | | assert_eq!(values.len(), IcedConstants::CPUID_FEATURE_ENUM_COUNT); |
2442 | | for (i, value) in values.into_iter().enumerate() { |
2443 | | assert_eq!(i, value as usize); |
2444 | | } |
2445 | | |
2446 | | let values1: Vec<CpuidFeature> = CpuidFeature::values().collect(); |
2447 | | let mut values2: Vec<CpuidFeature> = CpuidFeature::values().rev().collect(); |
2448 | | values2.reverse(); |
2449 | | assert_eq!(values1, values2); |
2450 | | } |
2451 | | #[cfg(feature = "instr_info")] |
2452 | | #[rustfmt::skip] |
2453 | | impl TryFrom<usize> for CpuidFeature { |
2454 | | type Error = IcedError; |
2455 | | #[inline] |
2456 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
2457 | 0 | if value < IcedConstants::CPUID_FEATURE_ENUM_COUNT { |
2458 | | // SAFETY: all values 0-max are valid enum values |
2459 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
2460 | | } else { |
2461 | 0 | Err(IcedError::new("Invalid CpuidFeature value")) |
2462 | | } |
2463 | 0 | } |
2464 | | } |
2465 | | #[cfg(feature = "instr_info")] |
2466 | | #[test] |
2467 | | #[rustfmt::skip] |
2468 | | fn test_cpuidfeature_try_from_usize() { |
2469 | | for value in CpuidFeature::values() { |
2470 | | let converted = <CpuidFeature as TryFrom<usize>>::try_from(value as usize).unwrap(); |
2471 | | assert_eq!(converted, value); |
2472 | | } |
2473 | | assert!(<CpuidFeature as TryFrom<usize>>::try_from(IcedConstants::CPUID_FEATURE_ENUM_COUNT).is_err()); |
2474 | | assert!(<CpuidFeature as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
2475 | | } |
2476 | | #[cfg(feature = "serde")] |
2477 | | #[cfg(feature = "instr_info")] |
2478 | | #[rustfmt::skip] |
2479 | | #[allow(clippy::zero_sized_map_values)] |
2480 | | const _: () = { |
2481 | | use core::marker::PhantomData; |
2482 | | use serde::de; |
2483 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
2484 | | type EnumType = CpuidFeature; |
2485 | | impl Serialize for EnumType { |
2486 | | #[inline] |
2487 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
2488 | | where |
2489 | | S: Serializer, |
2490 | | { |
2491 | | serializer.serialize_u8(*self as u8) |
2492 | | } |
2493 | | } |
2494 | | impl<'de> Deserialize<'de> for EnumType { |
2495 | | #[inline] |
2496 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
2497 | | where |
2498 | | D: Deserializer<'de>, |
2499 | | { |
2500 | | struct Visitor<'de> { |
2501 | | marker: PhantomData<EnumType>, |
2502 | | lifetime: PhantomData<&'de ()>, |
2503 | | } |
2504 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
2505 | | type Value = EnumType; |
2506 | | #[inline] |
2507 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
2508 | | formatter.write_str("enum CpuidFeature") |
2509 | | } |
2510 | | #[inline] |
2511 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
2512 | | where |
2513 | | E: de::Error, |
2514 | | { |
2515 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
2516 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
2517 | | return Ok(value); |
2518 | | } |
2519 | | } |
2520 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid CpuidFeature variant value")) |
2521 | | } |
2522 | | } |
2523 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
2524 | | } |
2525 | | } |
2526 | | }; |
2527 | | // GENERATOR-END: CpuidFeature |
2528 | | |
2529 | | // GENERATOR-BEGIN: RflagsBits |
2530 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
2531 | | /// `RFLAGS` bits, FPU condition code bits and misc bits (`UIF`) supported by the instruction info code |
2532 | | #[allow(missing_copy_implementations)] |
2533 | | #[allow(missing_debug_implementations)] |
2534 | | #[cfg(feature = "instr_info")] |
2535 | | pub struct RflagsBits; |
2536 | | #[cfg(feature = "instr_info")] |
2537 | | impl RflagsBits { |
2538 | | /// No bit is set |
2539 | | pub const NONE: u32 = 0x0000_0000; |
2540 | | /// `RFLAGS.OF` |
2541 | | pub const OF: u32 = 0x0000_0001; |
2542 | | /// `RFLAGS.SF` |
2543 | | pub const SF: u32 = 0x0000_0002; |
2544 | | /// `RFLAGS.ZF` |
2545 | | pub const ZF: u32 = 0x0000_0004; |
2546 | | /// `RFLAGS.AF` |
2547 | | pub const AF: u32 = 0x0000_0008; |
2548 | | /// `RFLAGS.CF` |
2549 | | pub const CF: u32 = 0x0000_0010; |
2550 | | /// `RFLAGS.PF` |
2551 | | pub const PF: u32 = 0x0000_0020; |
2552 | | /// `RFLAGS.DF` |
2553 | | pub const DF: u32 = 0x0000_0040; |
2554 | | /// `RFLAGS.IF` |
2555 | | pub const IF: u32 = 0x0000_0080; |
2556 | | /// `RFLAGS.AC` |
2557 | | pub const AC: u32 = 0x0000_0100; |
2558 | | /// `UIF` |
2559 | | pub const UIF: u32 = 0x0000_0200; |
2560 | | /// FPU status word bit `C0` |
2561 | | pub const C0: u32 = 0x0000_0400; |
2562 | | /// FPU status word bit `C1` |
2563 | | pub const C1: u32 = 0x0000_0800; |
2564 | | /// FPU status word bit `C2` |
2565 | | pub const C2: u32 = 0x0000_1000; |
2566 | | /// FPU status word bit `C3` |
2567 | | pub const C3: u32 = 0x0000_2000; |
2568 | | } |
2569 | | // GENERATOR-END: RflagsBits |
2570 | | |
2571 | | // GENERATOR-BEGIN: OpAccess |
2572 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
2573 | | /// Operand, register and memory access |
2574 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
2575 | | #[cfg(feature = "instr_info")] |
2576 | | pub enum OpAccess { |
2577 | | /// Nothing is read and nothing is written |
2578 | | None = 0, |
2579 | | /// The value is read |
2580 | | Read = 1, |
2581 | | /// The value is sometimes read and sometimes not |
2582 | | CondRead = 2, |
2583 | | /// The value is completely overwritten |
2584 | | Write = 3, |
2585 | | /// Conditional write, sometimes it's written and sometimes it's not modified |
2586 | | CondWrite = 4, |
2587 | | /// The value is read and written |
2588 | | ReadWrite = 5, |
2589 | | /// The value is read and sometimes written |
2590 | | ReadCondWrite = 6, |
2591 | | /// The memory operand doesn't refer to memory (eg. `LEA` instruction) or it's an instruction that doesn't read the data to a register or doesn't write to the memory location, it just prefetches/invalidates it, eg. `INVLPG`, `PREFETCHNTA`, `VGATHERPF0DPS`, etc. Some of those instructions still check if the code can access the memory location. |
2592 | | NoMemAccess = 7, |
2593 | | } |
2594 | | #[cfg(feature = "instr_info")] |
2595 | | #[rustfmt::skip] |
2596 | | static GEN_DEBUG_OP_ACCESS: [&str; 8] = [ |
2597 | | "None", |
2598 | | "Read", |
2599 | | "CondRead", |
2600 | | "Write", |
2601 | | "CondWrite", |
2602 | | "ReadWrite", |
2603 | | "ReadCondWrite", |
2604 | | "NoMemAccess", |
2605 | | ]; |
2606 | | #[cfg(feature = "instr_info")] |
2607 | | impl fmt::Debug for OpAccess { |
2608 | | #[inline] |
2609 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
2610 | 0 | write!(f, "{}", GEN_DEBUG_OP_ACCESS[*self as usize]) |
2611 | 0 | } |
2612 | | } |
2613 | | #[cfg(feature = "instr_info")] |
2614 | | impl Default for OpAccess { |
2615 | | #[must_use] |
2616 | | #[inline] |
2617 | 0 | fn default() -> Self { |
2618 | 0 | OpAccess::None |
2619 | 0 | } |
2620 | | } |
2621 | | #[cfg(feature = "instr_info")] |
2622 | | #[allow(non_camel_case_types)] |
2623 | | #[allow(dead_code)] |
2624 | | pub(crate) type OpAccessUnderlyingType = u8; |
2625 | | #[cfg(feature = "instr_info")] |
2626 | | #[rustfmt::skip] |
2627 | | impl OpAccess { |
2628 | | /// Iterates over all `OpAccess` enum values |
2629 | | #[inline] |
2630 | 0 | pub fn values() -> impl Iterator<Item = OpAccess> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
2631 | | // SAFETY: all values 0-max are valid enum values |
2632 | 0 | (0..IcedConstants::OP_ACCESS_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, OpAccess>(x as u8) }) |
2633 | 0 | } |
2634 | | } |
2635 | | #[test] |
2636 | | #[cfg(feature = "instr_info")] |
2637 | | #[rustfmt::skip] |
2638 | | fn test_opaccess_values() { |
2639 | | let mut iter = OpAccess::values(); |
2640 | | assert_eq!(iter.size_hint(), (IcedConstants::OP_ACCESS_ENUM_COUNT, Some(IcedConstants::OP_ACCESS_ENUM_COUNT))); |
2641 | | assert_eq!(iter.len(), IcedConstants::OP_ACCESS_ENUM_COUNT); |
2642 | | assert!(iter.next().is_some()); |
2643 | | assert_eq!(iter.size_hint(), (IcedConstants::OP_ACCESS_ENUM_COUNT - 1, Some(IcedConstants::OP_ACCESS_ENUM_COUNT - 1))); |
2644 | | assert_eq!(iter.len(), IcedConstants::OP_ACCESS_ENUM_COUNT - 1); |
2645 | | |
2646 | | let values: Vec<OpAccess> = OpAccess::values().collect(); |
2647 | | assert_eq!(values.len(), IcedConstants::OP_ACCESS_ENUM_COUNT); |
2648 | | for (i, value) in values.into_iter().enumerate() { |
2649 | | assert_eq!(i, value as usize); |
2650 | | } |
2651 | | |
2652 | | let values1: Vec<OpAccess> = OpAccess::values().collect(); |
2653 | | let mut values2: Vec<OpAccess> = OpAccess::values().rev().collect(); |
2654 | | values2.reverse(); |
2655 | | assert_eq!(values1, values2); |
2656 | | } |
2657 | | #[cfg(feature = "instr_info")] |
2658 | | #[rustfmt::skip] |
2659 | | impl TryFrom<usize> for OpAccess { |
2660 | | type Error = IcedError; |
2661 | | #[inline] |
2662 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
2663 | 0 | if value < IcedConstants::OP_ACCESS_ENUM_COUNT { |
2664 | | // SAFETY: all values 0-max are valid enum values |
2665 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
2666 | | } else { |
2667 | 0 | Err(IcedError::new("Invalid OpAccess value")) |
2668 | | } |
2669 | 0 | } |
2670 | | } |
2671 | | #[cfg(feature = "instr_info")] |
2672 | | #[test] |
2673 | | #[rustfmt::skip] |
2674 | | fn test_opaccess_try_from_usize() { |
2675 | | for value in OpAccess::values() { |
2676 | | let converted = <OpAccess as TryFrom<usize>>::try_from(value as usize).unwrap(); |
2677 | | assert_eq!(converted, value); |
2678 | | } |
2679 | | assert!(<OpAccess as TryFrom<usize>>::try_from(IcedConstants::OP_ACCESS_ENUM_COUNT).is_err()); |
2680 | | assert!(<OpAccess as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
2681 | | } |
2682 | | #[cfg(feature = "serde")] |
2683 | | #[cfg(feature = "instr_info")] |
2684 | | #[rustfmt::skip] |
2685 | | #[allow(clippy::zero_sized_map_values)] |
2686 | | const _: () = { |
2687 | | use core::marker::PhantomData; |
2688 | | use serde::de; |
2689 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
2690 | | type EnumType = OpAccess; |
2691 | | impl Serialize for EnumType { |
2692 | | #[inline] |
2693 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
2694 | | where |
2695 | | S: Serializer, |
2696 | | { |
2697 | | serializer.serialize_u8(*self as u8) |
2698 | | } |
2699 | | } |
2700 | | impl<'de> Deserialize<'de> for EnumType { |
2701 | | #[inline] |
2702 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
2703 | | where |
2704 | | D: Deserializer<'de>, |
2705 | | { |
2706 | | struct Visitor<'de> { |
2707 | | marker: PhantomData<EnumType>, |
2708 | | lifetime: PhantomData<&'de ()>, |
2709 | | } |
2710 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
2711 | | type Value = EnumType; |
2712 | | #[inline] |
2713 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
2714 | | formatter.write_str("enum OpAccess") |
2715 | | } |
2716 | | #[inline] |
2717 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
2718 | | where |
2719 | | E: de::Error, |
2720 | | { |
2721 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
2722 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
2723 | | return Ok(value); |
2724 | | } |
2725 | | } |
2726 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid OpAccess variant value")) |
2727 | | } |
2728 | | } |
2729 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
2730 | | } |
2731 | | } |
2732 | | }; |
2733 | | // GENERATOR-END: OpAccess |
2734 | | |
2735 | | // GENERATOR-BEGIN: ConditionCode |
2736 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
2737 | | /// Instruction condition code (used by `Jcc`, `SETcc`, `CMOVcc`, `CMPccXADD`, `LOOPcc`) |
2738 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
2739 | | #[cfg(feature = "instr_info")] |
2740 | | #[allow(non_camel_case_types)] |
2741 | | pub enum ConditionCode { |
2742 | | /// The instruction doesn't have a condition code |
2743 | | None = 0, |
2744 | | /// Overflow (`OF=1`) |
2745 | | o = 1, |
2746 | | /// Not overflow (`OF=0`) |
2747 | | no = 2, |
2748 | | /// Below (unsigned) (`CF=1`) |
2749 | | b = 3, |
2750 | | /// Above or equal (unsigned) (`CF=0`) |
2751 | | ae = 4, |
2752 | | /// Equal / zero (`ZF=1`) |
2753 | | e = 5, |
2754 | | /// Not equal / zero (`ZF=0`) |
2755 | | ne = 6, |
2756 | | /// Below or equal (unsigned) (`CF=1 or ZF=1`) |
2757 | | be = 7, |
2758 | | /// Above (unsigned) (`CF=0 and ZF=0`) |
2759 | | a = 8, |
2760 | | /// Signed (`SF=1`) |
2761 | | s = 9, |
2762 | | /// Not signed (`SF=0`) |
2763 | | ns = 10, |
2764 | | /// Parity (`PF=1`) |
2765 | | p = 11, |
2766 | | /// Not parity (`PF=0`) |
2767 | | np = 12, |
2768 | | /// Less (signed) (`SF!=OF`) |
2769 | | l = 13, |
2770 | | /// Greater than or equal (signed) (`SF=OF`) |
2771 | | ge = 14, |
2772 | | /// Less than or equal (signed) (`ZF=1 or SF!=OF`) |
2773 | | le = 15, |
2774 | | /// Greater (signed) (`ZF=0 and SF=OF`) |
2775 | | g = 16, |
2776 | | } |
2777 | | #[cfg(feature = "instr_info")] |
2778 | | #[rustfmt::skip] |
2779 | | static GEN_DEBUG_CONDITION_CODE: [&str; 17] = [ |
2780 | | "None", |
2781 | | "o", |
2782 | | "no", |
2783 | | "b", |
2784 | | "ae", |
2785 | | "e", |
2786 | | "ne", |
2787 | | "be", |
2788 | | "a", |
2789 | | "s", |
2790 | | "ns", |
2791 | | "p", |
2792 | | "np", |
2793 | | "l", |
2794 | | "ge", |
2795 | | "le", |
2796 | | "g", |
2797 | | ]; |
2798 | | #[cfg(feature = "instr_info")] |
2799 | | impl fmt::Debug for ConditionCode { |
2800 | | #[inline] |
2801 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
2802 | 0 | write!(f, "{}", GEN_DEBUG_CONDITION_CODE[*self as usize]) |
2803 | 0 | } |
2804 | | } |
2805 | | #[cfg(feature = "instr_info")] |
2806 | | impl Default for ConditionCode { |
2807 | | #[must_use] |
2808 | | #[inline] |
2809 | 0 | fn default() -> Self { |
2810 | 0 | ConditionCode::None |
2811 | 0 | } |
2812 | | } |
2813 | | #[cfg(feature = "instr_info")] |
2814 | | #[allow(non_camel_case_types)] |
2815 | | #[allow(dead_code)] |
2816 | | pub(crate) type ConditionCodeUnderlyingType = u8; |
2817 | | #[cfg(feature = "instr_info")] |
2818 | | #[rustfmt::skip] |
2819 | | impl ConditionCode { |
2820 | | /// Iterates over all `ConditionCode` enum values |
2821 | | #[inline] |
2822 | 0 | pub fn values() -> impl Iterator<Item = ConditionCode> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
2823 | | // SAFETY: all values 0-max are valid enum values |
2824 | 0 | (0..IcedConstants::CONDITION_CODE_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, ConditionCode>(x as u8) }) |
2825 | 0 | } |
2826 | | } |
2827 | | #[test] |
2828 | | #[cfg(feature = "instr_info")] |
2829 | | #[rustfmt::skip] |
2830 | | fn test_conditioncode_values() { |
2831 | | let mut iter = ConditionCode::values(); |
2832 | | assert_eq!(iter.size_hint(), (IcedConstants::CONDITION_CODE_ENUM_COUNT, Some(IcedConstants::CONDITION_CODE_ENUM_COUNT))); |
2833 | | assert_eq!(iter.len(), IcedConstants::CONDITION_CODE_ENUM_COUNT); |
2834 | | assert!(iter.next().is_some()); |
2835 | | assert_eq!(iter.size_hint(), (IcedConstants::CONDITION_CODE_ENUM_COUNT - 1, Some(IcedConstants::CONDITION_CODE_ENUM_COUNT - 1))); |
2836 | | assert_eq!(iter.len(), IcedConstants::CONDITION_CODE_ENUM_COUNT - 1); |
2837 | | |
2838 | | let values: Vec<ConditionCode> = ConditionCode::values().collect(); |
2839 | | assert_eq!(values.len(), IcedConstants::CONDITION_CODE_ENUM_COUNT); |
2840 | | for (i, value) in values.into_iter().enumerate() { |
2841 | | assert_eq!(i, value as usize); |
2842 | | } |
2843 | | |
2844 | | let values1: Vec<ConditionCode> = ConditionCode::values().collect(); |
2845 | | let mut values2: Vec<ConditionCode> = ConditionCode::values().rev().collect(); |
2846 | | values2.reverse(); |
2847 | | assert_eq!(values1, values2); |
2848 | | } |
2849 | | #[cfg(feature = "instr_info")] |
2850 | | #[rustfmt::skip] |
2851 | | impl TryFrom<usize> for ConditionCode { |
2852 | | type Error = IcedError; |
2853 | | #[inline] |
2854 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
2855 | 0 | if value < IcedConstants::CONDITION_CODE_ENUM_COUNT { |
2856 | | // SAFETY: all values 0-max are valid enum values |
2857 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
2858 | | } else { |
2859 | 0 | Err(IcedError::new("Invalid ConditionCode value")) |
2860 | | } |
2861 | 0 | } |
2862 | | } |
2863 | | #[cfg(feature = "instr_info")] |
2864 | | #[test] |
2865 | | #[rustfmt::skip] |
2866 | | fn test_conditioncode_try_from_usize() { |
2867 | | for value in ConditionCode::values() { |
2868 | | let converted = <ConditionCode as TryFrom<usize>>::try_from(value as usize).unwrap(); |
2869 | | assert_eq!(converted, value); |
2870 | | } |
2871 | | assert!(<ConditionCode as TryFrom<usize>>::try_from(IcedConstants::CONDITION_CODE_ENUM_COUNT).is_err()); |
2872 | | assert!(<ConditionCode as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
2873 | | } |
2874 | | #[cfg(feature = "serde")] |
2875 | | #[cfg(feature = "instr_info")] |
2876 | | #[rustfmt::skip] |
2877 | | #[allow(clippy::zero_sized_map_values)] |
2878 | | const _: () = { |
2879 | | use core::marker::PhantomData; |
2880 | | use serde::de; |
2881 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
2882 | | type EnumType = ConditionCode; |
2883 | | impl Serialize for EnumType { |
2884 | | #[inline] |
2885 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
2886 | | where |
2887 | | S: Serializer, |
2888 | | { |
2889 | | serializer.serialize_u8(*self as u8) |
2890 | | } |
2891 | | } |
2892 | | impl<'de> Deserialize<'de> for EnumType { |
2893 | | #[inline] |
2894 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
2895 | | where |
2896 | | D: Deserializer<'de>, |
2897 | | { |
2898 | | struct Visitor<'de> { |
2899 | | marker: PhantomData<EnumType>, |
2900 | | lifetime: PhantomData<&'de ()>, |
2901 | | } |
2902 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
2903 | | type Value = EnumType; |
2904 | | #[inline] |
2905 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
2906 | | formatter.write_str("enum ConditionCode") |
2907 | | } |
2908 | | #[inline] |
2909 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
2910 | | where |
2911 | | E: de::Error, |
2912 | | { |
2913 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
2914 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
2915 | | return Ok(value); |
2916 | | } |
2917 | | } |
2918 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid ConditionCode variant value")) |
2919 | | } |
2920 | | } |
2921 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
2922 | | } |
2923 | | } |
2924 | | }; |
2925 | | // GENERATOR-END: ConditionCode |
2926 | | |
2927 | | // GENERATOR-BEGIN: MandatoryPrefix |
2928 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
2929 | | /// Mandatory prefix |
2930 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
2931 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
2932 | | pub enum MandatoryPrefix { |
2933 | | /// No mandatory prefix (legacy and 3DNow! tables only) |
2934 | | None = 0, |
2935 | | /// Empty mandatory prefix (no `66`, `F3` or `F2` prefix) |
2936 | | PNP = 1, |
2937 | | /// `66` prefix |
2938 | | P66 = 2, |
2939 | | /// `F3` prefix |
2940 | | PF3 = 3, |
2941 | | /// `F2` prefix |
2942 | | PF2 = 4, |
2943 | | } |
2944 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
2945 | | #[rustfmt::skip] |
2946 | | static GEN_DEBUG_MANDATORY_PREFIX: [&str; 5] = [ |
2947 | | "None", |
2948 | | "PNP", |
2949 | | "P66", |
2950 | | "PF3", |
2951 | | "PF2", |
2952 | | ]; |
2953 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
2954 | | impl fmt::Debug for MandatoryPrefix { |
2955 | | #[inline] |
2956 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
2957 | 0 | write!(f, "{}", GEN_DEBUG_MANDATORY_PREFIX[*self as usize]) |
2958 | 0 | } |
2959 | | } |
2960 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
2961 | | impl Default for MandatoryPrefix { |
2962 | | #[must_use] |
2963 | | #[inline] |
2964 | 0 | fn default() -> Self { |
2965 | 0 | MandatoryPrefix::None |
2966 | 0 | } |
2967 | | } |
2968 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
2969 | | #[allow(non_camel_case_types)] |
2970 | | #[allow(dead_code)] |
2971 | | pub(crate) type MandatoryPrefixUnderlyingType = u8; |
2972 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
2973 | | #[rustfmt::skip] |
2974 | | impl MandatoryPrefix { |
2975 | | /// Iterates over all `MandatoryPrefix` enum values |
2976 | | #[inline] |
2977 | 0 | pub fn values() -> impl Iterator<Item = MandatoryPrefix> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
2978 | | // SAFETY: all values 0-max are valid enum values |
2979 | 0 | (0..IcedConstants::MANDATORY_PREFIX_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, MandatoryPrefix>(x as u8) }) |
2980 | 0 | } |
2981 | | } |
2982 | | #[test] |
2983 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
2984 | | #[rustfmt::skip] |
2985 | | fn test_mandatoryprefix_values() { |
2986 | | let mut iter = MandatoryPrefix::values(); |
2987 | | assert_eq!(iter.size_hint(), (IcedConstants::MANDATORY_PREFIX_ENUM_COUNT, Some(IcedConstants::MANDATORY_PREFIX_ENUM_COUNT))); |
2988 | | assert_eq!(iter.len(), IcedConstants::MANDATORY_PREFIX_ENUM_COUNT); |
2989 | | assert!(iter.next().is_some()); |
2990 | | assert_eq!(iter.size_hint(), (IcedConstants::MANDATORY_PREFIX_ENUM_COUNT - 1, Some(IcedConstants::MANDATORY_PREFIX_ENUM_COUNT - 1))); |
2991 | | assert_eq!(iter.len(), IcedConstants::MANDATORY_PREFIX_ENUM_COUNT - 1); |
2992 | | |
2993 | | let values: Vec<MandatoryPrefix> = MandatoryPrefix::values().collect(); |
2994 | | assert_eq!(values.len(), IcedConstants::MANDATORY_PREFIX_ENUM_COUNT); |
2995 | | for (i, value) in values.into_iter().enumerate() { |
2996 | | assert_eq!(i, value as usize); |
2997 | | } |
2998 | | |
2999 | | let values1: Vec<MandatoryPrefix> = MandatoryPrefix::values().collect(); |
3000 | | let mut values2: Vec<MandatoryPrefix> = MandatoryPrefix::values().rev().collect(); |
3001 | | values2.reverse(); |
3002 | | assert_eq!(values1, values2); |
3003 | | } |
3004 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3005 | | #[rustfmt::skip] |
3006 | | impl TryFrom<usize> for MandatoryPrefix { |
3007 | | type Error = IcedError; |
3008 | | #[inline] |
3009 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
3010 | 0 | if value < IcedConstants::MANDATORY_PREFIX_ENUM_COUNT { |
3011 | | // SAFETY: all values 0-max are valid enum values |
3012 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
3013 | | } else { |
3014 | 0 | Err(IcedError::new("Invalid MandatoryPrefix value")) |
3015 | | } |
3016 | 0 | } |
3017 | | } |
3018 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3019 | | #[test] |
3020 | | #[rustfmt::skip] |
3021 | | fn test_mandatoryprefix_try_from_usize() { |
3022 | | for value in MandatoryPrefix::values() { |
3023 | | let converted = <MandatoryPrefix as TryFrom<usize>>::try_from(value as usize).unwrap(); |
3024 | | assert_eq!(converted, value); |
3025 | | } |
3026 | | assert!(<MandatoryPrefix as TryFrom<usize>>::try_from(IcedConstants::MANDATORY_PREFIX_ENUM_COUNT).is_err()); |
3027 | | assert!(<MandatoryPrefix as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
3028 | | } |
3029 | | #[cfg(feature = "serde")] |
3030 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3031 | | #[rustfmt::skip] |
3032 | | #[allow(clippy::zero_sized_map_values)] |
3033 | | const _: () = { |
3034 | | use core::marker::PhantomData; |
3035 | | use serde::de; |
3036 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
3037 | | type EnumType = MandatoryPrefix; |
3038 | | impl Serialize for EnumType { |
3039 | | #[inline] |
3040 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
3041 | | where |
3042 | | S: Serializer, |
3043 | | { |
3044 | | serializer.serialize_u8(*self as u8) |
3045 | | } |
3046 | | } |
3047 | | impl<'de> Deserialize<'de> for EnumType { |
3048 | | #[inline] |
3049 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
3050 | | where |
3051 | | D: Deserializer<'de>, |
3052 | | { |
3053 | | struct Visitor<'de> { |
3054 | | marker: PhantomData<EnumType>, |
3055 | | lifetime: PhantomData<&'de ()>, |
3056 | | } |
3057 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
3058 | | type Value = EnumType; |
3059 | | #[inline] |
3060 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
3061 | | formatter.write_str("enum MandatoryPrefix") |
3062 | | } |
3063 | | #[inline] |
3064 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
3065 | | where |
3066 | | E: de::Error, |
3067 | | { |
3068 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
3069 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
3070 | | return Ok(value); |
3071 | | } |
3072 | | } |
3073 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid MandatoryPrefix variant value")) |
3074 | | } |
3075 | | } |
3076 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
3077 | | } |
3078 | | } |
3079 | | }; |
3080 | | // GENERATOR-END: MandatoryPrefix |
3081 | | |
3082 | | // GENERATOR-BEGIN: OpCodeTableKind |
3083 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
3084 | | /// Opcode table |
3085 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
3086 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3087 | | #[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)] |
3088 | | pub enum OpCodeTableKind { |
3089 | | /// Legacy/`MAP0` table |
3090 | | Normal = 0, |
3091 | | /// `0F`/`MAP1` table (legacy, VEX, EVEX, MVEX) |
3092 | | T0F = 1, |
3093 | | /// `0F38`/`MAP2` table (legacy, VEX, EVEX, MVEX) |
3094 | | T0F38 = 2, |
3095 | | /// `0F3A`/`MAP3` table (legacy, VEX, EVEX, MVEX) |
3096 | | T0F3A = 3, |
3097 | | /// `MAP5` table (EVEX) |
3098 | | MAP5 = 4, |
3099 | | /// `MAP6` table (EVEX) |
3100 | | MAP6 = 5, |
3101 | | /// `MAP8` table (XOP) |
3102 | | MAP8 = 6, |
3103 | | /// `MAP9` table (XOP) |
3104 | | MAP9 = 7, |
3105 | | /// `MAP10` table (XOP) |
3106 | | MAP10 = 8, |
3107 | | } |
3108 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3109 | | #[rustfmt::skip] |
3110 | | static GEN_DEBUG_OP_CODE_TABLE_KIND: [&str; 9] = [ |
3111 | | "Normal", |
3112 | | "T0F", |
3113 | | "T0F38", |
3114 | | "T0F3A", |
3115 | | "MAP5", |
3116 | | "MAP6", |
3117 | | "MAP8", |
3118 | | "MAP9", |
3119 | | "MAP10", |
3120 | | ]; |
3121 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3122 | | impl fmt::Debug for OpCodeTableKind { |
3123 | | #[inline] |
3124 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
3125 | 0 | write!(f, "{}", GEN_DEBUG_OP_CODE_TABLE_KIND[*self as usize]) |
3126 | 0 | } |
3127 | | } |
3128 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3129 | | impl Default for OpCodeTableKind { |
3130 | | #[must_use] |
3131 | | #[inline] |
3132 | 0 | fn default() -> Self { |
3133 | 0 | OpCodeTableKind::Normal |
3134 | 0 | } |
3135 | | } |
3136 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3137 | | #[allow(non_camel_case_types)] |
3138 | | #[allow(dead_code)] |
3139 | | pub(crate) type OpCodeTableKindUnderlyingType = u8; |
3140 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3141 | | #[rustfmt::skip] |
3142 | | impl OpCodeTableKind { |
3143 | | /// Iterates over all `OpCodeTableKind` enum values |
3144 | | #[inline] |
3145 | 0 | pub fn values() -> impl Iterator<Item = OpCodeTableKind> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
3146 | | // SAFETY: all values 0-max are valid enum values |
3147 | 0 | (0..IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, OpCodeTableKind>(x as u8) }) |
3148 | 0 | } |
3149 | | } |
3150 | | #[test] |
3151 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3152 | | #[rustfmt::skip] |
3153 | | fn test_opcodetablekind_values() { |
3154 | | let mut iter = OpCodeTableKind::values(); |
3155 | | assert_eq!(iter.size_hint(), (IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT, Some(IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT))); |
3156 | | assert_eq!(iter.len(), IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT); |
3157 | | assert!(iter.next().is_some()); |
3158 | | assert_eq!(iter.size_hint(), (IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT - 1, Some(IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT - 1))); |
3159 | | assert_eq!(iter.len(), IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT - 1); |
3160 | | |
3161 | | let values: Vec<OpCodeTableKind> = OpCodeTableKind::values().collect(); |
3162 | | assert_eq!(values.len(), IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT); |
3163 | | for (i, value) in values.into_iter().enumerate() { |
3164 | | assert_eq!(i, value as usize); |
3165 | | } |
3166 | | |
3167 | | let values1: Vec<OpCodeTableKind> = OpCodeTableKind::values().collect(); |
3168 | | let mut values2: Vec<OpCodeTableKind> = OpCodeTableKind::values().rev().collect(); |
3169 | | values2.reverse(); |
3170 | | assert_eq!(values1, values2); |
3171 | | } |
3172 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3173 | | #[rustfmt::skip] |
3174 | | impl TryFrom<usize> for OpCodeTableKind { |
3175 | | type Error = IcedError; |
3176 | | #[inline] |
3177 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
3178 | 0 | if value < IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT { |
3179 | | // SAFETY: all values 0-max are valid enum values |
3180 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
3181 | | } else { |
3182 | 0 | Err(IcedError::new("Invalid OpCodeTableKind value")) |
3183 | | } |
3184 | 0 | } |
3185 | | } |
3186 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3187 | | #[test] |
3188 | | #[rustfmt::skip] |
3189 | | fn test_opcodetablekind_try_from_usize() { |
3190 | | for value in OpCodeTableKind::values() { |
3191 | | let converted = <OpCodeTableKind as TryFrom<usize>>::try_from(value as usize).unwrap(); |
3192 | | assert_eq!(converted, value); |
3193 | | } |
3194 | | assert!(<OpCodeTableKind as TryFrom<usize>>::try_from(IcedConstants::OP_CODE_TABLE_KIND_ENUM_COUNT).is_err()); |
3195 | | assert!(<OpCodeTableKind as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
3196 | | } |
3197 | | #[cfg(feature = "serde")] |
3198 | | #[cfg(all(feature = "encoder", feature = "op_code_info"))] |
3199 | | #[rustfmt::skip] |
3200 | | #[allow(clippy::zero_sized_map_values)] |
3201 | | const _: () = { |
3202 | | use core::marker::PhantomData; |
3203 | | use serde::de; |
3204 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
3205 | | type EnumType = OpCodeTableKind; |
3206 | | impl Serialize for EnumType { |
3207 | | #[inline] |
3208 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
3209 | | where |
3210 | | S: Serializer, |
3211 | | { |
3212 | | serializer.serialize_u8(*self as u8) |
3213 | | } |
3214 | | } |
3215 | | impl<'de> Deserialize<'de> for EnumType { |
3216 | | #[inline] |
3217 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
3218 | | where |
3219 | | D: Deserializer<'de>, |
3220 | | { |
3221 | | struct Visitor<'de> { |
3222 | | marker: PhantomData<EnumType>, |
3223 | | lifetime: PhantomData<&'de ()>, |
3224 | | } |
3225 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
3226 | | type Value = EnumType; |
3227 | | #[inline] |
3228 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
3229 | | formatter.write_str("enum OpCodeTableKind") |
3230 | | } |
3231 | | #[inline] |
3232 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
3233 | | where |
3234 | | E: de::Error, |
3235 | | { |
3236 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
3237 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
3238 | | return Ok(value); |
3239 | | } |
3240 | | } |
3241 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid OpCodeTableKind variant value")) |
3242 | | } |
3243 | | } |
3244 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
3245 | | } |
3246 | | } |
3247 | | }; |
3248 | | // GENERATOR-END: OpCodeTableKind |
3249 | | |
3250 | | // GENERATOR-BEGIN: InstrScale |
3251 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
3252 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
3253 | | #[allow(non_camel_case_types)] |
3254 | | #[allow(dead_code)] |
3255 | | pub(crate) enum InstrScale { |
3256 | | Scale1 = 0, |
3257 | | Scale2 = 1, |
3258 | | Scale4 = 2, |
3259 | | Scale8 = 3, |
3260 | | } |
3261 | | #[rustfmt::skip] |
3262 | | static GEN_DEBUG_INSTR_SCALE: [&str; 4] = [ |
3263 | | "Scale1", |
3264 | | "Scale2", |
3265 | | "Scale4", |
3266 | | "Scale8", |
3267 | | ]; |
3268 | | impl fmt::Debug for InstrScale { |
3269 | | #[inline] |
3270 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
3271 | 0 | write!(f, "{}", GEN_DEBUG_INSTR_SCALE[*self as usize]) |
3272 | 0 | } |
3273 | | } |
3274 | | impl Default for InstrScale { |
3275 | | #[must_use] |
3276 | | #[inline] |
3277 | 4.42k | fn default() -> Self { |
3278 | 4.42k | InstrScale::Scale1 |
3279 | 4.42k | } <iced_x86::enums::InstrScale as core::default::Default>::default Line | Count | Source | 3277 | 2.09k | fn default() -> Self { | 3278 | 2.09k | InstrScale::Scale1 | 3279 | 2.09k | } |
<iced_x86::enums::InstrScale as core::default::Default>::default Line | Count | Source | 3277 | 2.32k | fn default() -> Self { | 3278 | 2.32k | InstrScale::Scale1 | 3279 | 2.32k | } |
|
3280 | | } |
3281 | | #[allow(non_camel_case_types)] |
3282 | | #[allow(dead_code)] |
3283 | | pub(crate) type InstrScaleUnderlyingType = u8; |
3284 | | #[rustfmt::skip] |
3285 | | impl InstrScale { |
3286 | | /// Iterates over all `InstrScale` enum values |
3287 | | #[inline] |
3288 | | #[allow(dead_code)] |
3289 | 0 | pub(crate) fn values() -> impl Iterator<Item = InstrScale> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
3290 | | // SAFETY: all values 0-max are valid enum values |
3291 | 0 | (0..4).map(|x| unsafe { mem::transmute::<u8, InstrScale>(x as u8) }) |
3292 | 0 | } |
3293 | | } |
3294 | | #[test] |
3295 | | #[rustfmt::skip] |
3296 | | fn test_instrscale_values() { |
3297 | | let mut iter = InstrScale::values(); |
3298 | | assert_eq!(iter.size_hint(), (4, Some(4))); |
3299 | | assert_eq!(iter.len(), 4); |
3300 | | assert!(iter.next().is_some()); |
3301 | | assert_eq!(iter.size_hint(), (4 - 1, Some(4 - 1))); |
3302 | | assert_eq!(iter.len(), 4 - 1); |
3303 | | |
3304 | | let values: Vec<InstrScale> = InstrScale::values().collect(); |
3305 | | assert_eq!(values.len(), 4); |
3306 | | for (i, value) in values.into_iter().enumerate() { |
3307 | | assert_eq!(i, value as usize); |
3308 | | } |
3309 | | |
3310 | | let values1: Vec<InstrScale> = InstrScale::values().collect(); |
3311 | | let mut values2: Vec<InstrScale> = InstrScale::values().rev().collect(); |
3312 | | values2.reverse(); |
3313 | | assert_eq!(values1, values2); |
3314 | | } |
3315 | | #[rustfmt::skip] |
3316 | | impl TryFrom<usize> for InstrScale { |
3317 | | type Error = IcedError; |
3318 | | #[inline] |
3319 | 0 | fn try_from(value: usize) -> Result<Self, Self::Error> { |
3320 | 0 | if value < 4 { |
3321 | | // SAFETY: all values 0-max are valid enum values |
3322 | 0 | Ok(unsafe { mem::transmute(value as u8) }) |
3323 | | } else { |
3324 | 0 | Err(IcedError::new("Invalid InstrScale value")) |
3325 | | } |
3326 | 0 | } |
3327 | | } |
3328 | | #[test] |
3329 | | #[rustfmt::skip] |
3330 | | fn test_instrscale_try_from_usize() { |
3331 | | for value in InstrScale::values() { |
3332 | | let converted = <InstrScale as TryFrom<usize>>::try_from(value as usize).unwrap(); |
3333 | | assert_eq!(converted, value); |
3334 | | } |
3335 | | assert!(<InstrScale as TryFrom<usize>>::try_from(4).is_err()); |
3336 | | assert!(<InstrScale as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
3337 | | } |
3338 | | #[cfg(feature = "serde")] |
3339 | | #[rustfmt::skip] |
3340 | | #[allow(clippy::zero_sized_map_values)] |
3341 | | const _: () = { |
3342 | | use core::marker::PhantomData; |
3343 | | use serde::de; |
3344 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
3345 | | type EnumType = InstrScale; |
3346 | | impl Serialize for EnumType { |
3347 | | #[inline] |
3348 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
3349 | | where |
3350 | | S: Serializer, |
3351 | | { |
3352 | | serializer.serialize_u8(*self as u8) |
3353 | | } |
3354 | | } |
3355 | | impl<'de> Deserialize<'de> for EnumType { |
3356 | | #[inline] |
3357 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
3358 | | where |
3359 | | D: Deserializer<'de>, |
3360 | | { |
3361 | | struct Visitor<'de> { |
3362 | | marker: PhantomData<EnumType>, |
3363 | | lifetime: PhantomData<&'de ()>, |
3364 | | } |
3365 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
3366 | | type Value = EnumType; |
3367 | | #[inline] |
3368 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
3369 | | formatter.write_str("enum InstrScale") |
3370 | | } |
3371 | | #[inline] |
3372 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
3373 | | where |
3374 | | E: de::Error, |
3375 | | { |
3376 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
3377 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
3378 | | return Ok(value); |
3379 | | } |
3380 | | } |
3381 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid InstrScale variant value")) |
3382 | | } |
3383 | | } |
3384 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
3385 | | } |
3386 | | } |
3387 | | }; |
3388 | | // GENERATOR-END: InstrScale |
3389 | | |
3390 | | // GENERATOR-BEGIN: MvexConvFn |
3391 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
3392 | | /// MVEX conversion function |
3393 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
3394 | | #[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)] |
3395 | | #[cfg(feature = "mvex")] |
3396 | | #[allow(non_camel_case_types)] |
3397 | | pub enum MvexConvFn { |
3398 | | /// No conversion function |
3399 | | None = 0, |
3400 | | /// Sf32(xxx) |
3401 | | Sf32 = 1, |
3402 | | /// Sf64(xxx) |
3403 | | Sf64 = 2, |
3404 | | /// Si32(xxx) |
3405 | | Si32 = 3, |
3406 | | /// Si64(xxx) |
3407 | | Si64 = 4, |
3408 | | /// Uf32(xxx) |
3409 | | Uf32 = 5, |
3410 | | /// Uf64(xxx) |
3411 | | Uf64 = 6, |
3412 | | /// Ui32(xxx) |
3413 | | Ui32 = 7, |
3414 | | /// Ui64(xxx) |
3415 | | Ui64 = 8, |
3416 | | /// Df32(xxx) |
3417 | | Df32 = 9, |
3418 | | /// Df64(xxx) |
3419 | | Df64 = 10, |
3420 | | /// Di32(xxx) |
3421 | | Di32 = 11, |
3422 | | /// Di64(xxx) |
3423 | | Di64 = 12, |
3424 | | } |
3425 | | #[cfg(feature = "mvex")] |
3426 | | #[rustfmt::skip] |
3427 | | static GEN_DEBUG_MVEX_CONV_FN: [&str; 13] = [ |
3428 | | "None", |
3429 | | "Sf32", |
3430 | | "Sf64", |
3431 | | "Si32", |
3432 | | "Si64", |
3433 | | "Uf32", |
3434 | | "Uf64", |
3435 | | "Ui32", |
3436 | | "Ui64", |
3437 | | "Df32", |
3438 | | "Df64", |
3439 | | "Di32", |
3440 | | "Di64", |
3441 | | ]; |
3442 | | #[cfg(feature = "mvex")] |
3443 | | impl fmt::Debug for MvexConvFn { |
3444 | | #[inline] |
3445 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
3446 | | write!(f, "{}", GEN_DEBUG_MVEX_CONV_FN[*self as usize]) |
3447 | | } |
3448 | | } |
3449 | | #[cfg(feature = "mvex")] |
3450 | | impl Default for MvexConvFn { |
3451 | | #[must_use] |
3452 | | #[inline] |
3453 | | fn default() -> Self { |
3454 | | MvexConvFn::None |
3455 | | } |
3456 | | } |
3457 | | #[cfg(feature = "mvex")] |
3458 | | #[allow(non_camel_case_types)] |
3459 | | #[allow(dead_code)] |
3460 | | pub(crate) type MvexConvFnUnderlyingType = u8; |
3461 | | #[cfg(feature = "mvex")] |
3462 | | #[rustfmt::skip] |
3463 | | impl MvexConvFn { |
3464 | | /// Iterates over all `MvexConvFn` enum values |
3465 | | #[inline] |
3466 | | pub fn values() -> impl Iterator<Item = MvexConvFn> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
3467 | | // SAFETY: all values 0-max are valid enum values |
3468 | | (0..IcedConstants::MVEX_CONV_FN_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, MvexConvFn>(x as u8) }) |
3469 | | } |
3470 | | } |
3471 | | #[test] |
3472 | | #[cfg(feature = "mvex")] |
3473 | | #[rustfmt::skip] |
3474 | | fn test_mvexconvfn_values() { |
3475 | | let mut iter = MvexConvFn::values(); |
3476 | | assert_eq!(iter.size_hint(), (IcedConstants::MVEX_CONV_FN_ENUM_COUNT, Some(IcedConstants::MVEX_CONV_FN_ENUM_COUNT))); |
3477 | | assert_eq!(iter.len(), IcedConstants::MVEX_CONV_FN_ENUM_COUNT); |
3478 | | assert!(iter.next().is_some()); |
3479 | | assert_eq!(iter.size_hint(), (IcedConstants::MVEX_CONV_FN_ENUM_COUNT - 1, Some(IcedConstants::MVEX_CONV_FN_ENUM_COUNT - 1))); |
3480 | | assert_eq!(iter.len(), IcedConstants::MVEX_CONV_FN_ENUM_COUNT - 1); |
3481 | | |
3482 | | let values: Vec<MvexConvFn> = MvexConvFn::values().collect(); |
3483 | | assert_eq!(values.len(), IcedConstants::MVEX_CONV_FN_ENUM_COUNT); |
3484 | | for (i, value) in values.into_iter().enumerate() { |
3485 | | assert_eq!(i, value as usize); |
3486 | | } |
3487 | | |
3488 | | let values1: Vec<MvexConvFn> = MvexConvFn::values().collect(); |
3489 | | let mut values2: Vec<MvexConvFn> = MvexConvFn::values().rev().collect(); |
3490 | | values2.reverse(); |
3491 | | assert_eq!(values1, values2); |
3492 | | } |
3493 | | #[cfg(feature = "mvex")] |
3494 | | #[rustfmt::skip] |
3495 | | impl TryFrom<usize> for MvexConvFn { |
3496 | | type Error = IcedError; |
3497 | | #[inline] |
3498 | | fn try_from(value: usize) -> Result<Self, Self::Error> { |
3499 | | if value < IcedConstants::MVEX_CONV_FN_ENUM_COUNT { |
3500 | | // SAFETY: all values 0-max are valid enum values |
3501 | | Ok(unsafe { mem::transmute(value as u8) }) |
3502 | | } else { |
3503 | | Err(IcedError::new("Invalid MvexConvFn value")) |
3504 | | } |
3505 | | } |
3506 | | } |
3507 | | #[cfg(feature = "mvex")] |
3508 | | #[test] |
3509 | | #[rustfmt::skip] |
3510 | | fn test_mvexconvfn_try_from_usize() { |
3511 | | for value in MvexConvFn::values() { |
3512 | | let converted = <MvexConvFn as TryFrom<usize>>::try_from(value as usize).unwrap(); |
3513 | | assert_eq!(converted, value); |
3514 | | } |
3515 | | assert!(<MvexConvFn as TryFrom<usize>>::try_from(IcedConstants::MVEX_CONV_FN_ENUM_COUNT).is_err()); |
3516 | | assert!(<MvexConvFn as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
3517 | | } |
3518 | | #[cfg(feature = "serde")] |
3519 | | #[cfg(feature = "mvex")] |
3520 | | #[rustfmt::skip] |
3521 | | #[allow(clippy::zero_sized_map_values)] |
3522 | | const _: () = { |
3523 | | use core::marker::PhantomData; |
3524 | | use serde::de; |
3525 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
3526 | | type EnumType = MvexConvFn; |
3527 | | impl Serialize for EnumType { |
3528 | | #[inline] |
3529 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
3530 | | where |
3531 | | S: Serializer, |
3532 | | { |
3533 | | serializer.serialize_u8(*self as u8) |
3534 | | } |
3535 | | } |
3536 | | impl<'de> Deserialize<'de> for EnumType { |
3537 | | #[inline] |
3538 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
3539 | | where |
3540 | | D: Deserializer<'de>, |
3541 | | { |
3542 | | struct Visitor<'de> { |
3543 | | marker: PhantomData<EnumType>, |
3544 | | lifetime: PhantomData<&'de ()>, |
3545 | | } |
3546 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
3547 | | type Value = EnumType; |
3548 | | #[inline] |
3549 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
3550 | | formatter.write_str("enum MvexConvFn") |
3551 | | } |
3552 | | #[inline] |
3553 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
3554 | | where |
3555 | | E: de::Error, |
3556 | | { |
3557 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
3558 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
3559 | | return Ok(value); |
3560 | | } |
3561 | | } |
3562 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid MvexConvFn variant value")) |
3563 | | } |
3564 | | } |
3565 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
3566 | | } |
3567 | | } |
3568 | | }; |
3569 | | // GENERATOR-END: MvexConvFn |
3570 | | |
3571 | | // GENERATOR-BEGIN: MvexRegMemConv |
3572 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
3573 | | /// MVEX register/memory operand conversion |
3574 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
3575 | | #[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)] |
3576 | | #[cfg(feature = "mvex")] |
3577 | | #[allow(non_camel_case_types)] |
3578 | | pub enum MvexRegMemConv { |
3579 | | /// No operand conversion |
3580 | | None = 0, |
3581 | | /// Register swizzle: `zmm0` or `zmm0 {dcba}` |
3582 | | RegSwizzleNone = 1, |
3583 | | /// Register swizzle: `zmm0 {cdab}` |
3584 | | RegSwizzleCdab = 2, |
3585 | | /// Register swizzle: `zmm0 {badc}` |
3586 | | RegSwizzleBadc = 3, |
3587 | | /// Register swizzle: `zmm0 {dacb}` |
3588 | | RegSwizzleDacb = 4, |
3589 | | /// Register swizzle: `zmm0 {aaaa}` |
3590 | | RegSwizzleAaaa = 5, |
3591 | | /// Register swizzle: `zmm0 {bbbb}` |
3592 | | RegSwizzleBbbb = 6, |
3593 | | /// Register swizzle: `zmm0 {cccc}` |
3594 | | RegSwizzleCccc = 7, |
3595 | | /// Register swizzle: `zmm0 {dddd}` |
3596 | | RegSwizzleDddd = 8, |
3597 | | /// Memory Up/DownConv: `[rax]` / `zmm0` |
3598 | | MemConvNone = 9, |
3599 | | /// Memory UpConv: `[rax] {1to16}` or `[rax] {1to8}` |
3600 | | MemConvBroadcast1 = 10, |
3601 | | /// Memory UpConv: `[rax] {4to16}` or `[rax] {4to8}` |
3602 | | MemConvBroadcast4 = 11, |
3603 | | /// Memory Up/DownConv: `[rax] {float16}` / `zmm0 {float16}` |
3604 | | MemConvFloat16 = 12, |
3605 | | /// Memory Up/DownConv: `[rax] {uint8}` / `zmm0 {uint8}` |
3606 | | MemConvUint8 = 13, |
3607 | | /// Memory Up/DownConv: `[rax] {sint8}` / `zmm0 {sint8}` |
3608 | | MemConvSint8 = 14, |
3609 | | /// Memory Up/DownConv: `[rax] {uint16}` / `zmm0 {uint16}` |
3610 | | MemConvUint16 = 15, |
3611 | | /// Memory Up/DownConv: `[rax] {sint16}` / `zmm0 {sint16}` |
3612 | | MemConvSint16 = 16, |
3613 | | } |
3614 | | #[cfg(feature = "mvex")] |
3615 | | #[rustfmt::skip] |
3616 | | static GEN_DEBUG_MVEX_REG_MEM_CONV: [&str; 17] = [ |
3617 | | "None", |
3618 | | "RegSwizzleNone", |
3619 | | "RegSwizzleCdab", |
3620 | | "RegSwizzleBadc", |
3621 | | "RegSwizzleDacb", |
3622 | | "RegSwizzleAaaa", |
3623 | | "RegSwizzleBbbb", |
3624 | | "RegSwizzleCccc", |
3625 | | "RegSwizzleDddd", |
3626 | | "MemConvNone", |
3627 | | "MemConvBroadcast1", |
3628 | | "MemConvBroadcast4", |
3629 | | "MemConvFloat16", |
3630 | | "MemConvUint8", |
3631 | | "MemConvSint8", |
3632 | | "MemConvUint16", |
3633 | | "MemConvSint16", |
3634 | | ]; |
3635 | | #[cfg(feature = "mvex")] |
3636 | | impl fmt::Debug for MvexRegMemConv { |
3637 | | #[inline] |
3638 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
3639 | | write!(f, "{}", GEN_DEBUG_MVEX_REG_MEM_CONV[*self as usize]) |
3640 | | } |
3641 | | } |
3642 | | #[cfg(feature = "mvex")] |
3643 | | impl Default for MvexRegMemConv { |
3644 | | #[must_use] |
3645 | | #[inline] |
3646 | | fn default() -> Self { |
3647 | | MvexRegMemConv::None |
3648 | | } |
3649 | | } |
3650 | | #[cfg(feature = "mvex")] |
3651 | | #[allow(non_camel_case_types)] |
3652 | | #[allow(dead_code)] |
3653 | | pub(crate) type MvexRegMemConvUnderlyingType = u8; |
3654 | | #[cfg(feature = "mvex")] |
3655 | | #[rustfmt::skip] |
3656 | | impl MvexRegMemConv { |
3657 | | /// Iterates over all `MvexRegMemConv` enum values |
3658 | | #[inline] |
3659 | | pub fn values() -> impl Iterator<Item = MvexRegMemConv> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
3660 | | // SAFETY: all values 0-max are valid enum values |
3661 | | (0..IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, MvexRegMemConv>(x as u8) }) |
3662 | | } |
3663 | | } |
3664 | | #[test] |
3665 | | #[cfg(feature = "mvex")] |
3666 | | #[rustfmt::skip] |
3667 | | fn test_mvexregmemconv_values() { |
3668 | | let mut iter = MvexRegMemConv::values(); |
3669 | | assert_eq!(iter.size_hint(), (IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT, Some(IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT))); |
3670 | | assert_eq!(iter.len(), IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT); |
3671 | | assert!(iter.next().is_some()); |
3672 | | assert_eq!(iter.size_hint(), (IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT - 1, Some(IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT - 1))); |
3673 | | assert_eq!(iter.len(), IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT - 1); |
3674 | | |
3675 | | let values: Vec<MvexRegMemConv> = MvexRegMemConv::values().collect(); |
3676 | | assert_eq!(values.len(), IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT); |
3677 | | for (i, value) in values.into_iter().enumerate() { |
3678 | | assert_eq!(i, value as usize); |
3679 | | } |
3680 | | |
3681 | | let values1: Vec<MvexRegMemConv> = MvexRegMemConv::values().collect(); |
3682 | | let mut values2: Vec<MvexRegMemConv> = MvexRegMemConv::values().rev().collect(); |
3683 | | values2.reverse(); |
3684 | | assert_eq!(values1, values2); |
3685 | | } |
3686 | | #[cfg(feature = "mvex")] |
3687 | | #[rustfmt::skip] |
3688 | | impl TryFrom<usize> for MvexRegMemConv { |
3689 | | type Error = IcedError; |
3690 | | #[inline] |
3691 | | fn try_from(value: usize) -> Result<Self, Self::Error> { |
3692 | | if value < IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT { |
3693 | | // SAFETY: all values 0-max are valid enum values |
3694 | | Ok(unsafe { mem::transmute(value as u8) }) |
3695 | | } else { |
3696 | | Err(IcedError::new("Invalid MvexRegMemConv value")) |
3697 | | } |
3698 | | } |
3699 | | } |
3700 | | #[cfg(feature = "mvex")] |
3701 | | #[test] |
3702 | | #[rustfmt::skip] |
3703 | | fn test_mvexregmemconv_try_from_usize() { |
3704 | | for value in MvexRegMemConv::values() { |
3705 | | let converted = <MvexRegMemConv as TryFrom<usize>>::try_from(value as usize).unwrap(); |
3706 | | assert_eq!(converted, value); |
3707 | | } |
3708 | | assert!(<MvexRegMemConv as TryFrom<usize>>::try_from(IcedConstants::MVEX_REG_MEM_CONV_ENUM_COUNT).is_err()); |
3709 | | assert!(<MvexRegMemConv as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
3710 | | } |
3711 | | #[cfg(feature = "serde")] |
3712 | | #[cfg(feature = "mvex")] |
3713 | | #[rustfmt::skip] |
3714 | | #[allow(clippy::zero_sized_map_values)] |
3715 | | const _: () = { |
3716 | | use core::marker::PhantomData; |
3717 | | use serde::de; |
3718 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
3719 | | type EnumType = MvexRegMemConv; |
3720 | | impl Serialize for EnumType { |
3721 | | #[inline] |
3722 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
3723 | | where |
3724 | | S: Serializer, |
3725 | | { |
3726 | | serializer.serialize_u8(*self as u8) |
3727 | | } |
3728 | | } |
3729 | | impl<'de> Deserialize<'de> for EnumType { |
3730 | | #[inline] |
3731 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
3732 | | where |
3733 | | D: Deserializer<'de>, |
3734 | | { |
3735 | | struct Visitor<'de> { |
3736 | | marker: PhantomData<EnumType>, |
3737 | | lifetime: PhantomData<&'de ()>, |
3738 | | } |
3739 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
3740 | | type Value = EnumType; |
3741 | | #[inline] |
3742 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
3743 | | formatter.write_str("enum MvexRegMemConv") |
3744 | | } |
3745 | | #[inline] |
3746 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
3747 | | where |
3748 | | E: de::Error, |
3749 | | { |
3750 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
3751 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
3752 | | return Ok(value); |
3753 | | } |
3754 | | } |
3755 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid MvexRegMemConv variant value")) |
3756 | | } |
3757 | | } |
3758 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
3759 | | } |
3760 | | } |
3761 | | }; |
3762 | | // GENERATOR-END: MvexRegMemConv |
3763 | | |
3764 | | // GENERATOR-BEGIN: MvexTupleTypeLutKind |
3765 | | // ⚠️This was generated by GENERATOR!🦹♂️ |
3766 | | /// MVEX tuple type lut kind used together with the `MVEX.SSS` bits to get the tuple type |
3767 | | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
3768 | | #[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)] |
3769 | | #[cfg(feature = "mvex")] |
3770 | | #[allow(non_camel_case_types)] |
3771 | | pub enum MvexTupleTypeLutKind { |
3772 | | /// `i32` elements, eg. `Si32`/`Di32`/`Ui32` |
3773 | | Int32 = 0, |
3774 | | /// `i32` elements, eg. `Si32`/`Di32`/`Ui32` with half memory size (32 bytes instead of 64 bytes, eg. `VCVTUDQ2PD`/`VCVTDQ2PD`) |
3775 | | Int32_Half = 1, |
3776 | | /// `i32` elements, eg. `Si32`/`Di32`/`Ui32` with built-in `{4to16}` broadcast |
3777 | | Int32_4to16 = 2, |
3778 | | /// `i32` elements, eg. `Si32`/`Di32`/`Ui32` with built-in `{1to16}` broadcast or element level |
3779 | | Int32_1to16_or_elem = 3, |
3780 | | /// `i64` elements, eg. `Si64`/`Di64`/`Ui64` |
3781 | | Int64 = 4, |
3782 | | /// `i64` elements, eg. `Si64`/`Di64`/`Ui64` with built-in `{4to8}` broadcast |
3783 | | Int64_4to8 = 5, |
3784 | | /// `i64` elements, eg. `Si64`/`Di64`/`Ui64` with built-in `{1to8}` broadcast or element level |
3785 | | Int64_1to8_or_elem = 6, |
3786 | | /// `f32` elements, eg. `Sf32`/`Df32`/`Uf32` |
3787 | | Float32 = 7, |
3788 | | /// `f32` elements, eg. `Sf32`/`Df32`/`Uf32` with half memory size (32 bytes instead of 64 bytes, eg. `VCVTPS2PD` |
3789 | | Float32_Half = 8, |
3790 | | /// `f32` elements, eg. `Sf32`/`Df32`/`Uf32` with built-in `{4to16}` broadcast |
3791 | | Float32_4to16 = 9, |
3792 | | /// `f32` elements, eg. `Sf32`/`Df32`/`Uf32` with built-in `{1to16}` broadcast or element level |
3793 | | Float32_1to16_or_elem = 10, |
3794 | | /// `f64` elements, eg. `Sf64`/`Df64`/`Uf64` |
3795 | | Float64 = 11, |
3796 | | /// `f64` elements, eg. `Sf64`/`Df64`/`Uf64` with built-in `{4to8}` broadcast |
3797 | | Float64_4to8 = 12, |
3798 | | /// `f64` elements, eg. `Sf64`/`Df64`/`Uf64` with built-in `{1to8}` broadcast or element level |
3799 | | Float64_1to8_or_elem = 13, |
3800 | | } |
3801 | | #[cfg(feature = "mvex")] |
3802 | | #[rustfmt::skip] |
3803 | | static GEN_DEBUG_MVEX_TUPLE_TYPE_LUT_KIND: [&str; 14] = [ |
3804 | | "Int32", |
3805 | | "Int32_Half", |
3806 | | "Int32_4to16", |
3807 | | "Int32_1to16_or_elem", |
3808 | | "Int64", |
3809 | | "Int64_4to8", |
3810 | | "Int64_1to8_or_elem", |
3811 | | "Float32", |
3812 | | "Float32_Half", |
3813 | | "Float32_4to16", |
3814 | | "Float32_1to16_or_elem", |
3815 | | "Float64", |
3816 | | "Float64_4to8", |
3817 | | "Float64_1to8_or_elem", |
3818 | | ]; |
3819 | | #[cfg(feature = "mvex")] |
3820 | | impl fmt::Debug for MvexTupleTypeLutKind { |
3821 | | #[inline] |
3822 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
3823 | | write!(f, "{}", GEN_DEBUG_MVEX_TUPLE_TYPE_LUT_KIND[*self as usize]) |
3824 | | } |
3825 | | } |
3826 | | #[cfg(feature = "mvex")] |
3827 | | impl Default for MvexTupleTypeLutKind { |
3828 | | #[must_use] |
3829 | | #[inline] |
3830 | | fn default() -> Self { |
3831 | | MvexTupleTypeLutKind::Int32 |
3832 | | } |
3833 | | } |
3834 | | #[cfg(feature = "mvex")] |
3835 | | #[allow(non_camel_case_types)] |
3836 | | #[allow(dead_code)] |
3837 | | pub(crate) type MvexTupleTypeLutKindUnderlyingType = u8; |
3838 | | #[cfg(feature = "mvex")] |
3839 | | #[rustfmt::skip] |
3840 | | impl MvexTupleTypeLutKind { |
3841 | | /// Iterates over all `MvexTupleTypeLutKind` enum values |
3842 | | #[inline] |
3843 | | pub fn values() -> impl Iterator<Item = MvexTupleTypeLutKind> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { |
3844 | | // SAFETY: all values 0-max are valid enum values |
3845 | | (0..IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, MvexTupleTypeLutKind>(x as u8) }) |
3846 | | } |
3847 | | } |
3848 | | #[test] |
3849 | | #[cfg(feature = "mvex")] |
3850 | | #[rustfmt::skip] |
3851 | | fn test_mvextupletypelutkind_values() { |
3852 | | let mut iter = MvexTupleTypeLutKind::values(); |
3853 | | assert_eq!(iter.size_hint(), (IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT, Some(IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT))); |
3854 | | assert_eq!(iter.len(), IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT); |
3855 | | assert!(iter.next().is_some()); |
3856 | | assert_eq!(iter.size_hint(), (IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT - 1, Some(IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT - 1))); |
3857 | | assert_eq!(iter.len(), IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT - 1); |
3858 | | |
3859 | | let values: Vec<MvexTupleTypeLutKind> = MvexTupleTypeLutKind::values().collect(); |
3860 | | assert_eq!(values.len(), IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT); |
3861 | | for (i, value) in values.into_iter().enumerate() { |
3862 | | assert_eq!(i, value as usize); |
3863 | | } |
3864 | | |
3865 | | let values1: Vec<MvexTupleTypeLutKind> = MvexTupleTypeLutKind::values().collect(); |
3866 | | let mut values2: Vec<MvexTupleTypeLutKind> = MvexTupleTypeLutKind::values().rev().collect(); |
3867 | | values2.reverse(); |
3868 | | assert_eq!(values1, values2); |
3869 | | } |
3870 | | #[cfg(feature = "mvex")] |
3871 | | #[rustfmt::skip] |
3872 | | impl TryFrom<usize> for MvexTupleTypeLutKind { |
3873 | | type Error = IcedError; |
3874 | | #[inline] |
3875 | | fn try_from(value: usize) -> Result<Self, Self::Error> { |
3876 | | if value < IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT { |
3877 | | // SAFETY: all values 0-max are valid enum values |
3878 | | Ok(unsafe { mem::transmute(value as u8) }) |
3879 | | } else { |
3880 | | Err(IcedError::new("Invalid MvexTupleTypeLutKind value")) |
3881 | | } |
3882 | | } |
3883 | | } |
3884 | | #[cfg(feature = "mvex")] |
3885 | | #[test] |
3886 | | #[rustfmt::skip] |
3887 | | fn test_mvextupletypelutkind_try_from_usize() { |
3888 | | for value in MvexTupleTypeLutKind::values() { |
3889 | | let converted = <MvexTupleTypeLutKind as TryFrom<usize>>::try_from(value as usize).unwrap(); |
3890 | | assert_eq!(converted, value); |
3891 | | } |
3892 | | assert!(<MvexTupleTypeLutKind as TryFrom<usize>>::try_from(IcedConstants::MVEX_TUPLE_TYPE_LUT_KIND_ENUM_COUNT).is_err()); |
3893 | | assert!(<MvexTupleTypeLutKind as TryFrom<usize>>::try_from(core::usize::MAX).is_err()); |
3894 | | } |
3895 | | #[cfg(feature = "serde")] |
3896 | | #[cfg(feature = "mvex")] |
3897 | | #[rustfmt::skip] |
3898 | | #[allow(clippy::zero_sized_map_values)] |
3899 | | const _: () = { |
3900 | | use core::marker::PhantomData; |
3901 | | use serde::de; |
3902 | | use serde::{Deserialize, Deserializer, Serialize, Serializer}; |
3903 | | type EnumType = MvexTupleTypeLutKind; |
3904 | | impl Serialize for EnumType { |
3905 | | #[inline] |
3906 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
3907 | | where |
3908 | | S: Serializer, |
3909 | | { |
3910 | | serializer.serialize_u8(*self as u8) |
3911 | | } |
3912 | | } |
3913 | | impl<'de> Deserialize<'de> for EnumType { |
3914 | | #[inline] |
3915 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
3916 | | where |
3917 | | D: Deserializer<'de>, |
3918 | | { |
3919 | | struct Visitor<'de> { |
3920 | | marker: PhantomData<EnumType>, |
3921 | | lifetime: PhantomData<&'de ()>, |
3922 | | } |
3923 | | impl<'de> de::Visitor<'de> for Visitor<'de> { |
3924 | | type Value = EnumType; |
3925 | | #[inline] |
3926 | | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
3927 | | formatter.write_str("enum MvexTupleTypeLutKind") |
3928 | | } |
3929 | | #[inline] |
3930 | | fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> |
3931 | | where |
3932 | | E: de::Error, |
3933 | | { |
3934 | | if let Ok(v) = <usize as TryFrom<_>>::try_from(v) { |
3935 | | if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) { |
3936 | | return Ok(value); |
3937 | | } |
3938 | | } |
3939 | | Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid MvexTupleTypeLutKind variant value")) |
3940 | | } |
3941 | | } |
3942 | | deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData }) |
3943 | | } |
3944 | | } |
3945 | | }; |
3946 | | // GENERATOR-END: MvexTupleTypeLutKind |