aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/long_mode/mod.rs468
-rw-r--r--src/long_mode/vex.rs282
-rw-r--r--src/protected_mode/mod.rs475
-rw-r--r--src/protected_mode/vex.rs265
4 files changed, 697 insertions, 793 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 8d83986..578e2f2 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -10,7 +10,7 @@ pub use self::display::DisplayStyle;
use core::cmp::PartialEq;
use core::hint::unreachable_unchecked;
-use yaxpeax_arch::{AddressDiff, Decoder, LengthedInstruction};
+use yaxpeax_arch::{AddressDiff, Decoder, Reader, LengthedInstruction};
use core::fmt;
impl fmt::Display for DecodeError {
@@ -2657,6 +2657,7 @@ pub struct Arch;
impl yaxpeax_arch::Arch for Arch {
type Address = u64;
+ type Word = u8;
type Instruction = Instruction;
type DecodeError = DecodeError;
type Decoder = InstDecoder;
@@ -4095,16 +4096,14 @@ impl Default for InstDecoder {
}
}
-impl Decoder<Instruction> for InstDecoder {
- type Error = DecodeError;
-
- fn decode<T: IntoIterator<Item=u8>>(&self, bytes: T) -> Result<Instruction, Self::Error> {
+impl Decoder<Arch> for InstDecoder {
+ fn decode<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(&self, words: &mut T) -> Result<Instruction, <Arch as yaxpeax_arch::Arch>::DecodeError> {
let mut instr = Instruction::invalid();
- decode_one(self, bytes, &mut instr)
+ read_instr(self, words, &mut instr)
.map(|_: ()| instr)
}
- fn decode_into<T: IntoIterator<Item=u8>>(&self, instr: &mut Instruction, bytes: T) -> Result<(), Self::Error> {
- decode_one(self, bytes, instr)
+ fn decode_into<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(&self, instr: &mut Instruction, words: &mut T) -> Result<(), <Arch as yaxpeax_arch::Arch>::DecodeError> {
+ read_instr(self, words, instr)
}
}
@@ -5412,46 +5411,46 @@ const OPCODES: [OpcodeRecord; 256] = [
];
#[allow(non_snake_case)]
-pub(self) fn read_E<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, width: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8, width: u8) -> Result<OperandSpec, DecodeError> {
let bank = width_to_gp_reg_bank(width, instr.prefixes.rex().present());
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, bank)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
-pub(self) fn read_E_mm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E_mm<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
if modrm >= 0b11000000 {
instr.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
Ok(OperandSpec::RegMMM)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
-pub(self) fn read_E_st<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E_st<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
if modrm >= 0b11000000 {
instr.modrm_mmm = RegSpec { bank: RegisterBank::ST, num: modrm & 7 };
Ok(OperandSpec::RegMMM)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
-pub(self) fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E_xmm<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, RegisterBank::X)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
-pub(self) fn read_E_ymm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E_ymm<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, RegisterBank::Y)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
@@ -5459,7 +5458,7 @@ pub(self) fn read_E_vex<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut In
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, bank)
} else {
- let res = read_M(bytes_iter, instr, modrm, length)?;
+ let res = read_M(bytes_iter, instr, modrm)?;
if (modrm & 0b01_000_000) == 0b01_000_000 {
instr.prefixes.apply_compressed_disp(true);
}
@@ -5474,24 +5473,20 @@ fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) ->
}
#[allow(non_snake_case)]
-fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+fn read_sib<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
let modbits = modrm >> 6;
- let sibbyte = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- *length += 1;
+ let sibbyte = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
let disp = if modbits == 0b00 {
if (sibbyte & 7) == 0b101 {
- *length += 4;
- read_num(bytes_iter, 4)? as i32
+ read_num(words, 4)? as i32
} else {
0
}
} else if modbits == 0b01 {
- *length += 1;
- read_num(bytes_iter, 1)? as i8 as i32
+ read_num(words, 1)? as i8 as i32
} else {
- *length += 4;
- read_num(bytes_iter, 4)? as i32
+ read_num(words, 4)? as i32
};
instr.disp = disp as u32 as u64;
@@ -5594,7 +5589,7 @@ fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, m
}
#[allow(non_snake_case)]
-fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+fn read_M<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
let modbits = modrm >> 6;
let mmm = modrm & 7;
if instr.prefixes.rex().b() {
@@ -5608,10 +5603,9 @@ fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, mod
instr.sib_index.num = 0;
}
let op_spec = if mmm == 4 {
- return read_sib(bytes_iter, instr, modrm, length);
+ return read_sib(words, instr, modrm);
} else if mmm == 5 && modbits == 0b00 {
- *length += 4;
- let disp = read_num(bytes_iter, 4)? as i32;
+ let disp = read_num(words, 4)? as i32;
instr.modrm_mmm =
if !instr.prefixes.address_size() { RegSpec::rip() } else { RegSpec::eip() };
if disp == 0 {
@@ -5627,11 +5621,9 @@ fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, mod
OperandSpec::Deref
} else {
let disp = if modbits == 0b01 {
- *length += 1;
- read_num(bytes_iter, 1)? as i8 as i32
+ read_num(words, 1)? as i8 as i32
} else {
- *length += 4;
- read_num(bytes_iter, 4)? as i32
+ read_num(words, 4)? as i32
};
if disp == 0 {
OperandSpec::Deref
@@ -6958,8 +6950,8 @@ fn read_0f3a_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {
};
}
-fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction) -> Result<(), DecodeError> {
- let mut length = 0u8;
+fn read_instr<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(decoder: &InstDecoder, words: &mut T, instruction: &mut Instruction) -> Result<(), DecodeError> {
+ words.mark();
// use core::intrinsics::unlikely;
let mut prefixes = Prefixes::new(0);
@@ -6970,24 +6962,20 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
instruction.mem_size = 0;
let record: OpcodeRecord = loop {
- let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
- if length >= 15 {
+ let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
+ if words.offset() >= 15 {
return Err(DecodeError::TooLong);
}
let record = OPCODES[b as usize];
if (b & 0xf0) == 0x40 {
prefixes.rex_from(b);
} else if b == 0x0f {
- let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
+ let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
if b == 0x38 {
- let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
+ let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
break read_0f38_opcode(b, &mut prefixes);
} else if b == 0x3a {
- let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
+ let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
break read_0f3a_opcode(b, &mut prefixes);
} else {
break read_0f_opcode(b, &mut prefixes);
@@ -7017,7 +7005,7 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
return Err(DecodeError::InvalidPrefixes);
} else {
instruction.prefixes = prefixes;
- vex::two_byte_vex(&mut bytes_iter, instruction, length)?;
+ vex::two_byte_vex(words, instruction)?;
if decoder != &InstDecoder::default() {
decoder.revise_instruction(instruction)?;
@@ -7031,7 +7019,7 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
return Err(DecodeError::InvalidPrefixes);
} else {
instruction.prefixes = prefixes;
- vex::three_byte_vex(&mut bytes_iter, instruction, length)?;
+ vex::three_byte_vex(words, instruction)?;
if decoder != &InstDecoder::default() {
decoder.revise_instruction(instruction)?;
}
@@ -7044,7 +7032,7 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
return Err(DecodeError::InvalidPrefixes);
} else {
instruction.prefixes = prefixes;
- evex::read_evex(&mut bytes_iter, instruction, length, None)?;
+ evex::read_evex(words, instruction, length, None)?;
if decoder != &InstDecoder::default() {
decoder.revise_instruction(instruction)?;
}
@@ -7098,7 +7086,6 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
if length > 15 {
return Err(DecodeError::TooLong);
}
- instruction.length = length;
if instruction.prefixes.lock() {
if !LOCKABLE_INSTRUCTIONS.contains(&instruction.opcode) || !instruction.operands[0].is_memory() {
@@ -7147,7 +7134,8 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
OperandCode::ModRM_0x8f_Ev => 30
*/
-fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, length: &mut u8) -> Result<(), DecodeError> {
+#[inline(always)]
+fn read_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instruction: &mut Instruction, operand_code: OperandCode) -> Result<(), DecodeError> {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operand_count = 2;
let operand_code = OperandCodeBuilder::from_bits(operand_code as u16);
@@ -7192,7 +7180,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.modrm_rrr =
RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present());
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, 1, length)?;
+ read_imm_unsigned(words, 1)?;
instruction.operands[1] = OperandSpec::ImmU8;
}
3 => {
@@ -7208,7 +7196,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.modrm_rrr =
RegSpec::from_parts(reg, instruction.prefixes.rex().b(), bank);
instruction.imm =
- read_imm_ivq(&mut bytes_iter, opwidth, length)?;
+ read_imm_ivq(words, opwidth)?;
instruction.operands[1] = match opwidth {
2 => OperandSpec::ImmI16,
4 => OperandSpec::ImmI32,
@@ -7253,7 +7241,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
bank = RegisterBank::B;
}
};
- modrm = read_modrm(&mut bytes_iter, length)?;
+ modrm = read_modrm(words)?;
instruction.modrm_rrr.bank = bank;
instruction.modrm_rrr.num = ((modrm >> 3) & 7) + if instruction.prefixes.rex().r() { 0b1000 } else { 0 };
@@ -7267,14 +7255,14 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
}
read_modrm_reg(instruction, modrm, bank)?
} else {
- read_M(&mut bytes_iter, instruction, modrm, length)?
+ read_M(words, instruction, modrm)?
};
instruction.operands[1] = mem_oper;
}
if let Some((only_imm, immsz)) = operand_code.has_imm() {
instruction.imm =
- read_imm_signed(&mut bytes_iter, 1 << (immsz * 2), length)? as u64;
+ read_imm_signed(words, 1 << (immsz * 2))? as u64;
if only_imm {
if immsz == 0 {
instruction.operands[0] = OperandSpec::ImmI8;
@@ -7307,7 +7295,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
2 => {
instruction.operands[0] = mem_oper;
let numwidth = if opwidth == 8 { 4 } else { opwidth };
- instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
+ instruction.imm = read_imm_signed(words, numwidth)? as u64;
instruction.opcode = base_opcode_map((modrm >> 3) & 7);
instruction.operands[1] = match opwidth {
2 => OperandSpec::ImmI16,
@@ -7322,16 +7310,16 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
if modrm == 0xf8 {
if op == 3 {
instruction.opcode = Opcode::XABORT;
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
+ instruction.imm = read_imm_signed(words, 1)? as u64;
instruction.operands[0] = OperandSpec::ImmI8;
instruction.operand_count = 1;
return Ok(());
} else {
instruction.opcode = Opcode::XBEGIN;
instruction.imm = if opwidth == 2 {
- read_imm_signed(&mut bytes_iter, 2, length)? as i16 as i64 as u64
+ read_imm_signed(words, 2)? as i16 as i64 as u64
} else {
- read_imm_signed(&mut bytes_iter, 4, length)? as i32 as i64 as u64
+ read_imm_signed(words, 4)? as i32 as i64 as u64
};
instruction.operands[0] = OperandSpec::ImmI32;
instruction.operand_count = 1;
@@ -7346,7 +7334,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.operands[0] = mem_oper;
instruction.opcode = Opcode::MOV;
let numwidth = if opwidth == 8 { 4 } else { opwidth };
- instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
+ instruction.imm = read_imm_signed(words, numwidth)? as u64;
instruction.operands[1] = match opwidth {
1 => OperandSpec::ImmI8,
2 => OperandSpec::ImmI16,
@@ -7374,8 +7362,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
let num = match op {
5 |
6 => {
- *length += 1;
- read_num(&mut bytes_iter, 1)?
+ read_num(words, 1)?
}
_ => {
// these are the _1 variants, everything else is unreachable
@@ -7395,7 +7382,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
0 | 1 => {
instruction.opcode = Opcode::TEST;
let numwidth = if opwidth == 8 { 4 } else { opwidth };
- instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
+ instruction.imm = read_imm_signed(words, numwidth)? as u64;
instruction.operands[1] = match opwidth {
1 => OperandSpec::ImmI8,
2 => OperandSpec::ImmI16,
@@ -7473,9 +7460,9 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
}
15 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 1, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 1)?;
instruction.modrm_rrr =
RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present());
if instruction.operands[1] != OperandSpec::RegMMM {
@@ -7485,9 +7472,9 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
},
16 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 2)?;
instruction.modrm_rrr =
RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present());
if instruction.operands[1] != OperandSpec::RegMMM {
@@ -7497,9 +7484,9 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
},
17 => {
let opwidth = 8;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4 /* opwidth */, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4 /* opwidth */)?;
instruction.mem_size = 4;
instruction.modrm_rrr =
RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present());
@@ -7542,14 +7529,13 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
}
},
22 => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
- *length += 1;
+ read_num(words, 1)? as u8 as u64;
if instruction.operands[1] != OperandSpec::RegMMM {
if instruction.opcode == Opcode::CMPSS {
instruction.mem_size = 4;
@@ -7574,7 +7560,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.modrm_rrr =
RegSpec::gp_from_parts(0, false, opwidth, false);
instruction.imm =
- read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
+ read_imm_signed(words, numwidth)? as u64;
instruction.operands[1] = match opwidth {
2 => OperandSpec::ImmI16,
4 => OperandSpec::ImmI32,
@@ -7586,7 +7572,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
25 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vd, instruction.prefixes);
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, opwidth, length)?;
+ read_imm_unsigned(words, opwidth)?;
instruction.operands[0] = match opwidth {
2 => OperandSpec::ImmI16,
4 => OperandSpec::ImmI32,
@@ -7654,7 +7640,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
},
_ => {
let operand_code: OperandCode = unsafe { core::mem::transmute(operand_code.bits()) };
- unlikely_operands(decoder, bytes_iter, instruction, operand_code, mem_oper, length)?;
+ unlikely_operands(decoder, bytes_iter, instruction, operand_code, mem_oper)?;
}
};
}
@@ -7664,14 +7650,13 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, length: &mut u8) -> Result<(), DecodeError> {
match operand_code {
OperandCode::G_E_mm_Ib => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_mm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_mm(words, instruction, modrm)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, false, RegisterBank::MM);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
- *length += 1;
+ read_num(words, 1)? as u8 as u64;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 8;
}
@@ -7679,14 +7664,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 3;
}
OperandCode::G_Ev_xmm_Ib => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
- *length += 1;
+ read_num(words, 1)? as u8 as u64;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = match instruction.opcode {
Opcode::PEXTRB => 1,
@@ -7704,12 +7688,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 3;
}
OperandCode::PMOVX_E_G_xmm => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.operands[0] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_xmm(words, instruction, modrm)?;
if instruction.operands[0] != OperandSpec::RegMMM {
if [].contains(&instruction.opcode) {
instruction.mem_size = 2;
@@ -7723,12 +7707,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::PMOVX_G_E_xmm => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
instruction.operands[0] = OperandSpec::RegRRR;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
if instruction.operands[1] != OperandSpec::RegMMM {
if [Opcode::PMOVSXBQ, Opcode::PMOVZXBQ].contains(&instruction.opcode) {
instruction.mem_size = 2;
@@ -7744,12 +7728,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::INV_Gv_M => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::Q);
instruction.operands[0] = OperandSpec::RegRRR;
- instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_M(words, instruction, modrm)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -7766,24 +7750,23 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::G_U_xmm_Ub => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
if instruction.operands[1] != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::D);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
- *length += 1;
+ read_num(words, 1)? as u8 as u64;
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operand_count = 3;
}
OperandCode::ModRM_0xf20f78 => {
instruction.opcode = Opcode::INSERTQ;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm < 0b11_000_000 {
return Err(DecodeError::InvalidOperand);
@@ -7796,10 +7779,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm =
RegSpec::from_parts(modrm & 7, instruction.prefixes.rex().r(), RegisterBank::X);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
+ read_num(words, 1)? as u8 as u64;
instruction.disp =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
- *length += 2;
+ read_num(words, 1)? as u8 as u64;
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operands[3] = OperandSpec::ImmInDispField;
instruction.operand_count = 4;
@@ -7807,7 +7789,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
OperandCode::ModRM_0x660f78 => {
instruction.opcode = Opcode::EXTRQ;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm < 0b11_000_000 {
return Err(DecodeError::InvalidOperand);
@@ -7821,24 +7803,22 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm =
RegSpec::from_parts(modrm & 7, instruction.prefixes.rex().r(), RegisterBank::X);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
+ read_num(words, 1)? as u8 as u64;
instruction.disp =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
- *length += 2;
+ read_num(words, 1)? as u8 as u64;
instruction.operands[1] = OperandSpec::ImmU8;
instruction.operands[2] = OperandSpec::ImmInDispField;
instruction.operand_count = 3;
}
OperandCode::G_E_xmm_Ub => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
- *length += 1;
+ read_num(words, 1)? as u8 as u64;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 16;
}
@@ -7897,7 +7877,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
let numwidth = if opwidth == 8 { 4 } else { opwidth };
instruction.imm =
- read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
+ read_imm_signed(words, numwidth)? as u64;
instruction.operands[2] = match opwidth {
2 => OperandSpec::ImmI16,
4 => OperandSpec::ImmI32,
@@ -7910,7 +7890,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.imm =
- read_imm_signed(&mut bytes_iter, 1, length)? as u64;
+ read_imm_signed(words, 1)? as u64;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
}
@@ -7922,9 +7902,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 3;
}
OperandCode::G_mm_Ew_Ib => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, false, RegisterBank::MM);
if instruction.operands[1] == OperandSpec::RegMMM {
@@ -7933,8 +7913,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.mem_size = 2;
}
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u64;
- *length += 1;
+ read_num(words, 1)? as u8 as u64;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
}
@@ -7964,9 +7943,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
},
OperandCode::Gv_Ew_LSL => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 2)?;
// lsl is weird. the full register width is written, but only the low 16 bits are used.
if instruction.operands[1] == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::D;
@@ -7979,9 +7958,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
},
OperandCode::Gdq_Ev => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, opwidth)?;
// `opwidth` can be 2, 4, or 8 here. if opwidth is 2, the first operand is a dword.
// if opwidth is 4, both registers are dwords. and if opwidth is 8, both registers are
// qword.
@@ -8010,8 +7989,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
};
instruction.mem_size = opwidth;
let addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
- let imm = read_num(&mut bytes_iter, addr_width)?;
- *length += addr_width;
+ let imm = read_num(words, addr_width)?;
instruction.modrm_rrr =
RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present());
instruction.disp = imm;
@@ -8035,8 +8013,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
};
instruction.mem_size = opwidth;
let addr_width = if instruction.prefixes.address_size() { 4 } else { 8 };
- let imm = read_num(&mut bytes_iter, addr_width)?;
- *length += addr_width;
+ let imm = read_num(words, addr_width)?;
instruction.disp = imm;
instruction.operands[0] = if instruction.prefixes.address_size() {
OperandSpec::DispU32
@@ -8059,12 +8036,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
*/
OperandCode::Iw_Ib => {
- instruction.disp = read_num(&mut bytes_iter, 2)? as u64;
- instruction.imm = read_num(&mut bytes_iter, 1)? as u64;
+ instruction.disp = read_num(words, 2)? as u64;
+ instruction.imm = read_num(words, 1)? as u64;
instruction.operands[0] = OperandSpec::ImmInDispField;
instruction.operands[1] = OperandSpec::ImmU8;
instruction.operand_count = 2;
- *length += 3;
}
OperandCode::Fw => {
if instruction.prefixes.rex().w() {
@@ -8078,10 +8054,10 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::Mdq_Gdq => {
let opwidth = if instruction.prefixes.rex().w() { 8 } else { 4 };
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.operands[1] = instruction.operands[0];
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
} else {
@@ -8107,9 +8083,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 8, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 8)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::Q);
@@ -8123,12 +8099,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::Q);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 8, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 8)?;
instruction.operand_count = 2;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 8;
@@ -8155,10 +8131,10 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
//
// anyway, there are two operands, and the primary concern here is "what are they?".
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
if instruction.prefixes.rex().w() {
let op = instruction.operands[0];
instruction.operands[0] = instruction.operands[1];
@@ -8177,7 +8153,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0x0f0d => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 0b111;
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes);
@@ -8190,7 +8166,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::NOP;
}
}
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = 64;
}
@@ -8200,15 +8176,15 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
// 3dnow instructions are WILD, the opcode is encoded as an imm8 trailing the
// instruction.
- let modrm = read_modrm(&mut bytes_iter, length)?;
- instruction.operands[1] = read_E_mm(&mut bytes_iter, instruction, modrm, length)?;
+ let modrm = read_modrm(words)?;
+ instruction.operands[1] = read_E_mm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec { bank: RegisterBank::MM, num: (modrm >> 3) & 7 };
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 8;
}
- let opcode = read_modrm(&mut bytes_iter, length)?;
+ let opcode = read_modrm(words)?;
match opcode {
0x0c => {
instruction.opcode = Opcode::PI2FW;
@@ -8289,7 +8265,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::ModRM_0x0fc7 => {
if instruction.prefixes.repnz() {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let is_reg = (modrm & 0xc0) == 0xc0;
let r = (modrm >> 3) & 7;
@@ -8308,7 +8284,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
instruction.operand_count = 1;
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
return Ok(());
}
@@ -8319,7 +8295,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
if instruction.prefixes.operand_size() {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let is_reg = (modrm & 0xc0) == 0xc0;
let r = (modrm >> 3) & 7;
@@ -8338,13 +8314,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
instruction.operand_count = 1;
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
return Ok(());
}
6 => {
instruction.opcode = Opcode::VMCLEAR;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] == OperandSpec::RegMMM {
// this would be invalid as `vmclear`, so fall back to the parse as
// 66-prefixed rdrand. this is a register operand, so just demote it to the
@@ -8358,7 +8334,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Ok(());
}
7 => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] == OperandSpec::RegMMM {
// this would be invalid as `vmclear`, so fall back to the parse as
// 66-prefixed rdrand. this is a register operand, so just demote it to the
@@ -8379,7 +8355,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
if instruction.prefixes.rep() {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let is_reg = (modrm & 0xc0) == 0xc0;
let r = (modrm >> 3) & 7;
@@ -8398,12 +8374,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
instruction.operand_count = 1;
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
}
6 => {
instruction.opcode = Opcode::VMXON;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] == OperandSpec::RegMMM {
// invalid as `vmxon`, reg-form is `senduipi`
instruction.opcode = Opcode::SENDUIPI;
@@ -8416,7 +8392,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
7 => {
instruction.opcode = Opcode::RDPID;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -8429,7 +8405,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Ok(());
}
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let is_reg = (modrm & 0xc0) == 0xc0;
let r = (modrm >> 3) & 0b111;
@@ -8513,7 +8489,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = opcode;
instruction.operand_count = 1;
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
},
OperandCode::ModRM_0x0f71 => {
if instruction.prefixes.rep() || instruction.prefixes.repnz() {
@@ -8522,7 +8498,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
return Err(DecodeError::InvalidOperand);
}
@@ -8549,7 +8525,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
}
instruction.operands[0] = OperandSpec::RegMMM;
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
+ instruction.imm = read_imm_signed(words, 1)? as u64;
instruction.operands[1] = OperandSpec::ImmU8;
},
OperandCode::ModRM_0x0f72 => {
@@ -8559,7 +8535,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
return Err(DecodeError::InvalidOperand);
}
@@ -8586,7 +8562,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
}
instruction.operands[0] = OperandSpec::RegMMM;
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
+ instruction.imm = read_imm_signed(words, 1)? as u64;
instruction.operands[1] = OperandSpec::ImmU8;
},
OperandCode::ModRM_0x0f73 => {
@@ -8596,7 +8572,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
return Err(DecodeError::InvalidOperand);
}
@@ -8632,11 +8608,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
}
instruction.operands[0] = OperandSpec::RegMMM;
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
+ instruction.imm = read_imm_signed(words, 1)? as u64;
instruction.operands[1] = OperandSpec::ImmU8;
},
OperandCode::ModRM_0xf30f38d8 => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
match r {
0b000 => {
@@ -8644,7 +8620,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOperand);
}
instruction.opcode = Opcode::AESENCWIDE128KL;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
return Ok(());
}
0b001 => {
@@ -8652,7 +8628,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOperand);
}
instruction.opcode = Opcode::AESDECWIDE128KL;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
return Ok(());
}
0b010 => {
@@ -8660,7 +8636,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOperand);
}
instruction.opcode = Opcode::AESENCWIDE256KL;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
return Ok(());
}
0b011 => {
@@ -8668,7 +8644,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOperand);
}
instruction.opcode = Opcode::AESDECWIDE256KL;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
return Ok(());
}
_ => {
@@ -8677,7 +8653,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0xf30f38dc => {
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?;
+ read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm)?;
if let OperandSpec::RegMMM = instruction.operands[1] {
instruction.opcode = Opcode::LOADIWKEY;
} else {
@@ -8685,7 +8661,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0xf30f38dd => {
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?;
+ read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm)?;
if let OperandSpec::RegMMM = instruction.operands[1] {
return Err(DecodeError::InvalidOperand);
} else {
@@ -8693,7 +8669,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0xf30f38de => {
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?;
+ read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm)?;
if let OperandSpec::RegMMM = instruction.operands[1] {
return Err(DecodeError::InvalidOperand);
} else {
@@ -8701,7 +8677,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0xf30f38df => {
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?;
+ read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm)?;
if let OperandSpec::RegMMM = instruction.operands[1] {
return Err(DecodeError::InvalidOperand);
} else {
@@ -8710,13 +8686,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::ModRM_0xf30f38fa => {
instruction.opcode = Opcode::ENCODEKEY128;
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm, length)?;
+ read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm)?;
instruction.modrm_rrr.bank = RegisterBank::D;
instruction.modrm_mmm.bank = RegisterBank::D;
}
OperandCode::ModRM_0xf30f38fb => {
instruction.opcode = Opcode::ENCODEKEY256;
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm, length)?;
+ read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm)?;
instruction.modrm_rrr.bank = RegisterBank::D;
instruction.modrm_mmm.bank = RegisterBank::D;
}
@@ -8816,8 +8792,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operand_count = 3;
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u64;
- *length += 1;
+ read_num(words, 1)? as u64;
instruction.modrm_rrr.bank = RegisterBank::X;
if mem_oper == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::D;
@@ -8864,8 +8839,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operand_count = 3;
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u64;
- *length += 1;
+ read_num(words, 1)? as u64;
instruction.modrm_rrr.bank = RegisterBank::D;
if mem_oper == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::MM;
@@ -9027,7 +9001,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::Ew_Sw => {
let opwidth = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
// check r
if ((modrm >> 3) & 7) > 5 {
@@ -9046,12 +9020,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec { bank: RegisterBank::W, num: modrm & 7};
instruction.operands[0] = OperandSpec::RegMMM;
} else {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
instruction.mem_size = 2;
}
},
OperandCode::Sw_Ew => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
// check r
if ((modrm >> 3) & 7) > 5 {
@@ -9080,7 +9054,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec { bank: RegisterBank::W, num: modrm & 7};
instruction.operands[1] = OperandSpec::RegMMM;
} else {
- instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_M(words, instruction, modrm)?;
instruction.mem_size = 2;
}
},
@@ -9112,13 +9086,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::Iw => {
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, 2, length)?;
+ read_imm_unsigned(words, 2)?;
instruction.operands[0] = OperandSpec::ImmU16;
instruction.operand_count = 1;
}
OperandCode::ModRM_0x0f00 => {
instruction.operand_count = 1;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
if r == 0 {
instruction.opcode = Opcode::SLDT;
@@ -9146,14 +9120,14 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
} else {
unreachable!("r <= 8");
}
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 2)?;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = 2;
}
}
OperandCode::ModRM_0x0f01 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
if r == 0 {
let mod_bits = modrm >> 6;
@@ -9186,7 +9160,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::SGDT;
instruction.operand_count = 1;
instruction.mem_size = 63;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else if r == 1 {
let mod_bits = modrm >> 6;
@@ -9243,7 +9217,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::SIDT;
instruction.operand_count = 1;
instruction.mem_size = 63;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else if r == 2 {
let mod_bits = modrm >> 6;
@@ -9279,7 +9253,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::LGDT;
instruction.operand_count = 1;
instruction.mem_size = 63;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else if r == 3 {
let mod_bits = modrm >> 6;
@@ -9344,7 +9318,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::LIDT;
instruction.operand_count = 1;
instruction.mem_size = 63;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else if r == 4 {
// TODO: this permits storing only to word-size registers
@@ -9352,7 +9326,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::SMSW;
instruction.operand_count = 1;
instruction.mem_size = 2;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 2)?;
} else if r == 5 {
let mod_bits = modrm >> 6;
if mod_bits != 0b11 {
@@ -9360,7 +9334,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
instruction.opcode = Opcode::RSTORSSP;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 8, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 8)?;
instruction.mem_size = 8;
instruction.operand_count = 1;
return Ok(());
@@ -9464,7 +9438,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::LMSW;
instruction.operand_count = 1;
instruction.mem_size = 2;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 2)?;
} else if r == 7 {
let mod_bits = modrm >> 6;
let m = modrm & 7;
@@ -9514,14 +9488,14 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::INVLPG;
instruction.operand_count = 1;
instruction.mem_size = 1;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else {
unreachable!("r <= 8");
}
}
OperandCode::ModRM_0x0fae => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
let m = modrm & 7;
@@ -9540,7 +9514,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
};
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 1 /* opwidth */, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 1 /* opwidth */)?;
instruction.mem_size = 64;
instruction.operand_count = 1;
} else {
@@ -9554,7 +9528,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
};
let opwidth = if instruction.prefixes.rex().w() { 8 } else { 4 };
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
instruction.operand_count = 1;
}
@@ -9595,7 +9569,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
} else {
4
};
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = opwidth;
}
@@ -9676,7 +9650,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
match r {
6 => {
instruction.opcode = Opcode::CLRSSBSY;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 8, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 8)?;
instruction.operand_count = 1;
instruction.mem_size = 8;
return Ok(());
@@ -9752,12 +9726,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
][r as usize];
instruction.opcode = opcode;
instruction.mem_size = mem_size;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
}
}
OperandCode::ModRM_0x0fba => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
match r {
0 | 1 | 2 | 3 => {
@@ -9781,12 +9755,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = opwidth;
}
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
+ instruction.imm = read_imm_signed(words, 1)? as u64;
instruction.operands[1] = OperandSpec::ImmI8;
instruction.operand_count = 2;
}
@@ -9794,7 +9768,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
op @ OperandCode::Rq_Dq_0 |
op @ OperandCode::Cq_Rq_0 |
op @ OperandCode::Dq_Rq_0 => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let mut m = modrm & 7;
let mut r = (modrm >> 3) & 7;
if instruction.prefixes.rex().r() {
@@ -9973,7 +9947,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
OperandCode::x87_dd |
OperandCode::x87_de |
OperandCode::x87_df => {
- return decode_x87(decoder, bytes_iter, instruction, operand_code, length);
+ return decode_x87(decoder, bytes_iter, instruction, operand_code);
}
OperandCode::MOVDIR64B => {
// at this point we've done a read as if it was Gv_M (`lea` operands). because the
@@ -10043,7 +10017,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
}
// every x87 instruction is conditional on rrr bits
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 0b111;
let (opcode, x87_operands) = match operand_code {
@@ -10364,19 +10338,19 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
match x87_operands {
OperandCodeX87::Est => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operand_count = 1;
}
OperandCodeX87::St_Est => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_st(words, instruction, modrm)?;
instruction.operand_count = 2;
}
OperandCodeX87::St_Edst => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_st(words, instruction, modrm)?;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 4;
}
@@ -10385,7 +10359,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Eqst => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_st(words, instruction, modrm)?;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 8;
}
@@ -10394,7 +10368,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Ew => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 2)?;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 2;
}
@@ -10403,7 +10377,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Mm => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10413,7 +10387,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Mq => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10423,7 +10397,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Md => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10433,7 +10407,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Mw => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10441,20 +10415,20 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Ew => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 2)?;
instruction.operand_count = 1;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = 2;
}
}
OperandCodeX87::Est_St => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
instruction.operand_count = 2;
}
OperandCodeX87::Edst_St => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
instruction.operand_count = 2;
@@ -10463,7 +10437,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
}
}
OperandCodeX87::Eqst_St => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
instruction.operand_count = 2;
@@ -10472,7 +10446,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
}
}
OperandCodeX87::Ed_St => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
if instruction.operands[0] != OperandSpec::RegMMM {
@@ -10481,7 +10455,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Mm_St => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10491,7 +10465,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Mq_St => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10501,7 +10475,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Md_St => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10511,7 +10485,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Mw_St => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10521,7 +10495,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Ex87S => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
instruction.operand_count = 1;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
@@ -10536,39 +10510,24 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
Ok(())
}
-fn decode_one<'b, T: IntoIterator<Item=u8>>(decoder: &InstDecoder, bytes: T, instr: &'b mut Instruction) -> Result<(), DecodeError> {
- let bytes_iter = bytes.into_iter();
- read_instr(decoder, bytes_iter, instr)
-}
-
#[inline]
-fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u64, DecodeError> {
+fn read_num<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(bytes: &mut T, width: u8) -> Result<u64, DecodeError> {
match width {
- 1 => { bytes.next().map(|x| x as u64).ok_or(DecodeError::ExhaustedInput) }
+ 1 => { bytes.next().ok().ok_or(DecodeError::ExhaustedInput).map(|x| x as u64) }
2 => {
- bytes.next().and_then(|b0| {
- bytes.next().map(|b1| u16::from_le_bytes([b0, b1]) as u64)
- }).ok_or(DecodeError::ExhaustedInput)
+ let mut buf = [0u8; 2];
+ bytes.next_n(&mut buf).ok().ok_or(DecodeError::ExhaustedInput)?;
+ Ok(u16::from_le_bytes(buf) as u64)
}
4 => {
- bytes.next()
- .and_then(|b0| bytes.next().map(|b1| (b0, b1)))
- .and_then(|(b0, b1)| bytes.next().map(|b2| (b0, b1, b2)))
- .and_then(|(b0, b1, b2)| bytes.next().map(|b3| u32::from_le_bytes([b0, b1, b2, b3]) as u64))
- .ok_or(DecodeError::ExhaustedInput)
+ let mut buf = [0u8; 4];
+ bytes.next_n(&mut buf).ok().ok_or(DecodeError::ExhaustedInput)?;
+ Ok(u32::from_le_bytes(buf) as u64)
}
8 => {
- bytes.next()
- .and_then(|b0| bytes.next().map(|b1| (b0, b1)))
- .and_then(|(b0, b1)| bytes.next().map(|b2| (b0, b1, b2)))
- .and_then(|(b0, b1, b2)| bytes.next().map(|b3| (b0, b1, b2, b3)))
- .and_then(|(b0, b1, b2, b3)| bytes.next().map(|b4| (b0, b1, b2, b3, b4)))
- .and_then(|(b0, b1, b2, b3, b4)| bytes.next().map(|b5| (b0, b1, b2, b3, b4, b5)))
- .and_then(|(b0, b1, b2, b3, b4, b5)| bytes.next().map(|b6| (b0, b1, b2, b3, b4, b5, b6)))
- .and_then(|(b0, b1, b2, b3, b4, b5, b6)| {
- bytes.next().map(|b7| u64::from_le_bytes([b0, b1, b2, b3, b4, b5, b6, b7]) as u64)
- })
- .ok_or(DecodeError::ExhaustedInput)
+ let mut buf = [0u8; 8];
+ bytes.next_n(&mut buf).ok().ok_or(DecodeError::ExhaustedInput)?;
+ Ok(u64::from_le_bytes(buf))
}
_ => {
panic!("unsupported read size");
@@ -10577,18 +10536,15 @@ fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u64, Decod
}
#[inline]
-fn read_imm_ivq<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<u64, DecodeError> {
+fn read_imm_ivq<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(bytes: &mut T, width: u8) -> Result<u64, DecodeError> {
match width {
2 => {
- *length += 2;
Ok(read_num(bytes, 2)? as u16 as u64)
},
4 => {
- *length += 4;
Ok(read_num(bytes, 4)? as u32 as u64)
},
8 => {
- *length += 8;
Ok(read_num(bytes, 8)? as u64)
},
_ => {
@@ -10598,26 +10554,20 @@ fn read_imm_ivq<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8)
}
#[inline(always)]
-fn read_imm_signed<T: Iterator<Item=u8>>(bytes: &mut T, num_width: u8, length: &mut u8) -> Result<i64, DecodeError> {
+fn read_imm_signed<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(bytes: &mut T, num_width: u8) -> Result<i64, DecodeError> {
if num_width == 1 {
- *length += 1;
Ok(read_num(bytes, 1)? as i8 as i64)
} else if num_width == 2 {
- *length += 2;
Ok(read_num(bytes, 2)? as i16 as i64)
} else {
- *length += 4;
// this is for 4 and 8, the only values for num_width may be 1, 2, 4, and 8.
Ok(read_num(bytes, 4)? as i32 as i64)
}
}
#[inline]
-fn read_imm_unsigned<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<u64, DecodeError> {
- read_num(bytes, width).map(|res| {
- *length += width;
- res
- })
+fn read_imm_unsigned<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(bytes: &mut T, width: u8) -> Result<u64, DecodeError> {
+ read_num(bytes, width)
}
#[inline]
@@ -10647,6 +10597,6 @@ fn imm_width_from_prefixes_64(interpretation: SizeCode, prefixes: Prefixes) -> u
}
#[inline]
-fn read_modrm<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<u8, DecodeError> {
- bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })
+fn read_modrm<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T) -> Result<u8, DecodeError> {
+ words.next().ok().ok_or(DecodeError::ExhaustedInput)
}
diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs
index 31297f7..a3bdd6d 100644
--- a/src/long_mode/vex.rs
+++ b/src/long_mode/vex.rs
@@ -1,3 +1,6 @@
+use yaxpeax_arch::Reader;
+
+use crate::long_mode::Arch;
use crate::long_mode::OperandSpec;
use crate::long_mode::DecodeError;
use crate::long_mode::RegSpec;
@@ -97,10 +100,9 @@ enum VEXOperandCode {
}
#[inline(never)]
-pub(crate) fn three_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Instruction, mut length: u8) -> Result<(), DecodeError> {
- let vex_byte_one = bytes.next().ok_or(DecodeError::ExhaustedInput)?;
- let vex_byte_two = bytes.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 2;
+pub(crate) fn three_byte_vex<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instruction: &mut Instruction) -> Result<(), DecodeError> {
+ let vex_byte_one = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
+ let vex_byte_two = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
let p = vex_byte_two & 0x03;
let p = match p {
0x00 => VEXOpcodePrefix::None,
@@ -125,14 +127,11 @@ pub(crate) fn three_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &
};
instruction.prefixes.vex_from_c4(vex_byte_one, vex_byte_two);
- read_vex_instruction(m, bytes, instruction, &mut length, p)?;
- instruction.length = length;
- Ok(())
+ read_vex_instruction(m, words, instruction, p)
}
-pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Instruction, mut length: u8) -> Result<(), DecodeError> {
- let vex_byte = bytes.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
+pub(crate) fn two_byte_vex<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instruction: &mut Instruction) -> Result<(), DecodeError> {
+ let vex_byte = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
let p = vex_byte & 0x03;
let p = match p {
0x00 => VEXOpcodePrefix::None,
@@ -147,16 +146,14 @@ pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mu
};
instruction.prefixes.vex_from_c5(vex_byte);
- read_vex_instruction(VEXOpcodeMap::Map0F, bytes, instruction, &mut length, p)?;
- instruction.length = length;
- Ok(())
+ read_vex_instruction(VEXOpcodeMap::Map0F, words, instruction, p)
}
-fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Instruction, length: &mut u8, operand_code: VEXOperandCode) -> Result<(), DecodeError> {
+fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instruction: &mut Instruction, operand_code: VEXOperandCode) -> Result<(), DecodeError> {
// println!("operand code: {:?}", operand_code);
match operand_code {
VEXOperandCode::VPS_71 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -180,13 +177,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::X;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_71_L => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -213,13 +210,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_72 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -243,13 +240,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::X;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_72_L => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -273,13 +270,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_73 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -306,13 +303,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::X;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_73_L => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -345,17 +342,17 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VMOVSS_10 |
VEXOperandCode::VMOVSD_10 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
match mem_oper {
OperandSpec::RegMMM => {
@@ -381,10 +378,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
},
VEXOperandCode::VMOVSS_11 |
VEXOperandCode::VMOVSD_11 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[2] = OperandSpec::RegRRR;
match mem_oper {
OperandSpec::RegMMM => {
@@ -410,7 +407,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
},
VEXOperandCode::VMOVLPS_12 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.opcode = if modrm & 0xc0 == 0xc0 {
Opcode::VMOVHLPS
} else {
@@ -421,12 +418,12 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
- instruction.operands[2] = read_E_xmm(bytes, instruction, modrm, length)?;
+ instruction.operands[2] = read_E_xmm(words, instruction, modrm)?;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VMOVHPS_16 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.opcode = if modrm & 0xc0 == 0xc0 {
Opcode::VMOVLHPS
} else {
@@ -437,7 +434,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
- instruction.operands[2] = read_E_xmm(bytes, instruction, modrm, length)?;
+ instruction.operands[2] = read_E_xmm(words, instruction, modrm)?;
instruction.operand_count = 3;
Ok(())
}
@@ -450,10 +447,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operands[2] = OperandSpec::ImmU8;
@@ -477,7 +474,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.modrm_mmm.bank = RegisterBank::Q;
}
instruction.operand_count = 3;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
Ok(())
},
VEXOperandCode::G_xmm_Eq => {
@@ -485,10 +482,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 8, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 8)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -502,10 +499,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -519,10 +516,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 8, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 8)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
if mem_oper != OperandSpec::RegMMM {
@@ -536,10 +533,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
if mem_oper != OperandSpec::RegMMM {
@@ -553,10 +550,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
if let OperandSpec::RegMMM = mem_oper {
instruction.modrm_mmm.bank = RegisterBank::X;
} else {
@@ -572,10 +569,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Q);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
if let OperandSpec::RegMMM = mem_oper {
instruction.modrm_mmm.bank = RegisterBank::X;
} else {
@@ -596,10 +593,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
match (op, mem_oper) {
(VEXOperandCode::E_G_xmm, OperandSpec::RegMMM) => {
/* this is the only accepted operand */
@@ -629,10 +626,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -646,10 +643,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -663,16 +660,16 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operand_count = 3;
Ok(())
@@ -682,13 +679,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -701,13 +698,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -721,10 +718,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -738,10 +735,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -758,7 +755,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
match (op, modrm & 0xc0) {
(VEXOperandCode::G_U_xmm, 0xc0) => {
/* this is the only accepted operand */
@@ -774,7 +771,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -794,10 +791,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -811,10 +808,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -829,7 +826,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 == 0xc0 {
if let VEXOperandCode::G_ymm_M_xmm = op {
return Err(DecodeError::InvalidOperand);
@@ -837,7 +834,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -857,10 +854,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -876,7 +873,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
match (op, modrm & 0xc0) {
(VEXOperandCode::M_G_ymm, 0xc0) => {
return Err(DecodeError::InvalidOperand);
@@ -888,7 +885,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
if mem_oper != OperandSpec::RegMMM {
@@ -904,7 +901,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
match (op, modrm & 0xc0) {
(VEXOperandCode::G_M_ymm, 0xc0) => {
return Err(DecodeError::InvalidOperand);
@@ -916,7 +913,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -927,7 +924,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
op @ VEXOperandCode::G_V_E_ymm |
op @ VEXOperandCode::G_V_M_ymm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if let VEXOperandCode::G_V_M_ymm = op {
if modrm & 0xc0 == 0xc0 {
return Err(DecodeError::InvalidOperand);
@@ -936,7 +933,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -947,15 +944,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_ymm_imm8 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[3] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 32;
@@ -964,14 +961,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::M_V_G_ymm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 == 0xc0 {
return Err(DecodeError::InvalidOperand);
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegRRR;
@@ -982,13 +979,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_M_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 == 0xc0 {
return Err(DecodeError::InvalidOperand);
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1003,10 +1000,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1023,10 +1020,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_xmm_Ed => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1037,10 +1034,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_xmm_Eq => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 8, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 8)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1051,14 +1048,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_xmm_imm8 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[3] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -1067,15 +1064,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_ymm_V_ymm_E_xmm_imm8 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[3] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -1084,14 +1081,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::M_V_G_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 == 0xc0 {
return Err(DecodeError::InvalidOperand);
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegRRR;
@@ -1103,10 +1100,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
VEXOperandCode::G_Ex_V_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.sib_index.bank = RegisterBank::X;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
@@ -1118,10 +1115,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_Ey_V_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.vex_reg.bank = RegisterBank::X;
instruction.sib_index.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegRRR;
@@ -1134,10 +1131,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_Ey_V_ymm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.vex_reg.bank = RegisterBank::Y;
instruction.sib_index.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegRRR;
@@ -1154,7 +1151,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
let (opwidth, bank) = if instruction.prefixes.vex().w() {
(8, RegisterBank::Q)
} else {
@@ -1163,7 +1160,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), bank);
instruction.vex_reg.bank = bank;
- let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1174,7 +1171,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_E_V => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
let (opwidth, bank) = if instruction.prefixes.vex().w() {
(8, RegisterBank::Q)
} else {
@@ -1183,7 +1180,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), bank);
instruction.vex_reg.bank = bank;
- let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.operands[2] = OperandSpec::RegVex;
@@ -1194,7 +1191,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_E_Ib => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
let (opwidth, bank) = if instruction.prefixes.vex().w() {
(8, RegisterBank::Q)
} else {
@@ -1202,10 +1199,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
};
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), bank);
- let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = opwidth;
@@ -1214,7 +1211,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::BMI1_F3 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.opcode = match (modrm >> 3) & 7 {
1 => {
Opcode::BLSR
@@ -1237,7 +1234,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
};
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), bank);
- let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth)?;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = mem_oper;
instruction.operand_count = 2;
@@ -1248,7 +1245,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::MXCSR => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.opcode = match (modrm >> 3) & 7 {
2 => {
Opcode::VLDMXCSR
@@ -1261,7 +1258,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
return Err(DecodeError::InvalidOpcode);
}
};
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
if let OperandSpec::RegMMM = mem_oper {
return Err(DecodeError::InvalidOperand);
}
@@ -1276,13 +1273,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
if instruction.vex_reg.num != 0 {
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -1294,13 +1291,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
if instruction.vex_reg.num != 0 {
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 32;
@@ -1309,15 +1306,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_ymm_ymm4 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)? >> 4;
+ instruction.imm = read_imm_unsigned(words, 1)? >> 4;
instruction.operands[3] = OperandSpec::Reg4;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 32;
@@ -1326,15 +1323,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_xmm_xmm4 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), RegisterBank::X);
instruction.vex_reg.bank = RegisterBank::X;
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)? >> 4;
+ instruction.imm = read_imm_unsigned(words, 1)? >> 4;
instruction.operands[3] = OperandSpec::Reg4;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -1343,11 +1340,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_ymm_E_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1358,16 +1355,16 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_xmm_Ev_imm8 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex().x(), RegisterBank::X);
instruction.vex_reg.bank = RegisterBank::X;
// TODO: but the memory access is word-sized
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[3] = OperandSpec::ImmI8;
if mem_oper != OperandSpec::RegMMM {
match instruction.opcode {
@@ -1395,9 +1392,8 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
}
-fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &mut T, instruction: &mut Instruction, length: &mut u8, p: VEXOpcodePrefix) -> Result<(), DecodeError> {
- let opc = bytes.next().ok_or(DecodeError::ExhaustedInput)?;
- *length += 1;
+fn read_vex_instruction<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(opcode_map: VEXOpcodeMap, words: &mut T, instruction: &mut Instruction, p: VEXOpcodePrefix) -> Result<(), DecodeError> {
+ let opc = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
// the name of this bit is `L` in the documentation, so use the same name here.
#[allow(non_snake_case)]
@@ -3437,5 +3433,5 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &
}
};
instruction.opcode = opcode;
- read_vex_operands(bytes, instruction, length, operand_code)
+ read_vex_operands(words, instruction, operand_code)
}
diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs
index 76f3a43..c3a5334 100644
--- a/src/protected_mode/mod.rs
+++ b/src/protected_mode/mod.rs
@@ -9,7 +9,7 @@ pub use self::display::DisplayStyle;
use core::hint::unreachable_unchecked;
-use yaxpeax_arch::{AddressDiff, Decoder, LengthedInstruction};
+use yaxpeax_arch::{AddressDiff, Decoder, Reader, LengthedInstruction};
use core::fmt;
impl fmt::Display for DecodeError {
@@ -2552,6 +2552,7 @@ pub struct Arch;
impl yaxpeax_arch::Arch for Arch {
type Address = u32;
+ type Word = u8;
type Instruction = Instruction;
type DecodeError = DecodeError;
type Decoder = InstDecoder;
@@ -3990,16 +3991,14 @@ impl Default for InstDecoder {
}
}
-impl Decoder<Instruction> for InstDecoder {
- type Error = DecodeError;
-
- fn decode<T: IntoIterator<Item=u8>>(&self, bytes: T) -> Result<Instruction, Self::Error> {
+impl Decoder<Arch> for InstDecoder {
+ fn decode<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(&self, words: &mut T) -> Result<Instruction, <Arch as yaxpeax_arch::Arch>::DecodeError> {
let mut instr = Instruction::invalid();
- decode_one(self, bytes, &mut instr)
+ read_instr(self, words, &mut instr)
.map(|_: ()| instr)
}
- fn decode_into<T: IntoIterator<Item=u8>>(&self, instr: &mut Instruction, bytes: T) -> Result<(), Self::Error> {
- decode_one(self, bytes, instr)
+ fn decode_into<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(&self, instr: &mut Instruction, words: &mut T) -> Result<(), <Arch as yaxpeax_arch::Arch>::DecodeError> {
+ read_instr(self, words, instr)
}
}
@@ -5305,44 +5304,44 @@ const OPCODES: [OpcodeRecord; 256] = [
];
#[allow(non_snake_case)]
-pub(self) fn read_E<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, width: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8, width: u8) -> Result<OperandSpec, DecodeError> {
let bank = width_to_gp_reg_bank(width);
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, bank)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
-pub(self) fn read_E_mm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E_mm<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, RegisterBank::MM)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
-pub(self) fn read_E_st<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E_st<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, RegisterBank::ST)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
-pub(self) fn read_E_xmm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E_xmm<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, RegisterBank::X)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
-pub(self) fn read_E_ymm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+pub(self) fn read_E_ymm<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, RegisterBank::Y)
} else {
- read_M(bytes_iter, instr, modrm, length)
+ read_M(words, instr, modrm)
}
}
#[allow(non_snake_case)]
@@ -5350,7 +5349,7 @@ pub(self) fn read_E_vex<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut In
if modrm >= 0b11000000 {
read_modrm_reg(instr, modrm, bank)
} else {
- let res = read_M(bytes_iter, instr, modrm, length)?;
+ let res = read_M(bytes_iter, instr, modrm)?;
if (modrm & 0b01_000_000) == 0b01_000_000 {
instr.prefixes.apply_compressed_disp(true);
}
@@ -5365,24 +5364,20 @@ fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) ->
}
#[allow(non_snake_case)]
-fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+fn read_sib<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
let modbits = modrm >> 6;
- let sibbyte = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- *length += 1;
+ let sibbyte = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
let disp = if modbits == 0b00 {
if (sibbyte & 7) == 0b101 {
- *length += 4;
- read_num(bytes_iter, 4)? as i32 as u32
+ read_num(words, 4)? as i32 as u32
} else {
0
}
} else if modbits == 0b01 {
- *length += 1;
- read_num(bytes_iter, 1)? as i8 as i32 as u32
+ read_num(words, 1)? as i8 as i32 as u32
} else {
- *length += 4;
- read_num(bytes_iter, 4)? as i32 as u32
+ read_num(words, 4)? as i32 as u32
};
instr.disp = disp;
@@ -5445,7 +5440,7 @@ fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, m
}
#[allow(non_snake_case)]
-fn read_M_16bit<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+fn read_M_16bit<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
let modbits = modrm >> 6;
let mmm = modrm & 7;
if modbits == 0b00 && mmm == 0b110 {
@@ -5491,8 +5486,7 @@ fn read_M_16bit<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instructio
}
},
0b01 => {
- instr.disp = read_num(bytes_iter, 1)?;
- *length += 1;
+ instr.disp = read_num(words, 1)?;
if mmm > 3 {
Ok(OperandSpec::RegDisp)
} else {
@@ -5500,8 +5494,7 @@ fn read_M_16bit<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instructio
}
},
0b10 => {
- instr.disp = read_num(bytes_iter, 2)?;
- *length += 2;
+ instr.disp = read_num(words, 2)?;
if mmm > 3 {
Ok(OperandSpec::RegDisp)
} else {
@@ -5515,18 +5508,17 @@ fn read_M_16bit<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instructio
}
#[allow(non_snake_case)]
-fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
+fn read_M<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instr: &mut Instruction, modrm: u8) -> Result<OperandSpec, DecodeError> {
if instr.prefixes.address_size() {
- return read_M_16bit(bytes_iter, instr, modrm, length);
+ return read_M_16bit(words, instr, modrm);
}
instr.modrm_mmm.bank = RegisterBank::D;
let modbits = modrm >> 6;
let mmm = modrm & 7;
let op_spec = if mmm == 4 {
- return read_sib(bytes_iter, instr, modrm, length);
+ return read_sib(words, instr, modrm);
} else if mmm == 5 && modbits == 0b00 {
- *length += 4;
- instr.disp = read_num(bytes_iter, 4)?;
+ instr.disp = read_num(words, 4)?;
OperandSpec::DispU32
} else {
instr.modrm_mmm.num |= mmm;
@@ -5535,11 +5527,9 @@ fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, mod
OperandSpec::Deref
} else {
let disp = if modbits == 0b01 {
- *length += 1;
- read_num(bytes_iter, 1)? as i8 as i32
+ read_num(words, 1)? as i8 as i32
} else {
- *length += 4;
- read_num(bytes_iter, 4)? as i32
+ read_num(words, 4)? as i32
};
if disp == 0 {
OperandSpec::Deref
@@ -6859,28 +6849,24 @@ fn read_0f3a_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {
};
}
-fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction) -> Result<(), DecodeError> {
- let mut length = 0u8;
+fn read_instr<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(decoder: &InstDecoder, words: &mut T, instruction: &mut Instruction) -> Result<(), DecodeError> {
+ words.mark();
// use core::intrinsics::unlikely;
let mut prefixes = Prefixes::new(0);
let record: OpcodeRecord = loop {
- let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
- if length >= 15 {
+ let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
+ if words.offset() >= 15 {
return Err(DecodeError::TooLong);
}
let record = OPCODES[b as usize];
if b == 0x0f {
- let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
+ let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
if b == 0x38 {
- let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
+ let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
break read_0f38_opcode(b, &mut prefixes);
} else if b == 0x3a {
- let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
+ let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
break read_0f3a_opcode(b, &mut prefixes);
} else {
break read_0f_opcode(b, &mut prefixes);
@@ -6935,11 +6921,11 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
unsafe { unreachable_unchecked(); }
}
instruction.prefixes = prefixes;
- read_operands(decoder, bytes_iter, instruction, record.1, &mut length)?;
- if length > 15 {
+ read_operands(decoder, words, instruction, record.1)?;
+ instruction.length = words.offset() as u8;
+ if instruction.length > 15 {
return Err(DecodeError::TooLong);
}
- instruction.length = length;
if instruction.prefixes.lock() {
if !LOCKABLE_INSTRUCTIONS.contains(&instruction.opcode) || !instruction.operands[0].is_memory() {
@@ -6987,7 +6973,7 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
OperandCode::ModRM_0x8f_Ev => 30
*/
-fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, length: &mut u8) -> Result<(), DecodeError> {
+fn read_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(decoder: &InstDecoder, words: &mut T, instruction: &mut Instruction, operand_code: OperandCode) -> Result<(), DecodeError> {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operand_count = 2;
let operand_code = OperandCodeBuilder::from_bits(operand_code as u16);
@@ -7026,7 +7012,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.modrm_rrr =
RegSpec::from_parts(reg, RegisterBank::B);
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, 1, length)?;
+ read_imm_unsigned(words, 1)?;
instruction.operands[1] = OperandSpec::ImmU8;
}
3 => {
@@ -7035,13 +7021,13 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.modrm_rrr =
RegSpec::from_parts(reg, RegisterBank::D);
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, 4, length)?;
+ read_imm_unsigned(words, 4)?;
instruction.operands[1] = OperandSpec::ImmI32;
} else {
instruction.modrm_rrr =
RegSpec::from_parts(reg, RegisterBank::W);
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, 2, length)?;
+ read_imm_unsigned(words, 2)?;
instruction.operands[1] = OperandSpec::ImmI16;
}
}
@@ -7076,7 +7062,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.mem_size = 1;
bank = RegisterBank::B;
};
- modrm = read_modrm(&mut bytes_iter, length)?;
+ modrm = read_modrm(words)?;
instruction.modrm_rrr.bank = bank;
instruction.modrm_rrr.num = (modrm >> 3) & 7;
@@ -7086,14 +7072,14 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
}
read_modrm_reg(instruction, modrm, bank)?
} else {
- read_M(&mut bytes_iter, instruction, modrm, length)?
+ read_M(words, instruction, modrm)?
};
instruction.operands[1] = mem_oper;
}
if let Some((only_imm, immsz)) = operand_code.has_imm() {
instruction.imm =
- read_imm_signed(&mut bytes_iter, 1 << (immsz * 2), length)? as u32;
+ read_imm_signed(words, 1 << (immsz * 2))? as u32;
if only_imm {
if immsz == 0 {
instruction.operands[0] = OperandSpec::ImmI8;
@@ -7130,7 +7116,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
} else {
4
};
- instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u32;
+ instruction.imm = read_imm_signed(words, numwidth)? as u32;
instruction.opcode = base_opcode_map((modrm >> 3) & 7);
instruction.operands[1] = match numwidth {
2 => OperandSpec::ImmI16,
@@ -7142,7 +7128,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
3 => { // ModRM_0xc6_Eb_Ib
if modrm == 0xf8 {
instruction.opcode = Opcode::XABORT;
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u32;
+ instruction.imm = read_imm_signed(words, 1)? as u32;
instruction.operands[0] = OperandSpec::ImmI8;
instruction.operand_count = 1;
return Ok(());
@@ -7154,7 +7140,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.operands[0] = mem_oper;
instruction.opcode = Opcode::MOV;
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u32;
+ instruction.imm = read_imm_signed(words, 1)? as u32;
instruction.operands[1] = OperandSpec::ImmI8;
instruction.operand_count = 2;
}
@@ -7162,9 +7148,9 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
if modrm == 0xf8 {
instruction.opcode = Opcode::XBEGIN;
instruction.imm = if instruction.prefixes.operand_size() {
- read_imm_signed(&mut bytes_iter, 2, length)? as i16 as i32 as u32
+ read_imm_signed(words, 2)? as i16 as i32 as u32
} else {
- read_imm_signed(&mut bytes_iter, 4, length)? as i32 as u32
+ read_imm_signed(words, 4)? as i32 as u32
};
instruction.operands[0] = OperandSpec::ImmI32;
instruction.operand_count = 1;
@@ -7178,10 +7164,10 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.operands[0] = mem_oper;
instruction.opcode = Opcode::MOV;
if instruction.prefixes.operand_size() {
- instruction.imm = read_imm_signed(&mut bytes_iter, 2, length)? as u32;
+ instruction.imm = read_imm_signed(words, 2)? as u32;
instruction.operands[1] = OperandSpec::ImmI16;
} else {
- instruction.imm = read_imm_signed(&mut bytes_iter, 4, length)? as u32;
+ instruction.imm = read_imm_signed(words, 4)? as u32;
instruction.operands[1] = OperandSpec::ImmI32;
}
},
@@ -7203,8 +7189,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
let num = match op {
5 |
6 => {
- *length += 1;
- read_num(&mut bytes_iter, 1)?
+ read_num(words, 1)?
}
_ => {
// these are the _1 variants, everything else is unreachable
@@ -7232,7 +7217,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
match (modrm >> 3) & 7 {
0 | 1 => {
instruction.opcode = Opcode::TEST;
- instruction.imm = read_imm_signed(&mut bytes_iter, opwidth, length)? as u32;
+ instruction.imm = read_imm_signed(words, opwidth)? as u32;
instruction.operands[1] = match opwidth {
1 => OperandSpec::ImmI8,
2 => OperandSpec::ImmI16,
@@ -7308,9 +7293,9 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.operand_count = 1;
}
15 => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 1, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 1)?;
instruction.modrm_rrr = if instruction.prefixes.operand_size() {
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::W)
} else {
@@ -7322,9 +7307,9 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
instruction.operand_count = 2;
},
16 => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 2)?;
instruction.modrm_rrr = if instruction.prefixes.operand_size() {
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::W)
} else {
@@ -7372,14 +7357,13 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
}
},
22 => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u32;
- *length += 1;
+ read_num(words, 1)? as u8 as u32;
if instruction.operands[1] != OperandSpec::RegMMM {
if instruction.opcode == Opcode::CMPSS {
instruction.mem_size = 4;
@@ -7409,7 +7393,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
4
};
instruction.imm =
- read_imm_signed(&mut bytes_iter, opwidth, length)? as u32;
+ read_imm_signed(words, opwidth)? as u32;
instruction.operands[1] = match opwidth {
2 => OperandSpec::ImmI16,
4 => OperandSpec::ImmI32,
@@ -7424,7 +7408,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
4
};
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, opwidth, length)?;
+ read_imm_unsigned(words, opwidth)?;
instruction.operands[0] = match opwidth {
2 => OperandSpec::ImmI16,
4 => OperandSpec::ImmI32,
@@ -7487,36 +7471,36 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
},
_ => {
let operand_code: OperandCode = unsafe { core::mem::transmute(operand_code.bits()) };
- unlikely_operands(decoder, bytes_iter, instruction, operand_code, mem_oper, length)?;
+ unlikely_operands(decoder, words, instruction, operand_code, mem_oper)?;
}
};
}
Ok(())
}
-fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, length: &mut u8) -> Result<(), DecodeError> {
+fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(decoder: &InstDecoder, words: &mut T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec) -> Result<(), DecodeError> {
match operand_code {
OperandCode::G_E_mm_Ib => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_mm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_mm(words, instruction, modrm)?;
instruction.modrm_rrr = RegSpec { bank: RegisterBank::MM, num: (modrm >> 3) & 7 };
if instruction.operands[1] == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::MM;
} else {
instruction.mem_size = 8;
}
- instruction.imm = read_num(&mut bytes_iter, 1)? as u8 as u32;
+ instruction.imm = read_num(words, 1)? as u8 as u32;
*length += 1;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
}
OperandCode::G_Ev_xmm_Ib => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
instruction.modrm_rrr = RegSpec { bank: RegisterBank::X, num: (modrm >> 3) & 7 };
- instruction.imm = read_num(&mut bytes_iter, 1)? as u8 as u32;
+ instruction.imm = read_num(words, 1)? as u8 as u32;
*length += 1;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = match instruction.opcode {
@@ -7535,11 +7519,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 3;
}
OperandCode::PMOVX_E_G_xmm => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr = RegSpec { bank: RegisterBank::X, num: (modrm >> 3) & 7 };
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.operands[0] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_xmm(words, instruction, modrm)?;
if instruction.operands[0] != OperandSpec::RegMMM {
if [].contains(&instruction.opcode) {
instruction.mem_size = 2;
@@ -7553,11 +7537,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::PMOVX_G_E_xmm => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr = RegSpec { bank: RegisterBank::X, num: (modrm >> 3) & 7 };
instruction.operands[0] = OperandSpec::RegRRR;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
if instruction.operands[1] != OperandSpec::RegMMM {
if [Opcode::PMOVSXBQ, Opcode::PMOVZXBQ].contains(&instruction.opcode) {
instruction.mem_size = 2;
@@ -7573,11 +7557,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::INV_Gv_M => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr = RegSpec { bank: RegisterBank::D, num: (modrm >> 3) & 7 };
instruction.operands[0] = OperandSpec::RegRRR;
- instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_M(words, instruction, modrm)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -7594,7 +7578,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0xc4 => {
- let modrm = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?;
+ let modrm = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
if modrm & 0b11000000 == 0b11000000 {
// interpret the c4 as a vex prefix
if instruction.prefixes.lock() || instruction.prefixes.operand_size() || instruction.prefixes.rep() || instruction.prefixes.repnz() {
@@ -7602,8 +7586,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidPrefixes);
} else {
- vex::three_byte_vex(&mut bytes_iter, modrm, instruction, *length)?;
- *length = instruction.length;
+ vex::three_byte_vex(words, modrm, instruction)?;
if decoder != &InstDecoder::default() {
decoder.revise_instruction(instruction)?;
@@ -7614,7 +7597,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
// LES
instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, if instruction.prefixes.operand_size() { RegisterBank::W } else { RegisterBank::D });
instruction.operands[0] = OperandSpec::RegRRR;
- instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_M(words, instruction, modrm)?;
if instruction.prefixes.operand_size() {
instruction.mem_size = 4;
} else {
@@ -7623,7 +7606,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
},
OperandCode::ModRM_0xc5 => {
- let modrm = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?;
+ let modrm = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
if (modrm & 0b1100_0000) == 0b1100_0000 {
// interpret the c5 as a vex prefix
if instruction.prefixes.lock() || instruction.prefixes.operand_size() || instruction.prefixes.rep() || instruction.prefixes.repnz() {
@@ -7631,8 +7614,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidPrefixes);
} else {
- vex::two_byte_vex(&mut bytes_iter, modrm, instruction, *length)?;
- *length = instruction.length;
+ vex::two_byte_vex(words, modrm, instruction)?;
if decoder != &InstDecoder::default() {
decoder.revise_instruction(instruction)?;
@@ -7643,7 +7625,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
// LDS
instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, if instruction.prefixes.operand_size() { RegisterBank::W } else { RegisterBank::D });
instruction.operands[0] = OperandSpec::RegRRR;
- instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_M(words, instruction, modrm)?;
if instruction.prefixes.operand_size() {
instruction.mem_size = 4;
} else {
@@ -7652,24 +7634,23 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
},
OperandCode::G_U_xmm_Ub => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
if instruction.operands[1] != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u32;
- *length += 1;
+ read_num(words, 1)? as u8 as u32;
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operand_count = 3;
}
OperandCode::ModRM_0xf20f78 => {
instruction.opcode = Opcode::INSERTQ;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm < 0b11_000_000 {
return Err(DecodeError::InvalidOperand);
@@ -7682,10 +7663,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm =
RegSpec::from_parts(modrm & 7, RegisterBank::X);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u32;
+ read_num(words, 1)? as u8 as u32;
instruction.disp =
- read_num(&mut bytes_iter, 1)? as u8 as u32;
- *length += 2;
+ read_num(words, 1)? as u8 as u32;
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operands[3] = OperandSpec::ImmInDispField;
instruction.operand_count = 4;
@@ -7693,7 +7673,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
OperandCode::ModRM_0x660f78 => {
instruction.opcode = Opcode::EXTRQ;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm < 0b11_000_000 {
return Err(DecodeError::InvalidOperand);
@@ -7707,24 +7687,22 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm =
RegSpec::from_parts(modrm & 7, RegisterBank::X);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u32;
+ read_num(words, 1)? as u8 as u32;
instruction.disp =
- read_num(&mut bytes_iter, 1)? as u8 as u32;
- *length += 2;
+ read_num(words, 1)? as u8 as u32;
instruction.operands[1] = OperandSpec::ImmU8;
instruction.operands[2] = OperandSpec::ImmInDispField;
instruction.operand_count = 3;
}
OperandCode::G_E_xmm_Ub => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u32;
- *length += 1;
+ read_num(words, 1)? as u8 as u32;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 16;
}
@@ -7767,7 +7745,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
4
};
instruction.imm =
- read_imm_signed(&mut bytes_iter, opwidth, length)? as u32;
+ read_imm_signed(words, opwidth)? as u32;
instruction.operands[2] = match opwidth {
2 => OperandSpec::ImmI16,
4 => OperandSpec::ImmI32,
@@ -7779,7 +7757,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.imm =
- read_imm_signed(&mut bytes_iter, 1, length)? as u32;
+ read_imm_signed(words, 1)? as u32;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
}
@@ -7791,9 +7769,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 3;
}
OperandCode::G_mm_Ew_Ib => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::MM);
if instruction.operands[1] == OperandSpec::RegMMM {
@@ -7802,8 +7780,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.mem_size = 2;
}
instruction.imm =
- read_num(&mut bytes_iter, 1)? as u8 as u32;
- *length += 1;
+ read_num(words, 1)? as u8 as u32;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
}
@@ -7832,7 +7809,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 2;
},
OperandCode::Gv_Ew_LSL => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if instruction.prefixes.operand_size() {
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::W);
@@ -7841,7 +7818,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
};
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 2)?;
// lsl is weird. the full register width is written, but only the low 16 bits are used.
if instruction.operands[1] == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::D;
@@ -7851,14 +7828,14 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 2;
},
OperandCode::Gd_Ev => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let opwidth = if instruction.prefixes.operand_size() {
2
} else {
4
};
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, opwidth)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
instruction.operand_count = 2;
@@ -7887,8 +7864,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
};
let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 };
- let imm = read_num(&mut bytes_iter, addr_width)?;
- *length += addr_width;
+ let imm = read_num(words, addr_width)?;
instruction.disp = imm;
if instruction.prefixes.address_size() {
instruction.operands[1] = OperandSpec::DispU16;
@@ -7918,8 +7894,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
};
let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 };
- let imm = read_num(&mut bytes_iter, addr_width)?;
- *length += addr_width;
+ let imm = read_num(words, addr_width)?;
instruction.disp = imm;
instruction.operands[0] = if instruction.prefixes.address_size() {
OperandSpec::DispU16
@@ -7940,12 +7915,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
*/
OperandCode::Iw_Ib => {
- instruction.disp = read_num(&mut bytes_iter, 2)?;
- instruction.imm = read_num(&mut bytes_iter, 1)?;
+ instruction.disp = read_num(words, 2)?;
+ instruction.imm = read_num(words, 1)?;
instruction.operands[0] = OperandSpec::ImmInDispField;
instruction.operands[1] = OperandSpec::ImmU8;
instruction.operand_count = 2;
- *length += 3;
}
OperandCode::Fw => {
if instruction.prefixes.operand_size() {
@@ -7970,9 +7944,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
@@ -7986,12 +7960,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = 8;
}
@@ -8011,16 +7985,16 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
},
OperandCode::MOVQ_f30f => {
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_xmm(words, instruction, modrm)?;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 8;
}
}
OperandCode::ModRM_0x0f0d => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 0b111;
let opwidth = if instruction.prefixes.operand_size() {
@@ -8037,7 +8011,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::NOP;
}
}
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = 64;
}
@@ -8047,15 +8021,15 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
// 3dnow instructions are WILD, the opcode is encoded as an imm8 trailing the
// instruction.
- let modrm = read_modrm(&mut bytes_iter, length)?;
- instruction.operands[1] = read_E_mm(&mut bytes_iter, instruction, modrm, length)?;
+ let modrm = read_modrm(words)?;
+ instruction.operands[1] = read_E_mm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec { bank: RegisterBank::MM, num: (modrm >> 3) & 7 };
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 8;
}
- let opcode = read_modrm(&mut bytes_iter, length)?;
+ let opcode = read_modrm(words)?;
match opcode {
0x0c => {
instruction.opcode = Opcode::PI2FW;
@@ -8136,7 +8110,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::ModRM_0x0fc7 => {
if instruction.prefixes.repnz() {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let is_reg = (modrm & 0xc0) == 0xc0;
let r = (modrm >> 3) & 7;
@@ -8149,7 +8123,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::CMPXCHG8B;
instruction.mem_size = 8;
instruction.operand_count = 1;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
}
return Ok(());
}
@@ -8164,7 +8138,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
} else {
4
};
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let is_reg = (modrm & 0xc0) == 0xc0;
let r = (modrm >> 3) & 7;
@@ -8177,13 +8151,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::CMPXCHG8B;
instruction.mem_size = 8;
instruction.operand_count = 1;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
}
return Ok(());
}
6 => {
instruction.opcode = Opcode::VMCLEAR;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] == OperandSpec::RegMMM {
// this would be invalid as `vmclear`, so fall back to the parse as
// 66-prefixed rdrand. this is a register operand, so just demote it to the
@@ -8197,7 +8171,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Ok(());
}
7 => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] == OperandSpec::RegMMM {
// this would be invalid as `vmclear`, so fall back to the parse as
// 66-prefixed rdrand. this is a register operand, so just demote it to the
@@ -8222,7 +8196,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
} else {
4
};
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let is_reg = (modrm & 0xc0) == 0xc0;
let r = (modrm >> 3) & 7;
@@ -8235,12 +8209,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::CMPXCHG8B;
instruction.mem_size = 8;
instruction.operand_count = 1;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
}
}
6 => {
instruction.opcode = Opcode::VMXON;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] == OperandSpec::RegMMM {
// invalid as `vmxon`, reg-form is `senduipi`
instruction.opcode = Opcode::SENDUIPI;
@@ -8253,7 +8227,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
7 => {
instruction.opcode = Opcode::RDPID;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -8266,7 +8240,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Ok(());
}
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let is_reg = (modrm & 0xc0) == 0xc0;
let r = (modrm >> 3) & 0b111;
@@ -8337,7 +8311,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
} else {
4
};
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
},
OperandCode::ModRM_0x0f71 => {
if instruction.prefixes.rep() || instruction.prefixes.repnz() {
@@ -8346,7 +8320,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
return Err(DecodeError::InvalidOperand);
}
@@ -8373,13 +8347,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
}
instruction.operands[0] = OperandSpec::RegMMM;
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u32;
+ instruction.imm = read_imm_signed(words, 1)? as u32;
instruction.operands[1] = OperandSpec::ImmU8;
},
OperandCode::ModRM_0x0f72 => {
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
return Err(DecodeError::InvalidOperand);
}
@@ -8406,7 +8380,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
}
instruction.operands[0] = OperandSpec::RegMMM;
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u32;
+ instruction.imm = read_imm_signed(words, 1)? as u32;
instruction.operands[1] = OperandSpec::ImmU8;
},
OperandCode::ModRM_0x0f73 => {
@@ -8416,7 +8390,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
return Err(DecodeError::InvalidOperand);
}
@@ -8452,11 +8426,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 };
}
instruction.operands[0] = OperandSpec::RegMMM;
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u32;
+ instruction.imm = read_imm_signed(words, 1)? as u32;
instruction.operands[1] = OperandSpec::ImmU8;
},
OperandCode::ModRM_0xf30f38d8 => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
match r {
0b000 => {
@@ -8464,7 +8438,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOperand);
}
instruction.opcode = Opcode::AESENCWIDE128KL;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
return Ok(());
}
0b001 => {
@@ -8472,7 +8446,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOperand);
}
instruction.opcode = Opcode::AESDECWIDE128KL;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
return Ok(());
}
0b010 => {
@@ -8480,7 +8454,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOperand);
}
instruction.opcode = Opcode::AESENCWIDE256KL;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
return Ok(());
}
0b011 => {
@@ -8488,7 +8462,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOperand);
}
instruction.opcode = Opcode::AESDECWIDE256KL;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
return Ok(());
}
_ => {
@@ -8497,7 +8471,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0xf30f38dc => {
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?;
+ read_operands(decoder, words, instruction, OperandCode::G_E_xmm)?;
if let OperandSpec::RegMMM = instruction.operands[1] {
instruction.opcode = Opcode::LOADIWKEY;
} else {
@@ -8505,7 +8479,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0xf30f38dd => {
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?;
+ read_operands(decoder, words, instruction, OperandCode::G_E_xmm)?;
if let OperandSpec::RegMMM = instruction.operands[1] {
return Err(DecodeError::InvalidOperand);
} else {
@@ -8513,7 +8487,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0xf30f38de => {
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?;
+ read_operands(decoder, words, instruction, OperandCode::G_E_xmm)?;
if let OperandSpec::RegMMM = instruction.operands[1] {
return Err(DecodeError::InvalidOperand);
} else {
@@ -8521,7 +8495,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0xf30f38df => {
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?;
+ read_operands(decoder, words, instruction, OperandCode::G_E_xmm)?;
if let OperandSpec::RegMMM = instruction.operands[1] {
return Err(DecodeError::InvalidOperand);
} else {
@@ -8530,13 +8504,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::ModRM_0xf30f38fa => {
instruction.opcode = Opcode::ENCODEKEY128;
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm, length)?;
+ read_operands(decoder, words, instruction, OperandCode::G_U_xmm)?;
instruction.modrm_rrr.bank = RegisterBank::D;
instruction.modrm_mmm.bank = RegisterBank::D;
}
OperandCode::ModRM_0xf30f38fb => {
instruction.opcode = Opcode::ENCODEKEY256;
- read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm, length)?;
+ read_operands(decoder, words, instruction, OperandCode::G_U_xmm)?;
instruction.modrm_rrr.bank = RegisterBank::D;
instruction.modrm_mmm.bank = RegisterBank::D;
}
@@ -8596,8 +8570,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operand_count = 3;
instruction.imm =
- read_num(&mut bytes_iter, 1)?;
- *length += 1;
+ read_num(words, 1)?;
instruction.modrm_rrr.bank = RegisterBank::X;
if mem_oper == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::D;
@@ -8640,8 +8613,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operand_count = 3;
instruction.imm =
- read_num(&mut bytes_iter, 1)?;
- *length += 1;
+ read_num(words, 1)?;
instruction.modrm_rrr.bank = RegisterBank::D;
if mem_oper == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::MM;
@@ -8802,18 +8774,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_rrr.bank = RegisterBank::X;
}
OperandCode::Ew_Gw => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec { bank: RegisterBank::W, num: (modrm >> 3) & 7 };
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 2)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.mem_size = 2;
instruction.operand_count = 2;
},
OperandCode::Ew_Sw => {
let opwidth = 2;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
// check r
if ((modrm >> 3) & 7) > 5 {
@@ -8832,12 +8804,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec { bank: RegisterBank::W, num: modrm & 7};
instruction.operands[0] = OperandSpec::RegMMM;
} else {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
instruction.mem_size = 2;
}
},
OperandCode::Sw_Ew => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
// check r
if ((modrm >> 3) & 7) > 5 {
@@ -8866,7 +8838,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec { bank: RegisterBank::W, num: modrm & 7};
instruction.operands[1] = OperandSpec::RegMMM;
} else {
- instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_M(words, instruction, modrm)?;
instruction.mem_size = 2;
}
},
@@ -8894,13 +8866,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::Iw => {
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, 2, length)?;
+ read_imm_unsigned(words, 2)?;
instruction.operands[0] = OperandSpec::ImmU16;
instruction.operand_count = 1;
}
OperandCode::ModRM_0x0f00 => {
instruction.operand_count = 1;
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
if r == 0 {
instruction.opcode = Opcode::SLDT;
@@ -8928,7 +8900,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
} else {
unreachable!("r <= 8");
}
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 2)?;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = 2;
}
@@ -8939,7 +8911,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
} else {
4
};
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
if r == 0 {
let mod_bits = modrm >> 6;
@@ -8972,7 +8944,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::SGDT;
instruction.operand_count = 1;
instruction.mem_size = 63;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else if r == 1 {
let mod_bits = modrm >> 6;
@@ -9029,7 +9001,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::SIDT;
instruction.operand_count = 1;
instruction.mem_size = 63;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else if r == 2 {
let mod_bits = modrm >> 6;
@@ -9065,7 +9037,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::LGDT;
instruction.operand_count = 1;
instruction.mem_size = 63;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else if r == 3 {
let mod_bits = modrm >> 6;
@@ -9130,7 +9102,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::LIDT;
instruction.operand_count = 1;
instruction.mem_size = 63;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else if r == 4 {
// TODO: this permits storing only to word-size registers
@@ -9138,7 +9110,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::SMSW;
instruction.operand_count = 1;
instruction.mem_size = 2;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 2)?;
} else if r == 5 {
let mod_bits = modrm >> 6;
if mod_bits != 0b11 {
@@ -9146,7 +9118,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
instruction.opcode = Opcode::RSTORSSP;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
instruction.mem_size = 8;
instruction.operand_count = 1;
return Ok(());
@@ -9250,7 +9222,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::LMSW;
instruction.operand_count = 1;
instruction.mem_size = 2;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 2)?;
} else if r == 7 {
let mod_bits = modrm >> 6;
let m = modrm & 7;
@@ -9300,14 +9272,14 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::INVLPG;
instruction.operand_count = 1;
instruction.mem_size = 1;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
}
} else {
unreachable!("r <= 8");
}
}
OperandCode::ModRM_0x0fae => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
let m = modrm & 7;
@@ -9326,7 +9298,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
};
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 1 /* opwidth */, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 1 /* opwidth */)?;
instruction.mem_size = 64;
instruction.operand_count = 1;
} else {
@@ -9339,7 +9311,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
};
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
instruction.operand_count = 1;
}
@@ -9375,7 +9347,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
return Err(DecodeError::InvalidOpcode);
}
instruction.opcode = Opcode::PTWRITE;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = 4;
}
@@ -9431,7 +9403,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
match r {
6 => {
instruction.opcode = Opcode::CLRSSBSY;
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
instruction.operand_count = 1;
instruction.mem_size = 8;
return Ok(());
@@ -9507,7 +9479,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
][r as usize];
instruction.opcode = opcode;
instruction.mem_size = mem_size;
- instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_M(words, instruction, modrm)?;
}
},
OperandCode::ModRM_0x0fba => {
@@ -9516,7 +9488,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
} else {
4
};
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 7;
match r {
0 | 1 | 2 | 3 => {
@@ -9540,12 +9512,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = opwidth;
}
- instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u32;
+ instruction.imm = read_imm_signed(words, 1)? as u32;
instruction.operands[1] = OperandSpec::ImmI8;
instruction.operand_count = 2;
}
@@ -9553,7 +9525,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
op @ OperandCode::Rq_Dq_0 |
op @ OperandCode::Cq_Rq_0 |
op @ OperandCode::Dq_Rq_0 => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let m = modrm & 7;
let r = (modrm >> 3) & 7;
@@ -9742,7 +9714,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
OperandCode::x87_dd |
OperandCode::x87_de |
OperandCode::x87_df => {
- return decode_x87(decoder, bytes_iter, instruction, operand_code, length);
+ return decode_x87(decoder, words, instruction, operand_code);
}
OperandCode::M_Gv => {
// `lea` operands (`Gv_M`) opportunistically reject a register form of `mmm` early, but
@@ -9756,7 +9728,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = temp;
}
OperandCode::ModRM_0x62 => {
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
if modrm < 0xc0 {
instruction.modrm_rrr =
@@ -9769,18 +9741,14 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
instruction.operands[0] = OperandSpec::RegRRR;
- instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_M(words, instruction, modrm)?;
instruction.operand_count = 2;
} else {
let prefixes = &instruction.prefixes;
if prefixes.lock() || prefixes.operand_size() || prefixes.rep_any() {
return Err(DecodeError::InvalidPrefixes);
} else {
- evex::read_evex(&mut bytes_iter, instruction, *length, Some(modrm))?;
- // there's an unavoidable `instruction.length = *length;` after
- // `unlikely_operands`. the current length is correct, so store it back to
- // length to make the reassignment store a correct length.
- *length = instruction.length;
+ evex::read_evex(words, instruction, Some(modrm))?;
}
}
}
@@ -9800,7 +9768,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
Ok(())
}
-fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, length: &mut u8) -> Result<(), DecodeError> {
+fn decode_x87<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(_decoder: &InstDecoder, words: &mut T, instruction: &mut Instruction, operand_code: OperandCode) -> Result<(), DecodeError> {
#[allow(non_camel_case_types)]
enum OperandCodeX87 {
Est,
@@ -9826,7 +9794,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
}
// every x87 instruction is conditional on rrr bits
- let modrm = read_modrm(&mut bytes_iter, length)?;
+ let modrm = read_modrm(words)?;
let r = (modrm >> 3) & 0b111;
let (opcode, x87_operands) = match operand_code {
@@ -10147,19 +10115,19 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
match x87_operands {
OperandCodeX87::Est => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operand_count = 1;
}
OperandCodeX87::St_Est => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_st(words, instruction, modrm)?;
instruction.operand_count = 2;
}
OperandCodeX87::St_Edst => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_st(words, instruction, modrm)?;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 4;
}
@@ -10168,7 +10136,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Eqst => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[1] = read_E_st(words, instruction, modrm)?;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 8;
}
@@ -10177,7 +10145,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Ew => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 2)?;
if instruction.operands[1] != OperandSpec::RegMMM {
instruction.mem_size = 2;
}
@@ -10186,7 +10154,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Mm => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10196,7 +10164,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Mq => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10206,7 +10174,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Md => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[1] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10216,7 +10184,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
OperandCodeX87::St_Mw => {
instruction.operands[0] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
- instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[1] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10224,20 +10192,20 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Ew => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 2)?;
instruction.operand_count = 1;
if instruction.operands[0] != OperandSpec::RegMMM {
instruction.mem_size = 2;
}
}
OperandCodeX87::Est_St => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
instruction.operand_count = 2;
}
OperandCodeX87::Edst_St => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
instruction.operand_count = 2;
@@ -10246,7 +10214,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
}
}
OperandCodeX87::Eqst_St => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
instruction.operand_count = 2;
@@ -10255,7 +10223,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
}
}
OperandCodeX87::Ed_St => {
- instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?;
+ instruction.operands[0] = read_E_st(words, instruction, modrm)?;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.modrm_rrr = RegSpec::st(0);
if instruction.operands[0] != OperandSpec::RegMMM {
@@ -10264,7 +10232,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Mm_St => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10274,7 +10242,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Mq_St => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10284,7 +10252,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Md_St => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10294,7 +10262,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Mw_St => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -10304,7 +10272,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
instruction.operand_count = 2;
}
OperandCodeX87::Ex87S => {
- instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
+ instruction.operands[0] = read_E(words, instruction, modrm, 4)?;
instruction.operand_count = 1;
if instruction.operands[0] == OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
@@ -10319,26 +10287,21 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i
Ok(())
}
-fn decode_one<'b, T: IntoIterator<Item=u8>>(decoder: &InstDecoder, bytes: T, instr: &'b mut Instruction) -> Result<(), DecodeError> {
- let bytes_iter = bytes.into_iter();
- read_instr(decoder, bytes_iter, instr)
-}
-
#[inline]
-fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u32, DecodeError> {
+fn read_num<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(bytes: &mut T, width: u8) -> Result<u32, DecodeError> {
match width {
- 1 => { bytes.next().map(|x| x as u32).ok_or(DecodeError::ExhaustedInput) }
+ 1 => { bytes.next().map(|x| x as u32).ok().ok_or(DecodeError::ExhaustedInput) }
2 => {
bytes.next().and_then(|b0| {
bytes.next().map(|b1| u16::from_le_bytes([b0, b1]) as u32)
- }).ok_or(DecodeError::ExhaustedInput)
+ }).ok().ok_or(DecodeError::ExhaustedInput)
}
4 => {
bytes.next()
.and_then(|b0| bytes.next().map(|b1| (b0, b1)))
.and_then(|(b0, b1)| bytes.next().map(|b2| (b0, b1, b2)))
.and_then(|(b0, b1, b2)| bytes.next().map(|b3| u32::from_le_bytes([b0, b1, b2, b3])))
- .ok_or(DecodeError::ExhaustedInput)
+ .ok().ok_or(DecodeError::ExhaustedInput)
}
_ => {
panic!("unsupported read size");
@@ -10347,28 +10310,22 @@ fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u32, Decod
}
#[inline]
-fn read_imm_signed<T: Iterator<Item=u8>>(bytes: &mut T, num_width: u8, length: &mut u8) -> Result<i32, DecodeError> {
+fn read_imm_signed<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(bytes: &mut T, num_width: u8) -> Result<i32, DecodeError> {
if num_width == 1 {
- *length += 1;
Ok(read_num(bytes, 1)? as i8 as i32)
} else if num_width == 2 {
- *length += 2;
Ok(read_num(bytes, 2)? as i16 as i32)
} else {
- *length += 4;
Ok(read_num(bytes, 4)? as i32)
}
}
#[inline]
-fn read_imm_unsigned<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<u32, DecodeError> {
- read_num(bytes, width).map(|res| {
- *length += width;
- res
- })
+fn read_imm_unsigned<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(bytes: &mut T, width: u8) -> Result<u32, DecodeError> {
+ read_num(bytes, width)
}
#[inline]
-fn read_modrm<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<u8, DecodeError> {
- bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })
+fn read_modrm<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T) -> Result<u8, DecodeError> {
+ words.next().ok().ok_or(DecodeError::ExhaustedInput)
}
diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs
index 73d10b5..2f871c6 100644
--- a/src/protected_mode/vex.rs
+++ b/src/protected_mode/vex.rs
@@ -1,3 +1,6 @@
+use yaxpeax_arch::Reader;
+
+use crate::protected_mode::Arch;
use crate::protected_mode::OperandSpec;
use crate::protected_mode::DecodeError;
use crate::protected_mode::RegSpec;
@@ -94,9 +97,8 @@ enum VEXOperandCode {
}
#[inline(never)]
-pub(crate) fn three_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, vex_byte_one: u8, instruction: &mut Instruction, mut length: u8) -> Result<(), DecodeError> {
- let vex_byte_two = bytes.next().ok_or(DecodeError::ExhaustedInput)?;
- length += 1;
+pub(crate) fn three_byte_vex<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, vex_byte_one: u8, instruction: &mut Instruction) -> Result<(), DecodeError> {
+ let vex_byte_two = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
let p = vex_byte_two & 0x03;
let p = match p {
0x00 => VEXOpcodePrefix::None,
@@ -121,13 +123,13 @@ pub(crate) fn three_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, vex_byte_one:
};
instruction.prefixes.vex_from_c4(vex_byte_one, vex_byte_two);
- read_vex_instruction(m, bytes, instruction, &mut length, p)?;
+ read_vex_instruction(m, words, instruction, p)?;
+ instruction.length = words.offset() as u8;
instruction.vex_reg.num &= 0b0111; // ignore bit 4 in 32-bit mode
- instruction.length = length;
Ok(())
}
-pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, vex_byte: u8, instruction: &mut Instruction, mut length: u8) -> Result<(), DecodeError> {
+pub(crate) fn two_byte_vex<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, vex_byte: u8, instruction: &mut Instruction) -> Result<(), DecodeError> {
let p = vex_byte & 0x03;
let p = match p {
0x00 => VEXOpcodePrefix::None,
@@ -142,17 +144,17 @@ pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, vex_byte: u8, in
};
instruction.prefixes.vex_from_c5(vex_byte);
- read_vex_instruction(VEXOpcodeMap::Map0F, bytes, instruction, &mut length, p)?;
+ read_vex_instruction(VEXOpcodeMap::Map0F, words, instruction, p)?;
+ instruction.length = words.offset() as u8;
instruction.vex_reg.num &= 0b0111; // ignore bit 4 in 32-bit mode
- instruction.length = length;
Ok(())
}
-fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Instruction, length: &mut u8, operand_code: VEXOperandCode) -> Result<(), DecodeError> {
+fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instruction: &mut Instruction, operand_code: VEXOperandCode) -> Result<(), DecodeError> {
// println!("operand code: {:?}", operand_code);
match operand_code {
VEXOperandCode::VPS_71 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -176,13 +178,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::X;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_71_L => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -209,13 +211,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_72 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -239,13 +241,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::X;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_72_L => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -269,13 +271,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_73 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -302,13 +304,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::X;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VPS_73_L => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 != 0xc0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
@@ -341,17 +343,17 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.vex_reg.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VMOVSS_10 |
VEXOperandCode::VMOVSD_10 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
match mem_oper {
OperandSpec::RegMMM => {
@@ -377,10 +379,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
},
VEXOperandCode::VMOVSS_11 |
VEXOperandCode::VMOVSD_11 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[2] = OperandSpec::RegRRR;
match mem_oper {
OperandSpec::RegMMM => {
@@ -406,7 +408,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
},
VEXOperandCode::VMOVLPS_12 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.opcode = if modrm & 0xc0 == 0xc0 {
Opcode::VMOVHLPS
} else {
@@ -417,12 +419,12 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
- instruction.operands[2] = read_E_xmm(bytes, instruction, modrm, length)?;
+ instruction.operands[2] = read_E_xmm(words, instruction, modrm)?;
instruction.operand_count = 3;
Ok(())
}
VEXOperandCode::VMOVHPS_16 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.opcode = if modrm & 0xc0 == 0xc0 {
Opcode::VMOVLHPS
} else {
@@ -433,7 +435,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
- instruction.operands[2] = read_E_xmm(bytes, instruction, modrm, length)?;
+ instruction.operands[2] = read_E_xmm(words, instruction, modrm)?;
instruction.operand_count = 3;
Ok(())
}
@@ -446,10 +448,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operands[2] = OperandSpec::ImmU8;
@@ -471,7 +473,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
}
instruction.operand_count = 3;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
Ok(())
},
VEXOperandCode::G_xmm_Ed => {
@@ -479,10 +481,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -496,10 +498,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
if mem_oper != OperandSpec::RegMMM {
@@ -513,10 +515,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words instruction, modrm, 4)?;
if let OperandSpec::RegMMM = mem_oper {
instruction.modrm_mmm.bank = RegisterBank::X;
} else {
@@ -532,10 +534,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
if let OperandSpec::RegMMM = mem_oper {
instruction.modrm_mmm.bank = RegisterBank::X;
} else {
@@ -552,10 +554,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
match (op, mem_oper) {
(VEXOperandCode::E_G_xmm, OperandSpec::RegMMM) => {
/* this is the only accepted operand */
@@ -585,10 +587,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -602,10 +604,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -619,16 +621,16 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operand_count = 3;
Ok(())
@@ -638,13 +640,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -657,13 +659,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -677,10 +679,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -694,10 +696,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -714,7 +716,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
match (op, modrm & 0xc0) {
(VEXOperandCode::G_U_xmm, 0xc0) => {
/* this is the only accepted operand */
@@ -730,7 +732,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -750,10 +752,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -767,10 +769,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -785,7 +787,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 == 0xc0 {
if let VEXOperandCode::G_ymm_M_xmm = op {
return Err(DecodeError::InvalidOperand);
@@ -793,7 +795,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -813,10 +815,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -832,7 +834,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
match (op, modrm & 0xc0) {
(VEXOperandCode::M_G_ymm, 0xc0) => {
return Err(DecodeError::InvalidOperand);
@@ -844,7 +846,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
if mem_oper != OperandSpec::RegMMM {
@@ -860,7 +862,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
match (op, modrm & 0xc0) {
(VEXOperandCode::G_M_ymm, 0xc0) => {
return Err(DecodeError::InvalidOperand);
@@ -872,7 +874,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -883,7 +885,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
op @ VEXOperandCode::G_V_E_ymm |
op @ VEXOperandCode::G_V_M_ymm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if let VEXOperandCode::G_V_M_ymm = op {
if modrm & 0xc0 == 0xc0 {
return Err(DecodeError::InvalidOperand);
@@ -892,7 +894,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -903,15 +905,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_ymm_imm8 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[3] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 32;
@@ -920,14 +922,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::M_V_G_ymm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 == 0xc0 {
return Err(DecodeError::InvalidOperand);
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegRRR;
@@ -938,13 +940,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_M_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 == 0xc0 {
return Err(DecodeError::InvalidOperand);
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -959,10 +961,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -979,10 +981,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_xmm_Ed => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -993,14 +995,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_xmm_imm8 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[3] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -1009,15 +1011,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_ymm_V_ymm_E_xmm_imm8 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[3] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -1026,14 +1028,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::M_V_G_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
if modrm & 0xc0 == 0xc0 {
return Err(DecodeError::InvalidOperand);
}
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegRRR;
@@ -1045,10 +1047,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
VEXOperandCode::G_Ex_V_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.sib_index.bank = RegisterBank::X;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
@@ -1060,10 +1062,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_Ey_V_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.vex_reg.bank = RegisterBank::X;
instruction.sib_index.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegRRR;
@@ -1076,10 +1078,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_Ey_V_ymm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.vex_reg.bank = RegisterBank::Y;
instruction.sib_index.bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegRRR;
@@ -1096,12 +1098,12 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
let (opwidth, bank) = (4, RegisterBank::D);
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, bank);
instruction.vex_reg.bank = bank;
- let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1112,12 +1114,12 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_E_V => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
let (opwidth, bank) = (4, RegisterBank::D);
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, bank);
instruction.vex_reg.bank = bank;
- let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.operands[2] = OperandSpec::RegVex;
@@ -1128,14 +1130,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_E_Ib => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
let (opwidth, bank) = (4, RegisterBank::D);
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, bank);
- let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmI8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = opwidth;
@@ -1144,7 +1146,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::BMI1_F3 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.opcode = match (modrm >> 3) & 7 {
1 => {
Opcode::BLSR
@@ -1163,7 +1165,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
let (opwidth, bank) = (4, RegisterBank::D);
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, bank);
- let mem_oper = read_E(bytes, instruction, modrm, opwidth, length)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth)?;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = mem_oper;
instruction.operand_count = 2;
@@ -1174,7 +1176,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::MXCSR => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.opcode = match (modrm >> 3) & 7 {
2 => {
Opcode::VLDMXCSR
@@ -1187,7 +1189,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
return Err(DecodeError::InvalidOpcode);
}
};
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
if let OperandSpec::RegMMM = mem_oper {
return Err(DecodeError::InvalidOperand);
}
@@ -1202,13 +1204,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
if instruction.vex_reg.num != 0 {
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -1220,13 +1222,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
if instruction.vex_reg.num != 0 {
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[2] = OperandSpec::ImmU8;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 32;
@@ -1235,15 +1237,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_ymm_ymm4 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)? >> 4;
+ instruction.imm = read_imm_unsigned(words, 1)? >> 4;
instruction.operands[3] = OperandSpec::Reg4;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 32;
@@ -1252,15 +1254,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_E_xmm_xmm4 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
instruction.vex_reg.bank = RegisterBank::X;
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)? >> 4;
+ instruction.imm = read_imm_unsigned(words, 1)? >> 4;
instruction.operands[3] = OperandSpec::Reg4;
if mem_oper != OperandSpec::RegMMM {
instruction.mem_size = 16;
@@ -1269,11 +1271,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_ymm_E_xmm => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
- let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1284,16 +1286,16 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_V_xmm_Ev_imm8 => {
- let modrm = read_modrm(bytes, length)?;
+ let modrm = read_modrm(words)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
instruction.vex_reg.bank = RegisterBank::X;
// TODO: but the memory access is word-sized
- let mem_oper = read_E(bytes, instruction, modrm, 4, length)?;
+ let mem_oper = read_E(words, instruction, modrm, 4)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
- instruction.imm = read_imm_unsigned(bytes, 1, length)?;
+ instruction.imm = read_imm_unsigned(words, 1)?;
instruction.operands[3] = OperandSpec::ImmI8;
if mem_oper != OperandSpec::RegMMM {
match instruction.opcode {
@@ -1319,9 +1321,8 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
}
-fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &mut T, instruction: &mut Instruction, length: &mut u8, p: VEXOpcodePrefix) -> Result<(), DecodeError> {
- let opc = bytes.next().ok_or(DecodeError::ExhaustedInput)?;
- *length += 1;
+fn read_vex_instruction<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(opcode_map: VEXOpcodeMap, words: &mut T, instruction: &mut Instruction, p: VEXOpcodePrefix) -> Result<(), DecodeError> {
+ let opc = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
// the name of this bit is `L` in the documentation, so use the same name here.
#[allow(non_snake_case)]
@@ -3361,5 +3362,5 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &
}
};
instruction.opcode = opcode;
- read_vex_operands(bytes, instruction, length, operand_code)
+ read_vex_operands(words, instruction, operand_code)
}