diff options
-rw-r--r-- | src/long_mode/mod.rs | 468 | ||||
-rw-r--r-- | src/long_mode/vex.rs | 282 | ||||
-rw-r--r-- | src/protected_mode/mod.rs | 475 | ||||
-rw-r--r-- | src/protected_mode/vex.rs | 265 |
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) } |