aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG39
-rw-r--r--src/lib.rs4
-rw-r--r--src/long_mode/display.rs76
-rw-r--r--src/long_mode/mod.rs493
-rw-r--r--src/protected_mode/display.rs76
-rw-r--r--src/protected_mode/mod.rs483
-rw-r--r--src/real_mode/display.rs76
-rw-r--r--src/real_mode/mod.rs487
-rw-r--r--test/long_mode/operand.rs16
-rw-r--r--test/protected_mode/operand.rs12
10 files changed, 868 insertions, 894 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 3a0193e..26046bb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,44 @@
-## 1.3.0
+## 2.0.0
* upgrade to `yaxpeax-arch 0.3.1`, which brings with it a deprecation of the
`Colorize` and `ShowContextual` traits.
+* because common use of yaxpeax-x86 involves using both this crate and
+ `yaxpeax-arch`, moving to a newer major version of `yaxpeax-arch` is a major
+ version bump of `yaxpeax-x86` as well. so, 2.0.0!
+
+changes:
+
+* `Operand` variants have had their naming made more consistent.
+ - many variants starting with "Reg" actually describe a memory access. they
+ now begin with "Mem" instead.
+ - several variants mentioned "Scale" in their name, but not "Index", even
+ though they use an index register. they now do.
+ - several variants mentioned their constituent parts out of order. for
+ example, "RegIndexBaseScaleDisp", even though the parts were specified as
+ base, then index, then scale, then displacement. these names have been
+ adjusted to reflect the order of their fields, which is roughly the order
+ those fields are shown when printed.
+ - `DisplacementU*` operands have always been access to memory at the absolute
+ address they specify. their names are now `AbsoluteU*`
+* `Operand`, across the board, now uses struct-style enum variants, rather than tuple-style.
+* the two changes together mean an operand that was
+ `RegIndexBaseScaleDisp(reg, reg, u8, i32)`
+ is now
+ `MemBaseIndexScaleDisp { base, index, scale, disp }`
+ and similar for other variants.
+* two operand kinds, and their masked variants, were never actually constructed, and have been deleted.
+ - long ago yaxpeax-x86 returned different Operand variants when an index
+ register was used with scale 1, to hint that no scaling actually occurred.
+ this was eventually changed to return a scaling Operand variant with
+ scale==1, but the old variants remained.
+ - RegIndexBase has been removed
+ - RegIndexBaseDisp has been removed
+* `Prefixes::selects_cs()` has been moved to `Prefixes::cs()`, and the old
+ useless functions are no more. `inst.prefixes().cs()` is finally a reasonable
+ way to determine if an instruction reads or writes through the cs prefix.
+
+fixes:
+
* fix 32-bit call/jmp not respecting 66 prefix if set - such cases use 16-bit
operands, but decoded as if they used 32-bit operands.
diff --git a/src/lib.rs b/src/lib.rs
index 836a50c..7ab6cb8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -35,10 +35,10 @@
//! #[cfg(features="fmt")]
//! assert_eq!("xor eax, dword [rcx]", inst.to_string());
//!
-//! assert_eq!(Operand::Register(RegSpec::eax()), inst.operand(0));
+//! assert_eq!(Operand::Register { reg: RegSpec::eax() }, inst.operand(0));
//! #[cfg(features="fmt")]
//! assert_eq!("eax", inst.operand(0).to_string());
-//! assert_eq!(Operand::RegDeref(RegSpec::rcx()), inst.operand(1));
+//! assert_eq!(Operand::MemDeref { base: RegSpec::rcx() }, inst.operand(1));
//!
//! // an operand in isolation does not know the size of memory it references, if any
//! #[cfg(features="fmt")]
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs
index 6cf2def..469bb90 100644
--- a/src/long_mode/display.rs
+++ b/src/long_mode/display.rs
@@ -430,9 +430,9 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
#[cfg_attr(not(feature="profiling"), inline(always))]
#[cfg_attr(feature="profiling", inline(never))]
- fn visit_disp(&mut self, reg: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp(&mut self, base: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_char('[')?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(base)?;
self.f.write_fixed_size(" ")?;
{
@@ -447,23 +447,23 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
self.f.write_fixed_size("]")
}
- fn visit_deref(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref(&mut self, base: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(base)?;
self.f.write_fixed_size("]")
}
- fn visit_reg_scale(&mut self, reg: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale(&mut self, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size("]")?;
Ok(())
}
- fn visit_reg_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp(&mut self, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size(" ")?;
@@ -480,7 +480,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
self.f.write_char(']')
}
- fn visit_index_base_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -489,7 +489,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size("]")
}
- fn visit_index_base_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -510,9 +510,9 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
self.f.write_fixed_size("]")
}
- fn visit_reg_disp_masked(&mut self, spec: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp_masked(&mut self, base: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_char('[')?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(base)?;
self.f.write_char(' ')?;
let mut v = disp as u32;
if disp < 0 {
@@ -528,18 +528,18 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_reg_deref_masked(&mut self, spec: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref_masked(&mut self, base: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(base)?;
self.f.write_fixed_size("]")?;
self.f.write_char('{')?;
self.f.write_reg(mask_reg)?;
self.f.write_char('}')?;
Ok(())
}
- fn visit_reg_scale_masked(&mut self, spec: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_masked(&mut self, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size("]")?;
@@ -548,9 +548,9 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_reg_scale_disp_masked(&mut self, spec: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp_masked(&mut self, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size(" ")?;
@@ -568,7 +568,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -579,7 +579,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -599,7 +599,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -612,7 +612,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -3860,7 +3860,7 @@ pub(crate) fn contextualize_c<T: DisplaySink>(instr: &Instruction, out: &mut T)
let mut out = yaxpeax_arch::display::FmtSink::new(out);
use core::fmt::Write;
match op {
- Operand::ImmediateI8(rel) => {
+ Operand::ImmediateI8 { imm: rel } => {
let rel = if rel >= 0 {
out.write_str("$+")?;
rel as u8
@@ -3870,7 +3870,7 @@ pub(crate) fn contextualize_c<T: DisplaySink>(instr: &Instruction, out: &mut T)
};
out.write_prefixed_u8(rel)
}
- Operand::ImmediateI32(rel) => {
+ Operand::ImmediateI32 { imm: rel } => {
let rel = if rel >= 0 {
out.write_str("$+")?;
rel as u32
@@ -4272,10 +4272,10 @@ impl<'a, F: DisplaySink> super::OperandVisitor for RelativeBranchPrinter<'a, F>
fn visit_reg(&mut self, _reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_deref(&mut self, _reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref(&mut self, _base: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_disp(&mut self, _reg: RegSpec, _disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp(&mut self, _base: RegSpec, _disp: i32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
#[cfg_attr(feature="profiling", inline(never))]
@@ -4338,16 +4338,16 @@ impl<'a, F: DisplaySink> super::OperandVisitor for RelativeBranchPrinter<'a, F>
fn visit_abs_u64(&mut self, _imm: u64) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale(&mut self, _reg: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale(&mut self, _index: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale_disp(&mut self, _reg: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp(&mut self, _index: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale_disp(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
fn visit_other(&mut self) -> Result<Self::Ok, Self::Error> {
@@ -4362,28 +4362,28 @@ impl<'a, F: DisplaySink> super::OperandVisitor for RelativeBranchPrinter<'a, F>
fn visit_reg_mask_merge_sae_noround(&mut self, _spec: RegSpec, _mask: RegSpec, _merge_mode: MergeMode) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_disp_masked(&mut self, _spec: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp_masked(&mut self, _base: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_deref_masked(&mut self, _spec: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref_masked(&mut self, _base: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale_masked(&mut self, _spec: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_masked(&mut self, _index: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale_disp_masked(&mut self, _spec: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp_masked(&mut self, _index: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_masked(&mut self, _base: RegSpec, _index: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_masked(&mut self, _base: RegSpec, _index: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
}
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 0aaa35f..6dabd6d 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -368,91 +368,81 @@ enum SizeCode {
#[non_exhaustive]
pub enum Operand {
/// a sign-extended byte
- ImmediateI8(i8),
+ ImmediateI8 { imm: i8 },
/// a zero-extended byte
- ImmediateU8(u8),
+ ImmediateU8 { imm: u8 },
/// a sign-extended word
- ImmediateI16(i16),
+ ImmediateI16 { imm: i16 },
/// a zero-extended word
- ImmediateU16(u16),
+ ImmediateU16 { imm: u16 },
/// a sign-extended dword
- ImmediateI32(i32),
+ ImmediateI32 { imm: i32 },
/// a zero-extended dword
- ImmediateU32(u32),
+ ImmediateU32 { imm: u32 },
/// a sign-extended qword
- ImmediateI64(i64),
+ ImmediateI64 { imm: i64 },
/// a zero-extended qword
- ImmediateU64(u64),
+ ImmediateU64 { imm: u64 },
/// a bare register operand, such as `rcx`.
- Register(RegSpec),
+ Register { reg: RegSpec },
/// an `avx512` register operand with optional mask register and merge mode, such as
/// `zmm3{k4}{z}`.
///
/// if the mask register is `k0`, there is no masking applied, and the default x86 operation is
/// `MergeMode::Merge`.
- RegisterMaskMerge(RegSpec, RegSpec, MergeMode),
+ RegisterMaskMerge { reg: RegSpec, mask: RegSpec, merge: MergeMode },
/// an `avx512` register operand with optional mask register, merge mode, and suppressed
/// exceptions, such as `zmm3{k4}{z}{rd-sae}`.
///
/// if the mask register is `k0`, there is no masking applied, and the default x86 operation is
/// `MergeMode::Merge`.
- RegisterMaskMergeSae(RegSpec, RegSpec, MergeMode, SaeMode),
+ RegisterMaskMergeSae { reg: RegSpec, mask: RegSpec, merge: MergeMode, sae: SaeMode },
/// an `avx512` register operand with optional mask register, merge mode, and suppressed
/// exceptions, with no overridden rounding mode, such as `zmm3{k4}{z}{sae}`.
///
/// if the mask register is `k0`, there is no masking applied, and the default x86 operation is
/// `MergeMode::Merge`.
- RegisterMaskMergeSaeNoround(RegSpec, RegSpec, MergeMode),
+ RegisterMaskMergeSaeNoround { reg: RegSpec, mask: RegSpec, merge: MergeMode },
/// a memory access to a literal dword address. it's extremely rare that a well-formed x86
/// instruction uses this mode. as an example, `[0x1133]`
- DisplacementU32(u32),
+ AbsoluteU32 { addr: u32 },
/// a memory access to a literal qword address. it's relatively rare that a well-formed x86
/// instruction uses this mode, but plausible. for example, `gs:[0x14]`. segment overrides,
/// however, are maintained on the instruction itself.
- DisplacementU64(u64),
+ AbsoluteU64 { addr: u64 },
/// a simple dereference of the address held in some register. for example: `[rsi]`.
- RegDeref(RegSpec),
+ MemDeref { base: RegSpec },
/// a dereference of the address held in some register with offset. for example: `[rsi + 0x14]`.
- RegDisp(RegSpec, i32),
+ Disp { base: RegSpec, disp: i32 },
/// a dereference of the address held in some register scaled by 1, 2, 4, or 8. this is almost always used with the `lea` instruction. for example: `[rdx * 4]`.
- RegScale(RegSpec, u8),
- /// a dereference of the address from summing two registers. for example: `[rbp + rax]`
- RegIndexBase(RegSpec, RegSpec),
- /// a dereference of the address from summing two registers with offset. for example: `[rdi + rcx + 0x40]`
- RegIndexBaseDisp(RegSpec, RegSpec, i32),
+ MemIndexScale { index: RegSpec, scale: u8 },
/// a dereference of the address held in some register scaled by 1, 2, 4, or 8 with offset. this is almost always used with the `lea` instruction. for example: `[rax * 4 + 0x30]`.
- RegScaleDisp(RegSpec, u8, i32),
+ MemIndexScaleDisp { index: RegSpec, scale: u8, disp: i32 },
/// a dereference of the address from summing a register and index register scaled by 1, 2, 4,
/// or 8. for
/// example: `[rsi + rcx * 4]`
- RegIndexBaseScale(RegSpec, RegSpec, u8),
+ MemBaseIndexScale { base: RegSpec, index: RegSpec, scale: u8 },
/// a dereference of the address from summing a register and index register scaled by 1, 2, 4,
/// or 8, with offset. for
/// example: `[rsi + rcx * 4 + 0x1234]`
- RegIndexBaseScaleDisp(RegSpec, RegSpec, u8, i32),
+ MemBaseIndexScaleDisp { base: RegSpec, index: RegSpec, scale: u8, disp: i32 },
/// an `avx512` dereference of register with optional masking. for example: `[rdx]{k3}`
- RegDerefMasked(RegSpec, RegSpec),
+ MemDerefMasked { base: RegSpec, mask: RegSpec },
/// an `avx512` dereference of register plus offset, with optional masking. for example: `[rsp + 0x40]{k3}`
- RegDispMasked(RegSpec, i32, RegSpec),
+ DispMasked { base: RegSpec, disp: i32, mask: RegSpec },
/// an `avx512` dereference of a register scaled by 1, 2, 4, or 8, with optional masking. this
/// seems extraordinarily unlikely to occur in practice. for example: `[rsi * 4]{k2}`
- RegScaleMasked(RegSpec, u8, RegSpec),
- /// an `avx512` dereference of a register plus index scaled by 1, 2, 4, or 8, with optional masking.
- /// for example: `[rsi + rax * 4]{k6}`
- RegIndexBaseMasked(RegSpec, RegSpec, RegSpec),
- /// an `avx512` dereference of a register plus offset, with optional masking. for example:
- /// `[rsi + rax + 0x1313]{k6}`
- RegIndexBaseDispMasked(RegSpec, RegSpec, i32, RegSpec),
+ MemIndexScaleMasked { index: RegSpec, scale: u8, mask: RegSpec },
/// an `avx512` dereference of a register scaled by 1, 2, 4, or 8 plus offset, with optional
/// masking. this seems extraordinarily unlikely to occur in practice. for example: `[rsi *
/// 4 + 0x1357]{k2}`
- RegScaleDispMasked(RegSpec, u8, i32, RegSpec),
+ MemIndexScaleDispMasked { index: RegSpec, scale: u8, disp: i32, mask: RegSpec },
/// an `avx512` dereference of a register plus index scaled by 1, 2, 4, or 8, with optional
/// masking. for example: `[rsi + rax * 4]{k6}`
- RegIndexBaseScaleMasked(RegSpec, RegSpec, u8, RegSpec),
+ MemBaseIndexScaleMasked { base: RegSpec, index: RegSpec, scale: u8, mask: RegSpec },
/// an `avx512` dereference of a register plus index scaled by 1, 2, 4, or 8 and offset, with
/// optional masking. for example: `[rsi + rax * 4 + 0x1313]{k6}`
- RegIndexBaseScaleDispMasked(RegSpec, RegSpec, u8, i32, RegSpec),
+ MemBaseIndexScaleDispMasked { base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask: RegSpec },
/// no operand. it is a bug for `yaxpeax-x86` to construct an `Operand` of this kind for public
/// use; the instruction's `operand_count` should be reduced so as to make this invisible to
/// library clients.
@@ -466,11 +456,11 @@ impl OperandSpec {
OperandSpec::RegMMM => OperandSpec::RegMMM_maskmerge,
OperandSpec::RegVex => OperandSpec::RegVex_maskmerge,
OperandSpec::Deref => OperandSpec::Deref_mask,
- OperandSpec::RegDisp => OperandSpec::RegDisp_mask,
- OperandSpec::RegScale => OperandSpec::RegScale_mask,
- OperandSpec::RegScaleDisp => OperandSpec::RegScaleDisp_mask,
- OperandSpec::RegIndexBaseScale => OperandSpec::RegIndexBaseScale_mask,
- OperandSpec::RegIndexBaseScaleDisp => OperandSpec::RegIndexBaseScaleDisp_mask,
+ OperandSpec::Disp => OperandSpec::Disp_mask,
+ OperandSpec::MemIndexScale => OperandSpec::MemIndexScale_mask,
+ OperandSpec::MemIndexScaleDisp => OperandSpec::MemIndexScaleDisp_mask,
+ OperandSpec::MemBaseIndexScale => OperandSpec::MemBaseIndexScale_mask,
+ OperandSpec::MemBaseIndexScaleDisp => OperandSpec::MemBaseIndexScaleDisp_mask,
o => o,
}
}
@@ -551,10 +541,10 @@ pub trait OperandVisitor {
fn visit_reg(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error>;
fn visit_deref(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error>;
fn visit_disp(&mut self, reg: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale(&mut self, reg: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale(&mut self, reg: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
fn visit_i8(&mut self, imm: i8) -> Result<Self::Ok, Self::Error>;
fn visit_u8(&mut self, imm: u8) -> Result<Self::Ok, Self::Error>;
fn visit_i16(&mut self, imm: i16) -> Result<Self::Ok, Self::Error>;
@@ -568,14 +558,14 @@ pub trait OperandVisitor {
fn visit_reg_mask_merge(&mut self, base: RegSpec, mask: RegSpec, merge_mode: MergeMode) -> Result<Self::Ok, Self::Error>;
fn visit_reg_mask_merge_sae(&mut self, base: RegSpec, mask: RegSpec, merge_mode: MergeMode, sae_mode: SaeMode) -> Result<Self::Ok, Self::Error>;
fn visit_reg_mask_merge_sae_noround(&mut self, base: RegSpec, mask: RegSpec, merge_mode: MergeMode) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_disp_masked(&mut self, base: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_deref_masked(&mut self, base: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale_masked(&mut self, base: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale_disp_masked(&mut self, base: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_disp_masked(&mut self, base: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_deref_masked(&mut self, base: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale_masked(&mut self, base: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale_disp_masked(&mut self, base: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
fn visit_other(&mut self) -> Result<Self::Ok, Self::Error>;
}
@@ -588,140 +578,140 @@ impl Operand {
}
// the register in modrm_rrr
OperandSpec::RegRRR => {
- Operand::Register(inst.regs[0])
+ Operand::Register { reg: inst.regs[0] }
}
OperandSpec::RegRRR_maskmerge => {
- Operand::RegisterMaskMerge(
- inst.regs[0],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMerge {
+ reg: inst.regs[0],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::RegRRR_maskmerge_sae => {
- Operand::RegisterMaskMergeSae(
- inst.regs[0],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- SaeMode::from(inst.prefixes.evex_unchecked().vex().l(), inst.prefixes.evex_unchecked().lp()),
- )
+ Operand::RegisterMaskMergeSae {
+ reg: inst.regs[0],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ sae: SaeMode::from(inst.prefixes.evex_unchecked().vex().l(), inst.prefixes.evex_unchecked().lp()),
+ }
}
OperandSpec::RegRRR_maskmerge_sae_noround => {
- Operand::RegisterMaskMergeSaeNoround(
- inst.regs[0],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMergeSaeNoround {
+ reg: inst.regs[0],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
// the register in modrm_mmm (eg modrm mod bits were 11)
OperandSpec::RegMMM => {
- Operand::Register(inst.regs[1])
+ Operand::Register { reg: inst.regs[1] }
}
OperandSpec::RegMMM_maskmerge => {
- Operand::RegisterMaskMerge(
- inst.regs[1],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMerge {
+ reg: inst.regs[1],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::RegMMM_maskmerge_sae_noround => {
- Operand::RegisterMaskMergeSaeNoround(
- inst.regs[1],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMergeSaeNoround {
+ reg: inst.regs[1],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::RegVex => {
- Operand::Register(inst.regs[3])
+ Operand::Register { reg: inst.regs[3]}
}
OperandSpec::RegVex_maskmerge => {
- Operand::RegisterMaskMerge(
- inst.regs[3],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMerge {
+ reg: inst.regs[3],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::Reg4 => {
- Operand::Register(RegSpec { num: inst.imm as u8, bank: inst.regs[3].bank })
- }
- OperandSpec::ImmI8 => Operand::ImmediateI8(inst.imm as i8),
- OperandSpec::ImmU8 => Operand::ImmediateU8(inst.imm as u8),
- OperandSpec::ImmI16 => Operand::ImmediateI16(inst.imm as i16),
- OperandSpec::ImmU16 => Operand::ImmediateU16(inst.imm as u16),
- OperandSpec::ImmI32 => Operand::ImmediateI32(inst.imm as i32),
- OperandSpec::ImmI64 => Operand::ImmediateI64(inst.imm as i64),
- OperandSpec::ImmInDispField => Operand::ImmediateU16(inst.disp as u16),
- OperandSpec::DispU32 => Operand::DisplacementU32(inst.disp as u32),
- OperandSpec::DispU64 => Operand::DisplacementU64(inst.disp as u64),
+ Operand::Register { reg: RegSpec { num: inst.imm as u8, bank: inst.regs[3].bank }}
+ }
+ OperandSpec::ImmI8 => Operand::ImmediateI8 { imm: inst.imm as i8 },
+ OperandSpec::ImmU8 => Operand::ImmediateU8 { imm: inst.imm as u8 },
+ OperandSpec::ImmI16 => Operand::ImmediateI16 { imm: inst.imm as i16 },
+ OperandSpec::ImmU16 => Operand::ImmediateU16 { imm: inst.imm as u16 },
+ OperandSpec::ImmI32 => Operand::ImmediateI32 { imm: inst.imm as i32 },
+ OperandSpec::ImmI64 => Operand::ImmediateI64 { imm: inst.imm as i64 },
+ OperandSpec::ImmInDispField => Operand::ImmediateU16 { imm: inst.disp as u16 },
+ OperandSpec::DispU32 => Operand::AbsoluteU32 { addr: inst.disp as u32 },
+ OperandSpec::DispU64 => Operand::AbsoluteU64 { addr: inst.disp as u64 },
OperandSpec::Deref => {
- Operand::RegDeref(inst.regs[1])
+ Operand::MemDeref { base: inst.regs[1] }
}
OperandSpec::Deref_esi => {
- Operand::RegDeref(RegSpec::esi())
+ Operand::MemDeref { base: RegSpec::esi() }
}
OperandSpec::Deref_edi => {
- Operand::RegDeref(RegSpec::edi())
+ Operand::MemDeref { base: RegSpec::edi() }
}
OperandSpec::Deref_rsi => {
- Operand::RegDeref(RegSpec::rsi())
+ Operand::MemDeref { base: RegSpec::rsi() }
}
OperandSpec::Deref_rdi => {
- Operand::RegDeref(RegSpec::rdi())
+ Operand::MemDeref { base: RegSpec::rdi() }
}
- OperandSpec::RegDisp => {
- Operand::RegDisp(inst.regs[1], inst.disp as i32)
+ OperandSpec::Disp => {
+ Operand::Disp { base: inst.regs[1], disp: inst.disp as i32 }
}
- OperandSpec::RegScale => {
- Operand::RegScale(inst.regs[2], inst.scale)
+ OperandSpec::MemIndexScale => {
+ Operand::MemIndexScale { index: inst.regs[2], scale: inst.scale }
}
- OperandSpec::RegScaleDisp => {
- Operand::RegScaleDisp(inst.regs[2], inst.scale, inst.disp as i32)
+ OperandSpec::MemIndexScaleDisp => {
+ Operand::MemIndexScaleDisp { index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
- OperandSpec::RegIndexBaseScale => {
- Operand::RegIndexBaseScale(inst.regs[1], inst.regs[2], inst.scale)
+ OperandSpec::MemBaseIndexScale => {
+ Operand::MemBaseIndexScale { base: inst.regs[1], index: inst.regs[2], scale: inst.scale }
}
- OperandSpec::RegIndexBaseScaleDisp => {
- Operand::RegIndexBaseScaleDisp(inst.regs[1], inst.regs[2], inst.scale, inst.disp as i32)
+ OperandSpec::MemBaseIndexScaleDisp => {
+ Operand::MemBaseIndexScaleDisp { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
OperandSpec::Deref_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegDerefMasked(inst.regs[1], RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemDerefMasked { base: inst.regs[1], mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegDeref(inst.regs[1])
+ Operand::MemDeref { base: inst.regs[1] }
}
}
- OperandSpec::RegDisp_mask => {
+ OperandSpec::Disp_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegDispMasked(inst.regs[1], inst.disp as i32, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::DispMasked { base: inst.regs[1], disp: inst.disp as i32, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegDisp(inst.regs[1], inst.disp as i32)
+ Operand::Disp { base: inst.regs[1], disp: inst.disp as i32 }
}
}
- OperandSpec::RegScale_mask => {
+ OperandSpec::MemIndexScale_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegScaleMasked(inst.regs[2], inst.scale, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemIndexScaleMasked { index: inst.regs[2], scale: inst.scale, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegScale(inst.regs[2], inst.scale)
+ Operand::MemIndexScale { index: inst.regs[2], scale: inst.scale }
}
}
- OperandSpec::RegScaleDisp_mask => {
+ OperandSpec::MemIndexScaleDisp_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegScaleDispMasked(inst.regs[2], inst.scale, inst.disp as i32, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemIndexScaleDispMasked { index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegScaleDisp(inst.regs[2], inst.scale, inst.disp as i32)
+ Operand::MemIndexScaleDisp { index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
}
- OperandSpec::RegIndexBaseScale_mask => {
+ OperandSpec::MemBaseIndexScale_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegIndexBaseScaleMasked(inst.regs[1], inst.regs[2], inst.scale, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemBaseIndexScaleMasked { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegIndexBaseScale(inst.regs[1], inst.regs[2], inst.scale)
+ Operand::MemBaseIndexScale { base: inst.regs[1], index: inst.regs[2], scale: inst.scale }
}
}
- OperandSpec::RegIndexBaseScaleDisp_mask => {
+ OperandSpec::MemBaseIndexScaleDisp_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegIndexBaseScaleDispMasked(inst.regs[1], inst.regs[2], inst.scale, inst.disp as i32, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemBaseIndexScaleDispMasked { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegIndexBaseScaleDisp(inst.regs[1], inst.regs[2], inst.scale, inst.disp as i32)
+ Operand::MemBaseIndexScaleDisp { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
}
}
@@ -733,38 +723,34 @@ impl Operand {
/// memory.
pub fn is_memory(&self) -> bool {
match self {
- Operand::DisplacementU32(_) |
- Operand::DisplacementU64(_) |
- Operand::RegDeref(_) |
- Operand::RegDisp(_, _) |
- Operand::RegScale(_, _) |
- Operand::RegIndexBase(_, _) |
- Operand::RegIndexBaseDisp(_, _, _) |
- Operand::RegScaleDisp(_, _, _) |
- Operand::RegIndexBaseScale(_, _, _) |
- Operand::RegIndexBaseScaleDisp(_, _, _, _) |
- Operand::RegDerefMasked(_, _) |
- Operand::RegDispMasked(_, _, _) |
- Operand::RegScaleMasked(_, _, _) |
- Operand::RegIndexBaseMasked(_, _, _) |
- Operand::RegIndexBaseDispMasked(_, _, _, _) |
- Operand::RegScaleDispMasked(_, _, _, _) |
- Operand::RegIndexBaseScaleMasked(_, _, _, _) |
- Operand::RegIndexBaseScaleDispMasked(_, _, _, _, _) => {
+ Operand::AbsoluteU32 { .. } |
+ Operand::AbsoluteU64 { .. } |
+ Operand::MemDeref { .. } |
+ Operand::Disp { .. } |
+ Operand::MemIndexScale { .. } |
+ Operand::MemIndexScaleDisp { .. } |
+ Operand::MemBaseIndexScale { .. } |
+ Operand::MemBaseIndexScaleDisp { .. } |
+ Operand::MemDerefMasked { .. } |
+ Operand::DispMasked { .. } |
+ Operand::MemIndexScaleMasked { .. } |
+ Operand::MemIndexScaleDispMasked { .. } |
+ Operand::MemBaseIndexScaleMasked { .. } |
+ Operand::MemBaseIndexScaleDispMasked { .. } => {
true
},
- Operand::ImmediateI8(_) |
- Operand::ImmediateU8(_) |
- Operand::ImmediateI16(_) |
- Operand::ImmediateU16(_) |
- Operand::ImmediateU32(_) |
- Operand::ImmediateI32(_) |
- Operand::ImmediateU64(_) |
- Operand::ImmediateI64(_) |
- Operand::Register(_) |
- Operand::RegisterMaskMerge(_, _, _) |
- Operand::RegisterMaskMergeSae(_, _, _, _) |
- Operand::RegisterMaskMergeSaeNoround(_, _, _) |
+ Operand::ImmediateI8 { .. } |
+ Operand::ImmediateU8 { .. } |
+ Operand::ImmediateI16 { .. } |
+ Operand::ImmediateU16 { .. } |
+ Operand::ImmediateU32 { .. } |
+ Operand::ImmediateI32 { .. } |
+ Operand::ImmediateU64 { .. } |
+ Operand::ImmediateI64 { .. } |
+ Operand::Register { .. } |
+ Operand::RegisterMaskMerge { .. } |
+ Operand::RegisterMaskMergeSae { .. } |
+ Operand::RegisterMaskMergeSaeNoround { .. } |
Operand::Nothing => {
false
}
@@ -776,26 +762,26 @@ impl Operand {
/// `Operand` came from; `None` here means the authoritative width is `instr.mem_size()`.
pub fn width(&self) -> Option<u8> {
match self {
- Operand::Register(reg) => {
+ Operand::Register { reg } => {
Some(reg.width())
}
- Operand::RegisterMaskMerge(reg, _, _) => {
+ Operand::RegisterMaskMerge { reg, .. } => {
Some(reg.width())
}
- Operand::ImmediateI8(_) |
- Operand::ImmediateU8(_) => {
+ Operand::ImmediateI8 { .. } |
+ Operand::ImmediateU8 { .. } => {
Some(1)
}
- Operand::ImmediateI16(_) |
- Operand::ImmediateU16(_) => {
+ Operand::ImmediateI16 { .. } |
+ Operand::ImmediateU16 { .. } => {
Some(2)
}
- Operand::ImmediateI32(_) |
- Operand::ImmediateU32(_) => {
+ Operand::ImmediateI32 { .. } |
+ Operand::ImmediateU32 { .. } => {
Some(4)
}
- Operand::ImmediateI64(_) |
- Operand::ImmediateU64(_) => {
+ Operand::ImmediateI64 { .. } |
+ Operand::ImmediateU64 { .. } => {
Some(8)
}
// memory operands or `Nothing`
@@ -813,42 +799,38 @@ impl Operand {
Operand::Nothing => {
visitor.visit_other()
}
- Operand::Register(reg) => {
+ Operand::Register { reg } => {
visitor.visit_reg(*reg)
}
- Operand::RegDeref(reg) => {
- visitor.visit_deref(*reg)
- }
- Operand::RegDisp(reg, disp) => {
- visitor.visit_disp(*reg, *disp)
- }
- Operand::ImmediateI8(imm) => visitor.visit_i8(*imm),
- Operand::ImmediateU8(imm) => visitor.visit_u8(*imm),
- Operand::ImmediateI16(imm) => visitor.visit_i16(*imm),
- Operand::ImmediateU16(imm) => visitor.visit_u16(*imm),
- Operand::ImmediateI32(imm) => visitor.visit_i32(*imm),
- Operand::ImmediateU32(imm) => visitor.visit_u32(*imm),
- Operand::ImmediateI64(imm) => visitor.visit_i64(*imm),
- Operand::ImmediateU64(imm) => visitor.visit_u64(*imm),
- Operand::DisplacementU32(disp) => visitor.visit_abs_u32(*disp),
- Operand::DisplacementU64(disp) => visitor.visit_abs_u64(*disp),
- Operand::RegScale(reg, scale) => visitor.visit_reg_scale(*reg, *scale),
- Operand::RegScaleDisp(reg, scale, disp) => visitor.visit_reg_scale_disp(*reg, *scale, *disp),
- Operand::RegIndexBase(_, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegIndexBaseDisp(_, _, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegIndexBaseScale(base, index, scale) => visitor.visit_index_base_scale(*base, *index, *scale),
- Operand::RegIndexBaseScaleDisp(base, index, scale, disp) => visitor.visit_index_base_scale_disp(*base, *index, *scale, *disp),
- Operand::RegisterMaskMerge(reg, mask, merge) => visitor.visit_reg_mask_merge(*reg, *mask, *merge),
- Operand::RegisterMaskMergeSae(reg, mask, merge, sae) => visitor.visit_reg_mask_merge_sae(*reg, *mask, *merge, *sae),
- Operand::RegisterMaskMergeSaeNoround(reg, mask, merge) => visitor.visit_reg_mask_merge_sae_noround(*reg, *mask, *merge),
- Operand::RegDerefMasked(reg, mask) => visitor.visit_reg_deref_masked(*reg, *mask),
- Operand::RegDispMasked(reg, disp, mask) => visitor.visit_reg_disp_masked(*reg, *disp, *mask),
- Operand::RegScaleMasked(reg, scale, mask) => visitor.visit_reg_scale_masked(*reg, *scale, *mask),
- Operand::RegIndexBaseMasked(_, _, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegIndexBaseDispMasked(_, _, _, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegScaleDispMasked(base, scale, disp, mask) => visitor.visit_reg_scale_disp_masked(*base, *scale, *disp, *mask),
- Operand::RegIndexBaseScaleMasked(base, index, scale, mask) => visitor.visit_index_base_scale_masked(*base, *index, *scale, *mask),
- Operand::RegIndexBaseScaleDispMasked(base, index, scale, disp, mask) => visitor.visit_index_base_scale_disp_masked(*base, *index, *scale, *disp, *mask),
+ Operand::MemDeref { base } => {
+ visitor.visit_deref(*base)
+ }
+ Operand::Disp { base, disp } => {
+ visitor.visit_disp(*base, *disp)
+ }
+ Operand::ImmediateI8 { imm } => visitor.visit_i8(*imm),
+ Operand::ImmediateU8 { imm } => visitor.visit_u8(*imm),
+ Operand::ImmediateI16 { imm } => visitor.visit_i16(*imm),
+ Operand::ImmediateU16 { imm } => visitor.visit_u16(*imm),
+ Operand::ImmediateI32 { imm } => visitor.visit_i32(*imm),
+ Operand::ImmediateU32 { imm } => visitor.visit_u32(*imm),
+ Operand::ImmediateI64 { imm } => visitor.visit_i64(*imm),
+ Operand::ImmediateU64 { imm } => visitor.visit_u64(*imm),
+ Operand::AbsoluteU32 { addr } => visitor.visit_abs_u32(*addr),
+ Operand::AbsoluteU64 { addr } => visitor.visit_abs_u64(*addr),
+ Operand::MemIndexScale { index, scale } => visitor.visit_index_scale(*index, *scale),
+ Operand::MemIndexScaleDisp { index, scale, disp } => visitor.visit_index_scale_disp(*index, *scale, *disp),
+ Operand::MemBaseIndexScale { base, index, scale } => visitor.visit_base_index_scale(*base, *index, *scale),
+ Operand::MemBaseIndexScaleDisp { base, index, scale, disp } => visitor.visit_base_index_scale_disp(*base, *index, *scale, *disp),
+ Operand::RegisterMaskMerge { reg, mask, merge } => visitor.visit_reg_mask_merge(*reg, *mask, *merge),
+ Operand::RegisterMaskMergeSae { reg, mask, merge, sae } => visitor.visit_reg_mask_merge_sae(*reg, *mask, *merge, *sae),
+ Operand::RegisterMaskMergeSaeNoround { reg, mask, merge } => visitor.visit_reg_mask_merge_sae_noround(*reg, *mask, *merge),
+ Operand::MemDerefMasked { base, mask } => visitor.visit_deref_masked(*base, *mask),
+ Operand::DispMasked { base, disp, mask } => visitor.visit_disp_masked(*base, *disp, *mask),
+ Operand::MemIndexScaleMasked { index, scale, mask } => visitor.visit_index_scale_masked(*index, *scale, *mask),
+ Operand::MemIndexScaleDispMasked { index, scale, disp, mask } => visitor.visit_index_scale_disp_masked(*index, *scale, *disp, *mask),
+ Operand::MemBaseIndexScaleMasked { base, index, scale, mask } => visitor.visit_base_index_scale_masked(*base, *index, *scale, *mask),
+ Operand::MemBaseIndexScaleDispMasked { base, index, scale, disp, mask } => visitor.visit_base_index_scale_disp_masked(*base, *index, *scale, *disp, *mask),
}
}
}
@@ -941,16 +923,16 @@ const REGISTER_CLASS_NAMES: &[&'static str] = &[
/// }
/// }
///
-/// if let Operand::Register(regspec) = instruction.operand(0) {
+/// if let Operand::Register { reg } = instruction.operand(0) {
/// #[cfg(feature="fmt")]
-/// println!("first operand is {}", regspec);
-/// show_register_class_info(regspec.class());
+/// println!("first operand is {}", reg);
+/// show_register_class_info(reg.class());
/// }
///
-/// if let Operand::Register(regspec) = instruction.operand(1) {
+/// if let Operand::Register { reg } = instruction.operand(1) {
/// #[cfg(feature="fmt")]
-/// println!("first operand is {}", regspec);
-/// show_register_class_info(regspec.class());
+/// println!("first operand is {}", reg);
+/// show_register_class_info(reg.class());
/// }
/// ```
///
@@ -2753,17 +2735,17 @@ enum OperandSpec {
Deref_edi = 0x90,
Deref_rsi = 0x91,
Deref_rdi = 0x92,
- RegDisp = 0x93,
- RegScale = 0x94,
- RegScaleDisp = 0x95,
- RegIndexBaseScale = 0x96,
- RegIndexBaseScaleDisp = 0x97,
+ Disp = 0x93,
+ MemIndexScale = 0x94,
+ MemIndexScaleDisp = 0x95,
+ MemBaseIndexScale = 0x96,
+ MemBaseIndexScaleDisp = 0x97,
Deref_mask = 0xce,
- RegDisp_mask = 0xd3,
- RegScale_mask = 0xd4,
- RegScaleDisp_mask = 0xd5,
- RegIndexBaseScale_mask = 0xd6,
- RegIndexBaseScaleDisp_mask = 0xd7,
+ Disp_mask = 0xd3,
+ MemIndexScale_mask = 0xd4,
+ MemIndexScaleDisp_mask = 0xd5,
+ MemBaseIndexScale_mask = 0xd6,
+ MemBaseIndexScaleDisp_mask = 0xd7,
}
// the Hash, Eq, and PartialEq impls here are possibly misleading.
@@ -4471,7 +4453,7 @@ impl Instruction {
// visitor.visit_other()
visitor.visit_deref(RegSpec::rdi())
}
- OperandSpec::RegDisp => {
+ OperandSpec::Disp => {
visitor.visit_disp(self.regs[1], self.disp as i32)
}
OperandSpec::RegRRR_maskmerge => {
@@ -4526,61 +4508,58 @@ impl Instruction {
OperandSpec::ImmInDispField => visitor.visit_u16(self.disp as u16),
OperandSpec::DispU32 => visitor.visit_abs_u32(self.disp as u32),
OperandSpec::DispU64 => visitor.visit_abs_u64(self.disp as u64),
- OperandSpec::RegScale => {
- visitor.visit_reg_scale(self.regs[2], self.scale)
+ OperandSpec::MemIndexScale => {
+ visitor.visit_index_scale(self.regs[2], self.scale)
}
- OperandSpec::RegScaleDisp => {
- visitor.visit_reg_scale_disp(self.regs[2], self.scale, self.disp as i32)
+ OperandSpec::MemIndexScaleDisp => {
+ visitor.visit_index_scale_disp(self.regs[2], self.scale, self.disp as i32)
}
- OperandSpec::RegIndexBaseScale => {
- visitor.visit_index_base_scale(self.regs[1], self.regs[2], self.scale)
- /*
- Operand::RegIndexBaseScale(self.regs[1], self.regs[2], self.scale)
- */
+ OperandSpec::MemBaseIndexScale => {
+ visitor.visit_base_index_scale(self.regs[1], self.regs[2], self.scale)
}
- OperandSpec::RegIndexBaseScaleDisp => {
- visitor.visit_index_base_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
+ OperandSpec::MemBaseIndexScaleDisp => {
+ visitor.visit_base_index_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
}
OperandSpec::Deref_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_deref_masked(self.regs[1], RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_deref_masked(self.regs[1], RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
visitor.visit_deref(self.regs[1])
}
}
- OperandSpec::RegDisp_mask => {
+ OperandSpec::Disp_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_disp_masked(self.regs[1], self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_disp_masked(self.regs[1], self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
visitor.visit_disp(self.regs[1], self.disp as i32)
}
}
- OperandSpec::RegScale_mask => {
+ OperandSpec::MemIndexScale_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_scale_masked(self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_index_scale_masked(self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_reg_scale(self.regs[2], self.scale)
+ visitor.visit_index_scale(self.regs[2], self.scale)
}
}
- OperandSpec::RegScaleDisp_mask => {
+ OperandSpec::MemIndexScaleDisp_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_scale_disp_masked(self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_index_scale_disp_masked(self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_reg_scale_disp(self.regs[2], self.scale, self.disp as i32)
+ visitor.visit_index_scale_disp(self.regs[2], self.scale, self.disp as i32)
}
}
- OperandSpec::RegIndexBaseScale_mask => {
+ OperandSpec::MemBaseIndexScale_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_index_base_scale_masked(self.regs[1], self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_base_index_scale_masked(self.regs[1], self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_index_base_scale(self.regs[1], self.regs[2], self.scale)
+ visitor.visit_base_index_scale(self.regs[1], self.regs[2], self.scale)
}
}
- OperandSpec::RegIndexBaseScaleDisp_mask => {
+ OperandSpec::MemBaseIndexScaleDisp_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_index_base_scale_disp_masked(self.regs[1], self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_base_index_scale_disp_masked(self.regs[1], self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_index_base_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
+ visitor.visit_base_index_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
}
}
}
@@ -6253,7 +6232,7 @@ fn read_sib<
InnerDescription::Misc("mod bits select no base register")
.with_id(sib_start + 0)
);
- OperandSpec::RegScale
+ OperandSpec::MemIndexScale
} else {
sink.record(
modrm_start + 6,
@@ -6261,7 +6240,7 @@ fn read_sib<
InnerDescription::RegisterNumber("mod", 0b101, instr.regs[1])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScale
+ OperandSpec::MemBaseIndexScale
}
}
} else {
@@ -6280,7 +6259,7 @@ fn read_sib<
InnerDescription::RegisterNumber("iii", instr.regs[2].num & 0b111, instr.regs[2])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScale
+ OperandSpec::MemBaseIndexScale
}
}
@@ -6314,7 +6293,7 @@ fn read_sib<
InnerDescription::RegisterNumber("mod", 0b101, instr.regs[1])
.with_id(sib_start + 0)
);
- OperandSpec::RegDisp
+ OperandSpec::Disp
}
} else {
sink.record(
@@ -6330,7 +6309,7 @@ fn read_sib<
InnerDescription::Misc("mod bits select no base register, [index+disp] only")
.with_id(sib_start + 0)
);
- OperandSpec::RegScaleDisp
+ OperandSpec::MemIndexScaleDisp
} else {
sink.record(
modrm_start + 6,
@@ -6338,7 +6317,7 @@ fn read_sib<
InnerDescription::RegisterNumber("mod", 0b101, instr.regs[1])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScaleDisp
+ OperandSpec::MemBaseIndexScaleDisp
}
}
} else {
@@ -6355,7 +6334,7 @@ fn read_sib<
InnerDescription::Misc("iii + rex.x selects no index register")
.with_id(sib_start + 0)
);
- OperandSpec::RegDisp
+ OperandSpec::Disp
} else {
sink.record(
sib_start + 3,
@@ -6363,7 +6342,7 @@ fn read_sib<
InnerDescription::RegisterNumber("iii", instr.regs[2].num & 0b111, instr.regs[2])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScaleDisp
+ OperandSpec::MemBaseIndexScaleDisp
}
}
};
@@ -6449,7 +6428,7 @@ fn read_M<
OperandSpec::Deref
} else {
instr.disp = disp as i64 as u64;
- OperandSpec::RegDisp
+ OperandSpec::Disp
}
} else {
sink.record(
@@ -6491,7 +6470,7 @@ fn read_M<
OperandSpec::Deref
} else {
instr.disp = disp as i64 as u64;
- OperandSpec::RegDisp
+ OperandSpec::Disp
}
}
};
diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs
index dc31dbf..1629b4e 100644
--- a/src/protected_mode/display.rs
+++ b/src/protected_mode/display.rs
@@ -406,9 +406,9 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
#[cfg_attr(not(feature="profiling"), inline(always))]
#[cfg_attr(feature="profiling", inline(never))]
- fn visit_disp(&mut self, reg: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp(&mut self, base: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_char('[')?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(base)?;
self.f.write_fixed_size(" ")?;
{
@@ -423,23 +423,23 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
self.f.write_fixed_size("]")
}
- fn visit_deref(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref(&mut self, base: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(base)?;
self.f.write_fixed_size("]")
}
- fn visit_reg_scale(&mut self, reg: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale(&mut self, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size("]")?;
Ok(())
}
- fn visit_reg_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp(&mut self, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size(" ")?;
@@ -456,7 +456,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
self.f.write_char(']')
}
- fn visit_index_base_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -465,7 +465,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size("]")
}
- fn visit_index_base_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -486,9 +486,9 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
self.f.write_fixed_size("]")
}
- fn visit_reg_disp_masked(&mut self, spec: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp_masked(&mut self, base: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_char('[')?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(base)?;
self.f.write_char(' ')?;
let mut v = disp as u32;
if disp < 0 {
@@ -504,18 +504,18 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_reg_deref_masked(&mut self, spec: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref_masked(&mut self, base: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(base)?;
self.f.write_fixed_size("]")?;
self.f.write_char('{')?;
self.f.write_reg(mask_reg)?;
self.f.write_char('}')?;
Ok(())
}
- fn visit_reg_scale_masked(&mut self, spec: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_masked(&mut self, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size("]")?;
@@ -524,9 +524,9 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_reg_scale_disp_masked(&mut self, spec: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp_masked(&mut self, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size(" ")?;
@@ -544,7 +544,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -555,7 +555,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -575,7 +575,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -588,7 +588,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -2420,7 +2420,7 @@ pub(crate) fn contextualize_c<T: DisplaySink>(instr: &Instruction, out: &mut T)
let mut out = yaxpeax_arch::display::FmtSink::new(out);
use core::fmt::Write;
match op {
- Operand::ImmediateI8(rel) => {
+ Operand::ImmediateI8 { imm: rel } => {
let rel = if rel >= 0 {
out.write_str("$+")?;
rel as u8
@@ -2430,7 +2430,7 @@ pub(crate) fn contextualize_c<T: DisplaySink>(instr: &Instruction, out: &mut T)
};
out.write_prefixed_u8(rel)
}
- Operand::ImmediateI32(rel) => {
+ Operand::ImmediateI32 { imm: rel } => {
let rel = if rel >= 0 {
out.write_str("$+")?;
rel as u32
@@ -2824,10 +2824,10 @@ impl<'a, F: DisplaySink> super::OperandVisitor for RelativeBranchPrinter<'a, F>
fn visit_reg(&mut self, _reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_deref(&mut self, _reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref(&mut self, _base: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_disp(&mut self, _reg: RegSpec, _disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp(&mut self, _base: RegSpec, _disp: i32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
#[cfg_attr(feature="profiling", inline(never))]
@@ -2884,16 +2884,16 @@ impl<'a, F: DisplaySink> super::OperandVisitor for RelativeBranchPrinter<'a, F>
fn visit_abs_u32(&mut self, _imm: u32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale(&mut self, _reg: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale(&mut self, _index: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale_disp(&mut self, _reg: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp(&mut self, _index: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale_disp(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
fn visit_other(&mut self) -> Result<Self::Ok, Self::Error> {
@@ -2908,28 +2908,28 @@ impl<'a, F: DisplaySink> super::OperandVisitor for RelativeBranchPrinter<'a, F>
fn visit_reg_mask_merge_sae_noround(&mut self, _spec: RegSpec, _mask: RegSpec, _merge_mode: MergeMode) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_disp_masked(&mut self, _spec: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp_masked(&mut self, _base: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_deref_masked(&mut self, _spec: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref_masked(&mut self, _base: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale_masked(&mut self, _spec: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_masked(&mut self, _index: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale_disp_masked(&mut self, _spec: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp_masked(&mut self, _index: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_masked(&mut self, _base: RegSpec, _index: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_masked(&mut self, _base: RegSpec, _index: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
fn visit_absolute_far_address(&mut self, _segment: u16, _address: u32) -> Result<Self::Ok, Self::Error> {
diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs
index 154a746..081be20 100644
--- a/src/protected_mode/mod.rs
+++ b/src/protected_mode/mod.rs
@@ -306,87 +306,77 @@ enum SizeCode {
#[non_exhaustive]
pub enum Operand {
/// a sign-extended byte
- ImmediateI8(i8),
+ ImmediateI8 { imm: i8 },
/// a zero-extended byte
- ImmediateU8(u8),
+ ImmediateU8 { imm: u8 },
/// a sign-extended word
- ImmediateI16(i16),
+ ImmediateI16 { imm: i16 },
/// a zero-extended word
- ImmediateU16(u16),
+ ImmediateU16 { imm: u16 },
/// a sign-extended dword
- ImmediateI32(i32),
+ ImmediateI32 { imm: i32 },
/// a zero-extended dword
- ImmediateU32(u32),
+ ImmediateU32 { imm: u32 },
/// a bare register operand, such as `rcx`.
- Register(RegSpec),
+ Register { reg: RegSpec },
/// an `avx512` register operand with optional mask register and merge mode, such as
/// `zmm3{k4}{z}`.
///
/// if the mask register is `k0`, there is no masking applied, and the default x86 operation is
/// `MergeMode::Merge`.
- RegisterMaskMerge(RegSpec, RegSpec, MergeMode),
+ RegisterMaskMerge { reg: RegSpec, mask: RegSpec, merge: MergeMode },
/// an `avx512` register operand with optional mask register, merge mode, and suppressed
/// exceptions, such as `zmm3{k4}{z}{rd-sae}`.
///
/// if the mask register is `k0`, there is no masking applied, and the default x86 operation is
/// `MergeMode::Merge`.
- RegisterMaskMergeSae(RegSpec, RegSpec, MergeMode, SaeMode),
+ RegisterMaskMergeSae { reg: RegSpec, mask: RegSpec, merge: MergeMode, sae: SaeMode },
/// an `avx512` register operand with optional mask register, merge mode, and suppressed
/// exceptions, with no overridden rounding mode, such as `zmm3{k4}{z}{sae}`.
///
/// if the mask register is `k0`, there is no masking applied, and the default x86 operation is
/// `MergeMode::Merge`.
- RegisterMaskMergeSaeNoround(RegSpec, RegSpec, MergeMode),
+ RegisterMaskMergeSaeNoround { reg: RegSpec, mask: RegSpec, merge: MergeMode },
/// a memory access to a literal word address. it's extremely rare that a well-formed x86
/// instruction uses this mode. as an example, `[0x1133]`
- DisplacementU16(u16),
+ AbsoluteU16 { addr: u16 },
/// a memory access to a literal qword address. it's relatively rare that a well-formed x86
/// instruction uses this mode, but plausible. for example, `fs:[0x14]`. segment overrides,
/// however, are maintained on the instruction itself.
- DisplacementU32(u32),
+ AbsoluteU32 { addr: u32 },
/// a simple dereference of the address held in some register. for example: `[esi]`.
- RegDeref(RegSpec),
+ MemDeref { base: RegSpec },
/// a dereference of the address held in some register with offset. for example: `[esi + 0x14]`.
- RegDisp(RegSpec, i32),
+ Disp { base: RegSpec, disp: i32 },
/// a dereference of the address held in some register scaled by 1, 2, 4, or 8. this is almost always used with the `lea` instruction. for example: `[edx * 4]`.
- RegScale(RegSpec, u8),
- /// a dereference of the address from summing two registers. for example: `[ebp + rax]`
- RegIndexBase(RegSpec, RegSpec),
- /// a dereference of the address from summing two registers with offset. for example: `[edi + ecx + 0x40]`
- RegIndexBaseDisp(RegSpec, RegSpec, i32),
+ MemIndexScale { index: RegSpec, scale: u8 },
/// a dereference of the address held in some register scaled by 1, 2, 4, or 8 with offset. this is almost always used with the `lea` instruction. for example: `[eax * 4 + 0x30]`.
- RegScaleDisp(RegSpec, u8, i32),
+ MemIndexScaleDisp { index: RegSpec, scale: u8, disp: i32 },
/// a dereference of the address from summing a register and index register scaled by 1, 2, 4,
/// or 8. for
/// example: `[esi + ecx * 4]`
- RegIndexBaseScale(RegSpec, RegSpec, u8),
+ MemBaseIndexScale { base: RegSpec, index: RegSpec, scale: u8 },
/// a dereference of the address from summing a register and index register scaled by 1, 2, 4,
/// or 8, with offset. for
/// example: `[esi + ecx * 4 + 0x1234]`
- RegIndexBaseScaleDisp(RegSpec, RegSpec, u8, i32),
+ MemBaseIndexScaleDisp { base: RegSpec, index: RegSpec, scale: u8, disp: i32 },
/// an `avx512` dereference of register with optional masking. for example: `[edx]{k3}`
- RegDerefMasked(RegSpec, RegSpec),
+ MemDerefMasked { base: RegSpec, mask: RegSpec },
/// an `avx512` dereference of register plus offset, with optional masking. for example: `[esp + 0x40]{k3}`
- RegDispMasked(RegSpec, i32, RegSpec),
+ DispMasked { base: RegSpec, disp: i32, mask: RegSpec },
/// an `avx512` dereference of a register scaled by 1, 2, 4, or 8, with optional masking. this
/// seems extraordinarily unlikely to occur in practice. for example: `[esi * 4]{k2}`
- RegScaleMasked(RegSpec, u8, RegSpec),
- /// an `avx512` dereference of a register plus index scaled by 1, 2, 4, or 8, with optional masking.
- /// for example: `[esi + eax * 4]{k6}`
- RegIndexBaseMasked(RegSpec, RegSpec, RegSpec),
- /// an `avx512` dereference of a register plus offset, with optional masking. for example:
- /// `[esi + eax + 0x1313]{k6}`
- RegIndexBaseDispMasked(RegSpec, RegSpec, i32, RegSpec),
+ MemIndexScaleMasked { index: RegSpec, scale: u8, mask: RegSpec },
/// an `avx512` dereference of a register scaled by 1, 2, 4, or 8 plus offset, with optional
/// masking. this seems extraordinarily unlikely to occur in practice. for example: `[esi *
/// 4 + 0x1357]{k2}`
- RegScaleDispMasked(RegSpec, u8, i32, RegSpec),
+ MemIndexScaleDispMasked { index: RegSpec, scale: u8, disp: i32, mask: RegSpec },
/// an `avx512` dereference of a register plus index scaled by 1, 2, 4, or 8, with optional
/// masking. for example: `[esi + eax * 4]{k6}`
- RegIndexBaseScaleMasked(RegSpec, RegSpec, u8, RegSpec),
+ MemBaseIndexScaleMasked { base: RegSpec, index: RegSpec, scale: u8, mask: RegSpec },
/// an `avx512` dereference of a register plus index scaled by 1, 2, 4, or 8 and offset, with
/// optional masking. for example: `[esi + eax * 4 + 0x1313]{k6}`
- RegIndexBaseScaleDispMasked(RegSpec, RegSpec, u8, i32, RegSpec),
+ MemBaseIndexScaleDispMasked { base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask: RegSpec },
/// no operand. it is a bug for `yaxpeax-x86` to construct an `Operand` of this kind for public
/// use; the instruction's `operand_count` should be reduced so as to make this invisible to
/// library clients.
@@ -403,11 +393,11 @@ impl OperandSpec {
OperandSpec::RegMMM => OperandSpec::RegMMM_maskmerge,
OperandSpec::RegVex => OperandSpec::RegVex_maskmerge,
OperandSpec::Deref => OperandSpec::Deref_mask,
- OperandSpec::RegDisp => OperandSpec::RegDisp_mask,
- OperandSpec::RegScale => OperandSpec::RegScale_mask,
- OperandSpec::RegScaleDisp => OperandSpec::RegScaleDisp_mask,
- OperandSpec::RegIndexBaseScale => OperandSpec::RegIndexBaseScale_mask,
- OperandSpec::RegIndexBaseScaleDisp => OperandSpec::RegIndexBaseScaleDisp_mask,
+ OperandSpec::Disp => OperandSpec::Disp_mask,
+ OperandSpec::MemIndexScale => OperandSpec::MemIndexScale_mask,
+ OperandSpec::MemIndexScaleDisp => OperandSpec::MemIndexScaleDisp_mask,
+ OperandSpec::MemBaseIndexScale => OperandSpec::MemBaseIndexScale_mask,
+ OperandSpec::MemBaseIndexScaleDisp => OperandSpec::MemBaseIndexScaleDisp_mask,
o => o,
}
}
@@ -487,10 +477,10 @@ pub trait OperandVisitor {
fn visit_reg(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error>;
fn visit_deref(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error>;
fn visit_disp(&mut self, reg: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale(&mut self, reg: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale(&mut self, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale_disp(&mut self, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
fn visit_i8(&mut self, imm: i8) -> Result<Self::Ok, Self::Error>;
fn visit_u8(&mut self, imm: u8) -> Result<Self::Ok, Self::Error>;
fn visit_i16(&mut self, imm: i16) -> Result<Self::Ok, Self::Error>;
@@ -502,14 +492,14 @@ pub trait OperandVisitor {
fn visit_reg_mask_merge(&mut self, base: RegSpec, mask: RegSpec, merge_mode: MergeMode) -> Result<Self::Ok, Self::Error>;
fn visit_reg_mask_merge_sae(&mut self, base: RegSpec, mask: RegSpec, merge_mode: MergeMode, sae_mode: SaeMode) -> Result<Self::Ok, Self::Error>;
fn visit_reg_mask_merge_sae_noround(&mut self, base: RegSpec, mask: RegSpec, merge_mode: MergeMode) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_disp_masked(&mut self, base: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_deref_masked(&mut self, base: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale_masked(&mut self, base: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale_disp_masked(&mut self, base: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_disp_masked(&mut self, base: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_deref_masked(&mut self, base: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale_masked(&mut self, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale_disp_masked(&mut self, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
fn visit_absolute_far_address(&mut self, segment: u16, address: u32) -> Result<Self::Ok, Self::Error>;
fn visit_other(&mut self) -> Result<Self::Ok, Self::Error>;
@@ -523,139 +513,139 @@ impl Operand {
}
// the register in regs[0]
OperandSpec::RegRRR => {
- Operand::Register(inst.regs[0])
+ Operand::Register { reg: inst.regs[0] }
}
OperandSpec::RegRRR_maskmerge => {
- Operand::RegisterMaskMerge(
- inst.regs[0],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMerge {
+ reg: inst.regs[0],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::RegRRR_maskmerge_sae => {
- Operand::RegisterMaskMergeSae(
- inst.regs[0],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- SaeMode::from(inst.prefixes.evex_unchecked().vex().l(), inst.prefixes.evex_unchecked().lp()),
- )
+ Operand::RegisterMaskMergeSae {
+ reg: inst.regs[0],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ sae: SaeMode::from(inst.prefixes.evex_unchecked().vex().l(), inst.prefixes.evex_unchecked().lp()),
+ }
}
OperandSpec::RegRRR_maskmerge_sae_noround => {
- Operand::RegisterMaskMergeSaeNoround(
- inst.regs[0],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMergeSaeNoround {
+ reg: inst.regs[0],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
// the register in regs[1] (eg modrm mod bits were 11)
OperandSpec::RegMMM => {
- Operand::Register(inst.regs[1])
+ Operand::Register { reg: inst.regs[1] }
}
OperandSpec::RegMMM_maskmerge => {
- Operand::RegisterMaskMerge(
- inst.regs[1],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMerge {
+ reg: inst.regs[1],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::RegMMM_maskmerge_sae_noround => {
- Operand::RegisterMaskMergeSaeNoround(
- inst.regs[1],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMergeSaeNoround {
+ reg: inst.regs[1],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::RegVex => {
- Operand::Register(inst.regs[3])
+ Operand::Register { reg: inst.regs[3] }
}
OperandSpec::RegVex_maskmerge => {
- Operand::RegisterMaskMerge(
- inst.regs[3],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMerge {
+ reg: inst.regs[3],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::Reg4 => {
- Operand::Register(RegSpec { num: inst.imm as u8, bank: inst.regs[3].bank })
- }
- OperandSpec::ImmI8 => Operand::ImmediateI8(inst.imm as i8),
- OperandSpec::ImmU8 => Operand::ImmediateU8(inst.imm as u8),
- OperandSpec::ImmI16 => Operand::ImmediateI16(inst.imm as i16),
- OperandSpec::ImmU16 => Operand::ImmediateU16(inst.imm as u16),
- OperandSpec::ImmI32 => Operand::ImmediateI32(inst.imm as i32),
- OperandSpec::ImmInDispField => Operand::ImmediateU16(inst.disp as u16),
- OperandSpec::DispU16 => Operand::DisplacementU16(inst.disp as u16),
- OperandSpec::DispU32 => Operand::DisplacementU32(inst.disp),
+ Operand::Register { reg: RegSpec { num: inst.imm as u8, bank: inst.regs[3].bank }}
+ }
+ OperandSpec::ImmI8 => Operand::ImmediateI8 { imm: inst.imm as i8 },
+ OperandSpec::ImmU8 => Operand::ImmediateU8 { imm: inst.imm as u8 },
+ OperandSpec::ImmI16 => Operand::ImmediateI16 { imm: inst.imm as i16 },
+ OperandSpec::ImmU16 => Operand::ImmediateU16 { imm: inst.imm as u16 },
+ OperandSpec::ImmI32 => Operand::ImmediateI32 { imm: inst.imm as i32 },
+ OperandSpec::ImmInDispField => Operand::ImmediateU16 { imm: inst.disp as u16 },
+ OperandSpec::DispU16 => Operand::AbsoluteU16 { addr: inst.disp as u16 },
+ OperandSpec::DispU32 => Operand::AbsoluteU32 { addr: inst.disp },
OperandSpec::Deref => {
- Operand::RegDeref(inst.regs[1])
+ Operand::MemDeref { base: inst.regs[1] }
}
OperandSpec::Deref_si => {
- Operand::RegDeref(RegSpec::si())
+ Operand::MemDeref { base: RegSpec::si() }
}
OperandSpec::Deref_di => {
- Operand::RegDeref(RegSpec::di())
+ Operand::MemDeref { base: RegSpec::di() }
}
OperandSpec::Deref_esi => {
- Operand::RegDeref(RegSpec::esi())
+ Operand::MemDeref { base: RegSpec::esi() }
}
OperandSpec::Deref_edi => {
- Operand::RegDeref(RegSpec::edi())
+ Operand::MemDeref { base: RegSpec::edi() }
}
- OperandSpec::RegDisp => {
- Operand::RegDisp(inst.regs[1], inst.disp as i32)
+ OperandSpec::Disp => {
+ Operand::Disp { base: inst.regs[1], disp: inst.disp as i32 }
}
- OperandSpec::RegScale => {
- Operand::RegScale(inst.regs[2], inst.scale)
+ OperandSpec::MemIndexScale => {
+ Operand::MemIndexScale { index: inst.regs[2], scale: inst.scale }
}
- OperandSpec::RegScaleDisp => {
- Operand::RegScaleDisp(inst.regs[2], inst.scale, inst.disp as i32)
+ OperandSpec::MemIndexScaleDisp => {
+ Operand::MemIndexScaleDisp { index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
- OperandSpec::RegIndexBaseScale => {
- Operand::RegIndexBaseScale(inst.regs[1], inst.regs[2], inst.scale)
+ OperandSpec::MemBaseIndexScale => {
+ Operand::MemBaseIndexScale { base: inst.regs[1], index: inst.regs[2], scale: inst.scale }
}
- OperandSpec::RegIndexBaseScaleDisp => {
- Operand::RegIndexBaseScaleDisp(inst.regs[1], inst.regs[2], inst.scale, inst.disp as i32)
+ OperandSpec::MemBaseIndexScaleDisp => {
+ Operand::MemBaseIndexScaleDisp { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
OperandSpec::Deref_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegDerefMasked(inst.regs[1], RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemDerefMasked { base: inst.regs[1], mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegDeref(inst.regs[1])
+ Operand::MemDeref { base: inst.regs[1] }
}
}
- OperandSpec::RegDisp_mask => {
+ OperandSpec::Disp_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegDispMasked(inst.regs[1], inst.disp as i32, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::DispMasked { base: inst.regs[1], disp: inst.disp as i32, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegDisp(inst.regs[1], inst.disp as i32)
+ Operand::Disp { base: inst.regs[1], disp: inst.disp as i32 }
}
}
- OperandSpec::RegScale_mask => {
+ OperandSpec::MemIndexScale_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegScaleMasked(inst.regs[2], inst.scale, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemIndexScaleMasked { index: inst.regs[2], scale: inst.scale, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegScale(inst.regs[2], inst.scale)
+ Operand::MemIndexScale { index: inst.regs[2], scale: inst.scale }
}
}
- OperandSpec::RegScaleDisp_mask => {
+ OperandSpec::MemIndexScaleDisp_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegScaleDispMasked(inst.regs[2], inst.scale, inst.disp as i32, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemIndexScaleDispMasked { index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegScaleDisp(inst.regs[2], inst.scale, inst.disp as i32)
+ Operand::MemIndexScaleDisp { index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
}
- OperandSpec::RegIndexBaseScale_mask => {
+ OperandSpec::MemBaseIndexScale_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegIndexBaseScaleMasked(inst.regs[1], inst.regs[2], inst.scale, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemBaseIndexScaleMasked { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegIndexBaseScale(inst.regs[1], inst.regs[2], inst.scale)
+ Operand::MemBaseIndexScale { base: inst.regs[1], index: inst.regs[2], scale: inst.scale }
}
}
- OperandSpec::RegIndexBaseScaleDisp_mask => {
+ OperandSpec::MemBaseIndexScaleDisp_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegIndexBaseScaleDispMasked(inst.regs[1], inst.regs[2], inst.scale, inst.disp as i32, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemBaseIndexScaleDispMasked { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegIndexBaseScaleDisp(inst.regs[1], inst.regs[2], inst.scale, inst.disp as i32)
+ Operand::MemBaseIndexScaleDisp { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
}
OperandSpec::AbsoluteFarAddress => {
@@ -672,36 +662,32 @@ impl Operand {
/// memory.
pub fn is_memory(&self) -> bool {
match self {
- Operand::DisplacementU16(_) |
- Operand::DisplacementU32(_) |
- Operand::RegDeref(_) |
- Operand::RegDisp(_, _) |
- Operand::RegScale(_, _) |
- Operand::RegIndexBase(_, _) |
- Operand::RegIndexBaseDisp(_, _, _) |
- Operand::RegScaleDisp(_, _, _) |
- Operand::RegIndexBaseScale(_, _, _) |
- Operand::RegIndexBaseScaleDisp(_, _, _, _) |
- Operand::RegDerefMasked(_, _) |
- Operand::RegDispMasked(_, _, _) |
- Operand::RegScaleMasked(_, _, _) |
- Operand::RegIndexBaseMasked(_, _, _) |
- Operand::RegIndexBaseDispMasked(_, _, _, _) |
- Operand::RegScaleDispMasked(_, _, _, _) |
- Operand::RegIndexBaseScaleMasked(_, _, _, _) |
- Operand::RegIndexBaseScaleDispMasked(_, _, _, _, _) => {
+ Operand::AbsoluteU16 { .. } |
+ Operand::AbsoluteU32 { .. } |
+ Operand::MemDeref { .. } |
+ Operand::Disp { .. } |
+ Operand::MemIndexScale { .. } |
+ Operand::MemIndexScaleDisp { .. } |
+ Operand::MemBaseIndexScale { .. } |
+ Operand::MemBaseIndexScaleDisp { .. } |
+ Operand::MemDerefMasked { .. } |
+ Operand::DispMasked { .. } |
+ Operand::MemIndexScaleMasked { .. } |
+ Operand::MemIndexScaleDispMasked { .. } |
+ Operand::MemBaseIndexScaleMasked { .. } |
+ Operand::MemBaseIndexScaleDispMasked { .. } => {
true
},
- Operand::ImmediateI8(_) |
- Operand::ImmediateU8(_) |
- Operand::ImmediateI16(_) |
- Operand::ImmediateU16(_) |
- Operand::ImmediateU32(_) |
- Operand::ImmediateI32(_) |
- Operand::Register(_) |
- Operand::RegisterMaskMerge(_, _, _) |
- Operand::RegisterMaskMergeSae(_, _, _, _) |
- Operand::RegisterMaskMergeSaeNoround(_, _, _) |
+ Operand::ImmediateI8 { .. } |
+ Operand::ImmediateU8 { .. } |
+ Operand::ImmediateI16 { .. } |
+ Operand::ImmediateU16 { .. } |
+ Operand::ImmediateU32 { .. } |
+ Operand::ImmediateI32 { .. } |
+ Operand::Register { .. } |
+ Operand::RegisterMaskMerge { .. } |
+ Operand::RegisterMaskMergeSae { .. } |
+ Operand::RegisterMaskMergeSaeNoround { .. } |
Operand::AbsoluteFarAddress { .. } |
Operand::Nothing => {
false
@@ -714,22 +700,22 @@ impl Operand {
/// `Operand` came from; `None` here means the authoritative width is `instr.mem_size()`.
pub fn width(&self) -> Option<u8> {
match self {
- Operand::Register(reg) => {
+ Operand::Register { reg } => {
Some(reg.width())
}
- Operand::RegisterMaskMerge(reg, _, _) => {
+ Operand::RegisterMaskMerge { reg, .. } => {
Some(reg.width())
}
- Operand::ImmediateI8(_) |
- Operand::ImmediateU8(_) => {
+ Operand::ImmediateI8 { .. } |
+ Operand::ImmediateU8 { .. } => {
Some(1)
}
- Operand::ImmediateI16(_) |
- Operand::ImmediateU16(_) => {
+ Operand::ImmediateI16 { .. } |
+ Operand::ImmediateU16 { .. } => {
Some(2)
}
- Operand::ImmediateI32(_) |
- Operand::ImmediateU32(_) => {
+ Operand::ImmediateI32 { .. } |
+ Operand::ImmediateU32 { .. } => {
Some(4)
}
// memory operands or `Nothing`
@@ -747,40 +733,36 @@ impl Operand {
Operand::Nothing => {
visitor.visit_other()
}
- Operand::Register(reg) => {
+ Operand::Register { reg } => {
visitor.visit_reg(*reg)
}
- Operand::RegDeref(reg) => {
- visitor.visit_deref(*reg)
- }
- Operand::RegDisp(reg, disp) => {
- visitor.visit_disp(*reg, *disp)
- }
- Operand::ImmediateI8(imm) => visitor.visit_i8(*imm),
- Operand::ImmediateU8(imm) => visitor.visit_u8(*imm),
- Operand::ImmediateI16(imm) => visitor.visit_i16(*imm),
- Operand::ImmediateU16(imm) => visitor.visit_u16(*imm),
- Operand::ImmediateI32(imm) => visitor.visit_i32(*imm),
- Operand::ImmediateU32(imm) => visitor.visit_u32(*imm),
- Operand::DisplacementU16(disp) => visitor.visit_abs_u16(*disp),
- Operand::DisplacementU32(disp) => visitor.visit_abs_u32(*disp),
- Operand::RegScale(reg, scale) => visitor.visit_reg_scale(*reg, *scale),
- Operand::RegScaleDisp(reg, scale, disp) => visitor.visit_reg_scale_disp(*reg, *scale, *disp),
- Operand::RegIndexBase(_, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegIndexBaseDisp(_, _, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegIndexBaseScale(base, index, scale) => visitor.visit_index_base_scale(*base, *index, *scale),
- Operand::RegIndexBaseScaleDisp(base, index, scale, disp) => visitor.visit_index_base_scale_disp(*base, *index, *scale, *disp),
- Operand::RegisterMaskMerge(reg, mask, merge) => visitor.visit_reg_mask_merge(*reg, *mask, *merge),
- Operand::RegisterMaskMergeSae(reg, mask, merge, sae) => visitor.visit_reg_mask_merge_sae(*reg, *mask, *merge, *sae),
- Operand::RegisterMaskMergeSaeNoround(reg, mask, merge) => visitor.visit_reg_mask_merge_sae_noround(*reg, *mask, *merge),
- Operand::RegDerefMasked(reg, mask) => visitor.visit_reg_deref_masked(*reg, *mask),
- Operand::RegDispMasked(reg, disp, mask) => visitor.visit_reg_disp_masked(*reg, *disp, *mask),
- Operand::RegScaleMasked(reg, scale, mask) => visitor.visit_reg_scale_masked(*reg, *scale, *mask),
- Operand::RegIndexBaseMasked(_, _, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegIndexBaseDispMasked(_, _, _, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegScaleDispMasked(base, scale, disp, mask) => visitor.visit_reg_scale_disp_masked(*base, *scale, *disp, *mask),
- Operand::RegIndexBaseScaleMasked(base, index, scale, mask) => visitor.visit_index_base_scale_masked(*base, *index, *scale, *mask),
- Operand::RegIndexBaseScaleDispMasked(base, index, scale, disp, mask) => visitor.visit_index_base_scale_disp_masked(*base, *index, *scale, *disp, *mask),
+ Operand::MemDeref { base } => {
+ visitor.visit_deref(*base)
+ }
+ Operand::Disp { base, disp } => {
+ visitor.visit_disp(*base, *disp)
+ }
+ Operand::ImmediateI8 { imm } => visitor.visit_i8(*imm),
+ Operand::ImmediateU8 { imm } => visitor.visit_u8(*imm),
+ Operand::ImmediateI16 { imm } => visitor.visit_i16(*imm),
+ Operand::ImmediateU16 { imm } => visitor.visit_u16(*imm),
+ Operand::ImmediateI32 { imm } => visitor.visit_i32(*imm),
+ Operand::ImmediateU32 { imm } => visitor.visit_u32(*imm),
+ Operand::AbsoluteU16 { addr } => visitor.visit_abs_u16(*addr),
+ Operand::AbsoluteU32 { addr } => visitor.visit_abs_u32(*addr),
+ Operand::MemIndexScale { index, scale } => visitor.visit_index_scale(*index, *scale),
+ Operand::MemIndexScaleDisp { index, scale, disp } => visitor.visit_index_scale_disp(*index, *scale, *disp),
+ Operand::MemBaseIndexScale { base, index, scale } => visitor.visit_base_index_scale(*base, *index, *scale),
+ Operand::MemBaseIndexScaleDisp { base, index, scale, disp } => visitor.visit_base_index_scale_disp(*base, *index, *scale, *disp),
+ Operand::RegisterMaskMerge { reg, mask, merge } => visitor.visit_reg_mask_merge(*reg, *mask, *merge),
+ Operand::RegisterMaskMergeSae { reg, mask, merge, sae } => visitor.visit_reg_mask_merge_sae(*reg, *mask, *merge, *sae),
+ Operand::RegisterMaskMergeSaeNoround { reg, mask, merge } => visitor.visit_reg_mask_merge_sae_noround(*reg, *mask, *merge),
+ Operand::MemDerefMasked { base, mask } => visitor.visit_deref_masked(*base, *mask),
+ Operand::DispMasked { base, disp, mask } => visitor.visit_disp_masked(*base, *disp, *mask),
+ Operand::MemIndexScaleMasked { index, scale, mask } => visitor.visit_index_scale_masked(*index, *scale, *mask),
+ Operand::MemIndexScaleDispMasked { index, scale, disp, mask } => visitor.visit_index_scale_disp_masked(*index, *scale, *disp, *mask),
+ Operand::MemBaseIndexScaleMasked { base, index, scale, mask } => visitor.visit_base_index_scale_masked(*base, *index, *scale, *mask),
+ Operand::MemBaseIndexScaleDispMasked { base, index, scale, disp, mask } => visitor.visit_base_index_scale_disp_masked(*base, *index, *scale, *disp, *mask),
Operand::AbsoluteFarAddress { segment, address } => visitor.visit_absolute_far_address(*segment, *address),
}
}
@@ -865,16 +847,16 @@ const REGISTER_CLASS_NAMES: &[&'static str] = &[
/// }
/// }
///
-/// if let Operand::Register(regspec) = instruction.operand(0) {
+/// if let Operand::Register { reg } = instruction.operand(0) {
/// #[cfg(feature="fmt")]
-/// println!("first operand is {}", regspec);
-/// show_register_class_info(regspec.class());
+/// println!("first operand is {}", reg);
+/// show_register_class_info(reg.class());
/// }
///
-/// if let Operand::Register(regspec) = instruction.operand(1) {
+/// if let Operand::Register { reg } = instruction.operand(1) {
/// #[cfg(feature="fmt")]
-/// println!("first operand is {}", regspec);
-/// show_register_class_info(regspec.class());
+/// println!("second operand is {}", reg);
+/// show_register_class_info(reg.class());
/// }
/// ```
///
@@ -2667,17 +2649,17 @@ enum OperandSpec {
Deref_di = 0x90,
Deref_esi = 0x91,
Deref_edi = 0x92,
- RegDisp = 0x93,
- RegScale = 0x94,
- RegScaleDisp = 0x95,
- RegIndexBaseScale = 0x96,
- RegIndexBaseScaleDisp = 0x97,
+ Disp = 0x93,
+ MemIndexScale = 0x94,
+ MemIndexScaleDisp = 0x95,
+ MemBaseIndexScale = 0x96,
+ MemBaseIndexScaleDisp = 0x97,
Deref_mask = 0xce,
- RegDisp_mask = 0xd3,
- RegScale_mask = 0xd4,
- RegScaleDisp_mask = 0xd5,
- RegIndexBaseScale_mask = 0xd6,
- RegIndexBaseScaleDisp_mask = 0xd7,
+ Disp_mask = 0xd3,
+ MemIndexScale_mask = 0xd4,
+ MemIndexScaleDisp_mask = 0xd5,
+ MemBaseIndexScale_mask = 0xd6,
+ MemBaseIndexScaleDisp_mask = 0xd7,
// u16:u{16,32} immediate address for a far call
AbsoluteFarAddress = 0x18,
}
@@ -4385,7 +4367,7 @@ impl Instruction {
// visitor.visit_other()
visitor.visit_deref(RegSpec::edi())
}
- OperandSpec::RegDisp => {
+ OperandSpec::Disp => {
visitor.visit_disp(self.regs[1], self.disp as i32)
}
OperandSpec::RegRRR_maskmerge => {
@@ -4439,61 +4421,58 @@ impl Instruction {
OperandSpec::ImmInDispField => visitor.visit_u16(self.disp as u16),
OperandSpec::DispU16 => visitor.visit_abs_u16(self.disp as u16),
OperandSpec::DispU32 => visitor.visit_abs_u32(self.disp as u32),
- OperandSpec::RegScale => {
- visitor.visit_reg_scale(self.regs[2], self.scale)
+ OperandSpec::MemIndexScale => {
+ visitor.visit_index_scale(self.regs[2], self.scale)
}
- OperandSpec::RegScaleDisp => {
- visitor.visit_reg_scale_disp(self.regs[2], self.scale, self.disp as i32)
+ OperandSpec::MemIndexScaleDisp => {
+ visitor.visit_index_scale_disp(self.regs[2], self.scale, self.disp as i32)
}
- OperandSpec::RegIndexBaseScale => {
- visitor.visit_index_base_scale(self.regs[1], self.regs[2], self.scale)
- /*
- Operand::RegIndexBaseScale(self.regs[1], self.regs[2], self.scale)
- */
+ OperandSpec::MemBaseIndexScale => {
+ visitor.visit_base_index_scale(self.regs[1], self.regs[2], self.scale)
}
- OperandSpec::RegIndexBaseScaleDisp => {
- visitor.visit_index_base_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
+ OperandSpec::MemBaseIndexScaleDisp => {
+ visitor.visit_base_index_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
}
OperandSpec::Deref_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_deref_masked(self.regs[1], RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_deref_masked(self.regs[1], RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
visitor.visit_deref(self.regs[1])
}
}
- OperandSpec::RegDisp_mask => {
+ OperandSpec::Disp_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_disp_masked(self.regs[1], self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_disp_masked(self.regs[1], self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
visitor.visit_disp(self.regs[1], self.disp as i32)
}
}
- OperandSpec::RegScale_mask => {
+ OperandSpec::MemIndexScale_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_scale_masked(self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_index_scale_masked(self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_reg_scale(self.regs[2], self.scale)
+ visitor.visit_index_scale(self.regs[2], self.scale)
}
}
- OperandSpec::RegScaleDisp_mask => {
+ OperandSpec::MemIndexScaleDisp_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_scale_disp_masked(self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_index_scale_disp_masked(self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_reg_scale_disp(self.regs[2], self.scale, self.disp as i32)
+ visitor.visit_index_scale_disp(self.regs[2], self.scale, self.disp as i32)
}
}
- OperandSpec::RegIndexBaseScale_mask => {
+ OperandSpec::MemBaseIndexScale_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_index_base_scale_masked(self.regs[1], self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_base_index_scale_masked(self.regs[1], self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_index_base_scale(self.regs[1], self.regs[2], self.scale)
+ visitor.visit_base_index_scale(self.regs[1], self.regs[2], self.scale)
}
}
- OperandSpec::RegIndexBaseScaleDisp_mask => {
+ OperandSpec::MemBaseIndexScaleDisp_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_index_base_scale_disp_masked(self.regs[1], self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_base_index_scale_disp_masked(self.regs[1], self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_index_base_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
+ visitor.visit_base_index_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
}
}
OperandSpec::AbsoluteFarAddress => {
@@ -6155,7 +6134,7 @@ fn read_sib<
InnerDescription::Misc("mod bits select no base register")
.with_id(sib_start + 0)
);
- OperandSpec::RegScale
+ OperandSpec::MemIndexScale
} else {
sink.record(
modrm_start + 6,
@@ -6163,7 +6142,7 @@ fn read_sib<
InnerDescription::RegisterNumber("mod", 0b101, instr.regs[1])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScale
+ OperandSpec::MemBaseIndexScale
}
}
} else {
@@ -6182,7 +6161,7 @@ fn read_sib<
InnerDescription::RegisterNumber("iii", instr.regs[2].num, instr.regs[2])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScale
+ OperandSpec::MemBaseIndexScale
}
}
@@ -6216,7 +6195,7 @@ fn read_sib<
InnerDescription::RegisterNumber("mod", 0b101, instr.regs[1])
.with_id(sib_start + 0)
);
- OperandSpec::RegDisp
+ OperandSpec::Disp
}
} else {
sink.record(
@@ -6232,7 +6211,7 @@ fn read_sib<
InnerDescription::Misc("mod bits select no base register, [index+disp] only")
.with_id(sib_start + 0)
);
- OperandSpec::RegScaleDisp
+ OperandSpec::MemIndexScaleDisp
} else {
sink.record(
modrm_start + 6,
@@ -6240,7 +6219,7 @@ fn read_sib<
InnerDescription::RegisterNumber("mod", 0b101, instr.regs[1])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScaleDisp
+ OperandSpec::MemBaseIndexScaleDisp
}
}
} else {
@@ -6257,7 +6236,7 @@ fn read_sib<
InnerDescription::Misc("iii selects no index register")
.with_id(sib_start + 0)
);
- OperandSpec::RegDisp
+ OperandSpec::Disp
} else {
sink.record(
sib_start + 3,
@@ -6265,7 +6244,7 @@ fn read_sib<
InnerDescription::RegisterNumber("iii", instr.regs[2].num, instr.regs[2])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScaleDisp
+ OperandSpec::MemBaseIndexScaleDisp
}
}
};
@@ -6375,7 +6354,7 @@ fn read_M_16bit<
Ok(OperandSpec::Deref)
} else {
instr.scale = 1;
- Ok(OperandSpec::RegIndexBaseScale)
+ Ok(OperandSpec::MemBaseIndexScale)
}
},
0b01 => {
@@ -6396,13 +6375,13 @@ fn read_M_16bit<
);
if mmm > 3 {
if instr.disp != 0 {
- Ok(OperandSpec::RegDisp)
+ Ok(OperandSpec::Disp)
} else {
Ok(OperandSpec::Deref)
}
} else {
instr.scale = 1;
- Ok(OperandSpec::RegIndexBaseScaleDisp)
+ Ok(OperandSpec::MemBaseIndexScaleDisp)
}
},
0b10 => {
@@ -6423,13 +6402,13 @@ fn read_M_16bit<
);
if mmm > 3 {
if instr.disp != 0 {
- Ok(OperandSpec::RegDisp)
+ Ok(OperandSpec::Disp)
} else {
Ok(OperandSpec::Deref)
}
} else {
instr.scale = 1;
- Ok(OperandSpec::RegIndexBaseScaleDisp)
+ Ok(OperandSpec::MemBaseIndexScaleDisp)
}
},
_ => {
@@ -6523,7 +6502,7 @@ fn read_M<
OperandSpec::Deref
} else {
instr.disp = disp as i32 as u32;
- OperandSpec::RegDisp
+ OperandSpec::Disp
}
}
};
diff --git a/src/real_mode/display.rs b/src/real_mode/display.rs
index 38f95bb..bea11fc 100644
--- a/src/real_mode/display.rs
+++ b/src/real_mode/display.rs
@@ -406,9 +406,9 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
#[cfg_attr(not(feature="profiling"), inline(always))]
#[cfg_attr(feature="profiling", inline(never))]
- fn visit_disp(&mut self, reg: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp(&mut self, base: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_char('[')?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(base)?;
self.f.write_fixed_size(" ")?;
{
@@ -423,23 +423,23 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
self.f.write_fixed_size("]")
}
- fn visit_deref(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref(&mut self, base: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(base)?;
self.f.write_fixed_size("]")
}
- fn visit_reg_scale(&mut self, reg: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale(&mut self, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size("]")?;
Ok(())
}
- fn visit_reg_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp(&mut self, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(reg)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size(" ")?;
@@ -456,7 +456,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
self.f.write_char(']')
}
- fn visit_index_base_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -465,7 +465,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size("]")
}
- fn visit_index_base_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -486,9 +486,9 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
}
self.f.write_fixed_size("]")
}
- fn visit_reg_disp_masked(&mut self, spec: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp_masked(&mut self, base: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_char('[')?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(base)?;
self.f.write_char(' ')?;
let mut v = disp as u32;
if disp < 0 {
@@ -504,18 +504,18 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_reg_deref_masked(&mut self, spec: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref_masked(&mut self, base: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(base)?;
self.f.write_fixed_size("]")?;
self.f.write_char('{')?;
self.f.write_reg(mask_reg)?;
self.f.write_char('}')?;
Ok(())
}
- fn visit_reg_scale_masked(&mut self, spec: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_masked(&mut self, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size("]")?;
@@ -524,9 +524,9 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_reg_scale_disp_masked(&mut self, spec: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp_masked(&mut self, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
- self.f.write_reg(spec)?;
+ self.f.write_reg(index)?;
self.f.write_fixed_size(" * ")?;
self.f.write_char((0x30 + scale) as char)?; // translate scale=1 to '1', scale=2 to '2', etc
self.f.write_fixed_size(" ")?;
@@ -544,7 +544,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -555,7 +555,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -575,7 +575,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -588,7 +588,7 @@ impl <T: DisplaySink> super::OperandVisitor for DisplayingOperandVisitor<'_, T>
self.f.write_char('}')?;
Ok(())
}
- fn visit_index_base_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
self.f.write_fixed_size("[")?;
self.f.write_reg(base)?;
self.f.write_fixed_size(" + ")?;
@@ -2420,7 +2420,7 @@ pub(crate) fn contextualize_c<T: DisplaySink>(instr: &Instruction, out: &mut T)
let mut out = yaxpeax_arch::display::FmtSink::new(out);
use core::fmt::Write;
match op {
- Operand::ImmediateI8(rel) => {
+ Operand::ImmediateI8 { imm: rel } => {
let rel = if rel >= 0 {
out.write_str("$+")?;
rel as u8
@@ -2430,7 +2430,7 @@ pub(crate) fn contextualize_c<T: DisplaySink>(instr: &Instruction, out: &mut T)
};
out.write_prefixed_u8(rel)
}
- Operand::ImmediateI32(rel) => {
+ Operand::ImmediateI32 { imm: rel } => {
let rel = if rel >= 0 {
out.write_str("$+")?;
rel as u32
@@ -2824,10 +2824,10 @@ impl<'a, F: DisplaySink> super::OperandVisitor for RelativeBranchPrinter<'a, F>
fn visit_reg(&mut self, _reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_deref(&mut self, _reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref(&mut self, _base: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_disp(&mut self, _reg: RegSpec, _disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp(&mut self, _base: RegSpec, _disp: i32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
#[cfg_attr(feature="profiling", inline(never))]
@@ -2884,16 +2884,16 @@ impl<'a, F: DisplaySink> super::OperandVisitor for RelativeBranchPrinter<'a, F>
fn visit_abs_u32(&mut self, _imm: u32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale(&mut self, _reg: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale(&mut self, _index: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale_disp(&mut self, _reg: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp(&mut self, _index: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale_disp(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
fn visit_other(&mut self) -> Result<Self::Ok, Self::Error> {
@@ -2908,28 +2908,28 @@ impl<'a, F: DisplaySink> super::OperandVisitor for RelativeBranchPrinter<'a, F>
fn visit_reg_mask_merge_sae_noround(&mut self, _spec: RegSpec, _mask: RegSpec, _merge_mode: MergeMode) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_disp_masked(&mut self, _spec: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_disp_masked(&mut self, _base: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_deref_masked(&mut self, _spec: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_deref_masked(&mut self, _base: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale_masked(&mut self, _spec: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_masked(&mut self, _index: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_reg_scale_disp_masked(&mut self, _spec: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_index_scale_disp_masked(&mut self, _index: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_masked(&mut self, _base: RegSpec, _index: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_masked(&mut self, _base: RegSpec, _index: RegSpec, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
- fn visit_index_base_scale_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
+ fn visit_base_index_scale_disp_masked(&mut self, _base: RegSpec, _index: RegSpec, _scale: u8, _disp: i32, _mask_reg: RegSpec) -> Result<Self::Ok, Self::Error> {
Ok(false)
}
fn visit_absolute_far_address(&mut self, _segment: u16, _address: u32) -> Result<Self::Ok, Self::Error> {
diff --git a/src/real_mode/mod.rs b/src/real_mode/mod.rs
index b29cd1a..b06a525 100644
--- a/src/real_mode/mod.rs
+++ b/src/real_mode/mod.rs
@@ -306,87 +306,77 @@ enum SizeCode {
#[non_exhaustive]
pub enum Operand {
/// a sign-extended byte
- ImmediateI8(i8),
+ ImmediateI8 { imm: i8 },
/// a zero-extended byte
- ImmediateU8(u8),
+ ImmediateU8 { imm: u8 },
/// a sign-extended word
- ImmediateI16(i16),
+ ImmediateI16 { imm: i16 },
/// a zero-extended word
- ImmediateU16(u16),
+ ImmediateU16 { imm: u16 },
/// a sign-extended dword
- ImmediateI32(i32),
+ ImmediateI32 { imm: i32 },
/// a zero-extended dword
- ImmediateU32(u32),
+ ImmediateU32 { imm: u32 },
/// a bare register operand, such as `rcx`.
- Register(RegSpec),
+ Register { reg: RegSpec },
/// an `avx512` register operand with optional mask register and merge mode, such as
/// `zmm3{k4}{z}`.
///
/// if the mask register is `k0`, there is no masking applied, and the default x86 operation is
/// `MergeMode::Merge`.
- RegisterMaskMerge(RegSpec, RegSpec, MergeMode),
+ RegisterMaskMerge { reg: RegSpec, mask: RegSpec, merge: MergeMode },
/// an `avx512` register operand with optional mask register, merge mode, and suppressed
/// exceptions, such as `zmm3{k4}{z}{rd-sae}`.
///
/// if the mask register is `k0`, there is no masking applied, and the default x86 operation is
/// `MergeMode::Merge`.
- RegisterMaskMergeSae(RegSpec, RegSpec, MergeMode, SaeMode),
+ RegisterMaskMergeSae { reg: RegSpec, mask: RegSpec, merge: MergeMode, sae: SaeMode },
/// an `avx512` register operand with optional mask register, merge mode, and suppressed
/// exceptions, with no overridden rounding mode, such as `zmm3{k4}{z}{sae}`.
///
/// if the mask register is `k0`, there is no masking applied, and the default x86 operation is
/// `MergeMode::Merge`.
- RegisterMaskMergeSaeNoround(RegSpec, RegSpec, MergeMode),
+ RegisterMaskMergeSaeNoround { reg: RegSpec, mask: RegSpec, merge: MergeMode },
/// a memory access to a literal word address. it's extremely rare that a well-formed x86
/// instruction uses this mode. as an example, `[0x1133]`
- DisplacementU16(u16),
+ AbsoluteU16 { addr: u16 },
/// a memory access to a literal qword address. it's relatively rare that a well-formed x86
/// instruction uses this mode, but plausible. for example, `fs:[0x14]`. segment overrides,
/// however, are maintained on the instruction itself.
- DisplacementU32(u32),
+ AbsoluteU32 { addr: u32 },
/// a simple dereference of the address held in some register. for example: `[esi]`.
- RegDeref(RegSpec),
+ MemDeref { base: RegSpec },
/// a dereference of the address held in some register with offset. for example: `[esi + 0x14]`.
- RegDisp(RegSpec, i32),
+ MemDisp { base: RegSpec, disp: i32 },
/// a dereference of the address held in some register scaled by 1, 2, 4, or 8. this is almost always used with the `lea` instruction. for example: `[edx * 4]`.
- RegScale(RegSpec, u8),
- /// a dereference of the address from summing two registers. for example: `[ebp + rax]`
- RegIndexBase(RegSpec, RegSpec),
- /// a dereference of the address from summing two registers with offset. for example: `[edi + ecx + 0x40]`
- RegIndexBaseDisp(RegSpec, RegSpec, i32),
+ MemIndexScale { index: RegSpec, scale: u8 },
/// a dereference of the address held in some register scaled by 1, 2, 4, or 8 with offset. this is almost always used with the `lea` instruction. for example: `[eax * 4 + 0x30]`.
- RegScaleDisp(RegSpec, u8, i32),
+ MemIndexScaleDisp { index: RegSpec, scale: u8, disp: i32 },
/// a dereference of the address from summing a register and index register scaled by 1, 2, 4,
/// or 8. for
/// example: `[esi + ecx * 4]`
- RegIndexBaseScale(RegSpec, RegSpec, u8),
+ MemBaseIndexScale { base: RegSpec, index: RegSpec, scale: u8 },
/// a dereference of the address from summing a register and index register scaled by 1, 2, 4,
/// or 8, with offset. for
/// example: `[esi + ecx * 4 + 0x1234]`
- RegIndexBaseScaleDisp(RegSpec, RegSpec, u8, i32),
+ MemBaseIndexScaleDisp { base: RegSpec, index: RegSpec, scale: u8, disp: i32 },
/// an `avx512` dereference of register with optional masking. for example: `[edx]{k3}`
- RegDerefMasked(RegSpec, RegSpec),
+ MemDerefMasked { base: RegSpec, mask: RegSpec },
/// an `avx512` dereference of register plus offset, with optional masking. for example: `[esp + 0x40]{k3}`
- RegDispMasked(RegSpec, i32, RegSpec),
+ MemDispMasked { base: RegSpec, disp: i32, mask: RegSpec },
/// an `avx512` dereference of a register scaled by 1, 2, 4, or 8, with optional masking. this
/// seems extraordinarily unlikely to occur in practice. for example: `[esi * 4]{k2}`
- RegScaleMasked(RegSpec, u8, RegSpec),
- /// an `avx512` dereference of a register plus index scaled by 1, 2, 4, or 8, with optional masking.
- /// for example: `[esi + eax * 4]{k6}`
- RegIndexBaseMasked(RegSpec, RegSpec, RegSpec),
- /// an `avx512` dereference of a register plus offset, with optional masking. for example:
- /// `[esi + eax + 0x1313]{k6}`
- RegIndexBaseDispMasked(RegSpec, RegSpec, i32, RegSpec),
+ MemIndexScaleMasked { index: RegSpec, scale: u8, mask: RegSpec },
/// an `avx512` dereference of a register scaled by 1, 2, 4, or 8 plus offset, with optional
/// masking. this seems extraordinarily unlikely to occur in practice. for example: `[esi *
/// 4 + 0x1357]{k2}`
- RegScaleDispMasked(RegSpec, u8, i32, RegSpec),
+ MemIndexScaleDispMasked { index: RegSpec, scale: u8, disp: i32, mask: RegSpec },
/// an `avx512` dereference of a register plus index scaled by 1, 2, 4, or 8, with optional
/// masking. for example: `[esi + eax * 4]{k6}`
- RegIndexBaseScaleMasked(RegSpec, RegSpec, u8, RegSpec),
+ MemBaseIndexScaleMasked { base: RegSpec, index: RegSpec, scale: u8, mask: RegSpec },
/// an `avx512` dereference of a register plus index scaled by 1, 2, 4, or 8 and offset, with
/// optional masking. for example: `[esi + eax * 4 + 0x1313]{k6}`
- RegIndexBaseScaleDispMasked(RegSpec, RegSpec, u8, i32, RegSpec),
+ MemBaseIndexScaleDispMasked { base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask: RegSpec },
/// no operand. it is a bug for `yaxpeax-x86` to construct an `Operand` of this kind for public
/// use; the instruction's `operand_count` should be reduced so as to make this invisible to
/// library clients.
@@ -403,11 +393,11 @@ impl OperandSpec {
OperandSpec::RegMMM => OperandSpec::RegMMM_maskmerge,
OperandSpec::RegVex => OperandSpec::RegVex_maskmerge,
OperandSpec::Deref => OperandSpec::Deref_mask,
- OperandSpec::RegDisp => OperandSpec::RegDisp_mask,
- OperandSpec::RegScale => OperandSpec::RegScale_mask,
- OperandSpec::RegScaleDisp => OperandSpec::RegScaleDisp_mask,
- OperandSpec::RegIndexBaseScale => OperandSpec::RegIndexBaseScale_mask,
- OperandSpec::RegIndexBaseScaleDisp => OperandSpec::RegIndexBaseScaleDisp_mask,
+ OperandSpec::Disp => OperandSpec::Disp_mask,
+ OperandSpec::MemIndexScale => OperandSpec::MemIndexScale_mask,
+ OperandSpec::MemIndexScaleDisp => OperandSpec::MemIndexScaleDisp_mask,
+ OperandSpec::MemBaseIndexScale => OperandSpec::MemBaseIndexScale_mask,
+ OperandSpec::MemBaseIndexScaleDisp => OperandSpec::MemBaseIndexScaleDisp_mask,
o => o,
}
}
@@ -485,12 +475,12 @@ pub trait OperandVisitor {
type Error;
fn visit_reg(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_deref(&mut self, reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_disp(&mut self, reg: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale(&mut self, reg: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale_disp(&mut self, reg: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
+ fn visit_deref(&mut self, base: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_disp(&mut self, base: RegSpec, disp: i32) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale(&mut self, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale(&mut self, base: RegSpec, index: RegSpec, scale: u8) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale_disp(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale_disp(&mut self, index: RegSpec, scale: u8, disp: i32) -> Result<Self::Ok, Self::Error>;
fn visit_i8(&mut self, imm: i8) -> Result<Self::Ok, Self::Error>;
fn visit_u8(&mut self, imm: u8) -> Result<Self::Ok, Self::Error>;
fn visit_i16(&mut self, imm: i16) -> Result<Self::Ok, Self::Error>;
@@ -502,14 +492,14 @@ pub trait OperandVisitor {
fn visit_reg_mask_merge(&mut self, base: RegSpec, mask: RegSpec, merge_mode: MergeMode) -> Result<Self::Ok, Self::Error>;
fn visit_reg_mask_merge_sae(&mut self, base: RegSpec, mask: RegSpec, merge_mode: MergeMode, sae_mode: SaeMode) -> Result<Self::Ok, Self::Error>;
fn visit_reg_mask_merge_sae_noround(&mut self, base: RegSpec, mask: RegSpec, merge_mode: MergeMode) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_disp_masked(&mut self, base: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_deref_masked(&mut self, base: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale_masked(&mut self, base: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_reg_scale_disp_masked(&mut self, base: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
- fn visit_index_base_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_disp_masked(&mut self, base: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_deref_masked(&mut self, base: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale_masked(&mut self, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_index_scale_disp_masked(&mut self, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_masked(&mut self, base: RegSpec, index: RegSpec, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_disp_masked(&mut self, base: RegSpec, index: RegSpec, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
+ fn visit_base_index_scale_disp_masked(&mut self, base: RegSpec, index: RegSpec, scale: u8, disp: i32, mask_reg: RegSpec) -> Result<Self::Ok, Self::Error>;
fn visit_absolute_far_address(&mut self, segment: u16, address: u32) -> Result<Self::Ok, Self::Error>;
fn visit_other(&mut self) -> Result<Self::Ok, Self::Error>;
@@ -523,139 +513,139 @@ impl Operand {
}
// the register in regs[0]
OperandSpec::RegRRR => {
- Operand::Register(inst.regs[0])
+ Operand::Register { reg: inst.regs[0] }
}
OperandSpec::RegRRR_maskmerge => {
- Operand::RegisterMaskMerge(
- inst.regs[0],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMerge {
+ reg: inst.regs[0],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::RegRRR_maskmerge_sae => {
- Operand::RegisterMaskMergeSae(
- inst.regs[0],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- SaeMode::from(inst.prefixes.evex_unchecked().vex().l(), inst.prefixes.evex_unchecked().lp()),
- )
+ Operand::RegisterMaskMergeSae {
+ reg: inst.regs[0],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ sae: SaeMode::from(inst.prefixes.evex_unchecked().vex().l(), inst.prefixes.evex_unchecked().lp()),
+ }
}
OperandSpec::RegRRR_maskmerge_sae_noround => {
- Operand::RegisterMaskMergeSaeNoround(
- inst.regs[0],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMergeSaeNoround {
+ reg: inst.regs[0],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
// the register in regs[1] (eg modrm mod bits were 11)
OperandSpec::RegMMM => {
- Operand::Register(inst.regs[1])
+ Operand::Register { reg: inst.regs[1] }
}
OperandSpec::RegMMM_maskmerge => {
- Operand::RegisterMaskMerge(
- inst.regs[1],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMerge {
+ reg: inst.regs[1],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::RegMMM_maskmerge_sae_noround => {
- Operand::RegisterMaskMergeSaeNoround(
- inst.regs[1],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMergeSaeNoround {
+ reg: inst.regs[1],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::RegVex => {
- Operand::Register(inst.regs[3])
+ Operand::Register { reg: inst.regs[3] }
}
OperandSpec::RegVex_maskmerge => {
- Operand::RegisterMaskMerge(
- inst.regs[3],
- RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
- MergeMode::from(inst.prefixes.evex_unchecked().merge()),
- )
+ Operand::RegisterMaskMerge {
+ reg: inst.regs[3],
+ mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()),
+ merge: MergeMode::from(inst.prefixes.evex_unchecked().merge()),
+ }
}
OperandSpec::Reg4 => {
- Operand::Register(RegSpec { num: inst.imm as u8, bank: inst.regs[3].bank })
- }
- OperandSpec::ImmI8 => Operand::ImmediateI8(inst.imm as i8),
- OperandSpec::ImmU8 => Operand::ImmediateU8(inst.imm as u8),
- OperandSpec::ImmI16 => Operand::ImmediateI16(inst.imm as i16),
- OperandSpec::ImmU16 => Operand::ImmediateU16(inst.imm as u16),
- OperandSpec::ImmI32 => Operand::ImmediateI32(inst.imm as i32),
- OperandSpec::ImmInDispField => Operand::ImmediateU16(inst.disp as u16),
- OperandSpec::DispU16 => Operand::DisplacementU16(inst.disp as u16),
- OperandSpec::DispU32 => Operand::DisplacementU32(inst.disp),
+ Operand::Register { reg: RegSpec { num: inst.imm as u8, bank: inst.regs[3].bank } }
+ }
+ OperandSpec::ImmI8 => Operand::ImmediateI8 { imm: inst.imm as i8 },
+ OperandSpec::ImmU8 => Operand::ImmediateU8 { imm: inst.imm as u8 },
+ OperandSpec::ImmI16 => Operand::ImmediateI16 { imm: inst.imm as i16 },
+ OperandSpec::ImmU16 => Operand::ImmediateU16 { imm: inst.imm as u16 },
+ OperandSpec::ImmI32 => Operand::ImmediateI32 { imm: inst.imm as i32 },
+ OperandSpec::ImmInDispField => Operand::ImmediateU16 { imm: inst.disp as u16 },
+ OperandSpec::DispU16 => Operand::AbsoluteU16 { addr: inst.disp as u16 },
+ OperandSpec::DispU32 => Operand::AbsoluteU32 { addr: inst.disp },
OperandSpec::Deref => {
- Operand::RegDeref(inst.regs[1])
+ Operand::MemDeref { base: inst.regs[1] }
}
OperandSpec::Deref_si => {
- Operand::RegDeref(RegSpec::si())
+ Operand::MemDeref { base: RegSpec::si() }
}
OperandSpec::Deref_di => {
- Operand::RegDeref(RegSpec::di())
+ Operand::MemDeref { base: RegSpec::di() }
}
OperandSpec::Deref_esi => {
- Operand::RegDeref(RegSpec::esi())
+ Operand::MemDeref { base: RegSpec::esi() }
}
OperandSpec::Deref_edi => {
- Operand::RegDeref(RegSpec::edi())
+ Operand::MemDeref { base: RegSpec::edi() }
}
- OperandSpec::RegDisp => {
- Operand::RegDisp(inst.regs[1], inst.disp as i32)
+ OperandSpec::Disp => {
+ Operand::MemDisp { base: inst.regs[1], disp: inst.disp as i32 }
}
- OperandSpec::RegScale => {
- Operand::RegScale(inst.regs[2], inst.scale)
+ OperandSpec::MemIndexScale => {
+ Operand::MemIndexScale { index: inst.regs[2], scale: inst.scale }
}
- OperandSpec::RegScaleDisp => {
- Operand::RegScaleDisp(inst.regs[2], inst.scale, inst.disp as i32)
+ OperandSpec::MemIndexScaleDisp => {
+ Operand::MemIndexScaleDisp { index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
- OperandSpec::RegIndexBaseScale => {
- Operand::RegIndexBaseScale(inst.regs[1], inst.regs[2], inst.scale)
+ OperandSpec::MemBaseIndexScale => {
+ Operand::MemBaseIndexScale { base: inst.regs[1], index: inst.regs[2], scale: inst.scale }
}
- OperandSpec::RegIndexBaseScaleDisp => {
- Operand::RegIndexBaseScaleDisp(inst.regs[1], inst.regs[2], inst.scale, inst.disp as i32)
+ OperandSpec::MemBaseIndexScaleDisp => {
+ Operand::MemBaseIndexScaleDisp { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
OperandSpec::Deref_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegDerefMasked(inst.regs[1], RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemDerefMasked { base: inst.regs[1], mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegDeref(inst.regs[1])
+ Operand::MemDeref { base: inst.regs[1] }
}
}
- OperandSpec::RegDisp_mask => {
+ OperandSpec::Disp_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegDispMasked(inst.regs[1], inst.disp as i32, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemDispMasked { base: inst.regs[1], disp: inst.disp as i32, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegDisp(inst.regs[1], inst.disp as i32)
+ Operand::MemDisp { base: inst.regs[1], disp: inst.disp as i32 }
}
}
- OperandSpec::RegScale_mask => {
+ OperandSpec::MemIndexScale_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegScaleMasked(inst.regs[2], inst.scale, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemIndexScaleMasked { index: inst.regs[2], scale: inst.scale, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegScale(inst.regs[2], inst.scale)
+ Operand::MemIndexScale { index: inst.regs[2], scale: inst.scale }
}
}
- OperandSpec::RegScaleDisp_mask => {
+ OperandSpec::MemIndexScaleDisp_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegScaleDispMasked(inst.regs[2], inst.scale, inst.disp as i32, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemIndexScaleDispMasked { index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegScaleDisp(inst.regs[2], inst.scale, inst.disp as i32)
+ Operand::MemIndexScaleDisp { index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
}
- OperandSpec::RegIndexBaseScale_mask => {
+ OperandSpec::MemBaseIndexScale_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegIndexBaseScaleMasked(inst.regs[1], inst.regs[2], inst.scale, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemBaseIndexScaleMasked { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegIndexBaseScale(inst.regs[1], inst.regs[2], inst.scale)
+ Operand::MemBaseIndexScale { base: inst.regs[1], index: inst.regs[2], scale: inst.scale }
}
}
- OperandSpec::RegIndexBaseScaleDisp_mask => {
+ OperandSpec::MemBaseIndexScaleDisp_mask => {
if inst.prefixes.evex_unchecked().mask_reg() != 0 {
- Operand::RegIndexBaseScaleDispMasked(inst.regs[1], inst.regs[2], inst.scale, inst.disp as i32, RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()))
+ Operand::MemBaseIndexScaleDispMasked { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32, mask: RegSpec::mask(inst.prefixes.evex_unchecked().mask_reg()) }
} else {
- Operand::RegIndexBaseScaleDisp(inst.regs[1], inst.regs[2], inst.scale, inst.disp as i32)
+ Operand::MemBaseIndexScaleDisp { base: inst.regs[1], index: inst.regs[2], scale: inst.scale, disp: inst.disp as i32 }
}
}
OperandSpec::AbsoluteFarAddress => {
@@ -672,36 +662,32 @@ impl Operand {
/// memory.
pub fn is_memory(&self) -> bool {
match self {
- Operand::DisplacementU16(_) |
- Operand::DisplacementU32(_) |
- Operand::RegDeref(_) |
- Operand::RegDisp(_, _) |
- Operand::RegScale(_, _) |
- Operand::RegIndexBase(_, _) |
- Operand::RegIndexBaseDisp(_, _, _) |
- Operand::RegScaleDisp(_, _, _) |
- Operand::RegIndexBaseScale(_, _, _) |
- Operand::RegIndexBaseScaleDisp(_, _, _, _) |
- Operand::RegDerefMasked(_, _) |
- Operand::RegDispMasked(_, _, _) |
- Operand::RegScaleMasked(_, _, _) |
- Operand::RegIndexBaseMasked(_, _, _) |
- Operand::RegIndexBaseDispMasked(_, _, _, _) |
- Operand::RegScaleDispMasked(_, _, _, _) |
- Operand::RegIndexBaseScaleMasked(_, _, _, _) |
- Operand::RegIndexBaseScaleDispMasked(_, _, _, _, _) => {
+ Operand::AbsoluteU16 { .. } |
+ Operand::AbsoluteU32 { .. } |
+ Operand::MemDeref { .. } |
+ Operand::MemDisp { .. } |
+ Operand::MemIndexScale { .. } |
+ Operand::MemIndexScaleDisp { .. } |
+ Operand::MemBaseIndexScale { .. } |
+ Operand::MemBaseIndexScaleDisp { .. } |
+ Operand::MemDerefMasked { .. } |
+ Operand::MemDispMasked { .. } |
+ Operand::MemIndexScaleMasked { .. } |
+ Operand::MemIndexScaleDispMasked { .. } |
+ Operand::MemBaseIndexScaleMasked { .. } |
+ Operand::MemBaseIndexScaleDispMasked { .. } => {
true
},
- Operand::ImmediateI8(_) |
- Operand::ImmediateU8(_) |
- Operand::ImmediateI16(_) |
- Operand::ImmediateU16(_) |
- Operand::ImmediateU32(_) |
- Operand::ImmediateI32(_) |
- Operand::Register(_) |
- Operand::RegisterMaskMerge(_, _, _) |
- Operand::RegisterMaskMergeSae(_, _, _, _) |
- Operand::RegisterMaskMergeSaeNoround(_, _, _) |
+ Operand::ImmediateI8 { .. } |
+ Operand::ImmediateU8 { .. } |
+ Operand::ImmediateI16 { .. } |
+ Operand::ImmediateU16 { .. } |
+ Operand::ImmediateU32 { .. } |
+ Operand::ImmediateI32 { .. } |
+ Operand::Register { .. } |
+ Operand::RegisterMaskMerge { .. } |
+ Operand::RegisterMaskMergeSae { .. } |
+ Operand::RegisterMaskMergeSaeNoround { .. } |
Operand::AbsoluteFarAddress { .. } |
Operand::Nothing => {
false
@@ -714,22 +700,22 @@ impl Operand {
/// `Operand` came from; `None` here means the authoritative width is `instr.mem_size()`.
pub fn width(&self) -> Option<u8> {
match self {
- Operand::Register(reg) => {
+ Operand::Register { reg } => {
Some(reg.width())
}
- Operand::RegisterMaskMerge(reg, _, _) => {
+ Operand::RegisterMaskMerge { reg, .. } => {
Some(reg.width())
}
- Operand::ImmediateI8(_) |
- Operand::ImmediateU8(_) => {
+ Operand::ImmediateI8 { .. } |
+ Operand::ImmediateU8 { .. } => {
Some(1)
}
- Operand::ImmediateI16(_) |
- Operand::ImmediateU16(_) => {
+ Operand::ImmediateI16 { .. } |
+ Operand::ImmediateU16 { .. } => {
Some(2)
}
- Operand::ImmediateI32(_) |
- Operand::ImmediateU32(_) => {
+ Operand::ImmediateI32 { .. } |
+ Operand::ImmediateU32 { .. } => {
Some(4)
}
// memory operands or `Nothing`
@@ -747,40 +733,36 @@ impl Operand {
Operand::Nothing => {
visitor.visit_other()
}
- Operand::Register(reg) => {
+ Operand::Register { reg } => {
visitor.visit_reg(*reg)
}
- Operand::RegDeref(reg) => {
- visitor.visit_deref(*reg)
- }
- Operand::RegDisp(reg, disp) => {
- visitor.visit_disp(*reg, *disp)
- }
- Operand::ImmediateI8(imm) => visitor.visit_i8(*imm),
- Operand::ImmediateU8(imm) => visitor.visit_u8(*imm),
- Operand::ImmediateI16(imm) => visitor.visit_i16(*imm),
- Operand::ImmediateU16(imm) => visitor.visit_u16(*imm),
- Operand::ImmediateI32(imm) => visitor.visit_i32(*imm),
- Operand::ImmediateU32(imm) => visitor.visit_u32(*imm),
- Operand::DisplacementU16(disp) => visitor.visit_abs_u16(*disp),
- Operand::DisplacementU32(disp) => visitor.visit_abs_u32(*disp),
- Operand::RegScale(reg, scale) => visitor.visit_reg_scale(*reg, *scale),
- Operand::RegScaleDisp(reg, scale, disp) => visitor.visit_reg_scale_disp(*reg, *scale, *disp),
- Operand::RegIndexBase(_, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegIndexBaseDisp(_, _, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegIndexBaseScale(base, index, scale) => visitor.visit_index_base_scale(*base, *index, *scale),
- Operand::RegIndexBaseScaleDisp(base, index, scale, disp) => visitor.visit_index_base_scale_disp(*base, *index, *scale, *disp),
- Operand::RegisterMaskMerge(reg, mask, merge) => visitor.visit_reg_mask_merge(*reg, *mask, *merge),
- Operand::RegisterMaskMergeSae(reg, mask, merge, sae) => visitor.visit_reg_mask_merge_sae(*reg, *mask, *merge, *sae),
- Operand::RegisterMaskMergeSaeNoround(reg, mask, merge) => visitor.visit_reg_mask_merge_sae_noround(*reg, *mask, *merge),
- Operand::RegDerefMasked(reg, mask) => visitor.visit_reg_deref_masked(*reg, *mask),
- Operand::RegDispMasked(reg, disp, mask) => visitor.visit_reg_disp_masked(*reg, *disp, *mask),
- Operand::RegScaleMasked(reg, scale, mask) => visitor.visit_reg_scale_masked(*reg, *scale, *mask),
- Operand::RegIndexBaseMasked(_, _, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegIndexBaseDispMasked(_, _, _, _) => { /* not actually reachable anymore */ visitor.visit_other() },
- Operand::RegScaleDispMasked(base, scale, disp, mask) => visitor.visit_reg_scale_disp_masked(*base, *scale, *disp, *mask),
- Operand::RegIndexBaseScaleMasked(base, index, scale, mask) => visitor.visit_index_base_scale_masked(*base, *index, *scale, *mask),
- Operand::RegIndexBaseScaleDispMasked(base, index, scale, disp, mask) => visitor.visit_index_base_scale_disp_masked(*base, *index, *scale, *disp, *mask),
+ Operand::MemDeref { base } => {
+ visitor.visit_deref(*base)
+ }
+ Operand::MemDisp { base, disp } => {
+ visitor.visit_disp(*base, *disp)
+ }
+ Operand::ImmediateI8 { imm } => visitor.visit_i8(*imm),
+ Operand::ImmediateU8 { imm } => visitor.visit_u8(*imm),
+ Operand::ImmediateI16 { imm } => visitor.visit_i16(*imm),
+ Operand::ImmediateU16 { imm } => visitor.visit_u16(*imm),
+ Operand::ImmediateI32 { imm } => visitor.visit_i32(*imm),
+ Operand::ImmediateU32 { imm } => visitor.visit_u32(*imm),
+ Operand::AbsoluteU16 { addr } => visitor.visit_abs_u16(*addr),
+ Operand::AbsoluteU32 { addr } => visitor.visit_abs_u32(*addr),
+ Operand::MemIndexScale { index, scale } => visitor.visit_index_scale(*index, *scale),
+ Operand::MemIndexScaleDisp { index, scale, disp } => visitor.visit_index_scale_disp(*index, *scale, *disp),
+ Operand::MemBaseIndexScale { base, index, scale } => visitor.visit_base_index_scale(*base, *index, *scale),
+ Operand::MemBaseIndexScaleDisp { base, index, scale, disp } => visitor.visit_base_index_scale_disp(*base, *index, *scale, *disp),
+ Operand::RegisterMaskMerge { reg, mask, merge } => visitor.visit_reg_mask_merge(*reg, *mask, *merge),
+ Operand::RegisterMaskMergeSae { reg, mask, merge, sae } => visitor.visit_reg_mask_merge_sae(*reg, *mask, *merge, *sae),
+ Operand::RegisterMaskMergeSaeNoround { reg, mask, merge } => visitor.visit_reg_mask_merge_sae_noround(*reg, *mask, *merge),
+ Operand::MemDerefMasked { base, mask } => visitor.visit_deref_masked(*base, *mask),
+ Operand::MemDispMasked { base, disp, mask } => visitor.visit_disp_masked(*base, *disp, *mask),
+ Operand::MemIndexScaleMasked { index, scale, mask } => visitor.visit_index_scale_masked(*index, *scale, *mask),
+ Operand::MemIndexScaleDispMasked { index, scale, disp, mask } => visitor.visit_index_scale_disp_masked(*index, *scale, *disp, *mask),
+ Operand::MemBaseIndexScaleMasked { base, index, scale, mask } => visitor.visit_base_index_scale_masked(*base, *index, *scale, *mask),
+ Operand::MemBaseIndexScaleDispMasked { base, index, scale, disp, mask } => visitor.visit_base_index_scale_disp_masked(*base, *index, *scale, *disp, *mask),
Operand::AbsoluteFarAddress { segment, address } => visitor.visit_absolute_far_address(*segment, *address),
}
}
@@ -865,16 +847,16 @@ const REGISTER_CLASS_NAMES: &[&'static str] = &[
/// }
/// }
///
-/// if let Operand::Register(regspec) = instruction.operand(0) {
+/// if let Operand::Register { reg } = instruction.operand(0) {
/// #[cfg(feature="fmt")]
-/// println!("first operand is {}", regspec);
-/// show_register_class_info(regspec.class());
+/// println!("first operand is {}", reg);
+/// show_register_class_info(reg.class());
/// }
///
-/// if let Operand::Register(regspec) = instruction.operand(1) {
+/// if let Operand::Register { reg } = instruction.operand(1) {
/// #[cfg(feature="fmt")]
-/// println!("first operand is {}", regspec);
-/// show_register_class_info(regspec.class());
+/// println!("second operand is {}", reg);
+/// show_register_class_info(reg.class());
/// }
/// ```
///
@@ -2667,17 +2649,17 @@ enum OperandSpec {
Deref_di = 0x90,
Deref_esi = 0x91,
Deref_edi = 0x92,
- RegDisp = 0x93,
- RegScale = 0x94,
- RegScaleDisp = 0x95,
- RegIndexBaseScale = 0x96,
- RegIndexBaseScaleDisp = 0x97,
+ Disp = 0x93,
+ MemIndexScale = 0x94,
+ MemIndexScaleDisp = 0x95,
+ MemBaseIndexScale = 0x96,
+ MemBaseIndexScaleDisp = 0x97,
Deref_mask = 0xce,
- RegDisp_mask = 0xd3,
- RegScale_mask = 0xd4,
- RegScaleDisp_mask = 0xd5,
- RegIndexBaseScale_mask = 0xd6,
- RegIndexBaseScaleDisp_mask = 0xd7,
+ Disp_mask = 0xd3,
+ MemIndexScale_mask = 0xd4,
+ MemIndexScaleDisp_mask = 0xd5,
+ MemBaseIndexScale_mask = 0xd6,
+ MemBaseIndexScaleDisp_mask = 0xd7,
// u16:u{16,32} immediate address for a far call
AbsoluteFarAddress = 0x18,
}
@@ -4385,7 +4367,7 @@ impl Instruction {
// visitor.visit_other()
visitor.visit_deref(RegSpec::edi())
}
- OperandSpec::RegDisp => {
+ OperandSpec::Disp => {
visitor.visit_disp(self.regs[1], self.disp as i32)
}
OperandSpec::RegRRR_maskmerge => {
@@ -4439,61 +4421,58 @@ impl Instruction {
OperandSpec::ImmInDispField => visitor.visit_u16(self.disp as u16),
OperandSpec::DispU16 => visitor.visit_abs_u16(self.disp as u16),
OperandSpec::DispU32 => visitor.visit_abs_u32(self.disp as u32),
- OperandSpec::RegScale => {
- visitor.visit_reg_scale(self.regs[2], self.scale)
+ OperandSpec::MemIndexScale => {
+ visitor.visit_index_scale(self.regs[2], self.scale)
}
- OperandSpec::RegScaleDisp => {
- visitor.visit_reg_scale_disp(self.regs[2], self.scale, self.disp as i32)
+ OperandSpec::MemIndexScaleDisp => {
+ visitor.visit_index_scale_disp(self.regs[2], self.scale, self.disp as i32)
}
- OperandSpec::RegIndexBaseScale => {
- visitor.visit_index_base_scale(self.regs[1], self.regs[2], self.scale)
- /*
- Operand::RegIndexBaseScale(self.regs[1], self.regs[2], self.scale)
- */
+ OperandSpec::MemBaseIndexScale => {
+ visitor.visit_base_index_scale(self.regs[1], self.regs[2], self.scale)
}
- OperandSpec::RegIndexBaseScaleDisp => {
- visitor.visit_index_base_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
+ OperandSpec::MemBaseIndexScaleDisp => {
+ visitor.visit_base_index_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
}
OperandSpec::Deref_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_deref_masked(self.regs[1], RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_deref_masked(self.regs[1], RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
visitor.visit_deref(self.regs[1])
}
}
- OperandSpec::RegDisp_mask => {
+ OperandSpec::Disp_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_disp_masked(self.regs[1], self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_disp_masked(self.regs[1], self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
visitor.visit_disp(self.regs[1], self.disp as i32)
}
}
- OperandSpec::RegScale_mask => {
+ OperandSpec::MemIndexScale_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_scale_masked(self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_index_scale_masked(self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_reg_scale(self.regs[2], self.scale)
+ visitor.visit_index_scale(self.regs[2], self.scale)
}
}
- OperandSpec::RegScaleDisp_mask => {
+ OperandSpec::MemIndexScaleDisp_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_reg_scale_disp_masked(self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_index_scale_disp_masked(self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_reg_scale_disp(self.regs[2], self.scale, self.disp as i32)
+ visitor.visit_index_scale_disp(self.regs[2], self.scale, self.disp as i32)
}
}
- OperandSpec::RegIndexBaseScale_mask => {
+ OperandSpec::MemBaseIndexScale_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_index_base_scale_masked(self.regs[1], self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_base_index_scale_masked(self.regs[1], self.regs[2], self.scale, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_index_base_scale(self.regs[1], self.regs[2], self.scale)
+ visitor.visit_base_index_scale(self.regs[1], self.regs[2], self.scale)
}
}
- OperandSpec::RegIndexBaseScaleDisp_mask => {
+ OperandSpec::MemBaseIndexScaleDisp_mask => {
if self.prefixes.evex_unchecked().mask_reg() != 0 {
- visitor.visit_index_base_scale_disp_masked(self.regs[1], self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
+ visitor.visit_base_index_scale_disp_masked(self.regs[1], self.regs[2], self.scale, self.disp as i32, RegSpec::mask(self.prefixes.evex_unchecked().mask_reg()))
} else {
- visitor.visit_index_base_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
+ visitor.visit_base_index_scale_disp(self.regs[1], self.regs[2], self.scale, self.disp as i32)
}
}
OperandSpec::AbsoluteFarAddress => {
@@ -6155,7 +6134,7 @@ fn read_sib<
InnerDescription::Misc("mod bits select no base register")
.with_id(sib_start + 0)
);
- OperandSpec::RegScale
+ OperandSpec::MemIndexScale
} else {
sink.record(
modrm_start + 6,
@@ -6163,7 +6142,7 @@ fn read_sib<
InnerDescription::RegisterNumber("mod", 0b101, instr.regs[1])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScale
+ OperandSpec::MemBaseIndexScale
}
}
} else {
@@ -6182,7 +6161,7 @@ fn read_sib<
InnerDescription::RegisterNumber("iii", instr.regs[2].num, instr.regs[2])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScale
+ OperandSpec::MemBaseIndexScale
}
}
@@ -6216,7 +6195,7 @@ fn read_sib<
InnerDescription::RegisterNumber("mod", 0b101, instr.regs[1])
.with_id(sib_start + 0)
);
- OperandSpec::RegDisp
+ OperandSpec::Disp
}
} else {
sink.record(
@@ -6232,7 +6211,7 @@ fn read_sib<
InnerDescription::Misc("mod bits select no base register, [index+disp] only")
.with_id(sib_start + 0)
);
- OperandSpec::RegScaleDisp
+ OperandSpec::MemIndexScaleDisp
} else {
sink.record(
modrm_start + 6,
@@ -6240,7 +6219,7 @@ fn read_sib<
InnerDescription::RegisterNumber("mod", 0b101, instr.regs[1])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScaleDisp
+ OperandSpec::MemBaseIndexScaleDisp
}
}
} else {
@@ -6257,7 +6236,7 @@ fn read_sib<
InnerDescription::Misc("iii selects no index register")
.with_id(sib_start + 0)
);
- OperandSpec::RegDisp
+ OperandSpec::Disp
} else {
sink.record(
sib_start + 3,
@@ -6265,7 +6244,7 @@ fn read_sib<
InnerDescription::RegisterNumber("iii", instr.regs[2].num, instr.regs[2])
.with_id(sib_start + 0)
);
- OperandSpec::RegIndexBaseScaleDisp
+ OperandSpec::MemBaseIndexScaleDisp
}
}
};
@@ -6375,7 +6354,7 @@ fn read_M_16bit<
Ok(OperandSpec::Deref)
} else {
instr.scale = 1;
- Ok(OperandSpec::RegIndexBaseScale)
+ Ok(OperandSpec::MemBaseIndexScale)
}
},
0b01 => {
@@ -6396,13 +6375,13 @@ fn read_M_16bit<
);
if mmm > 3 {
if instr.disp != 0 {
- Ok(OperandSpec::RegDisp)
+ Ok(OperandSpec::Disp)
} else {
Ok(OperandSpec::Deref)
}
} else {
instr.scale = 1;
- Ok(OperandSpec::RegIndexBaseScaleDisp)
+ Ok(OperandSpec::MemBaseIndexScaleDisp)
}
},
0b10 => {
@@ -6423,13 +6402,13 @@ fn read_M_16bit<
);
if mmm > 3 {
if instr.disp != 0 {
- Ok(OperandSpec::RegDisp)
+ Ok(OperandSpec::Disp)
} else {
Ok(OperandSpec::Deref)
}
} else {
instr.scale = 1;
- Ok(OperandSpec::RegIndexBaseScaleDisp)
+ Ok(OperandSpec::MemBaseIndexScaleDisp)
}
},
_ => {
@@ -6525,7 +6504,7 @@ fn read_M<
OperandSpec::Deref
} else {
instr.disp = disp as i32 as u32;
- OperandSpec::RegDisp
+ OperandSpec::Disp
}
}
};
diff --git a/test/long_mode/operand.rs b/test/long_mode/operand.rs
index a47e6c8..0faa1c3 100644
--- a/test/long_mode/operand.rs
+++ b/test/long_mode/operand.rs
@@ -3,19 +3,19 @@ use yaxpeax_x86::MemoryAccessSize;
#[test]
fn register_widths() {
- assert_eq!(Operand::Register(RegSpec::rsp()).width(), Some(8));
- assert_eq!(Operand::Register(RegSpec::esp()).width(), Some(4));
- assert_eq!(Operand::Register(RegSpec::sp()).width(), Some(2));
- assert_eq!(Operand::Register(RegSpec::cl()).width(), Some(1));
- assert_eq!(Operand::Register(RegSpec::ch()).width(), Some(1));
- assert_eq!(Operand::Register(RegSpec::gs()).width(), Some(2));
+ assert_eq!(Operand::Register { reg: RegSpec::rsp() }.width(), Some(8));
+ assert_eq!(Operand::Register { reg: RegSpec::esp() }.width(), Some(4));
+ assert_eq!(Operand::Register { reg: RegSpec::sp() }.width(), Some(2));
+ assert_eq!(Operand::Register { reg: RegSpec::cl() }.width(), Some(1));
+ assert_eq!(Operand::Register { reg: RegSpec::ch() }.width(), Some(1));
+ assert_eq!(Operand::Register { reg: RegSpec::gs() }.width(), Some(2));
}
#[test]
fn memory_widths() {
// the register operand directly doesn't report a size - it comes from the `Instruction` for
- // which this is an operand.
- assert_eq!(Operand::RegDeref(RegSpec::rsp()).width(), None);
+ // which this is an operand .
+ assert_eq!(Operand::MemDeref { base: RegSpec::rsp() }.width(), None);
fn mem_size_of(data: &[u8]) -> MemoryAccessSize {
let decoder = InstDecoder::default();
diff --git a/test/protected_mode/operand.rs b/test/protected_mode/operand.rs
index 6eb9ba5..78a34b4 100644
--- a/test/protected_mode/operand.rs
+++ b/test/protected_mode/operand.rs
@@ -3,18 +3,18 @@ use yaxpeax_x86::MemoryAccessSize;
#[test]
fn register_widths() {
- assert_eq!(Operand::Register(RegSpec::esp()).width(), Some(4));
- assert_eq!(Operand::Register(RegSpec::sp()).width(), Some(2));
- assert_eq!(Operand::Register(RegSpec::cl()).width(), Some(1));
- assert_eq!(Operand::Register(RegSpec::ch()).width(), Some(1));
- assert_eq!(Operand::Register(RegSpec::gs()).width(), Some(2));
+ assert_eq!(Operand::Register { reg: RegSpec::esp() }.width(), Some(4));
+ assert_eq!(Operand::Register { reg: RegSpec::sp() }.width(), Some(2));
+ assert_eq!(Operand::Register { reg: RegSpec::cl() }.width(), Some(1));
+ assert_eq!(Operand::Register { reg: RegSpec::ch() }.width(), Some(1));
+ assert_eq!(Operand::Register { reg: RegSpec::gs() }.width(), Some(2));
}
#[test]
fn memory_widths() {
// the register operand directly doesn't report a size - it comes from the `Instruction` for
// which this is an operand.
- assert_eq!(Operand::RegDeref(RegSpec::esp()).width(), None);
+ assert_eq!(Operand::MemDeref { base: RegSpec::esp() }.width(), None);
fn mem_size_of(data: &[u8]) -> MemoryAccessSize {
let decoder = InstDecoder::default();