From 22444c4172c647e464b5e68808e3b3959ce17a3a Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 8 Aug 2020 13:56:09 -0700 Subject: drilled a new speed hole: rex doesn't need to be held through read_M or read_sib --- src/long_mode/mod.rs | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 20e5445..57f5d08 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -5272,7 +5272,13 @@ fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) -> #[allow(non_snake_case)] fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { let modbits = modrm >> 6; - let addr_width = if instr.prefixes.address_size() { RegisterBank::D } else { RegisterBank::Q }; + if instr.prefixes.address_size() { + instr.sib_index.bank = RegisterBank::D; + instr.modrm_mmm.bank = RegisterBank::D; + } else { + instr.sib_index.bank = RegisterBank::Q; + instr.modrm_mmm.bank = RegisterBank::Q; + }; let sibbyte = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?; *length += 1; @@ -5300,8 +5306,7 @@ fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, m OperandSpec::DispU32 } else { if instr.prefixes.rex().x() { - let reg = RegSpec::from_parts(0b100, true, addr_width); - instr.sib_index = reg; + instr.sib_index.num = 0b1100; let scale = 1u8 << (sibbyte >> 6); instr.scale = scale; @@ -5312,8 +5317,7 @@ fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, m OperandSpec::RegIndexBaseScaleDisp } } else { - let reg = RegSpec::from_parts(0b101, instr.prefixes.rex().b(), addr_width); - instr.modrm_mmm = reg; + instr.modrm_mmm.num = 0b101 + if instr.prefixes.rex().b() { 0b1000 } else { 0 }; if disp == 0 { OperandSpec::Deref @@ -5324,9 +5328,9 @@ fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, m } } } else { - instr.modrm_mmm = RegSpec::from_parts(5, instr.prefixes.rex().b(), addr_width); + instr.modrm_mmm.num = 0b101 + if instr.prefixes.rex().b() { 0b1000 } else { 0 }; + instr.sib_index.num = ((sibbyte >> 3) & 7) + if instr.prefixes.rex().x() { 0b1000 } else { 0 }; - instr.sib_index = RegSpec::from_parts((sibbyte >> 3) & 7, instr.prefixes.rex().x(), addr_width); let scale = 1u8 << (sibbyte >> 6); instr.scale = scale; @@ -5346,12 +5350,11 @@ fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, m } } } else { - instr.modrm_mmm = RegSpec::from_parts(sibbyte & 7, instr.prefixes.rex().b(), addr_width); + instr.modrm_mmm.num = (sibbyte & 7) + if instr.prefixes.rex().b() { 0b1000 } else { 0 }; if ((sibbyte >> 3) & 7) == 0b100 { if instr.prefixes.rex().x() { - let reg = RegSpec::from_parts(0b100, true, addr_width); - instr.sib_index = reg; + instr.sib_index.num = 0b1100; let scale = 1u8 << (sibbyte >> 6); instr.scale = scale; @@ -5370,7 +5373,7 @@ fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, m } } } else { - instr.sib_index = RegSpec::from_parts((sibbyte >> 3) & 7, instr.prefixes.rex().x(), addr_width); + instr.sib_index.num = ((sibbyte >> 3) & 7) + if instr.prefixes.rex().x() { 0b1000 } else { 0 }; let scale = 1u8 << (sibbyte >> 6); instr.scale = scale; if disp == 0 { @@ -5387,7 +5390,6 @@ fn read_sib>(bytes_iter: &mut T, instr: &mut Instruction, m #[allow(non_snake_case)] fn read_M>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result { let modbits = modrm >> 6; - let addr_width = if instr.prefixes.address_size() { RegisterBank::D } else { RegisterBank::Q }; let mmm = modrm & 7; let op_spec = if mmm == 4 { return read_sib(bytes_iter, instr, modrm, length); @@ -5395,7 +5397,7 @@ fn read_M>(bytes_iter: &mut T, instr: &mut Instruction, mod *length += 4; let disp = read_num(bytes_iter, 4)? as i32; instr.modrm_mmm = - if addr_width == RegisterBank::Q { RegSpec::rip() } else { RegSpec::eip() }; + if !instr.prefixes.address_size() { RegSpec::rip() } else { RegSpec::eip() }; if disp == 0 { OperandSpec::Deref } else { @@ -5403,7 +5405,12 @@ fn read_M>(bytes_iter: &mut T, instr: &mut Instruction, mod OperandSpec::RegDisp } } else { - instr.modrm_mmm = RegSpec::from_parts(mmm, instr.prefixes.rex().b(), addr_width); + if instr.prefixes.address_size() { + instr.modrm_mmm.bank = RegisterBank::D + } else { + instr.modrm_mmm.bank = RegisterBank::Q + }; + instr.modrm_mmm.num = mmm + if instr.prefixes.rex().b() { 0b1000 } else { 0 }; if modbits == 0b00 { OperandSpec::Deref -- cgit v1.1