1macro_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 if data_ptr + SIZE - 1 < $slf.max_data_ptr {
14 let result = $from_le(unsafe { ptr::read_unaligned(data_ptr as *const $mem_ty) }) as $ret_ty;
18 $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 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#[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#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
181#[cfg_attr(not(feature = "exhaustive_enums"), non_exhaustive)]
182pub enum DecoderError {
183 None = 0,
185 InvalidInstruction = 1,
187 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 #[inline]
215 pub fn values() -> impl Iterator<Item = DecoderError> + DoubleEndedIterator + ExactSizeIterator + FusedIterator {
216 (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 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#[allow(missing_copy_implementations)]
320#[allow(missing_debug_implementations)]
321pub struct DecoderOptions;
322impl DecoderOptions {
323 pub const NONE: u32 = 0x0000_0000;
325 pub const NO_INVALID_CHECK: u32 = 0x0000_0001;
329 pub const AMD: u32 = 0x0000_0002;
331 pub const FORCE_RESERVED_NOP: u32 = 0x0000_0004;
335 pub const UMOV: u32 = 0x0000_0008;
337 pub const XBTS: u32 = 0x0000_0010;
339 pub const CMPXCHG486A: u32 = 0x0000_0020;
341 pub const OLD_FPU: u32 = 0x0000_0040;
343 pub const PCOMMIT: u32 = 0x0000_0080;
345 pub const LOADALL286: u32 = 0x0000_0100;
347 pub const LOADALL386: u32 = 0x0000_0200;
349 pub const CL1INVMB: u32 = 0x0000_0400;
351 pub const MOV_TR: u32 = 0x0000_0800;
353 pub const JMPE: u32 = 0x0000_1000;
355 pub const NO_PAUSE: u32 = 0x0000_2000;
357 pub const NO_WBNOINVD: u32 = 0x0000_4000;
359 pub const UDBG: u32 = 0x0000_8000;
361 pub const NO_MPFX_0FBC: u32 = 0x0001_0000;
363 pub const NO_MPFX_0FBD: u32 = 0x0002_0000;
365 pub const NO_LAHF_SAHF_64: u32 = 0x0004_0000;
367 pub const MPX: u32 = 0x0008_0000;
369 pub const CYRIX: u32 = 0x0010_0000;
371 pub const CYRIX_SMINT_0F7E: u32 = 0x0020_0000;
373 pub const CYRIX_DMI: u32 = 0x0040_0000;
375 pub const ALTINST: u32 = 0x0080_0000;
377 pub const KNC: u32 = 0x0100_0000;
379}
380pub(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}
393pub(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#[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, mod_: u32, reg: u32, rm: u32, extra_register_base: u32, extra_index_register_base: u32, extra_base_register_base: u32, extra_index_register_base_vsib: u32,
450 flags: u32, mandatory_prefix: DecoderMandatoryPrefix,
452
453 vvvv: u32, vvvv_invalid_check: u32, mem_index: u32, vector_length: VectorLength,
458 aaa: u32,
459 extra_register_base_evex: u32, extra_base_register_base_evex: u32, address_size: OpSize,
463 operand_size: OpSize,
464 segment_prio: u8, dummy: u8,
466 }
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#[allow(missing_debug_implementations)]
495#[allow(dead_code)]
496pub struct Decoder<'a>
497where
498 Self: Send + Sync,
499{
500 ip: u64,
502
503 data_ptr: usize,
508 data_ptr_end: usize,
513 max_data_ptr: usize,
520 instr_start_data_ptr: usize,
522
523 handlers_map0: &'static [(OpCodeHandlerDecodeFn, &'static OpCodeHandler); 0x100],
524 #[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 options: u32,
555 invalid_check_mask: u32,
557 is64b_mode_and_w: u32,
559 reg15_mask: u32,
561 mask_e0: u32,
563 rex_mask: u32,
564 bitness: u32,
565 default_address_size: OpSize,
567 default_operand_size: OpSize,
568 segment_prio: u8, dummy: u8, default_inverted_address_size: OpSize,
572 default_inverted_operand_size: OpSize,
573 is64b_mode: bool,
575 default_code_size: CodeSize,
576 displ_index: u8,
578
579 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 #[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 #[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 #[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 #[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 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 #[must_use]
1035 #[inline]
1036 pub const fn ip(&self) -> u64 {
1037 self.ip
1038 }
1039
1040 #[inline]
1050 pub fn set_ip(&mut self, new_value: u64) {
1051 self.ip = new_value;
1052 }
1053
1054 #[must_use]
1056 #[inline]
1057 pub const fn bitness(&self) -> u32 {
1058 self.bitness
1059 }
1060
1061 #[must_use]
1066 #[inline]
1067 pub const fn max_position(&self) -> usize {
1068 self.data.len()
1069 }
1070
1071 #[must_use]
1079 #[inline]
1080 pub fn position(&self) -> usize {
1081 self.data_ptr - self.data.as_ptr() as usize
1082 }
1083
1084 #[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 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 #[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 #[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 #[must_use]
1253 #[inline]
1254 pub const fn last_error(&self) -> DecoderError {
1255 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 #[must_use]
1303 #[inline]
1304 pub fn decode(&mut self) -> Instruction {
1305 let mut instruction = mem::MaybeUninit::uninit();
1306 unsafe {
1308 self.decode_out_ptr(instruction.as_mut_ptr());
1309 instruction.assume_init()
1310 }
1311 }
1312
1313 #[inline]
1356 pub fn decode_out(&mut self, instruction: &mut Instruction) {
1357 unsafe {
1358 self.decode_out_ptr(instruction);
1359 }
1360 }
1361
1362 #[allow(clippy::useless_let_if_seq)]
1364 unsafe fn decode_out_ptr(&mut self, instruction: *mut Instruction) {
1365 unsafe { ptr::write(instruction, Instruction::default()) };
1369 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 self.state.vvvv = 0;
1381 self.state.vvvv_invalid_check = 0;
1382
1383 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 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); 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 instruction.set_memory_displacement64(addr);
1429 if (flags & (StateFlags::IP_REL64 | StateFlags::IS_INVALID | StateFlags::LOCK)) == StateFlags::IP_REL64 {
1431 return;
1432 }
1433 if (flags & StateFlags::IP_REL64) == 0 {
1434 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 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_len >= IcedConstants::MAX_INSTRUCTION_LENGTH {
1454 flags &= !StateFlags::NO_MORE_BYTES;
1455 }
1456 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 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 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 self.state.mandatory_prefix = unsafe { mem::transmute(b & 3) };
1614
1615 b = !b;
1616 self.state.extra_register_base = (b >> 4) & 8;
1617
1618 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 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 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 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 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 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 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 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 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 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 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 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 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 #[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 #[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 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 #[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 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 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 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 #[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#[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 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 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 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 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}