diff options
| -rw-r--r-- | src/long_mode/mod.rs | 32 | 
1 files changed, 18 insertions, 14 deletions
| diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 533efa4..4d5cf59 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -6466,7 +6466,9 @@ impl DecodeCtx {  fn read_opc_hotpath<      T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>,      S: DescriptionSink<FieldDescription>, ->(&mut self, mut b: u8, nextb: &mut u8, record: &mut OpcodeRecord, words: &mut T, instruction: &mut Instruction, sink: &mut S) -> Result<bool, DecodeError> { +>(&mut self, words: &mut T, instruction: &mut Instruction, sink: &mut S) -> Result<Result<OperandCode, (u8, OpcodeRecord)>, DecodeError> { +    let mut b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; +      if b >= 0x40 && b < 0x50 {          sink.record((words.offset() - 1) as u32 * 8, (words.offset() - 1) as u32 * 8 + 7, FieldDescription {              desc: InnerDescription::RexPrefix(b), @@ -6478,7 +6480,7 @@ fn read_opc_hotpath<          }          self.rb_size = RegisterBank::rB;          b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; -        *record = unsafe { +        record = unsafe {              core::ptr::read_volatile(&OPCODES[b as usize])          };      } else if b == 0x66 { @@ -6487,20 +6489,24 @@ fn read_opc_hotpath<              id: words.offset() as u32 * 8 - 8,          });          b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; -        *record = unsafe { +        record = unsafe {              core::ptr::read_volatile(&OPCODES[b as usize])          };          instruction.prefixes.set_operand_size();          self.vqp_size = RegisterBank::W; +    } else { +        record = unsafe { +            core::ptr::read_volatile(&OPCODES[b as usize]) +        };      }      if let Interpretation::Instruction(opc) = record.0 {          record_opcode_record_found(words, sink, opc, record.1, 1);          instruction.opcode = opc; -        return Ok(true); +        return Ok(Ok(record.1));      } else if b == 0x0f {          let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; -        let (r, len) = if b == 0x38 { +        let (record, len) = if b == 0x38 {              let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;              (self.read_0f38_opcode(b, &mut instruction.prefixes), 3)          } else if b == 0x3a { @@ -6509,17 +6515,15 @@ fn read_opc_hotpath<          } else {              (self.read_0f_opcode(b, &mut instruction.prefixes), 2)          }; -        *record = r;          if let Interpretation::Instruction(opc) = record.0 {              record_opcode_record_found(words, sink, opc, record.1, len);              instruction.opcode = opc;          } else {              unsafe { unreachable_unchecked(); }          } -        return Ok(true); +        return Ok(Ok(record.1));      } else { -        *nextb = b; -        return Ok(false); +        return Ok(Err((b, record)));      }  } @@ -6529,8 +6533,6 @@ fn read_with_annotations<      S: DescriptionSink<FieldDescription>,  >(mut self, decoder: &InstDecoder, words: &mut T, instruction: &mut Instruction, sink: &mut S) -> Result<(), DecodeError> {      words.mark(); -    let mut nextb = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; -    let mut next_rec = OPCODES[nextb as usize];      instruction.prefixes = Prefixes::new(0);  //    const RAXRAXRAXRAX: [RegSpec; 4] = [RegSpec::rax(); 4]; @@ -6539,9 +6541,10 @@ fn read_with_annotations<      instruction.regs[1] = RegSpec::rax();      instruction.regs[2] = RegSpec::rax(); -    let record: OperandCode = if self.read_opc_hotpath(nextb, &mut nextb, &mut next_rec, words, instruction, sink)? { -        next_rec.1 -    } else { +    let hotpath_res = self.read_opc_hotpath(words, instruction, sink)?; +    let record: OperandCode = match hotpath_res { +        Ok(code) => code, +        Err((mut nextb, mut next_rec)) => {          let prefixes = &mut instruction.prefixes;          let record = loop {              let mut record = next_rec; @@ -6684,6 +6687,7 @@ fn read_with_annotations<          }          record.1 +    }      };      self.read_operands(decoder, words, instruction, record, sink)?; | 
