diff options
author | iximeow <me@iximeow.net> | 2022-04-22 19:49:43 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2022-05-30 11:18:22 -0700 |
commit | 67be1c0983244645a3c762b7aa0601f0d0ba4bb3 (patch) | |
tree | fcca0ca75d1f131567f4771d2b32dfc259a503a1 | |
parent | 6353f58170d28a142e3b012c2c86f684d50dea45 (diff) |
66 prefixes are common, 0f opcodes are common
-rw-r--r-- | src/long_mode/mod.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index d22db30..5b3113c 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -6428,6 +6428,16 @@ fn read_opc_hotpath< core::ptr::read_volatile(&OPCODES[b as usize]) }; instruction.prefixes.rex_from(b); + } else if b == 0x66 { + sink.record((words.offset() - 2) as u32 * 8, (words.offset() - 2) as u32 * 8 + 7, FieldDescription { + desc: InnerDescription::Misc("operand size override (to 16 bits)"), + id: words.offset() as u32 * 8 - 16, + }); + b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; + record = unsafe { + core::ptr::read_volatile(&OPCODES[b as usize]) + }; + instruction.prefixes.set_operand_size(); } if let Interpretation::Instruction(opc) = record.0 { @@ -6452,6 +6462,32 @@ fn read_opc_hotpath< instruction.operand_count = 2; instruction.opcode = opc; return Ok(Some(record.1)); + } else if b == 0x0f { + if words.offset() > 1 { + sink.record( + words.offset() as u32 * 8 - 8 - 1, words.offset() as u32 * 8 - 8 - 1, + InnerDescription::Boundary("prefixes end") + .with_id(words.offset() as u32 * 8 - 9) + ); + } + let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; + instruction.mem_size = 0; + instruction.operand_count = 2; + let record = if b == 0x38 { + let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; + read_0f38_opcode(b, &mut instruction.prefixes) + } else if b == 0x3a { + let b = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; + read_0f3a_opcode(b, &mut instruction.prefixes) + } else { + read_0f_opcode(b, &mut instruction.prefixes) + }; + if let Interpretation::Instruction(opc) = record.0 { + instruction.opcode = opc; + } else { + unsafe { unreachable_unchecked(); } + } + return Ok(Some(record.1)); } else { *nextb = b; *next_rec = record; |