From 214da3dc5cbea216f5a3eb601a46e882bbf69a92 Mon Sep 17 00:00:00 2001 From: iximeow Date: Thu, 13 Jun 2024 15:33:21 -0700 Subject: use a bit of Opcode to indicate rep/repne applicability this reduces a `slice::contains` to a single bit test, and regroups prefix printing to deduplicate checks of the `rep` prefix seemingly this reduces instruction counts by about 1%, cycles by 0.3% or so. --- src/long_mode/display.rs | 18 +++++++++--------- src/long_mode/mod.rs | 30 +++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 18 deletions(-) (limited to 'src/long_mode') diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index b6cca48..71bb1dd 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -638,6 +638,13 @@ const MNEMONICS: &[&'static str] = &[ "not", "xadd", "xchg", + "cmps", + "scas", + "movs", + "lods", + "stos", + "ins", + "outs", "invalid", "bt", "bsf", @@ -719,17 +726,10 @@ const MNEMONICS: &[&'static str] = &[ "cwd", "cdq", "cqo", - "lods", - "stos", "lahf", "sahf", - "cmps", - "scas", - "movs", "test", - "ins", "in", - "outs", "out", "imul", "jo", @@ -3613,7 +3613,7 @@ fn contextualize_intel(instr: &Instruction, colors: } if instr.prefixes.rep_any() { - if [Opcode::MOVS, Opcode::CMPS, Opcode::LODS, Opcode::STOS, Opcode::INS, Opcode::OUTS].contains(&instr.opcode) { + if instr.opcode.can_rep() { if instr.prefixes.rep() { write!(out, "rep ")?; } else if instr.prefixes.repnz() { @@ -3769,7 +3769,7 @@ fn contextualize_c(instr: &Instruction, colors: &Y, } if instr.prefixes.rep_any() { - if [Opcode::MOVS, Opcode::CMPS, Opcode::LODS, Opcode::STOS, Opcode::INS, Opcode::OUTS].contains(&instr.opcode) { + if instr.opcode.can_rep() { let word_str = match instr.mem_size { 1 => "byte", 2 => "word", diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 7aab852..41d6f2d 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -1101,7 +1101,16 @@ pub enum Opcode { NOT = 0x1019, XADD = 0x101a, XCHG = 0x101b, - Invalid = 0x1c, + + CMPS = 0x201c, + SCAS = 0x201d, + MOVS = 0x201e, + LODS = 0x201f, + STOS = 0x2020, + INS = 0x2021, + OUTS = 0x2022, + + Invalid = 0x23, // XADD, BT, // BTS, @@ -1186,17 +1195,10 @@ pub enum Opcode { CWD, CDQ, CQO, - LODS, - STOS, LAHF, SAHF, - CMPS, - SCAS, - MOVS, TEST, - INS, IN, - OUTS, OUT, IMUL, JO, @@ -4338,6 +4340,16 @@ impl Opcode { _ => None, } } + + #[inline(always)] + fn can_lock(&self) -> bool { + (*self as u32) & 0x1000 != 0 + } + + #[inline(always)] + fn can_rep(&self) -> bool { + (*self as u32) & 0x2000 != 0 + } } impl Default for Instruction { @@ -6835,7 +6847,7 @@ fn read_with_annotations< self.read_operands(decoder, words, instruction, record, sink)?; if self.check_lock { - if (instruction.opcode as u32) < 0x1000 || !instruction.operands[0].is_memory() { + if !instruction.opcode.can_lock() || !instruction.operands[0].is_memory() { return Err(DecodeError::InvalidPrefixes); } } -- cgit v1.1