Skip to main content

closure_ffi_iced_x86/
decoder.rs

1// SPDX-License-Identifier: MIT
2// Copyright (C) 2018-present iced project and contributors
3
4macro_rules! mk_read_xx {
5	($slf:ident, $mem_ty:ty, $from_le:path, $ret_ty:ty, $err_expr:expr) => {
6		const SIZE: usize = mem::size_of::<$mem_ty>();
7		const _: () = assert!(SIZE >= 1);
8		const _: () = assert!(SIZE <= Decoder::MAX_READ_SIZE);
9		let data_ptr = $slf.data_ptr;
10		#[allow(trivial_numeric_casts)]
11		{
12			// This doesn't overflow data_ptr (verified in ctor since SIZE <= MAX_READ_SIZE)
13			if data_ptr + SIZE - 1 < $slf.max_data_ptr {
14				// SAFETY:
15				// - cast: It's OK to cast to an unaligned `*const uXX` since we call read_unaligned()
16				// - ptr::read_unaligned: ptr is readable and data (u8 slice) is initialized
17				let result = $from_le(unsafe { ptr::read_unaligned(data_ptr as *const $mem_ty) }) as $ret_ty;
18				// - data_ptr + SIZE doesn't overflow (verified in ctor since SIZE <= MAX_READ_SIZE)
19				// - data_ptr + SIZE <= self.max_data_ptr (see `if` check above)
20				$slf.data_ptr = data_ptr + SIZE;
21				result
22			} else {
23				$err_expr
24			}
25		}
26	};
27}
28macro_rules! mk_read_xx_fn_body {
29	($slf:ident, $mem_ty:ty, $from_le:path, $ret_ty:ty) => {
30		mk_read_xx!($slf, $mem_ty, $from_le, $ret_ty, {
31			$slf.state.flags |= StateFlags::IS_INVALID | StateFlags::NO_MORE_BYTES;
32			0
33		})
34	};
35}
36macro_rules! read_u8_break {
37	($slf:ident) => {{
38		mk_read_xx! {$slf, u8, u8::from_le, usize, break}
39	}};
40}
41#[cfg(not(feature = "__internal_flip"))]
42macro_rules! read_u16_break {
43	($slf:ident) => {{
44		mk_read_xx! {$slf, u16, u16::from_le, usize, break}
45	}};
46}
47macro_rules! read_u32_break {
48	($slf:ident) => {{
49		mk_read_xx! {$slf, u32, u32::from_le, usize, break}
50	}};
51}
52#[cfg(not(feature = "__internal_flip"))]
53macro_rules! read_op_mem_stmt_ret {
54	($decoder:ident, $instruction:ident, $stmts:block) => {{
55		debug_assert!($decoder.state.encoding() != EncodingKind::EVEX as u32 && $decoder.state.encoding() != EncodingKind::MVEX as u32);
56		let index = $decoder.state.mem_index as usize;
57		debug_assert!(index < $decoder.read_op_mem_fns.len());
58		// SAFETY: index is valid because modrm.mod = 0-2 (never 3 if we're here) so index will always be 0-10_111 (17h)
59		let handler = unsafe { *$decoder.read_op_mem_fns.get_unchecked(index) };
60
61		$stmts
62
63		if $decoder.state.address_size != OpSize::Size16 {
64			(handler)($instruction, $decoder)
65		} else {
66			$decoder.read_op_mem_16($instruction, TupleType::N1);
67			false
68		}
69	}};
70}
71#[cfg(not(feature = "__internal_flip"))]
72macro_rules! read_op_mem_stmt {
73	($decoder:ident, $instruction:ident, $stmts:block) => {
74		let _ = read_op_mem_stmt_ret!($decoder, $instruction, $stmts);
75	};
76}
77#[cfg(feature = "__internal_flip")]
78macro_rules! read_op_mem_stmt {
79	($decoder:ident, $instruction:ident, $stmts:block) => {
80		debug_assert!($decoder.state.encoding() != EncodingKind::EVEX as u32 && $decoder.state.encoding() != EncodingKind::MVEX as u32);
81		$stmts
82		if $decoder.state.address_size != OpSize::Size16 {
83			let _ = $decoder.read_op_mem_32_or_64($instruction);
84		} else {
85			$decoder.read_op_mem_16($instruction, TupleType::N1);
86		}
87	};
88}
89
90mod enums;
91mod handlers;
92mod table_de;
93#[cfg(test)]
94pub(crate) mod tests;
95
96use crate::decoder::handlers::tables::TABLES;
97use crate::decoder::handlers::{OpCodeHandler, OpCodeHandlerDecodeFn};
98use crate::iced_constants::IcedConstants;
99use crate::iced_error::IcedError;
100use crate::instruction_internal;
101use crate::tuple_type_tbl::get_disp8n;
102use crate::*;
103use core::iter::FusedIterator;
104use core::{cmp, fmt, mem, ptr};
105
106#[rustfmt::skip]
107#[cfg(any(feature = "__internal_flip", not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
108static READ_OP_MEM_VSIB_FNS: [fn(&mut Decoder<'_>, &mut Instruction, Register, TupleType, bool) -> bool; 0x18] = [
109	decoder_read_op_mem_vsib_0,
110	decoder_read_op_mem_vsib_0,
111	decoder_read_op_mem_vsib_0,
112	decoder_read_op_mem_vsib_0,
113	decoder_read_op_mem_vsib_0_4,
114	decoder_read_op_mem_vsib_0_5,
115	decoder_read_op_mem_vsib_0,
116	decoder_read_op_mem_vsib_0,
117
118	decoder_read_op_mem_vsib_1,
119	decoder_read_op_mem_vsib_1,
120	decoder_read_op_mem_vsib_1,
121	decoder_read_op_mem_vsib_1,
122	decoder_read_op_mem_vsib_1_4,
123	decoder_read_op_mem_vsib_1,
124	decoder_read_op_mem_vsib_1,
125	decoder_read_op_mem_vsib_1,
126
127	decoder_read_op_mem_vsib_2,
128	decoder_read_op_mem_vsib_2,
129	decoder_read_op_mem_vsib_2,
130	decoder_read_op_mem_vsib_2,
131	decoder_read_op_mem_vsib_2_4,
132	decoder_read_op_mem_vsib_2,
133	decoder_read_op_mem_vsib_2,
134	decoder_read_op_mem_vsib_2,
135];
136
137static MEM_REGS_16: [(Register, Register); 8] = [
138	(Register::BX, Register::SI),
139	(Register::BX, Register::DI),
140	(Register::BP, Register::SI),
141	(Register::BP, Register::DI),
142	(Register::SI, Register::None),
143	(Register::DI, Register::None),
144	(Register::BP, Register::None),
145	(Register::BX, Register::None),
146];
147
148// GENERATOR-BEGIN: OpSize
149// ⚠️This was generated by GENERATOR!🦹‍♂️
150#[derive(Copy, Clone, Eq, PartialEq)]
151#[allow(dead_code)]
152pub(crate) enum OpSize {
153	Size16,
154	Size32,
155	Size64,
156}
157#[rustfmt::skip]
158static GEN_DEBUG_OP_SIZE: [&str; 3] = [
159	"Size16",
160	"Size32",
161	"Size64",
162];
163impl fmt::Debug for OpSize {
164	#[inline]
165	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166		write!(f, "{}", GEN_DEBUG_OP_SIZE[*self as usize])
167	}
168}
169impl Default for OpSize {
170	#[inline]
171	fn default() -> Self {
172		OpSize::Size16
173	}
174}
175// GENERATOR-END: OpSize
176
177// GENERATOR-BEGIN: DecoderError
178// ⚠️This was generated by GENERATOR!🦹‍♂️
179/// Decoder error
180#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
181#[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)]
182pub enum DecoderError {
183	/// No error. The last decoded instruction is a valid instruction
184	None = 0,
185	/// It's an invalid instruction or an invalid encoding of an existing instruction (eg. some reserved bit is set/cleared)
186	InvalidInstruction = 1,
187	/// There's not enough bytes left to decode the instruction
188	NoMoreBytes = 2,
189}
190#[rustfmt::skip]
191static GEN_DEBUG_DECODER_ERROR: [&str; 3] = [
192	"None",
193	"InvalidInstruction",
194	"NoMoreBytes",
195];
196impl fmt::Debug for DecoderError {
197	#[inline]
198	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199		write!(f, "{}", GEN_DEBUG_DECODER_ERROR[*self as usize])
200	}
201}
202impl Default for DecoderError {
203	#[inline]
204	fn default() -> Self {
205		DecoderError::None
206	}
207}
208#[allow(non_camel_case_types)]
209#[allow(dead_code)]
210pub(crate) type DecoderErrorUnderlyingType = u8;
211#[rustfmt::skip]
212impl DecoderError {
213	/// Iterates over all `DecoderError` enum values
214	#[inline]
215	pub fn values() -> impl Iterator<Item = DecoderError> + DoubleEndedIterator + ExactSizeIterator + FusedIterator {
216		// SAFETY: all values 0-max are valid enum values
217		(0..IcedConstants::DECODER_ERROR_ENUM_COUNT).map(|x| unsafe { mem::transmute::<u8, DecoderError>(x as u8) })
218	}
219}
220#[test]
221#[rustfmt::skip]
222fn test_decodererror_values() {
223	let mut iter = DecoderError::values();
224	assert_eq!(iter.size_hint(), (IcedConstants::DECODER_ERROR_ENUM_COUNT, Some(IcedConstants::DECODER_ERROR_ENUM_COUNT)));
225	assert_eq!(iter.len(), IcedConstants::DECODER_ERROR_ENUM_COUNT);
226	assert!(iter.next().is_some());
227	assert_eq!(iter.size_hint(), (IcedConstants::DECODER_ERROR_ENUM_COUNT - 1, Some(IcedConstants::DECODER_ERROR_ENUM_COUNT - 1)));
228	assert_eq!(iter.len(), IcedConstants::DECODER_ERROR_ENUM_COUNT - 1);
229
230	let values: Vec<DecoderError> = DecoderError::values().collect();
231	assert_eq!(values.len(), IcedConstants::DECODER_ERROR_ENUM_COUNT);
232	for (i, value) in values.into_iter().enumerate() {
233		assert_eq!(i, value as usize);
234	}
235
236	let values1: Vec<DecoderError> = DecoderError::values().collect();
237	let mut values2: Vec<DecoderError> = DecoderError::values().rev().collect();
238	values2.reverse();
239	assert_eq!(values1, values2);
240}
241#[rustfmt::skip]
242impl TryFrom<usize> for DecoderError {
243	type Error = IcedError;
244	#[inline]
245	fn try_from(value: usize) -> Result<Self, Self::Error> {
246		if value < IcedConstants::DECODER_ERROR_ENUM_COUNT {
247			// SAFETY: all values 0-max are valid enum values
248			Ok(unsafe { mem::transmute(value as u8) })
249		} else {
250			Err(IcedError::new("Invalid DecoderError value"))
251		}
252	}
253}
254#[test]
255#[rustfmt::skip]
256fn test_decodererror_try_from_usize() {
257	for value in DecoderError::values() {
258		let converted = <DecoderError as TryFrom<usize>>::try_from(value as usize).unwrap();
259		assert_eq!(converted, value);
260	}
261	assert!(<DecoderError as TryFrom<usize>>::try_from(IcedConstants::DECODER_ERROR_ENUM_COUNT).is_err());
262	assert!(<DecoderError as TryFrom<usize>>::try_from(usize::MAX).is_err());
263}
264#[cfg(feature = "serde")]
265#[rustfmt::skip]
266#[allow(clippy::zero_sized_map_values)]
267const _: () = {
268	use core::marker::PhantomData;
269	use serde::de;
270	use serde::{Deserialize, Deserializer, Serialize, Serializer};
271	type EnumType = DecoderError;
272	impl Serialize for EnumType {
273		#[inline]
274		fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
275		where
276			S: Serializer,
277		{
278			serializer.serialize_u8(*self as u8)
279		}
280	}
281	impl<'de> Deserialize<'de> for EnumType {
282		#[inline]
283		fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
284		where
285			D: Deserializer<'de>,
286		{
287			struct Visitor<'de> {
288				marker: PhantomData<EnumType>,
289				lifetime: PhantomData<&'de ()>,
290			}
291			impl<'de> de::Visitor<'de> for Visitor<'de> {
292				type Value = EnumType;
293				#[inline]
294				fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
295					formatter.write_str("enum DecoderError")
296				}
297				#[inline]
298				fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
299				where
300					E: de::Error,
301				{
302					if let Ok(v) = <usize as TryFrom<_>>::try_from(v) {
303						if let Ok(value) = <EnumType as TryFrom<_>>::try_from(v) {
304							return Ok(value);
305						}
306					}
307					Err(de::Error::invalid_value(de::Unexpected::Unsigned(v), &"a valid DecoderError variant value"))
308				}
309			}
310			deserializer.deserialize_u8(Visitor { marker: PhantomData::<EnumType>, lifetime: PhantomData })
311		}
312	}
313};
314// GENERATOR-END: DecoderError
315
316// GENERATOR-BEGIN: DecoderOptions
317// ⚠️This was generated by GENERATOR!🦹‍♂️
318/// Decoder options
319#[allow(missing_copy_implementations)]
320#[allow(missing_debug_implementations)]
321pub struct DecoderOptions;
322impl DecoderOptions {
323	/// No option is enabled
324	pub const NONE: u32 = 0x0000_0000;
325	/// Disable some checks for invalid encodings of instructions, eg. most instructions can't use a `LOCK` prefix so if one is found, they're decoded as [`Code::INVALID`] unless this option is enabled.
326	///
327	/// [`Code::INVALID`]: enum.Code.html#variant.INVALID
328	pub const NO_INVALID_CHECK: u32 = 0x0000_0001;
329	/// AMD decoder: allow 16-bit branch/ret instructions in 64-bit mode, no `o64 CALL/JMP FAR [mem], o64 LSS/LFS/LGS`, `UD0` has no modr/m byte, decode `LOCK MOV CR`. The AMD decoder can still decode Intel instructions.
330	pub const AMD: u32 = 0x0000_0002;
331	/// Decode opcodes `0F0D` and `0F18-0F1F` as reserved-nop instructions (eg. [`Code::Reservednop_rm32_r32_0F1D`])
332	///
333	/// [`Code::Reservednop_rm32_r32_0F1D`]: enum.Code.html#variant.Reservednop_rm32_r32_0F1D
334	pub const FORCE_RESERVED_NOP: u32 = 0x0000_0004;
335	/// Decode `UMOV` instructions
336	pub const UMOV: u32 = 0x0000_0008;
337	/// Decode `XBTS`/`IBTS`
338	pub const XBTS: u32 = 0x0000_0010;
339	/// Decode `0FA6`/`0FA7` as `CMPXCHG`
340	pub const CMPXCHG486A: u32 = 0x0000_0020;
341	/// Decode some old removed FPU instructions (eg. `FRSTPM`)
342	pub const OLD_FPU: u32 = 0x0000_0040;
343	/// Decode `PCOMMIT`
344	pub const PCOMMIT: u32 = 0x0000_0080;
345	/// Decode 286 `STOREALL`/`LOADALL` (`0F04` and `0F05`)
346	pub const LOADALL286: u32 = 0x0000_0100;
347	/// Decode 386 `LOADALL`
348	pub const LOADALL386: u32 = 0x0000_0200;
349	/// Decode `CL1INVMB`
350	pub const CL1INVMB: u32 = 0x0000_0400;
351	/// Decode `MOV r32,tr` and `MOV tr,r32`
352	pub const MOV_TR: u32 = 0x0000_0800;
353	/// Decode `JMPE` instructions
354	pub const JMPE: u32 = 0x0000_1000;
355	/// Don't decode `PAUSE`, decode `NOP` instead
356	pub const NO_PAUSE: u32 = 0x0000_2000;
357	/// Don't decode `WBNOINVD`, decode `WBINVD` instead
358	pub const NO_WBNOINVD: u32 = 0x0000_4000;
359	/// Decode undocumented Intel `RDUDBG` and `WRUDBG` instructions
360	pub const UDBG: u32 = 0x0000_8000;
361	/// Don't decode `TZCNT`, decode `BSF` instead
362	pub const NO_MPFX_0FBC: u32 = 0x0001_0000;
363	/// Don't decode `LZCNT`, decode `BSR` instead
364	pub const NO_MPFX_0FBD: u32 = 0x0002_0000;
365	/// Don't decode `LAHF` and `SAHF` in 64-bit mode
366	pub const NO_LAHF_SAHF_64: u32 = 0x0004_0000;
367	/// Decode `MPX` instructions
368	pub const MPX: u32 = 0x0008_0000;
369	/// Decode most Cyrix instructions: `FPU`, `EMMI`, `SMM`, `DDI`
370	pub const CYRIX: u32 = 0x0010_0000;
371	/// Decode Cyrix `SMINT 0F7E` (Cyrix 6x86 or earlier)
372	pub const CYRIX_SMINT_0F7E: u32 = 0x0020_0000;
373	/// Decode Cyrix `DMI` instructions (AMD Geode GX/LX)
374	pub const CYRIX_DMI: u32 = 0x0040_0000;
375	/// Decode Centaur `ALTINST`
376	pub const ALTINST: u32 = 0x0080_0000;
377	/// Decode Intel Knights Corner instructions (requires the `mvex` feature)
378	pub const KNC: u32 = 0x0100_0000;
379}
380// GENERATOR-END: DecoderOptions
381
382// GENERATOR-BEGIN: HandlerFlags
383// ⚠️This was generated by GENERATOR!🦹‍♂️
384pub(crate) struct HandlerFlags;
385#[allow(dead_code)]
386impl HandlerFlags {
387	pub(crate) const NONE: u32 = 0x0000_0000;
388	pub(crate) const XACQUIRE: u32 = 0x0000_0001;
389	pub(crate) const XRELEASE: u32 = 0x0000_0002;
390	pub(crate) const XACQUIRE_XRELEASE_NO_LOCK: u32 = 0x0000_0004;
391	pub(crate) const LOCK: u32 = 0x0000_0008;
392}
393// GENERATOR-END: HandlerFlags
394
395// GENERATOR-BEGIN: StateFlags
396// ⚠️This was generated by GENERATOR!🦹‍♂️
397pub(crate) struct StateFlags;
398#[allow(dead_code)]
399impl StateFlags {
400	pub(crate) const IP_REL64: u32 = 0x0000_0001;
401	pub(crate) const IP_REL32: u32 = 0x0000_0002;
402	pub(crate) const HAS_REX: u32 = 0x0000_0008;
403	pub(crate) const B: u32 = 0x0000_0010;
404	pub(crate) const Z: u32 = 0x0000_0020;
405	pub(crate) const IS_INVALID: u32 = 0x0000_0040;
406	pub(crate) const W: u32 = 0x0000_0080;
407	pub(crate) const NO_IMM: u32 = 0x0000_0100;
408	pub(crate) const ADDR64: u32 = 0x0000_0200;
409	pub(crate) const BRANCH_IMM8: u32 = 0x0000_0400;
410	pub(crate) const XBEGIN: u32 = 0x0000_0800;
411	pub(crate) const LOCK: u32 = 0x0000_1000;
412	pub(crate) const ALLOW_LOCK: u32 = 0x0000_2000;
413	pub(crate) const NO_MORE_BYTES: u32 = 0x0000_4000;
414	pub(crate) const HAS66: u32 = 0x0000_8000;
415	pub(crate) const MVEX_SSS_MASK: u32 = 0x0000_0007;
416	pub(crate) const MVEX_SSS_SHIFT: u32 = 0x0000_0010;
417	pub(crate) const MVEX_EH: u32 = 0x0008_0000;
418	pub(crate) const ENCODING_MASK: u32 = 0x0000_0007;
419	pub(crate) const ENCODING_SHIFT: u32 = 0x0000_001D;
420}
421// GENERATOR-END: StateFlags
422
423// This is `repr(u32)` since we need the decoder field near other fields that also get cleared in `decode()`.
424// It could fit in a `u8` but then it wouldn't be cleared at the same time as the other fields since the
425// compiler would move other `u32` fields above it to align the fields.
426#[repr(u32)]
427#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
428enum DecoderMandatoryPrefix {
429	#[default]
430	PNP = 0,
431	P66 = 1,
432	PF3 = 2,
433	PF2 = 3,
434}
435
436#[derive(Default)]
437#[allow(dead_code)]
438struct State {
439	modrm: u32, // 0-0xFF
440	mod_: u32,  // 0-3
441	reg: u32,   // 0-7
442	rm: u32,    // 0-7
443
444	// ***************************
445	// These fields are cleared in decode_out() and should be close so the compiler can optimize clearing them.
446	extra_register_base: u32,       // R << 3
447	extra_index_register_base: u32, // X << 3
448	extra_base_register_base: u32,  // B << 3
449	extra_index_register_base_vsib: u32,
450	flags: u32, // StateFlags
451	mandatory_prefix: DecoderMandatoryPrefix,
452
453	vvvv: u32,               // V`vvvv. Not stored in inverted form. If 16/32-bit mode, bits [4:3] are cleared
454	vvvv_invalid_check: u32, // vvvv bits, even in 16/32-bit mode.
455	// ***************************
456	mem_index: u32, // (mod << 3 | rm) and an index into the mem handler tables if mod <= 2
457	vector_length: VectorLength,
458	aaa: u32,
459	extra_register_base_evex: u32,      // EVEX/MVEX.R' << 4
460	extra_base_register_base_evex: u32, // EVEX/MVEX.XB << 3
461	// The order of these 4 fields is important. They're accessed as a u32 (decode_out_ptr()) by the compiler so should be 4 byte aligned.
462	address_size: OpSize,
463	operand_size: OpSize,
464	segment_prio: u8, // 0=ES/CS/SS/DS, 1=FS/GS
465	dummy: u8,
466	// =================
467}
468
469impl State {
470	#[must_use]
471	#[inline(always)]
472	#[cfg(debug_assertions)]
473	const fn encoding(&self) -> u32 {
474		(self.flags >> StateFlags::ENCODING_SHIFT) & StateFlags::ENCODING_MASK
475	}
476
477	#[must_use]
478	#[inline(always)]
479	#[cfg(not(debug_assertions))]
480	#[allow(clippy::unused_self)]
481	fn encoding(&self) -> u32 {
482		EncodingKind::Legacy as u32
483	}
484
485	#[must_use]
486	#[inline]
487	#[cfg(feature = "mvex")]
488	fn sss(&self) -> u32 {
489		(self.flags >> StateFlags::MVEX_SSS_SHIFT) & StateFlags::MVEX_SSS_MASK
490	}
491}
492
493/// Decodes 16/32/64-bit x86 instructions
494#[allow(missing_debug_implementations)]
495#[allow(dead_code)]
496pub struct Decoder<'a>
497where
498	Self: Send + Sync,
499{
500	// Current RIP value
501	ip: u64,
502
503	// Next bytes to read if there's enough bytes left to read.
504	// This can be 1 byte past the last byte of `data`.
505	// Invariant: data.as_ptr() <= data_ptr <= max_data_ptr <= data.as_ptr() + data.len() == data_ptr_end
506	// Invariant: {data_ptr,max_data_ptr,data_ptr_end}.add(max(MAX_READ_SIZE, MAX_INSTRUCTION_LENGTH)) doesn't overflow
507	data_ptr: usize,
508	// This is `data.as_ptr() + data.len()` (1 byte past the last valid byte).
509	// This is guaranteed to be >= data_ptr (see the ctor), in other words, it can't overflow to 0
510	// Invariant: data.as_ptr() <= data_ptr <= max_data_ptr <= data.as_ptr() + data.len() == data_ptr_end
511	// Invariant: {data_ptr,max_data_ptr,data_ptr_end}.add(max(MAX_READ_SIZE, MAX_INSTRUCTION_LENGTH)) doesn't overflow
512	data_ptr_end: usize,
513	// Set to cmp::min(self.data_ptr + IcedConstants::MAX_INSTRUCTION_LENGTH, self.data_ptr_end)
514	// and is guaranteed to not overflow
515	// Initialized in decode() to at most 15 bytes after data_ptr so read_uXX() fails quickly after at most 15 read bytes
516	// (1MB prefixes won't cause it to read 1MB prefixes, it will stop after at most 15).
517	// Invariant: data.as_ptr() <= data_ptr <= max_data_ptr <= data.as_ptr() + data.len() == data_ptr_end
518	// Invariant: {data_ptr,max_data_ptr,data_ptr_end}.add(max(MAX_READ_SIZE, MAX_INSTRUCTION_LENGTH)) doesn't overflow
519	max_data_ptr: usize,
520	// Initialized to start of data (data_ptr) when decode() is called. Used to calculate current IP/offset (when decoding) if needed.
521	instr_start_data_ptr: usize,
522
523	handlers_map0: &'static [(OpCodeHandlerDecodeFn, &'static OpCodeHandler); 0x100],
524	// MAP0 is only used by MVEX. Don't allocate an extra array element if mvex feature is disabled (common case)
525	#[cfg(all(not(feature = "no_vex"), feature = "mvex"))]
526	handlers_vex_map0: &'static [(OpCodeHandlerDecodeFn, &'static OpCodeHandler); 0x100],
527	#[cfg(not(feature = "no_vex"))]
528	handlers_vex: [&'static [(OpCodeHandlerDecodeFn, &'static OpCodeHandler); 0x100]; 3],
529	#[cfg(not(feature = "no_evex"))]
530	handlers_evex: [&'static [(OpCodeHandlerDecodeFn, &'static OpCodeHandler); 0x100]; 6],
531	#[cfg(not(feature = "no_xop"))]
532	handlers_xop: [&'static [(OpCodeHandlerDecodeFn, &'static OpCodeHandler); 0x100]; 3],
533	#[cfg(feature = "mvex")]
534	handlers_mvex: [&'static [(OpCodeHandlerDecodeFn, &'static OpCodeHandler); 0x100]; 3],
535
536	#[cfg(not(all(not(feature = "no_vex"), feature = "mvex")))]
537	handlers_vex_map0: (),
538	#[cfg(feature = "no_vex")]
539	handlers_vex: [(); 3],
540	#[cfg(feature = "no_evex")]
541	handlers_evex: [(); 6],
542	#[cfg(feature = "no_xop")]
543	handlers_xop: [(); 3],
544	#[cfg(not(feature = "mvex"))]
545	handlers_mvex: [(); 3],
546
547	#[cfg(not(feature = "__internal_flip"))]
548	read_op_mem_fns: [fn(&mut Instruction, &mut Decoder<'a>) -> bool; 0x18],
549	#[cfg(feature = "__internal_flip")]
550	read_op_mem_fns: (),
551
552	state: State,
553	// DecoderOptions
554	options: u32,
555	// All 1s if we should check for invalid instructions, else 0
556	invalid_check_mask: u32,
557	// StateFlags::W if 64-bit mode, 0 if 16/32-bit mode
558	is64b_mode_and_w: u32,
559	// 7 in 16/32-bit mode, 15 in 64-bit mode
560	reg15_mask: u32,
561	// 0 in 16/32-bit mode, 0E0h in 64-bit mode
562	mask_e0: u32,
563	rex_mask: u32,
564	bitness: u32,
565	// The order of these 4 fields is important. They're accessed as a u32 (decode_out_ptr()) by the compiler so should be 4 byte aligned.
566	default_address_size: OpSize,
567	default_operand_size: OpSize,
568	segment_prio: u8, // Always 0
569	dummy: u8,        // Padding so the compiler can read 4 bytes, see decode_out_ptr()
570	// =================
571	default_inverted_address_size: OpSize,
572	default_inverted_operand_size: OpSize,
573	// true if 64-bit mode, false if 16/32-bit mode
574	is64b_mode: bool,
575	default_code_size: CodeSize,
576	// Offset of displacement in the instruction. Only used by get_constant_offsets() to return the offset of the displ
577	displ_index: u8,
578
579	// Input data provided by the user. When there's no more bytes left to read we'll return a NoMoreBytes error
580	data: &'a [u8],
581}
582
583macro_rules! write_base_reg {
584	($instruction:ident, $expr:expr) => {
585		debug_assert!($expr < IcedConstants::REGISTER_ENUM_COUNT as u32);
586		$instruction.set_memory_base(unsafe { mem::transmute($expr as RegisterUnderlyingType) });
587	};
588}
589
590macro_rules! write_index_reg {
591	($instruction:ident, $expr:expr) => {
592		debug_assert!($expr < IcedConstants::REGISTER_ENUM_COUNT as u32);
593		$instruction.set_memory_index(unsafe { mem::transmute($expr as RegisterUnderlyingType) });
594	};
595}
596
597impl<'a> Decoder<'a> {
598	const MAX_READ_SIZE: usize = 8;
599
600	/// Creates a decoder
601	///
602	/// # Panics
603	///
604	/// Panics if `bitness` is not one of 16, 32, 64.
605	///
606	/// # Arguments
607	///
608	/// * `bitness`: 16, 32 or 64
609	/// * `data`: Data to decode
610	/// * `options`: Decoder options, `0` or eg. `DecoderOptions::NO_INVALID_CHECK | DecoderOptions::AMD`
611	///
612	/// # Examples
613	///
614	/// ```
615	/// use iced_x86::*;
616	///
617	/// // xchg ah,[rdx+rsi+16h]
618	/// // xacquire lock add dword ptr [rax],5Ah
619	/// // vmovdqu64 zmm18{k3}{z},zmm11
620	/// let bytes = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3";
621	/// let mut decoder = Decoder::new(64, bytes, DecoderOptions::NONE);
622	/// decoder.set_ip(0x1234_5678);
623	///
624	/// let instr1 = decoder.decode();
625	/// assert_eq!(instr1.code(), Code::Xchg_rm8_r8);
626	/// assert_eq!(instr1.mnemonic(), Mnemonic::Xchg);
627	/// assert_eq!(instr1.len(), 4);
628	///
629	/// let instr2 = decoder.decode();
630	/// assert_eq!(instr2.code(), Code::Add_rm32_imm8);
631	/// assert_eq!(instr2.mnemonic(), Mnemonic::Add);
632	/// assert_eq!(instr2.len(), 5);
633	///
634	/// let instr3 = decoder.decode();
635	/// assert_eq!(instr3.code(), Code::EVEX_Vmovdqu64_zmm_k1z_zmmm512);
636	/// assert_eq!(instr3.mnemonic(), Mnemonic::Vmovdqu64);
637	/// assert_eq!(instr3.len(), 6);
638	/// ```
639	///
640	/// It's sometimes useful to decode some invalid instructions, eg. `lock add esi,ecx`.
641	/// Pass in [`DecoderOptions::NO_INVALID_CHECK`] to the constructor and the decoder
642	/// will decode some invalid encodings.
643	///
644	/// [`DecoderOptions::NO_INVALID_CHECK`]: struct.DecoderOptions.html#associatedconstant.NO_INVALID_CHECK
645	///
646	/// ```
647	/// use iced_x86::*;
648	///
649	/// // lock add esi,ecx   ; lock not allowed
650	/// let bytes = b"\xF0\x01\xCE";
651	/// let mut decoder = Decoder::new(64, bytes, DecoderOptions::NONE);
652	/// decoder.set_ip(0x1234_5678);
653	/// let instr = decoder.decode();
654	/// assert_eq!(instr.code(), Code::INVALID);
655	///
656	/// // We want to decode some instructions with invalid encodings
657	/// let mut decoder = Decoder::new(64, bytes, DecoderOptions::NO_INVALID_CHECK);
658	/// decoder.set_ip(0x1234_5678);
659	/// let instr = decoder.decode();
660	/// assert_eq!(instr.code(), Code::Add_rm32_r32);
661	/// assert!(instr.has_lock_prefix());
662	/// ```
663	#[must_use]
664	#[inline]
665	#[allow(clippy::unwrap_used)]
666	pub fn new(bitness: u32, data: &'a [u8], options: u32) -> Decoder<'a> {
667		Decoder::try_new(bitness, data, options).unwrap()
668	}
669
670	/// Creates a decoder
671	///
672	/// # Panics
673	///
674	/// Panics if `bitness` is not one of 16, 32, 64.
675	///
676	/// # Arguments
677	///
678	/// * `bitness`: 16, 32 or 64
679	/// * `data`: Data to decode
680	/// * `ip`: `RIP` value
681	/// * `options`: Decoder options, `0` or eg. `DecoderOptions::NO_INVALID_CHECK | DecoderOptions::AMD`
682	///
683	/// # Examples
684	///
685	/// ```
686	/// use iced_x86::*;
687	///
688	/// // xchg ah,[rdx+rsi+16h]
689	/// // xacquire lock add dword ptr [rax],5Ah
690	/// // vmovdqu64 zmm18{k3}{z},zmm11
691	/// let bytes = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3";
692	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
693	///
694	/// let instr1 = decoder.decode();
695	/// assert_eq!(instr1.code(), Code::Xchg_rm8_r8);
696	/// assert_eq!(instr1.mnemonic(), Mnemonic::Xchg);
697	/// assert_eq!(instr1.len(), 4);
698	///
699	/// let instr2 = decoder.decode();
700	/// assert_eq!(instr2.code(), Code::Add_rm32_imm8);
701	/// assert_eq!(instr2.mnemonic(), Mnemonic::Add);
702	/// assert_eq!(instr2.len(), 5);
703	///
704	/// let instr3 = decoder.decode();
705	/// assert_eq!(instr3.code(), Code::EVEX_Vmovdqu64_zmm_k1z_zmmm512);
706	/// assert_eq!(instr3.mnemonic(), Mnemonic::Vmovdqu64);
707	/// assert_eq!(instr3.len(), 6);
708	/// ```
709	///
710	/// It's sometimes useful to decode some invalid instructions, eg. `lock add esi,ecx`.
711	/// Pass in [`DecoderOptions::NO_INVALID_CHECK`] to the constructor and the decoder
712	/// will decode some invalid encodings.
713	///
714	/// [`DecoderOptions::NO_INVALID_CHECK`]: struct.DecoderOptions.html#associatedconstant.NO_INVALID_CHECK
715	///
716	/// ```
717	/// use iced_x86::*;
718	///
719	/// // lock add esi,ecx   ; lock not allowed
720	/// let bytes = b"\xF0\x01\xCE";
721	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
722	/// let instr = decoder.decode();
723	/// assert_eq!(instr.code(), Code::INVALID);
724	///
725	/// // We want to decode some instructions with invalid encodings
726	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NO_INVALID_CHECK);
727	/// let instr = decoder.decode();
728	/// assert_eq!(instr.code(), Code::Add_rm32_r32);
729	/// assert!(instr.has_lock_prefix());
730	/// ```
731	#[must_use]
732	#[inline]
733	#[allow(clippy::unwrap_used)]
734	pub fn with_ip(bitness: u32, data: &'a [u8], ip: u64, options: u32) -> Decoder<'a> {
735		Decoder::try_with_ip(bitness, data, ip, options).unwrap()
736	}
737
738	/// Creates a decoder
739	///
740	/// # Errors
741	///
742	/// Fails if `bitness` is not one of 16, 32, 64.
743	///
744	/// # Arguments
745	///
746	/// * `bitness`: 16, 32 or 64
747	/// * `data`: Data to decode
748	/// * `options`: Decoder options, `0` or eg. `DecoderOptions::NO_INVALID_CHECK | DecoderOptions::AMD`
749	///
750	/// # Examples
751	///
752	/// ```
753	/// use iced_x86::*;
754	///
755	/// // xchg ah,[rdx+rsi+16h]
756	/// // xacquire lock add dword ptr [rax],5Ah
757	/// // vmovdqu64 zmm18{k3}{z},zmm11
758	/// let bytes = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3";
759	/// let mut decoder = Decoder::try_new(64, bytes, DecoderOptions::NONE).unwrap();
760	/// decoder.set_ip(0x1234_5678);
761	///
762	/// let instr1 = decoder.decode();
763	/// assert_eq!(instr1.code(), Code::Xchg_rm8_r8);
764	/// assert_eq!(instr1.mnemonic(), Mnemonic::Xchg);
765	/// assert_eq!(instr1.len(), 4);
766	///
767	/// let instr2 = decoder.decode();
768	/// assert_eq!(instr2.code(), Code::Add_rm32_imm8);
769	/// assert_eq!(instr2.mnemonic(), Mnemonic::Add);
770	/// assert_eq!(instr2.len(), 5);
771	///
772	/// let instr3 = decoder.decode();
773	/// assert_eq!(instr3.code(), Code::EVEX_Vmovdqu64_zmm_k1z_zmmm512);
774	/// assert_eq!(instr3.mnemonic(), Mnemonic::Vmovdqu64);
775	/// assert_eq!(instr3.len(), 6);
776	/// ```
777	///
778	/// It's sometimes useful to decode some invalid instructions, eg. `lock add esi,ecx`.
779	/// Pass in [`DecoderOptions::NO_INVALID_CHECK`] to the constructor and the decoder
780	/// will decode some invalid encodings.
781	///
782	/// [`DecoderOptions::NO_INVALID_CHECK`]: struct.DecoderOptions.html#associatedconstant.NO_INVALID_CHECK
783	///
784	/// ```
785	/// use iced_x86::*;
786	///
787	/// // lock add esi,ecx   ; lock not allowed
788	/// let bytes = b"\xF0\x01\xCE";
789	/// let mut decoder = Decoder::try_new(64, bytes, DecoderOptions::NONE).unwrap();
790	/// decoder.set_ip(0x1234_5678);
791	/// let instr = decoder.decode();
792	/// assert_eq!(instr.code(), Code::INVALID);
793	///
794	/// // We want to decode some instructions with invalid encodings
795	/// let mut decoder = Decoder::try_new(64, bytes, DecoderOptions::NO_INVALID_CHECK).unwrap();
796	/// decoder.set_ip(0x1234_5678);
797	/// let instr = decoder.decode();
798	/// assert_eq!(instr.code(), Code::Add_rm32_r32);
799	/// assert!(instr.has_lock_prefix());
800	/// ```
801	#[inline]
802	pub fn try_new(bitness: u32, data: &'a [u8], options: u32) -> Result<Decoder<'a>, IcedError> {
803		Decoder::try_with_ip(bitness, data, 0, options)
804	}
805
806	/// Creates a decoder
807	///
808	/// # Errors
809	///
810	/// Fails if `bitness` is not one of 16, 32, 64.
811	///
812	/// # Arguments
813	///
814	/// * `bitness`: 16, 32 or 64
815	/// * `data`: Data to decode
816	/// * `ip`: `RIP` value
817	/// * `options`: Decoder options, `0` or eg. `DecoderOptions::NO_INVALID_CHECK | DecoderOptions::AMD`
818	///
819	/// # Examples
820	///
821	/// ```
822	/// use iced_x86::*;
823	///
824	/// // xchg ah,[rdx+rsi+16h]
825	/// // xacquire lock add dword ptr [rax],5Ah
826	/// // vmovdqu64 zmm18{k3}{z},zmm11
827	/// let bytes = b"\x86\x64\x32\x16\xF0\xF2\x83\x00\x5A\x62\xC1\xFE\xCB\x6F\xD3";
828	/// let mut decoder = Decoder::try_with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE).unwrap();
829	///
830	/// let instr1 = decoder.decode();
831	/// assert_eq!(instr1.code(), Code::Xchg_rm8_r8);
832	/// assert_eq!(instr1.mnemonic(), Mnemonic::Xchg);
833	/// assert_eq!(instr1.len(), 4);
834	///
835	/// let instr2 = decoder.decode();
836	/// assert_eq!(instr2.code(), Code::Add_rm32_imm8);
837	/// assert_eq!(instr2.mnemonic(), Mnemonic::Add);
838	/// assert_eq!(instr2.len(), 5);
839	///
840	/// let instr3 = decoder.decode();
841	/// assert_eq!(instr3.code(), Code::EVEX_Vmovdqu64_zmm_k1z_zmmm512);
842	/// assert_eq!(instr3.mnemonic(), Mnemonic::Vmovdqu64);
843	/// assert_eq!(instr3.len(), 6);
844	/// ```
845	///
846	/// It's sometimes useful to decode some invalid instructions, eg. `lock add esi,ecx`.
847	/// Pass in [`DecoderOptions::NO_INVALID_CHECK`] to the constructor and the decoder
848	/// will decode some invalid encodings.
849	///
850	/// [`DecoderOptions::NO_INVALID_CHECK`]: struct.DecoderOptions.html#associatedconstant.NO_INVALID_CHECK
851	///
852	/// ```
853	/// use iced_x86::*;
854	///
855	/// // lock add esi,ecx   ; lock not allowed
856	/// let bytes = b"\xF0\x01\xCE";
857	/// let mut decoder = Decoder::try_with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE).unwrap();
858	/// let instr = decoder.decode();
859	/// assert_eq!(instr.code(), Code::INVALID);
860	///
861	/// // We want to decode some instructions with invalid encodings
862	/// let mut decoder = Decoder::try_with_ip(64, bytes, 0x1234_5678, DecoderOptions::NO_INVALID_CHECK).unwrap();
863	/// let instr = decoder.decode();
864	/// assert_eq!(instr.code(), Code::Add_rm32_r32);
865	/// assert!(instr.has_lock_prefix());
866	/// ```
867	#[allow(clippy::missing_inline_in_public_items)]
868	#[allow(clippy::let_unit_value)]
869	#[allow(trivial_casts)]
870	pub fn try_with_ip(bitness: u32, data: &'a [u8], ip: u64, options: u32) -> Result<Decoder<'a>, IcedError> {
871		let is64b_mode;
872		let default_code_size;
873		let default_operand_size;
874		let default_inverted_operand_size;
875		let default_address_size;
876		let default_inverted_address_size;
877		match bitness {
878			64 => {
879				is64b_mode = true;
880				default_code_size = CodeSize::Code64;
881				default_operand_size = OpSize::Size32;
882				default_inverted_operand_size = OpSize::Size16;
883				default_address_size = OpSize::Size64;
884				default_inverted_address_size = OpSize::Size32;
885			}
886			32 => {
887				is64b_mode = false;
888				default_code_size = CodeSize::Code32;
889				default_operand_size = OpSize::Size32;
890				default_inverted_operand_size = OpSize::Size16;
891				default_address_size = OpSize::Size32;
892				default_inverted_address_size = OpSize::Size16;
893			}
894			16 => {
895				is64b_mode = false;
896				default_code_size = CodeSize::Code16;
897				default_operand_size = OpSize::Size16;
898				default_inverted_operand_size = OpSize::Size32;
899				default_address_size = OpSize::Size16;
900				default_inverted_address_size = OpSize::Size32;
901			}
902			_ => return Err(IcedError::new("Invalid bitness")),
903		}
904		let data_ptr_end = data.as_ptr() as usize + data.len();
905		if data_ptr_end < data.as_ptr() as usize || {
906			// Verify that max_data_ptr can never overflow and that data_ptr.add(N) can't overflow.
907			// Both of them can equal data_ptr_end (1 byte past the last valid byte).
908			// When reading a u8/u16/u32..., we calculate data_ptr.add({1,2,4,...MAX_READ_SIZE}) so it must not overflow.
909			// In decode(), we calculate data_ptr.add(MAX_INSTRUCTION_LENGTH) so it must not overflow.
910			data_ptr_end.wrapping_add(cmp::max(IcedConstants::MAX_INSTRUCTION_LENGTH, Decoder::MAX_READ_SIZE)) < data.as_ptr() as usize
911		} {
912			return Err(IcedError::new("Invalid slice"));
913		}
914
915		let tables = &*TABLES;
916
917		#[allow(clippy::unwrap_used)]
918		fn get_handlers(
919			handlers: &'static [(OpCodeHandlerDecodeFn, &'static OpCodeHandler)],
920		) -> &'static [(OpCodeHandlerDecodeFn, &'static OpCodeHandler); 0x100] {
921			debug_assert_eq!(handlers.len(), 0x100);
922			TryFrom::try_from(handlers).unwrap()
923		}
924		macro_rules! mk_handlers_local {
925			($name:ident, $feature:literal) => {
926				mk_handlers_local!($name, $name, $feature);
927			};
928			($name:ident, $field_name:ident, $feature:literal) => {
929				#[cfg(not(feature = $feature))]
930				let $name = get_handlers(&tables.$field_name);
931				#[cfg(feature = $feature)]
932				let $name = ();
933			};
934			($name:ident ; $feature:literal) => {
935				mk_handlers_local!($name, $name ; $feature);
936			};
937			($name:ident, $field_name:ident ; $feature:literal) => {
938				#[cfg(feature = $feature)]
939				let $name = get_handlers(&tables.$field_name);
940				#[cfg(not(feature = $feature))]
941				let $name = ();
942			};
943		}
944		#[cfg(all(not(feature = "no_vex"), feature = "mvex"))]
945		let handlers_vex_map0 = get_handlers(&tables.handlers_vex_map0);
946		#[cfg(not(all(not(feature = "no_vex"), feature = "mvex")))]
947		let handlers_vex_map0 = ();
948		mk_handlers_local!(handlers_vex_0f, "no_vex");
949		mk_handlers_local!(handlers_vex_0f38, "no_vex");
950		mk_handlers_local!(handlers_vex_0f3a, "no_vex");
951		mk_handlers_local!(handlers_evex_0f, "no_evex");
952		mk_handlers_local!(handlers_evex_0f38, "no_evex");
953		mk_handlers_local!(handlers_evex_0f3a, "no_evex");
954		mk_handlers_local!(handlers_evex_map4, invalid_map, "no_evex");
955		mk_handlers_local!(handlers_evex_map5, "no_evex");
956		mk_handlers_local!(handlers_evex_map6, "no_evex");
957		mk_handlers_local!(handlers_xop_map8, "no_xop");
958		mk_handlers_local!(handlers_xop_map9, "no_xop");
959		mk_handlers_local!(handlers_xop_map10, "no_xop");
960		mk_handlers_local!(handlers_mvex_0f ; "mvex");
961		mk_handlers_local!(handlers_mvex_0f38 ; "mvex");
962		mk_handlers_local!(handlers_mvex_0f3a ; "mvex");
963
964		#[rustfmt::skip]
965		#[cfg(not(feature = "__internal_flip"))]
966		let read_op_mem_fns = [
967			Decoder::read_op_mem_0,
968			Decoder::read_op_mem_0,
969			Decoder::read_op_mem_0,
970			Decoder::read_op_mem_0,
971			Decoder::read_op_mem_0_4,
972			Decoder::read_op_mem_0_5,
973			Decoder::read_op_mem_0,
974			Decoder::read_op_mem_0,
975
976			Decoder::read_op_mem_1,
977			Decoder::read_op_mem_1,
978			Decoder::read_op_mem_1,
979			Decoder::read_op_mem_1,
980			Decoder::read_op_mem_1_4,
981			Decoder::read_op_mem_1,
982			Decoder::read_op_mem_1,
983			Decoder::read_op_mem_1,
984
985			Decoder::read_op_mem_2,
986			Decoder::read_op_mem_2,
987			Decoder::read_op_mem_2,
988			Decoder::read_op_mem_2,
989			Decoder::read_op_mem_2_4,
990			Decoder::read_op_mem_2,
991			Decoder::read_op_mem_2,
992			Decoder::read_op_mem_2,
993		];
994		#[cfg(feature = "__internal_flip")]
995		let read_op_mem_fns = ();
996
997		Ok(Decoder {
998			ip,
999			data_ptr: data.as_ptr() as usize,
1000			data_ptr_end,
1001			max_data_ptr: data.as_ptr() as usize,
1002			instr_start_data_ptr: data.as_ptr() as usize,
1003			handlers_map0: get_handlers(&tables.handlers_map0),
1004			handlers_vex_map0,
1005			handlers_vex: [handlers_vex_0f, handlers_vex_0f38, handlers_vex_0f3a],
1006			handlers_evex: [handlers_evex_0f, handlers_evex_0f38, handlers_evex_0f3a, handlers_evex_map4, handlers_evex_map5, handlers_evex_map6],
1007			handlers_xop: [handlers_xop_map8, handlers_xop_map9, handlers_xop_map10],
1008			handlers_mvex: [handlers_mvex_0f, handlers_mvex_0f38, handlers_mvex_0f3a],
1009			read_op_mem_fns,
1010			state: State::default(),
1011			options,
1012			invalid_check_mask: if (options & DecoderOptions::NO_INVALID_CHECK) == 0 { u32::MAX } else { 0 },
1013			is64b_mode_and_w: if is64b_mode { StateFlags::W } else { 0 },
1014			reg15_mask: if is64b_mode { 0xF } else { 0x7 },
1015			mask_e0: if is64b_mode { 0xE0 } else { 0 },
1016			rex_mask: if is64b_mode { 0xF0 } else { 0 },
1017			bitness,
1018			default_address_size,
1019			default_operand_size,
1020			segment_prio: 0,
1021			dummy: 0,
1022			default_inverted_address_size,
1023			default_inverted_operand_size,
1024			is64b_mode,
1025			default_code_size,
1026			displ_index: 0,
1027			data,
1028		})
1029	}
1030
1031	/// Gets the current `IP`/`EIP`/`RIP` value, see also [`position()`]
1032	///
1033	/// [`position()`]: #method.position
1034	#[must_use]
1035	#[inline]
1036	pub const fn ip(&self) -> u64 {
1037		self.ip
1038	}
1039
1040	/// Sets the current `IP`/`EIP`/`RIP` value, see also [`try_set_position()`]
1041	///
1042	/// This method only updates the IP value, it does not change the data position, use [`try_set_position()`] to change the position.
1043	///
1044	/// [`try_set_position()`]: #method.try_set_position
1045	///
1046	/// # Arguments
1047	///
1048	/// * `new_value`: New IP
1049	#[inline]
1050	pub fn set_ip(&mut self, new_value: u64) {
1051		self.ip = new_value;
1052	}
1053
1054	/// Gets the bitness (16, 32 or 64)
1055	#[must_use]
1056	#[inline]
1057	pub const fn bitness(&self) -> u32 {
1058		self.bitness
1059	}
1060
1061	/// Gets the max value that can be passed to [`try_set_position()`]. This is the size of the data that gets
1062	/// decoded to instructions and it's the length of the slice that was passed to the constructor.
1063	///
1064	/// [`try_set_position()`]: #method.try_set_position
1065	#[must_use]
1066	#[inline]
1067	pub const fn max_position(&self) -> usize {
1068		self.data.len()
1069	}
1070
1071	/// Gets the current data position. This value is always <= [`max_position()`].
1072	/// When [`position()`] == [`max_position()`], it's not possible to decode more
1073	/// instructions and [`can_decode()`] returns `false`.
1074	///
1075	/// [`max_position()`]: #method.max_position
1076	/// [`position()`]: #method.position
1077	/// [`can_decode()`]: #method.can_decode
1078	#[must_use]
1079	#[inline]
1080	pub fn position(&self) -> usize {
1081		self.data_ptr - self.data.as_ptr() as usize
1082	}
1083
1084	/// Sets the current data position, which is the index into the data passed to the constructor.
1085	/// This value is always <= [`max_position()`]
1086	///
1087	/// [`max_position()`]: #method.max_position
1088	///
1089	/// # Errors
1090	///
1091	/// Fails if the new position is invalid.
1092	///
1093	/// # Arguments
1094	///
1095	/// * `new_pos`: New position and must be <= [`max_position()`]
1096	///
1097	/// # Examples
1098	///
1099	/// ```
1100	/// use iced_x86::*;
1101	///
1102	/// // nop and pause
1103	/// let bytes = b"\x90\xF3\x90";
1104	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
1105	///
1106	/// assert_eq!(decoder.position(), 0);
1107	/// assert_eq!(decoder.max_position(), 3);
1108	/// let instr = decoder.decode();
1109	/// assert_eq!(decoder.position(), 1);
1110	/// assert_eq!(instr.code(), Code::Nopd);
1111	///
1112	/// let instr = decoder.decode();
1113	/// assert_eq!(decoder.position(), 3);
1114	/// assert_eq!(instr.code(), Code::Pause);
1115	///
1116	/// // Start all over again
1117	/// decoder.set_position(0).unwrap();
1118	/// decoder.set_ip(0x1234_5678);
1119	/// assert_eq!(decoder.position(), 0);
1120	/// assert_eq!(decoder.decode().code(), Code::Nopd);
1121	/// assert_eq!(decoder.decode().code(), Code::Pause);
1122	/// assert_eq!(decoder.position(), 3);
1123	/// ```
1124	#[inline]
1125	#[allow(clippy::missing_inline_in_public_items)]
1126	pub fn set_position(&mut self, new_pos: usize) -> Result<(), IcedError> {
1127		if new_pos > self.data.len() {
1128			Err(IcedError::new("Invalid position"))
1129		} else {
1130			// - We verified the new offset above.
1131			// - Referencing 1 byte past the last valid byte is safe as long as we don't dereference it.
1132			self.data_ptr = self.data.as_ptr() as usize + new_pos;
1133			Ok(())
1134		}
1135	}
1136
1137	#[doc(hidden)]
1138	#[inline]
1139	pub fn try_set_position(&mut self, new_pos: usize) -> Result<(), IcedError> {
1140		self.set_position(new_pos)
1141	}
1142
1143	/// Returns `true` if there's at least one more byte to decode. It doesn't verify that the
1144	/// next instruction is valid, it only checks if there's at least one more byte to read.
1145	/// See also [`position()`] and [`max_position()`]
1146	///
1147	/// It's not required to call this method. If this method returns `false`, then [`decode_out()`]
1148	/// and [`decode()`] will return an instruction whose [`code()`] == [`Code::INVALID`].
1149	///
1150	/// [`position()`]: #method.position
1151	/// [`max_position()`]: #method.max_position
1152	/// [`decode_out()`]: #method.decode_out
1153	/// [`decode()`]: #method.decode
1154	/// [`code()`]: struct.Instruction.html#method.code
1155	/// [`Code::INVALID`]: enum.Code.html#variant.INVALID
1156	///
1157	/// # Examples
1158	///
1159	/// ```
1160	/// use iced_x86::*;
1161	///
1162	/// // nop and an incomplete instruction
1163	/// let bytes = b"\x90\xF3\x0F";
1164	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
1165	///
1166	/// // 3 bytes left to read
1167	/// assert!(decoder.can_decode());
1168	/// let instr = decoder.decode();
1169	/// assert_eq!(instr.code(), Code::Nopd);
1170	///
1171	/// // 2 bytes left to read
1172	/// assert!(decoder.can_decode());
1173	/// let instr = decoder.decode();
1174	/// // Not enough bytes left to decode a full instruction
1175	/// assert_eq!(instr.code(), Code::INVALID);
1176	///
1177	/// // 0 bytes left to read
1178	/// assert!(!decoder.can_decode());
1179	/// ```
1180	#[must_use]
1181	#[inline]
1182	#[allow(clippy::missing_const_for_fn)]
1183	pub fn can_decode(&self) -> bool {
1184		self.data_ptr != self.data_ptr_end
1185	}
1186
1187	/// Returns an iterator that borrows this instance to decode instructions until there's
1188	/// no more data to decode, i.e., until [`can_decode()`] returns `false`.
1189	///
1190	/// [`can_decode()`]: #method.can_decode
1191	///
1192	/// # Examples
1193	///
1194	/// ```
1195	/// use iced_x86::*;
1196	///
1197	/// // nop and pause
1198	/// let bytes = b"\x90\xF3\x90";
1199	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
1200	///
1201	/// let mut iter = decoder.iter();
1202	/// assert_eq!(iter.next().unwrap().code(), Code::Nopd);
1203	/// assert_eq!(iter.next().unwrap().code(), Code::Pause);
1204	/// assert!(iter.next().is_none());
1205	/// ```
1206	///
1207	/// `for` loop:
1208	///
1209	/// ```
1210	/// use iced_x86::*;
1211	///
1212	/// let bytes = b"\x90\xF3\x90";
1213	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
1214	///
1215	/// for instr in &mut decoder { // or decoder.iter()
1216	///     println!("code: {:?}", instr.code());
1217	/// }
1218	/// ```
1219	#[inline]
1220	pub fn iter<'b>(&'b mut self) -> DecoderIter<'a, 'b> {
1221		DecoderIter { decoder: self }
1222	}
1223
1224	#[must_use]
1225	#[inline(always)]
1226	fn read_u8(&mut self) -> usize {
1227		mk_read_xx_fn_body! {self, u8, u8::from_le, usize}
1228	}
1229
1230	#[must_use]
1231	#[inline(always)]
1232	fn read_u16(&mut self) -> usize {
1233		mk_read_xx_fn_body! {self, u16, u16::from_le, usize}
1234	}
1235
1236	#[must_use]
1237	#[inline(always)]
1238	fn read_u32(&mut self) -> usize {
1239		mk_read_xx_fn_body! {self, u32, u32::from_le, usize}
1240	}
1241
1242	#[must_use]
1243	#[inline(always)]
1244	fn read_u64(&mut self) -> u64 {
1245		mk_read_xx_fn_body! {self, u64, u64::from_le, u64}
1246	}
1247
1248	/// Gets the last decoder error. Unless you need to know the reason it failed,
1249	/// it's better to check [`instruction.is_invalid()`].
1250	///
1251	/// [`instruction.is_invalid()`]: struct.Instruction.html#method.is_invalid
1252	#[must_use]
1253	#[inline]
1254	pub const fn last_error(&self) -> DecoderError {
1255		// NoMoreBytes error has highest priority
1256		if (self.state.flags & StateFlags::NO_MORE_BYTES) != 0 {
1257			DecoderError::NoMoreBytes
1258		} else if (self.state.flags & StateFlags::IS_INVALID) != 0 {
1259			DecoderError::InvalidInstruction
1260		} else {
1261			DecoderError::None
1262		}
1263	}
1264
1265	/// Decodes and returns the next instruction, see also [`decode_out(&mut Instruction)`]
1266	/// which avoids copying the decoded instruction to the caller's return variable.
1267	/// See also [`last_error()`].
1268	///
1269	/// [`decode_out(&mut Instruction)`]: #method.decode_out
1270	/// [`last_error()`]: #method.last_error
1271	///
1272	/// # Examples
1273	///
1274	/// ```
1275	/// use iced_x86::*;
1276	///
1277	/// // xrelease lock add [rax],ebx
1278	/// let bytes = b"\xF0\xF3\x01\x18";
1279	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
1280	/// let instr = decoder.decode();
1281	///
1282	/// assert_eq!(instr.code(), Code::Add_rm32_r32);
1283	/// assert_eq!(instr.mnemonic(), Mnemonic::Add);
1284	/// assert_eq!(instr.len(), 4);
1285	/// assert_eq!(instr.op_count(), 2);
1286	///
1287	/// assert_eq!(instr.op0_kind(), OpKind::Memory);
1288	/// assert_eq!(instr.memory_base(), Register::RAX);
1289	/// assert_eq!(instr.memory_index(), Register::None);
1290	/// assert_eq!(instr.memory_index_scale(), 1);
1291	/// assert_eq!(instr.memory_displacement64(), 0);
1292	/// assert_eq!(instr.memory_segment(), Register::DS);
1293	/// assert_eq!(instr.segment_prefix(), Register::None);
1294	/// assert_eq!(instr.memory_size(), MemorySize::UInt32);
1295	///
1296	/// assert_eq!(instr.op1_kind(), OpKind::Register);
1297	/// assert_eq!(instr.op1_register(), Register::EBX);
1298	///
1299	/// assert!(instr.has_lock_prefix());
1300	/// assert!(instr.has_xrelease_prefix());
1301	/// ```
1302	#[must_use]
1303	#[inline]
1304	pub fn decode(&mut self) -> Instruction {
1305		let mut instruction = mem::MaybeUninit::uninit();
1306		// SAFETY: decode_out_ptr() initializes the whole instruction (all fields) with valid values
1307		unsafe {
1308			self.decode_out_ptr(instruction.as_mut_ptr());
1309			instruction.assume_init()
1310		}
1311	}
1312
1313	/// Decodes the next instruction. The difference between this method and [`decode()`] is that this
1314	/// method doesn't need to copy the result to the caller's return variable (saves 40 bytes of copying).
1315	/// See also [`last_error()`].
1316	///
1317	/// [`decode()`]: #method.decode
1318	/// [`last_error()`]: #method.last_error
1319	///
1320	/// # Arguments
1321	///
1322	/// * `instruction`: Updated with the decoded instruction. All fields are initialized (it's an `out` argument)
1323	///
1324	/// # Examples
1325	///
1326	/// ```
1327	/// use iced_x86::*;
1328	///
1329	/// // xrelease lock add [rax],ebx
1330	/// let bytes = b"\xF0\xF3\x01\x18";
1331	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
1332	/// let mut instr = Instruction::default();
1333	/// decoder.decode_out(&mut instr);
1334	///
1335	/// assert_eq!(instr.code(), Code::Add_rm32_r32);
1336	/// assert_eq!(instr.mnemonic(), Mnemonic::Add);
1337	/// assert_eq!(instr.len(), 4);
1338	/// assert_eq!(instr.op_count(), 2);
1339	///
1340	/// assert_eq!(instr.op0_kind(), OpKind::Memory);
1341	/// assert_eq!(instr.memory_base(), Register::RAX);
1342	/// assert_eq!(instr.memory_index(), Register::None);
1343	/// assert_eq!(instr.memory_index_scale(), 1);
1344	/// assert_eq!(instr.memory_displacement64(), 0);
1345	/// assert_eq!(instr.memory_segment(), Register::DS);
1346	/// assert_eq!(instr.segment_prefix(), Register::None);
1347	/// assert_eq!(instr.memory_size(), MemorySize::UInt32);
1348	///
1349	/// assert_eq!(instr.op1_kind(), OpKind::Register);
1350	/// assert_eq!(instr.op1_register(), Register::EBX);
1351	///
1352	/// assert!(instr.has_lock_prefix());
1353	/// assert!(instr.has_xrelease_prefix());
1354	/// ```
1355	#[inline]
1356	pub fn decode_out(&mut self, instruction: &mut Instruction) {
1357		unsafe {
1358			self.decode_out_ptr(instruction);
1359		}
1360	}
1361
1362	// SAFETY: `instruction` must be non-null, writable and aligned (`ptr::write()`) and not aliased
1363	#[allow(clippy::useless_let_if_seq)]
1364	unsafe fn decode_out_ptr(&mut self, instruction: *mut Instruction) {
1365		// SAFETY:
1366		// - the instruction has only primitive integer types, nothing needs to be dropped
1367		// - private method: no caller passes in a null ptr, a non-writable ptr or an unaligned ptr
1368		unsafe { ptr::write(instruction, Instruction::default()) };
1369		// SAFETY: private method: the only callers pass in their `&mut arg` or their own stack-allocated `MaybeUninit` instruction
1370		let instruction = unsafe { &mut *instruction };
1371
1372		self.state.extra_register_base = 0;
1373		self.state.extra_index_register_base = 0;
1374		self.state.extra_base_register_base = 0;
1375		self.state.extra_index_register_base_vsib = 0;
1376		self.state.flags = 0;
1377		self.state.mandatory_prefix = DecoderMandatoryPrefix::default();
1378		// These don't need to be cleared, but they're here so the compiler can re-use the
1379		// same XMM reg to clear the previous 2 u32s (including these 2 u32s).
1380		self.state.vvvv = 0;
1381		self.state.vvvv_invalid_check = 0;
1382
1383		// We only need to write addr/op size fields and init segment_prio to 0.
1384		// The fields are consecutive so the compiler can read all 4 fields (including dummy)
1385		// and write all 4 fields at the same time.
1386		self.state.address_size = self.default_address_size;
1387		self.state.operand_size = self.default_operand_size;
1388		self.state.segment_prio = self.segment_prio;
1389		self.state.dummy = self.dummy;
1390
1391		let data_ptr = self.data_ptr;
1392		self.instr_start_data_ptr = data_ptr;
1393		// The ctor has verified that the two expressions used in min() don't overflow and are >= data_ptr.
1394		// The calculated usize is a valid pointer in `self.data` slice or at most 1 byte past the last valid byte.
1395		self.max_data_ptr = cmp::min(data_ptr + IcedConstants::MAX_INSTRUCTION_LENGTH, self.data_ptr_end);
1396
1397		let b = self.read_u8();
1398		let mut handler = self.handlers_map0[b];
1399		if ((b as u32) & self.rex_mask) == 0x40 {
1400			debug_assert!(self.is64b_mode);
1401			handler = self.handlers_map0[self.read_u8()];
1402			let mut flags = self.state.flags | StateFlags::HAS_REX;
1403			if (b & 8) != 0 {
1404				flags |= StateFlags::W;
1405				self.state.operand_size = OpSize::Size64;
1406			}
1407			self.state.flags = flags;
1408			self.state.extra_register_base = (b as u32 & 4) << 1;
1409			self.state.extra_index_register_base = (b as u32 & 2) << 2;
1410			self.state.extra_base_register_base = (b as u32 & 1) << 3;
1411		}
1412		self.decode_table2(handler, instruction);
1413
1414		debug_assert_eq!(data_ptr, self.instr_start_data_ptr);
1415		let instr_len = (self.data_ptr as u32).wrapping_sub(data_ptr as u32);
1416		debug_assert!(instr_len <= IcedConstants::MAX_INSTRUCTION_LENGTH as u32); // Could be 0 if there were no bytes available
1417		instruction_internal::internal_set_len(instruction, instr_len);
1418		let orig_ip = self.ip;
1419		let ip = orig_ip.wrapping_add(instr_len as u64);
1420		self.ip = ip;
1421		instruction.set_next_ip(ip);
1422		instruction_internal::internal_set_code_size(instruction, self.default_code_size);
1423
1424		let mut flags = self.state.flags;
1425		if (flags & (StateFlags::IS_INVALID | StateFlags::LOCK | StateFlags::IP_REL64 | StateFlags::IP_REL32)) != 0 {
1426			let addr = ip.wrapping_add(instruction.memory_displacement64());
1427			// Assume it's IP_REL64 (very common if we're here). We'll undo this if it's not.
1428			instruction.set_memory_displacement64(addr);
1429			// RIP rel ops are common, but invalid/lock bits are usually never set, so exit early if possible
1430			if (flags & (StateFlags::IP_REL64 | StateFlags::IS_INVALID | StateFlags::LOCK)) == StateFlags::IP_REL64 {
1431				return;
1432			}
1433			if (flags & StateFlags::IP_REL64) == 0 {
1434				// Undo what we did above
1435				instruction.set_memory_displacement64(addr.wrapping_sub(ip));
1436			}
1437			if (flags & StateFlags::IP_REL32) != 0 {
1438				let addr = ip.wrapping_add(instruction.memory_displacement64());
1439				instruction.set_memory_displacement64(addr as u32 as u64);
1440			}
1441
1442			if (flags & StateFlags::IS_INVALID) != 0
1443				|| (((flags & (StateFlags::LOCK | StateFlags::ALLOW_LOCK)) & self.invalid_check_mask) == StateFlags::LOCK)
1444			{
1445				*instruction = Instruction::default();
1446				const _: () = assert!(Code::INVALID as u32 == 0);
1447				//instruction.set_code(Code::INVALID);
1448
1449				if (flags & StateFlags::NO_MORE_BYTES) != 0 {
1450					debug_assert_eq!(data_ptr, self.instr_start_data_ptr);
1451					let max_len = self.data_ptr_end - data_ptr;
1452					// If max-instr-len bytes is available, it's never no-more-bytes, and always invalid-instr
1453					if max_len >= IcedConstants::MAX_INSTRUCTION_LENGTH {
1454						flags &= !StateFlags::NO_MORE_BYTES;
1455					}
1456					// max_data_ptr is in self.data slice or at most 1 byte past the last valid byte
1457					self.data_ptr = self.max_data_ptr;
1458				}
1459
1460				self.state.flags = flags | StateFlags::IS_INVALID;
1461
1462				let instr_len = (self.data_ptr as u32).wrapping_sub(data_ptr as u32);
1463				instruction_internal::internal_set_len(instruction, instr_len);
1464				let ip = orig_ip.wrapping_add(instr_len as u64);
1465				self.ip = ip;
1466				instruction.set_next_ip(ip);
1467				instruction_internal::internal_set_code_size(instruction, self.default_code_size);
1468			}
1469		}
1470	}
1471
1472	#[inline(always)]
1473	fn reset_rex_prefix_state(&mut self) {
1474		self.state.flags &= !(StateFlags::HAS_REX | StateFlags::W);
1475		if (self.state.flags & StateFlags::HAS66) == 0 {
1476			self.state.operand_size = self.default_operand_size;
1477		} else {
1478			self.state.operand_size = self.default_inverted_operand_size;
1479		}
1480		self.state.extra_register_base = 0;
1481		self.state.extra_index_register_base = 0;
1482		self.state.extra_base_register_base = 0;
1483	}
1484
1485	#[inline(always)]
1486	fn call_opcode_handlers_map0_table(&mut self, instruction: &mut Instruction) {
1487		let b = self.read_u8();
1488		self.decode_table2(self.handlers_map0[b], instruction);
1489	}
1490
1491	#[must_use]
1492	#[inline]
1493	fn current_ip32(&self) -> u32 {
1494		debug_assert!(self.instr_start_data_ptr <= self.data_ptr);
1495		debug_assert!(self.data_ptr - self.instr_start_data_ptr <= IcedConstants::MAX_INSTRUCTION_LENGTH);
1496		((self.data_ptr - self.instr_start_data_ptr) as u32).wrapping_add(self.ip as u32)
1497	}
1498
1499	#[must_use]
1500	#[inline]
1501	fn current_ip64(&self) -> u64 {
1502		debug_assert!(self.instr_start_data_ptr <= self.data_ptr);
1503		debug_assert!(self.data_ptr - self.instr_start_data_ptr <= IcedConstants::MAX_INSTRUCTION_LENGTH);
1504		((self.data_ptr - self.instr_start_data_ptr) as u64).wrapping_add(self.ip)
1505	}
1506
1507	#[inline]
1508	fn clear_mandatory_prefix(&mut self, instruction: &mut Instruction) {
1509		debug_assert_eq!(self.state.encoding(), EncodingKind::Legacy as u32);
1510		instruction_internal::internal_clear_has_repe_repne_prefix(instruction);
1511	}
1512
1513	#[inline(always)]
1514	fn set_xacquire_xrelease(&mut self, instruction: &mut Instruction, flags: u32) {
1515		if instruction.has_lock_prefix() {
1516			self.set_xacquire_xrelease_core(instruction, flags);
1517		}
1518	}
1519
1520	#[allow(clippy::nonminimal_bool)]
1521	fn set_xacquire_xrelease_core(&mut self, instruction: &mut Instruction, flags: u32) {
1522		debug_assert!(!((flags & HandlerFlags::XACQUIRE_XRELEASE_NO_LOCK) == 0 && !instruction.has_lock_prefix()));
1523		match self.state.mandatory_prefix {
1524			DecoderMandatoryPrefix::PF2 => {
1525				self.clear_mandatory_prefix_f2(instruction);
1526				instruction.set_has_xacquire_prefix(true);
1527			}
1528			DecoderMandatoryPrefix::PF3 => {
1529				self.clear_mandatory_prefix_f3(instruction);
1530				instruction.set_has_xrelease_prefix(true);
1531			}
1532			_ => {}
1533		}
1534	}
1535
1536	#[inline]
1537	fn clear_mandatory_prefix_f3(&self, instruction: &mut Instruction) {
1538		debug_assert_eq!(self.state.encoding(), EncodingKind::Legacy as u32);
1539		debug_assert_eq!(self.state.mandatory_prefix, DecoderMandatoryPrefix::PF3);
1540		instruction.set_has_repe_prefix(false);
1541	}
1542
1543	#[inline]
1544	fn clear_mandatory_prefix_f2(&self, instruction: &mut Instruction) {
1545		debug_assert_eq!(self.state.encoding(), EncodingKind::Legacy as u32);
1546		debug_assert_eq!(self.state.mandatory_prefix, DecoderMandatoryPrefix::PF2);
1547		instruction.set_has_repne_prefix(false);
1548	}
1549
1550	#[inline]
1551	fn set_invalid_instruction(&mut self) {
1552		self.state.flags |= StateFlags::IS_INVALID;
1553	}
1554
1555	#[inline(always)]
1556	fn decode_table2(&mut self, (decode, handler): (OpCodeHandlerDecodeFn, &OpCodeHandler), instruction: &mut Instruction) {
1557		if handler.has_modrm {
1558			let m = self.read_u8() as u32;
1559			self.state.modrm = m;
1560			self.state.reg = (m >> 3) & 7;
1561			self.state.mod_ = m >> 6;
1562			self.state.rm = m & 7;
1563			self.state.mem_index = (self.state.mod_ << 3) | self.state.rm;
1564		}
1565		(decode)(handler, self, instruction);
1566	}
1567
1568	#[inline(always)]
1569	fn read_modrm(&mut self) {
1570		let m = self.read_u8() as u32;
1571		self.state.modrm = m;
1572		self.state.reg = (m >> 3) & 7;
1573		self.state.mod_ = m >> 6;
1574		self.state.rm = m & 7;
1575		self.state.mem_index = (self.state.mod_ << 3) | self.state.rm;
1576	}
1577
1578	#[cfg(feature = "no_vex")]
1579	fn vex2(&mut self, _instruction: &mut Instruction) {
1580		self.set_invalid_instruction();
1581	}
1582
1583	#[cfg(not(feature = "no_vex"))]
1584	fn vex2(&mut self, instruction: &mut Instruction) {
1585		const _: () = assert!(DecoderMandatoryPrefix::PNP as u32 == 0);
1586		if (((self.state.flags & StateFlags::HAS_REX) | (self.state.mandatory_prefix as u32)) & self.invalid_check_mask) != 0 {
1587			self.set_invalid_instruction();
1588		}
1589		// Undo what decode_out() did if it got a REX prefix
1590		self.state.flags &= !StateFlags::W;
1591		self.state.extra_index_register_base = 0;
1592		self.state.extra_base_register_base = 0;
1593
1594		if cfg!(debug_assertions) {
1595			self.state.flags |= (EncodingKind::VEX as u32) << StateFlags::ENCODING_SHIFT;
1596		}
1597
1598		let b = self.read_u8();
1599		let (decode, handler) = self.handlers_vex[0][b];
1600
1601		let mut b = self.state.modrm;
1602
1603		const _: () = assert!(VectorLength::L128 as u32 == 0);
1604		const _: () = assert!(VectorLength::L256 as u32 == 1);
1605		// SAFETY: 0<=(n&1)<=1 and those are valid enum variants, see const assert!() above
1606		self.state.vector_length = unsafe { mem::transmute((b >> 2) & 1) };
1607
1608		const _: () = assert!(DecoderMandatoryPrefix::PNP as u32 == 0);
1609		const _: () = assert!(DecoderMandatoryPrefix::P66 as u32 == 1);
1610		const _: () = assert!(DecoderMandatoryPrefix::PF3 as u32 == 2);
1611		const _: () = assert!(DecoderMandatoryPrefix::PF2 as u32 == 3);
1612		// SAFETY: 0<=(b&3)<=3 and those are valid enum variants, see const assert!() above
1613		self.state.mandatory_prefix = unsafe { mem::transmute(b & 3) };
1614
1615		b = !b;
1616		self.state.extra_register_base = (b >> 4) & 8;
1617
1618		// Bit 6 can only be 0 if it's 16/32-bit mode, so we don't need to change the mask
1619		b = (b >> 3) & 0x0F;
1620		self.state.vvvv = b;
1621		self.state.vvvv_invalid_check = b;
1622
1623		self.decode_table2((decode, handler), instruction);
1624	}
1625
1626	#[cfg(feature = "no_vex")]
1627	fn vex3(&mut self, _instruction: &mut Instruction) {
1628		self.set_invalid_instruction();
1629	}
1630
1631	#[cfg(not(feature = "no_vex"))]
1632	fn vex3(&mut self, instruction: &mut Instruction) {
1633		const _: () = assert!(DecoderMandatoryPrefix::PNP as u32 == 0);
1634		if (((self.state.flags & StateFlags::HAS_REX) | (self.state.mandatory_prefix as u32)) & self.invalid_check_mask) != 0 {
1635			self.set_invalid_instruction();
1636		}
1637		// Undo what decode_out() did if it got a REX prefix
1638		self.state.flags &= !StateFlags::W;
1639
1640		if cfg!(debug_assertions) {
1641			self.state.flags |= (EncodingKind::VEX as u32) << StateFlags::ENCODING_SHIFT;
1642		}
1643
1644		let b2 = self.read_u16() as u32;
1645
1646		const _: () = assert!(StateFlags::W == 0x80);
1647		self.state.flags |= b2 & 0x80;
1648
1649		const _: () = assert!(VectorLength::L128 as u32 == 0);
1650		const _: () = assert!(VectorLength::L256 as u32 == 1);
1651		// SAFETY: 0<=(n&1)<=1 and those are valid enum variants, see const assert!() above
1652		self.state.vector_length = unsafe { mem::transmute((b2 >> 2) & 1) };
1653
1654		const _: () = assert!(DecoderMandatoryPrefix::PNP as u32 == 0);
1655		const _: () = assert!(DecoderMandatoryPrefix::P66 as u32 == 1);
1656		const _: () = assert!(DecoderMandatoryPrefix::PF3 as u32 == 2);
1657		const _: () = assert!(DecoderMandatoryPrefix::PF2 as u32 == 3);
1658		// SAFETY: 0<=(b2&3)<=3 and those are valid enum variants, see const assert!() above
1659		self.state.mandatory_prefix = unsafe { mem::transmute(b2 & 3) };
1660
1661		let b = (!b2 >> 3) & 0x0F;
1662		self.state.vvvv_invalid_check = b;
1663		self.state.vvvv = b & self.reg15_mask;
1664		let b1 = self.state.modrm;
1665		let b1x = !b1 & self.mask_e0;
1666		self.state.extra_register_base = (b1x >> 4) & 8;
1667		self.state.extra_index_register_base = (b1x >> 3) & 8;
1668		self.state.extra_base_register_base = (b1x >> 2) & 8;
1669
1670		if let Some(&table) = self.handlers_vex.get(((b1 & 0x1F) as usize).wrapping_sub(1)) {
1671			self.decode_table2(table[(b2 >> 8) as usize], instruction);
1672		} else {
1673			#[cfg(feature = "mvex")]
1674			if (b1 & 0x1F) == 0 {
1675				self.decode_table2(self.handlers_vex_map0[(b2 >> 8) as usize], instruction);
1676				return;
1677			}
1678			self.set_invalid_instruction();
1679		}
1680	}
1681
1682	#[cfg(feature = "no_xop")]
1683	fn xop(&mut self, _instruction: &mut Instruction) {
1684		self.set_invalid_instruction();
1685	}
1686
1687	#[cfg(not(feature = "no_xop"))]
1688	fn xop(&mut self, instruction: &mut Instruction) {
1689		const _: () = assert!(DecoderMandatoryPrefix::PNP as u32 == 0);
1690		if (((self.state.flags & StateFlags::HAS_REX) | (self.state.mandatory_prefix as u32)) & self.invalid_check_mask) != 0 {
1691			self.set_invalid_instruction();
1692		}
1693		// Undo what decode_out() did if it got a REX prefix
1694		self.state.flags &= !StateFlags::W;
1695
1696		if cfg!(debug_assertions) {
1697			self.state.flags |= (EncodingKind::XOP as u32) << StateFlags::ENCODING_SHIFT;
1698		}
1699
1700		let b2 = self.read_u16() as u32;
1701
1702		const _: () = assert!(StateFlags::W == 0x80);
1703		self.state.flags |= b2 & 0x80;
1704
1705		const _: () = assert!(VectorLength::L128 as u32 == 0);
1706		const _: () = assert!(VectorLength::L256 as u32 == 1);
1707		// SAFETY: 0<=(n&1)<=1 and those are valid enum variants, see const assert!() above
1708		self.state.vector_length = unsafe { mem::transmute((b2 >> 2) & 1) };
1709
1710		const _: () = assert!(DecoderMandatoryPrefix::PNP as u32 == 0);
1711		const _: () = assert!(DecoderMandatoryPrefix::P66 as u32 == 1);
1712		const _: () = assert!(DecoderMandatoryPrefix::PF3 as u32 == 2);
1713		const _: () = assert!(DecoderMandatoryPrefix::PF2 as u32 == 3);
1714		// SAFETY: 0<=(b2&3)<=3 and those are valid enum variants, see const assert!() above
1715		self.state.mandatory_prefix = unsafe { mem::transmute(b2 & 3) };
1716
1717		let b = (!b2 >> 3) & 0x0F;
1718		self.state.vvvv_invalid_check = b;
1719		self.state.vvvv = b & self.reg15_mask;
1720		let b1 = self.state.modrm;
1721		let b1x = !b1 & self.mask_e0;
1722		self.state.extra_register_base = (b1x >> 4) & 8;
1723		self.state.extra_index_register_base = (b1x >> 3) & 8;
1724		self.state.extra_base_register_base = (b1x >> 2) & 8;
1725
1726		if let Some(&table) = self.handlers_xop.get(((b1 & 0x1F) as usize).wrapping_sub(8)) {
1727			self.decode_table2(table[(b2 >> 8) as usize], instruction);
1728		} else {
1729			self.set_invalid_instruction();
1730		}
1731	}
1732
1733	#[cfg(not(any(not(feature = "no_evex"), feature = "mvex")))]
1734	fn evex_mvex(&mut self, _instruction: &mut Instruction) {
1735		self.set_invalid_instruction();
1736	}
1737
1738	#[cfg(any(not(feature = "no_evex"), feature = "mvex"))]
1739	fn evex_mvex(&mut self, instruction: &mut Instruction) {
1740		const _: () = assert!(DecoderMandatoryPrefix::PNP as u32 == 0);
1741		if (((self.state.flags & StateFlags::HAS_REX) | (self.state.mandatory_prefix as u32)) & self.invalid_check_mask) != 0 {
1742			self.set_invalid_instruction();
1743		}
1744		// Undo what decode_out() did if it got a REX prefix
1745		self.state.flags &= !StateFlags::W;
1746
1747		let d = self.read_u32() as u32;
1748		if (d & 4) != 0 {
1749			#[cfg(feature = "no_evex")]
1750			self.set_invalid_instruction();
1751			#[cfg(not(feature = "no_evex"))]
1752			{
1753				let p0 = self.state.modrm;
1754				if (p0 & 8) == 0 {
1755					if cfg!(debug_assertions) {
1756						self.state.flags |= (EncodingKind::EVEX as u32) << StateFlags::ENCODING_SHIFT;
1757					}
1758
1759					const _: () = assert!(DecoderMandatoryPrefix::PNP as u32 == 0);
1760					const _: () = assert!(DecoderMandatoryPrefix::P66 as u32 == 1);
1761					const _: () = assert!(DecoderMandatoryPrefix::PF3 as u32 == 2);
1762					const _: () = assert!(DecoderMandatoryPrefix::PF2 as u32 == 3);
1763					// SAFETY: 0<=(d&3)<=3 and those are valid enum variants, see const assert!() above
1764					self.state.mandatory_prefix = unsafe { mem::transmute(d & 3) };
1765
1766					const _: () = assert!(StateFlags::W == 0x80);
1767					self.state.flags |= d & 0x80;
1768
1769					let p2 = d >> 8;
1770					let aaa = p2 & 7;
1771					self.state.aaa = aaa;
1772					instruction_internal::internal_set_op_mask(instruction, aaa);
1773					if (p2 & 0x80) != 0 {
1774						// invalid if aaa == 0 and if we check for invalid instructions (it's all 1s)
1775						if (aaa ^ self.invalid_check_mask) == u32::MAX {
1776							self.set_invalid_instruction();
1777						}
1778						self.state.flags |= StateFlags::Z;
1779						instruction.set_zeroing_masking(true);
1780					}
1781
1782					const _: () = assert!(StateFlags::B == 0x10);
1783					self.state.flags |= p2 & 0x10;
1784
1785					const _: () = assert!(VectorLength::L128 as u32 == 0);
1786					const _: () = assert!(VectorLength::L256 as u32 == 1);
1787					const _: () = assert!(VectorLength::L512 as u32 == 2);
1788					const _: () = assert!(VectorLength::Unknown as u32 == 3);
1789					// SAFETY: 0<=(n&3)<=3 and those are valid enum variants, see const assert!() above
1790					self.state.vector_length = unsafe { mem::transmute((p2 >> 5) & 3) };
1791
1792					let p1 = (!d >> 3) & 0x0F;
1793					if self.is64b_mode {
1794						let mut tmp = (!p2 & 8) << 1;
1795						self.state.extra_index_register_base_vsib = tmp;
1796						tmp += p1;
1797						self.state.vvvv = tmp;
1798						self.state.vvvv_invalid_check = tmp;
1799						let mut p0x = !p0;
1800						self.state.extra_register_base = (p0x >> 4) & 8;
1801						self.state.extra_index_register_base = (p0x >> 3) & 8;
1802						self.state.extra_register_base_evex = p0x & 0x10;
1803						p0x >>= 2;
1804						self.state.extra_base_register_base_evex = p0x & 0x18;
1805						self.state.extra_base_register_base = p0x & 8;
1806					} else {
1807						self.state.vvvv_invalid_check = p1;
1808						self.state.vvvv = p1 & 0x07;
1809						const _: () = assert!(StateFlags::IS_INVALID == 0x40);
1810						self.state.flags |= (!p2 & 8) << 3;
1811					}
1812
1813					if let Some(&table) = self.handlers_evex.get(((p0 & 7) as usize).wrapping_sub(1)) {
1814						let (decode, handler) = table[(d >> 16) as u8 as usize];
1815						debug_assert!(handler.has_modrm);
1816						let m = d >> 24;
1817						self.state.modrm = m;
1818						self.state.reg = (m >> 3) & 7;
1819						self.state.mod_ = m >> 6;
1820						self.state.rm = m & 7;
1821						self.state.mem_index = (self.state.mod_ << 3) | self.state.rm;
1822						// Invalid if LL=3 and no rc
1823						const _: () = assert!(StateFlags::B > 3);
1824						debug_assert!(self.state.vector_length as u32 <= 3);
1825						if (((self.state.flags & StateFlags::B) | (self.state.vector_length as u32)) & self.invalid_check_mask) == 3 {
1826							self.set_invalid_instruction();
1827						}
1828						(decode)(handler, self, instruction);
1829					} else {
1830						self.set_invalid_instruction();
1831					}
1832				} else {
1833					self.set_invalid_instruction();
1834				}
1835			}
1836		} else {
1837			#[cfg(not(feature = "mvex"))]
1838			self.set_invalid_instruction();
1839			#[cfg(feature = "mvex")]
1840			{
1841				if (self.options & DecoderOptions::KNC) == 0 || !self.is64b_mode {
1842					self.set_invalid_instruction();
1843				} else {
1844					let p0 = self.state.modrm;
1845					if cfg!(debug_assertions) {
1846						self.state.flags |= (EncodingKind::MVEX as u32) << StateFlags::ENCODING_SHIFT;
1847					}
1848
1849					const _: () = assert!(DecoderMandatoryPrefix::PNP as u32 == 0);
1850					const _: () = assert!(DecoderMandatoryPrefix::P66 as u32 == 1);
1851					const _: () = assert!(DecoderMandatoryPrefix::PF3 as u32 == 2);
1852					const _: () = assert!(DecoderMandatoryPrefix::PF2 as u32 == 3);
1853					// SAFETY: 0<=(d&3)<=3 and those are valid enum variants, see const assert!() above
1854					self.state.mandatory_prefix = unsafe { mem::transmute(d & 3) };
1855
1856					const _: () = assert!(StateFlags::W == 0x80);
1857					self.state.flags |= d & 0x80;
1858
1859					let p2 = d >> 8;
1860					let aaa = p2 & 7;
1861					self.state.aaa = aaa;
1862					instruction_internal::internal_set_op_mask(instruction, aaa);
1863
1864					const _: () = assert!(StateFlags::MVEX_SSS_SHIFT == 16);
1865					const _: () = assert!(StateFlags::MVEX_SSS_MASK == 7);
1866					const _: () = assert!(StateFlags::MVEX_EH == 1 << (StateFlags::MVEX_SSS_SHIFT + 3));
1867					self.state.flags |= (p2 & 0xF0) << (StateFlags::MVEX_SSS_SHIFT - 4);
1868
1869					let p1 = (!d >> 3) & 0x0F;
1870					let mut tmp = (!p2 & 8) << 1;
1871					self.state.extra_index_register_base_vsib = tmp;
1872					tmp += p1;
1873					self.state.vvvv = tmp;
1874					self.state.vvvv_invalid_check = tmp;
1875					let mut p0x = !p0;
1876					self.state.extra_register_base = (p0x >> 4) & 8;
1877					self.state.extra_index_register_base = (p0x >> 3) & 8;
1878					self.state.extra_register_base_evex = p0x & 0x10;
1879					p0x >>= 2;
1880					self.state.extra_base_register_base_evex = p0x & 0x18;
1881					self.state.extra_base_register_base = p0x & 8;
1882
1883					if let Some(&table) = self.handlers_mvex.get(((p0 & 0xF) as usize).wrapping_sub(1)) {
1884						let (decode, handler) = table[(d >> 16) as u8 as usize];
1885						debug_assert!(handler.has_modrm);
1886						let m = d >> 24;
1887						self.state.modrm = m;
1888						self.state.reg = (m >> 3) & 7;
1889						self.state.mod_ = m >> 6;
1890						self.state.rm = m & 7;
1891						self.state.mem_index = (self.state.mod_ << 3) | self.state.rm;
1892						(decode)(handler, self, instruction);
1893					} else {
1894						self.set_invalid_instruction();
1895					}
1896				}
1897			}
1898		}
1899	}
1900
1901	#[must_use]
1902	#[inline(always)]
1903	fn read_op_seg_reg(&mut self) -> u32 {
1904		let reg = self.state.reg;
1905		const _: () = assert!(Register::ES as u32 + 1 == Register::CS as u32);
1906		const _: () = assert!(Register::ES as u32 + 2 == Register::SS as u32);
1907		const _: () = assert!(Register::ES as u32 + 3 == Register::DS as u32);
1908		const _: () = assert!(Register::ES as u32 + 4 == Register::FS as u32);
1909		const _: () = assert!(Register::ES as u32 + 5 == Register::GS as u32);
1910		if reg < 6 {
1911			Register::ES as u32 + reg
1912		} else {
1913			self.set_invalid_instruction();
1914			Register::None as u32
1915		}
1916	}
1917
1918	#[inline(always)]
1919	#[cfg(any(not(feature = "no_vex"), not(feature = "no_xop")))]
1920	fn read_op_mem_sib(&mut self, instruction: &mut Instruction) {
1921		debug_assert!(self.state.encoding() != EncodingKind::EVEX as u32 && self.state.encoding() != EncodingKind::MVEX as u32);
1922		let is_valid = if self.state.address_size != OpSize::Size16 {
1923			self.read_op_mem_32_or_64(instruction)
1924		} else {
1925			self.read_op_mem_16(instruction, TupleType::N1);
1926			false
1927		};
1928		if self.invalid_check_mask != 0 && !is_valid {
1929			self.set_invalid_instruction();
1930		}
1931	}
1932
1933	// All MPX instructions in 64-bit mode force 64-bit addressing, and
1934	// all MPX instructions in 16/32-bit mode require 32-bit addressing
1935	// (see SDM Vol 1, 17.5.1 Intel MPX and Operating Modes)
1936	#[inline(always)]
1937	fn read_op_mem_mpx(&mut self, instruction: &mut Instruction) {
1938		debug_assert!(self.state.encoding() != EncodingKind::EVEX as u32 && self.state.encoding() != EncodingKind::MVEX as u32);
1939		if self.is64b_mode {
1940			self.state.address_size = OpSize::Size64;
1941			let _ = self.read_op_mem_32_or_64(instruction);
1942		} else if self.state.address_size != OpSize::Size16 {
1943			let _ = self.read_op_mem_32_or_64(instruction);
1944		} else {
1945			self.read_op_mem_16(instruction, TupleType::N1);
1946			if self.invalid_check_mask != 0 {
1947				self.set_invalid_instruction();
1948			}
1949		}
1950	}
1951
1952	#[inline(always)]
1953	#[cfg(any(not(feature = "no_evex"), feature = "mvex"))]
1954	fn read_op_mem_tuple_type(&mut self, instruction: &mut Instruction, tuple_type: TupleType) {
1955		debug_assert!(self.state.encoding() == EncodingKind::EVEX as u32 || self.state.encoding() == EncodingKind::MVEX as u32);
1956		if self.state.address_size != OpSize::Size16 {
1957			let index_reg = if self.state.address_size == OpSize::Size64 { Register::RAX } else { Register::EAX };
1958			let _ = decoder_read_op_mem_32_or_64_vsib(self, instruction, index_reg, tuple_type, false);
1959		} else {
1960			self.read_op_mem_16(instruction, tuple_type);
1961		}
1962	}
1963
1964	#[inline(always)]
1965	#[cfg(any(not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
1966	fn read_op_mem_vsib(&mut self, instruction: &mut Instruction, vsib_index: Register, tuple_type: TupleType) {
1967		let is_valid = if self.state.address_size != OpSize::Size16 {
1968			decoder_read_op_mem_32_or_64_vsib(self, instruction, vsib_index, tuple_type, true)
1969		} else {
1970			self.read_op_mem_16(instruction, tuple_type);
1971			false
1972		};
1973		if self.invalid_check_mask != 0 && !is_valid {
1974			self.set_invalid_instruction();
1975		}
1976	}
1977
1978	// It's small enough that the compiler wants to inline it but almost no-one will
1979	// disassemble code with 16-bit addressing.
1980	#[inline(never)]
1981	#[cold]
1982	fn read_op_mem_16(&mut self, instruction: &mut Instruction, tuple_type: TupleType) {
1983		debug_assert!(self.state.address_size == OpSize::Size16);
1984		debug_assert!(self.state.rm <= 7);
1985		// SAFETY: `MEM_REGS_16.len() == 8` and `0<=self.state.rm<=7`
1986		let (mut base_reg, index_reg) = unsafe { *MEM_REGS_16.get_unchecked(self.state.rm as usize) };
1987		match self.state.mod_ {
1988			0 => {
1989				if self.state.rm == 6 {
1990					instruction_internal::internal_set_memory_displ_size(instruction, 2);
1991					self.displ_index = self.data_ptr as u8;
1992					instruction.set_memory_displacement64(self.read_u16() as u64);
1993					base_reg = Register::None;
1994					debug_assert_eq!(index_reg, Register::None);
1995				}
1996			}
1997			1 => {
1998				instruction_internal::internal_set_memory_displ_size(instruction, 1);
1999				self.displ_index = self.data_ptr as u8;
2000				let b = self.read_u8();
2001				instruction.set_memory_displacement64(self.disp8n(tuple_type).wrapping_mul(b as i8 as u32) as u16 as u64);
2002			}
2003			_ => {
2004				debug_assert_eq!(self.state.mod_, 2);
2005				instruction_internal::internal_set_memory_displ_size(instruction, 2);
2006				self.displ_index = self.data_ptr as u8;
2007				instruction.set_memory_displacement64(self.read_u16() as u64);
2008			}
2009		}
2010		instruction.set_memory_base(base_reg);
2011		instruction.set_memory_index(index_reg);
2012	}
2013
2014	#[must_use]
2015	#[cfg(feature = "__internal_flip")]
2016	fn read_op_mem_32_or_64(&mut self, instruction: &mut Instruction) -> bool {
2017		let base_reg = if self.state.address_size == OpSize::Size64 { Register::RAX } else { Register::EAX };
2018		decoder_read_op_mem_32_or_64_vsib(self, instruction, base_reg, TupleType::N1, false)
2019	}
2020
2021	// Returns `true` if the SIB byte was read
2022	// This is a specialized version of read_op_mem_32_or_64_vsib() which takes less arguments. Keep them in sync.
2023	#[must_use]
2024	#[cfg(not(feature = "__internal_flip"))]
2025	#[inline(always)]
2026	fn read_op_mem_32_or_64(&mut self, instruction: &mut Instruction) -> bool {
2027		read_op_mem_stmt_ret!(self, instruction, {})
2028	}
2029
2030	#[cfg(not(feature = "__internal_flip"))]
2031	#[allow(clippy::never_loop)]
2032	fn read_op_mem_1(instruction: &mut Instruction, this: &mut Decoder<'_>) -> bool {
2033		loop {
2034			instruction_internal::internal_set_memory_displ_size(instruction, 1);
2035			this.displ_index = this.data_ptr as u8;
2036			let displ = read_u8_break!(this) as i8 as u64;
2037			if this.state.address_size == OpSize::Size64 {
2038				instruction.set_memory_displacement64(displ);
2039				write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + Register::RAX as u32);
2040			} else {
2041				instruction.set_memory_displacement64(displ as u32 as u64);
2042				write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + Register::EAX as u32);
2043			}
2044
2045			return false;
2046		}
2047		this.state.flags |= StateFlags::IS_INVALID | StateFlags::NO_MORE_BYTES;
2048		false
2049	}
2050
2051	#[cfg(not(feature = "__internal_flip"))]
2052	#[allow(clippy::never_loop)]
2053	fn read_op_mem_1_4(instruction: &mut Instruction, this: &mut Decoder<'_>) -> bool {
2054		loop {
2055			instruction_internal::internal_set_memory_displ_size(instruction, 1);
2056
2057			this.displ_index = this.data_ptr.wrapping_add(1) as u8;
2058			let w = read_u16_break!(this) as u32;
2059
2060			const _: () = assert!(InstrScale::Scale1 as u32 == 0);
2061			const _: () = assert!(InstrScale::Scale2 as u32 == 1);
2062			const _: () = assert!(InstrScale::Scale4 as u32 == 2);
2063			const _: () = assert!(InstrScale::Scale8 as u32 == 3);
2064			// SAFETY: 0-3 are valid variants
2065			instruction_internal::internal_set_memory_index_scale(instruction, unsafe { mem::transmute(((w >> 6) & 3) as InstrScaleUnderlyingType) });
2066			let index = ((w >> 3) & 7) + this.state.extra_index_register_base;
2067			if this.state.address_size == OpSize::Size64 {
2068				const BASE_REG: Register = Register::RAX;
2069				if index != 4 {
2070					write_index_reg!(instruction, index + BASE_REG as u32);
2071				}
2072
2073				write_base_reg!(instruction, (w & 7) + this.state.extra_base_register_base + BASE_REG as u32);
2074				let displ = (w >> 8) as i8 as u64;
2075				instruction.set_memory_displacement64(displ);
2076			} else {
2077				const BASE_REG: Register = Register::EAX;
2078				if index != 4 {
2079					write_index_reg!(instruction, index + BASE_REG as u32);
2080				}
2081
2082				write_base_reg!(instruction, (w & 7) + this.state.extra_base_register_base + BASE_REG as u32);
2083				let displ = (w >> 8) as i8 as u32 as u64;
2084				instruction.set_memory_displacement64(displ);
2085			}
2086
2087			return true;
2088		}
2089		this.state.flags |= StateFlags::IS_INVALID | StateFlags::NO_MORE_BYTES;
2090		true
2091	}
2092
2093	#[cfg(not(feature = "__internal_flip"))]
2094	fn read_op_mem_0(instruction: &mut Instruction, this: &mut Decoder<'_>) -> bool {
2095		if this.state.address_size == OpSize::Size64 {
2096			write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + Register::RAX as u32);
2097		} else {
2098			write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + Register::EAX as u32);
2099		};
2100
2101		false
2102	}
2103
2104	#[cfg(not(feature = "__internal_flip"))]
2105	#[allow(clippy::never_loop)]
2106	fn read_op_mem_0_5(instruction: &mut Instruction, this: &mut Decoder<'_>) -> bool {
2107		loop {
2108			this.displ_index = this.data_ptr as u8;
2109			let displ = read_u32_break!(this) as i32 as u64;
2110			if this.state.address_size == OpSize::Size64 {
2111				debug_assert!(this.is64b_mode);
2112				this.state.flags |= StateFlags::IP_REL64;
2113				instruction.set_memory_displacement64(displ);
2114				instruction_internal::internal_set_memory_displ_size(instruction, 4);
2115				instruction.set_memory_base(Register::RIP);
2116			} else if this.is64b_mode {
2117				this.state.flags |= StateFlags::IP_REL32;
2118				instruction.set_memory_displacement64(displ as u32 as u64);
2119				instruction_internal::internal_set_memory_displ_size(instruction, 3);
2120				instruction.set_memory_base(Register::EIP);
2121			} else {
2122				instruction.set_memory_displacement64(displ as u32 as u64);
2123				instruction_internal::internal_set_memory_displ_size(instruction, 3);
2124			}
2125
2126			return false;
2127		}
2128		this.state.flags |= StateFlags::IS_INVALID | StateFlags::NO_MORE_BYTES;
2129		false
2130	}
2131
2132	#[cfg(not(feature = "__internal_flip"))]
2133	#[allow(clippy::never_loop)]
2134	fn read_op_mem_2_4(instruction: &mut Instruction, this: &mut Decoder<'_>) -> bool {
2135		loop {
2136			let sib = read_u8_break!(this) as u32;
2137			this.displ_index = this.data_ptr as u8;
2138			let displ = read_u32_break!(this) as i32 as u64;
2139
2140			const _: () = assert!(InstrScale::Scale1 as u32 == 0);
2141			const _: () = assert!(InstrScale::Scale2 as u32 == 1);
2142			const _: () = assert!(InstrScale::Scale4 as u32 == 2);
2143			const _: () = assert!(InstrScale::Scale8 as u32 == 3);
2144			// SAFETY: 0-3 are valid variants
2145			instruction_internal::internal_set_memory_index_scale(instruction, unsafe { mem::transmute((sib >> 6) as InstrScaleUnderlyingType) });
2146			let index = ((sib >> 3) & 7) + this.state.extra_index_register_base;
2147			if this.state.address_size == OpSize::Size64 {
2148				const BASE_REG: Register = Register::RAX;
2149				if index != 4 {
2150					write_index_reg!(instruction, index + BASE_REG as u32);
2151				}
2152
2153				write_base_reg!(instruction, (sib & 7) + this.state.extra_base_register_base + BASE_REG as u32);
2154				instruction_internal::internal_set_memory_displ_size(instruction, 4);
2155				instruction.set_memory_displacement64(displ);
2156			} else {
2157				const BASE_REG: Register = Register::EAX;
2158				if index != 4 {
2159					write_index_reg!(instruction, index + BASE_REG as u32);
2160				}
2161
2162				write_base_reg!(instruction, (sib & 7) + this.state.extra_base_register_base + BASE_REG as u32);
2163				instruction_internal::internal_set_memory_displ_size(instruction, 3);
2164				instruction.set_memory_displacement64(displ as u32 as u64);
2165			}
2166
2167			return true;
2168		}
2169		this.state.flags |= StateFlags::IS_INVALID | StateFlags::NO_MORE_BYTES;
2170		true
2171	}
2172
2173	#[cfg(not(feature = "__internal_flip"))]
2174	#[allow(clippy::never_loop)]
2175	fn read_op_mem_2(instruction: &mut Instruction, this: &mut Decoder<'_>) -> bool {
2176		loop {
2177			this.displ_index = this.data_ptr as u8;
2178			let displ = read_u32_break!(this) as i32 as u64;
2179			if this.state.address_size == OpSize::Size64 {
2180				instruction.set_memory_displacement64(displ);
2181				instruction_internal::internal_set_memory_displ_size(instruction, 4);
2182				write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + Register::RAX as u32);
2183			} else {
2184				instruction.set_memory_displacement64(displ as u32 as u64);
2185				instruction_internal::internal_set_memory_displ_size(instruction, 3);
2186				write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + Register::EAX as u32);
2187			}
2188
2189			return false;
2190		}
2191		this.state.flags |= StateFlags::IS_INVALID | StateFlags::NO_MORE_BYTES;
2192		false
2193	}
2194
2195	#[cfg(not(feature = "__internal_flip"))]
2196	#[allow(clippy::never_loop)]
2197	fn read_op_mem_0_4(instruction: &mut Instruction, this: &mut Decoder<'_>) -> bool {
2198		loop {
2199			let sib = read_u8_break!(this) as u32;
2200			const _: () = assert!(InstrScale::Scale1 as u32 == 0);
2201			const _: () = assert!(InstrScale::Scale2 as u32 == 1);
2202			const _: () = assert!(InstrScale::Scale4 as u32 == 2);
2203			const _: () = assert!(InstrScale::Scale8 as u32 == 3);
2204			// SAFETY: 0-3 are valid variants
2205			instruction_internal::internal_set_memory_index_scale(instruction, unsafe { mem::transmute((sib >> 6) as InstrScaleUnderlyingType) });
2206			let index = ((sib >> 3) & 7) + this.state.extra_index_register_base;
2207			let base_reg = if this.state.address_size == OpSize::Size64 { Register::RAX } else { Register::EAX };
2208			if index != 4 {
2209				write_index_reg!(instruction, index + base_reg as u32);
2210			}
2211
2212			let base = sib & 7;
2213			if base == 5 {
2214				this.displ_index = this.data_ptr as u8;
2215				let displ = read_u32_break!(this) as i32 as u64;
2216				if this.state.address_size == OpSize::Size64 {
2217					instruction.set_memory_displacement64(displ);
2218					instruction_internal::internal_set_memory_displ_size(instruction, 4);
2219				} else {
2220					instruction.set_memory_displacement64(displ as u32 as u64);
2221					instruction_internal::internal_set_memory_displ_size(instruction, 3);
2222				}
2223			} else {
2224				write_base_reg!(instruction, base + this.state.extra_base_register_base + base_reg as u32);
2225				instruction_internal::internal_set_memory_displ_size(instruction, 0);
2226				instruction.set_memory_displacement64(0);
2227			}
2228
2229			return true;
2230		}
2231		this.state.flags |= StateFlags::IS_INVALID | StateFlags::NO_MORE_BYTES;
2232		true
2233	}
2234
2235	#[must_use]
2236	#[inline(always)]
2237	fn disp8n(&self, tuple_type: TupleType) -> u32 {
2238		get_disp8n(tuple_type, (self.state.flags & StateFlags::B) != 0)
2239	}
2240
2241	/// Gets the offsets of the constants (memory displacement and immediate) in the decoded instruction.
2242	/// The caller can check if there are any relocations at those addresses.
2243	///
2244	/// # Arguments
2245	///
2246	/// * `instruction`: The latest instruction that was decoded by this decoder
2247	///
2248	/// # Examples
2249	///
2250	/// ```
2251	/// use iced_x86::*;
2252	///
2253	/// // nop
2254	/// // xor dword ptr [rax-5AA5EDCCh],5Ah
2255	/// //                  00  01  02  03  04  05  06
2256	/// //                \opc\mrm\displacement___\imm
2257	/// let bytes = b"\x90\x83\xB3\x34\x12\x5A\xA5\x5A";
2258	/// let mut decoder = Decoder::with_ip(64, bytes, 0x1234_5678, DecoderOptions::NONE);
2259	/// assert_eq!(decoder.decode().code(), Code::Nopd);
2260	/// let instr = decoder.decode();
2261	/// let co = decoder.get_constant_offsets(&instr);
2262	///
2263	/// assert!(co.has_displacement());
2264	/// assert_eq!(co.displacement_offset(), 2);
2265	/// assert_eq!(co.displacement_size(), 4);
2266	/// assert!(co.has_immediate());
2267	/// assert_eq!(co.immediate_offset(), 6);
2268	/// assert_eq!(co.immediate_size(), 1);
2269	/// // It's not an instruction with two immediates (e.g. enter)
2270	/// assert!(!co.has_immediate2());
2271	/// assert_eq!(co.immediate_offset2(), 0);
2272	/// assert_eq!(co.immediate_size2(), 0);
2273	/// ```
2274	#[must_use]
2275	#[allow(clippy::missing_inline_in_public_items)]
2276	pub fn get_constant_offsets(&self, instruction: &Instruction) -> ConstantOffsets {
2277		let mut constant_offsets = ConstantOffsets::default();
2278
2279		let displ_size = instruction.memory_displ_size();
2280		if displ_size != 0 {
2281			constant_offsets.displacement_offset = self.displ_index.wrapping_sub(self.instr_start_data_ptr as u8);
2282			if displ_size == 8 && (self.state.flags & StateFlags::ADDR64) == 0 {
2283				constant_offsets.displacement_size = 4;
2284			} else {
2285				constant_offsets.displacement_size = displ_size as u8;
2286			}
2287		}
2288
2289		if (self.state.flags & StateFlags::NO_IMM) == 0 {
2290			let mut extra_imm_sub = 0;
2291			for i in (0..instruction.op_count()).rev() {
2292				match instruction.op_kind(i) {
2293					OpKind::Immediate8 | OpKind::Immediate8to16 | OpKind::Immediate8to32 | OpKind::Immediate8to64 => {
2294						constant_offsets.immediate_offset = instruction.len().wrapping_sub(extra_imm_sub).wrapping_sub(1) as u8;
2295						constant_offsets.immediate_size = 1;
2296						break;
2297					}
2298
2299					OpKind::Immediate16 => {
2300						constant_offsets.immediate_offset = instruction.len().wrapping_sub(extra_imm_sub).wrapping_sub(2) as u8;
2301						constant_offsets.immediate_size = 2;
2302						break;
2303					}
2304
2305					OpKind::Immediate32 | OpKind::Immediate32to64 => {
2306						constant_offsets.immediate_offset = instruction.len().wrapping_sub(extra_imm_sub).wrapping_sub(4) as u8;
2307						constant_offsets.immediate_size = 4;
2308						break;
2309					}
2310
2311					OpKind::Immediate64 => {
2312						constant_offsets.immediate_offset = instruction.len().wrapping_sub(extra_imm_sub).wrapping_sub(8) as u8;
2313						constant_offsets.immediate_size = 8;
2314						break;
2315					}
2316
2317					OpKind::Immediate8_2nd => {
2318						constant_offsets.immediate_offset2 = instruction.len().wrapping_sub(1) as u8;
2319						constant_offsets.immediate_size2 = 1;
2320						extra_imm_sub = 1;
2321					}
2322
2323					OpKind::NearBranch16 => {
2324						if (self.state.flags & StateFlags::BRANCH_IMM8) != 0 {
2325							constant_offsets.immediate_offset = instruction.len().wrapping_sub(1) as u8;
2326							constant_offsets.immediate_size = 1;
2327						} else if (self.state.flags & StateFlags::XBEGIN) == 0 {
2328							constant_offsets.immediate_offset = instruction.len().wrapping_sub(2) as u8;
2329							constant_offsets.immediate_size = 2;
2330						} else {
2331							debug_assert!((self.state.flags & StateFlags::XBEGIN) != 0);
2332							if self.state.operand_size != OpSize::Size16 {
2333								constant_offsets.immediate_offset = instruction.len().wrapping_sub(4) as u8;
2334								constant_offsets.immediate_size = 4;
2335							} else {
2336								constant_offsets.immediate_offset = instruction.len().wrapping_sub(2) as u8;
2337								constant_offsets.immediate_size = 2;
2338							}
2339						}
2340					}
2341
2342					OpKind::NearBranch32 | OpKind::NearBranch64 => {
2343						if (self.state.flags & StateFlags::BRANCH_IMM8) != 0 {
2344							constant_offsets.immediate_offset = instruction.len().wrapping_sub(1) as u8;
2345							constant_offsets.immediate_size = 1;
2346						} else if (self.state.flags & StateFlags::XBEGIN) == 0 {
2347							constant_offsets.immediate_offset = instruction.len().wrapping_sub(4) as u8;
2348							constant_offsets.immediate_size = 4;
2349						} else {
2350							debug_assert!((self.state.flags & StateFlags::XBEGIN) != 0);
2351							if self.state.operand_size != OpSize::Size16 {
2352								constant_offsets.immediate_offset = instruction.len().wrapping_sub(4) as u8;
2353								constant_offsets.immediate_size = 4;
2354							} else {
2355								constant_offsets.immediate_offset = instruction.len().wrapping_sub(2) as u8;
2356								constant_offsets.immediate_size = 2;
2357							}
2358						}
2359					}
2360
2361					OpKind::FarBranch16 => {
2362						constant_offsets.immediate_offset = instruction.len().wrapping_sub(2 + 2) as u8;
2363						constant_offsets.immediate_size = 2;
2364						constant_offsets.immediate_offset2 = instruction.len().wrapping_sub(2) as u8;
2365						constant_offsets.immediate_size2 = 2;
2366					}
2367
2368					OpKind::FarBranch32 => {
2369						constant_offsets.immediate_offset = instruction.len().wrapping_sub(4 + 2) as u8;
2370						constant_offsets.immediate_size = 4;
2371						constant_offsets.immediate_offset2 = instruction.len().wrapping_sub(2) as u8;
2372						constant_offsets.immediate_size2 = 2;
2373					}
2374
2375					_ => {}
2376				}
2377			}
2378		}
2379
2380		constant_offsets
2381	}
2382}
2383
2384// These are referenced from a static and I couldn't get it to work when they were inside an `impl` block
2385// so they're here instead of where they really belong.
2386
2387// Returns `true` if the SIB byte was read
2388// Same as read_op_mem_32_or_64() except it works with vsib memory operands. Keep them in sync.
2389#[must_use]
2390#[cfg(any(feature = "__internal_flip", not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
2391#[inline(always)]
2392fn decoder_read_op_mem_32_or_64_vsib(
2393	this: &mut Decoder<'_>, instruction: &mut Instruction, index_reg: Register, tuple_type: TupleType, is_vsib: bool,
2394) -> bool {
2395	debug_assert!(this.state.address_size == OpSize::Size32 || this.state.address_size == OpSize::Size64);
2396
2397	let index = this.state.mem_index as usize;
2398	debug_assert!(index < READ_OP_MEM_VSIB_FNS.len());
2399	// SAFETY: index is valid because modrm.mod = 0-2 (never 3 if we're here) so index will always be 0-10_111 (17h)
2400	unsafe { (READ_OP_MEM_VSIB_FNS.get_unchecked(index))(this, instruction, index_reg, tuple_type, is_vsib) }
2401}
2402
2403#[cfg(any(feature = "__internal_flip", not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
2404fn decoder_read_op_mem_vsib_1(
2405	this: &mut Decoder<'_>, instruction: &mut Instruction, _index_reg: Register, tuple_type: TupleType, _is_vsib: bool,
2406) -> bool {
2407	instruction_internal::internal_set_memory_displ_size(instruction, 1);
2408	this.displ_index = this.data_ptr as u8;
2409	let b = this.read_u8();
2410	if this.state.address_size == OpSize::Size64 {
2411		write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + Register::RAX as u32);
2412		instruction.set_memory_displacement64((this.disp8n(tuple_type) as u64).wrapping_mul(b as i8 as u64));
2413	} else {
2414		write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + Register::EAX as u32);
2415		instruction.set_memory_displacement64(this.disp8n(tuple_type).wrapping_mul(b as i8 as u32) as u64);
2416	}
2417
2418	false
2419}
2420
2421#[cfg(any(feature = "__internal_flip", not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
2422fn decoder_read_op_mem_vsib_1_4(
2423	this: &mut Decoder<'_>, instruction: &mut Instruction, index_reg: Register, tuple_type: TupleType, is_vsib: bool,
2424) -> bool {
2425	instruction_internal::internal_set_memory_displ_size(instruction, 1);
2426
2427	this.displ_index = this.data_ptr.wrapping_add(1) as u8;
2428	let sib = this.read_u16() as u32;
2429	let index = ((sib >> 3) & 7) + this.state.extra_index_register_base;
2430	if !is_vsib {
2431		if index != 4 {
2432			write_index_reg!(instruction, index + index_reg as u32);
2433		}
2434	} else {
2435		write_index_reg!(instruction, index + this.state.extra_index_register_base_vsib + index_reg as u32);
2436	}
2437
2438	const _: () = assert!(InstrScale::Scale1 as u32 == 0);
2439	const _: () = assert!(InstrScale::Scale2 as u32 == 1);
2440	const _: () = assert!(InstrScale::Scale4 as u32 == 2);
2441	const _: () = assert!(InstrScale::Scale8 as u32 == 3);
2442	// SAFETY: 0-3 are valid variants
2443	instruction_internal::internal_set_memory_index_scale(instruction, unsafe { mem::transmute(((sib >> 6) & 3) as InstrScaleUnderlyingType) });
2444	let base_reg = if this.state.address_size == OpSize::Size64 { Register::RAX } else { Register::EAX };
2445	write_base_reg!(instruction, (sib & 7) + this.state.extra_base_register_base + base_reg as u32);
2446
2447	let b = (sib >> 8) as i8 as u32;
2448	let displ = this.disp8n(tuple_type).wrapping_mul(b);
2449	if this.state.address_size == OpSize::Size64 {
2450		instruction.set_memory_displacement64(displ as i32 as u64);
2451	} else {
2452		instruction.set_memory_displacement64(displ as u64);
2453	}
2454
2455	true
2456}
2457
2458#[cfg(any(feature = "__internal_flip", not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
2459fn decoder_read_op_mem_vsib_0(
2460	this: &mut Decoder<'_>, instruction: &mut Instruction, _index_reg: Register, _tuple_type: TupleType, _is_vsib: bool,
2461) -> bool {
2462	let base_reg = if this.state.address_size == OpSize::Size64 { Register::RAX } else { Register::EAX };
2463	write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + base_reg as u32);
2464
2465	false
2466}
2467
2468#[cfg(any(feature = "__internal_flip", not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
2469fn decoder_read_op_mem_vsib_0_5(
2470	this: &mut Decoder<'_>, instruction: &mut Instruction, _index_reg: Register, _tuple_type: TupleType, _is_vsib: bool,
2471) -> bool {
2472	this.displ_index = this.data_ptr as u8;
2473	let d = this.read_u32();
2474	if this.state.address_size == OpSize::Size64 {
2475		debug_assert!(this.is64b_mode);
2476		this.state.flags |= StateFlags::IP_REL64;
2477		instruction.set_memory_displacement64(d as i32 as u64);
2478		instruction_internal::internal_set_memory_displ_size(instruction, 4);
2479		instruction.set_memory_base(Register::RIP);
2480	} else if this.is64b_mode {
2481		this.state.flags |= StateFlags::IP_REL32;
2482		instruction.set_memory_displacement64(d as u64);
2483		instruction_internal::internal_set_memory_displ_size(instruction, 3);
2484		instruction.set_memory_base(Register::EIP);
2485	} else {
2486		instruction.set_memory_displacement64(d as u64);
2487		instruction_internal::internal_set_memory_displ_size(instruction, 3);
2488	}
2489
2490	false
2491}
2492
2493#[cfg(any(feature = "__internal_flip", not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
2494fn decoder_read_op_mem_vsib_2_4(
2495	this: &mut Decoder<'_>, instruction: &mut Instruction, index_reg: Register, _tuple_type: TupleType, is_vsib: bool,
2496) -> bool {
2497	let sib = this.read_u8() as u32;
2498	this.displ_index = this.data_ptr as u8;
2499
2500	let index = ((sib >> 3) & 7) + this.state.extra_index_register_base;
2501	if !is_vsib {
2502		if index != 4 {
2503			write_index_reg!(instruction, index + index_reg as u32);
2504		}
2505	} else {
2506		write_index_reg!(instruction, index + this.state.extra_index_register_base_vsib + index_reg as u32);
2507	}
2508
2509	const _: () = assert!(InstrScale::Scale1 as u32 == 0);
2510	const _: () = assert!(InstrScale::Scale2 as u32 == 1);
2511	const _: () = assert!(InstrScale::Scale4 as u32 == 2);
2512	const _: () = assert!(InstrScale::Scale8 as u32 == 3);
2513	// SAFETY: 0-3 are valid variants
2514	instruction_internal::internal_set_memory_index_scale(instruction, unsafe { mem::transmute((sib >> 6) as InstrScaleUnderlyingType) });
2515
2516	let base_reg = if this.state.address_size == OpSize::Size64 { Register::RAX } else { Register::EAX };
2517	write_base_reg!(instruction, (sib & 7) + this.state.extra_base_register_base + base_reg as u32);
2518	let displ = this.read_u32() as u32;
2519	if this.state.address_size == OpSize::Size64 {
2520		instruction_internal::internal_set_memory_displ_size(instruction, 4);
2521		instruction.set_memory_displacement64(displ as i32 as u64);
2522	} else {
2523		instruction_internal::internal_set_memory_displ_size(instruction, 3);
2524		instruction.set_memory_displacement64(displ as u64);
2525	}
2526
2527	true
2528}
2529
2530#[cfg(any(feature = "__internal_flip", not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
2531fn decoder_read_op_mem_vsib_2(
2532	this: &mut Decoder<'_>, instruction: &mut Instruction, _index_reg: Register, _tuple_type: TupleType, _is_vsib: bool,
2533) -> bool {
2534	let base_reg = if this.state.address_size == OpSize::Size64 { Register::RAX } else { Register::EAX };
2535	write_base_reg!(instruction, this.state.extra_base_register_base + this.state.rm + base_reg as u32);
2536	this.displ_index = this.data_ptr as u8;
2537	let d = this.read_u32();
2538	if this.state.address_size == OpSize::Size64 {
2539		instruction.set_memory_displacement64(d as i32 as u64);
2540		instruction_internal::internal_set_memory_displ_size(instruction, 4);
2541	} else {
2542		instruction.set_memory_displacement64(d as u64);
2543		instruction_internal::internal_set_memory_displ_size(instruction, 3);
2544	}
2545
2546	false
2547}
2548
2549#[cfg(any(feature = "__internal_flip", not(feature = "no_evex"), not(feature = "no_vex"), not(feature = "no_xop"), feature = "mvex"))]
2550fn decoder_read_op_mem_vsib_0_4(
2551	this: &mut Decoder<'_>, instruction: &mut Instruction, index_reg: Register, _tuple_type: TupleType, is_vsib: bool,
2552) -> bool {
2553	let sib = this.read_u8() as u32;
2554	const _: () = assert!(InstrScale::Scale1 as u32 == 0);
2555	const _: () = assert!(InstrScale::Scale2 as u32 == 1);
2556	const _: () = assert!(InstrScale::Scale4 as u32 == 2);
2557	const _: () = assert!(InstrScale::Scale8 as u32 == 3);
2558	// SAFETY: 0-3 are valid variants
2559	instruction_internal::internal_set_memory_index_scale(instruction, unsafe { mem::transmute((sib >> 6) as InstrScaleUnderlyingType) });
2560	let index = ((sib >> 3) & 7) + this.state.extra_index_register_base;
2561	if !is_vsib {
2562		if index != 4 {
2563			write_index_reg!(instruction, index + index_reg as u32);
2564		}
2565	} else {
2566		write_index_reg!(instruction, index + this.state.extra_index_register_base_vsib + index_reg as u32);
2567	}
2568
2569	let base = sib & 7;
2570	if base == 5 {
2571		this.displ_index = this.data_ptr as u8;
2572		let d = this.read_u32();
2573		if this.state.address_size == OpSize::Size64 {
2574			instruction.set_memory_displacement64(d as i32 as u64);
2575			instruction_internal::internal_set_memory_displ_size(instruction, 4);
2576		} else {
2577			instruction.set_memory_displacement64(d as u64);
2578			instruction_internal::internal_set_memory_displ_size(instruction, 3);
2579		}
2580	} else {
2581		let base_reg = if this.state.address_size == OpSize::Size64 { Register::RAX } else { Register::EAX };
2582		write_base_reg!(instruction, base + this.state.extra_base_register_base + base_reg as u32);
2583		instruction_internal::internal_set_memory_displ_size(instruction, 0);
2584		instruction.set_memory_displacement64(0);
2585	}
2586
2587	true
2588}
2589
2590#[doc(hidden)]
2591#[allow(missing_debug_implementations)]
2592pub struct DecoderIter<'a, 'b> {
2593	decoder: &'b mut Decoder<'a>,
2594}
2595
2596impl Iterator for DecoderIter<'_, '_> {
2597	type Item = Instruction;
2598
2599	#[inline]
2600	fn next(&mut self) -> Option<Self::Item> {
2601		if self.decoder.can_decode() {
2602			Some(self.decoder.decode())
2603		} else {
2604			None
2605		}
2606	}
2607}
2608
2609impl FusedIterator for DecoderIter<'_, '_> {}
2610
2611#[doc(hidden)]
2612#[allow(missing_debug_implementations)]
2613pub struct DecoderIntoIter<'a> {
2614	decoder: Decoder<'a>,
2615}
2616
2617impl Iterator for DecoderIntoIter<'_> {
2618	type Item = Instruction;
2619
2620	#[inline]
2621	fn next(&mut self) -> Option<Self::Item> {
2622		if self.decoder.can_decode() {
2623			Some(self.decoder.decode())
2624		} else {
2625			None
2626		}
2627	}
2628}
2629
2630impl FusedIterator for DecoderIntoIter<'_> {}
2631
2632impl<'a> IntoIterator for Decoder<'a> {
2633	type Item = Instruction;
2634	type IntoIter = DecoderIntoIter<'a>;
2635
2636	#[inline]
2637	fn into_iter(self) -> Self::IntoIter {
2638		DecoderIntoIter { decoder: self }
2639	}
2640}
2641
2642impl<'a, 'b> IntoIterator for &'b mut Decoder<'a> {
2643	type Item = Instruction;
2644	type IntoIter = DecoderIter<'a, 'b>;
2645
2646	#[inline]
2647	fn into_iter(self) -> Self::IntoIter {
2648		DecoderIter { decoder: self }
2649	}
2650}