aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2024-06-13 15:33:21 -0700
committeriximeow <me@iximeow.net>2024-06-13 15:33:21 -0700
commit214da3dc5cbea216f5a3eb601a46e882bbf69a92 (patch)
tree0fa92a768d919c7939debb54cf8ec3c64c1d2e47
parent050bc1c972bc69b963429753b939cefc04812321 (diff)
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.
-rw-r--r--src/long_mode/display.rs18
-rw-r--r--src/long_mode/mod.rs30
2 files changed, 30 insertions, 18 deletions
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<T: fmt::Write, Y: YaxColors>(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<T: fmt::Write, Y: YaxColors>(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);
}
}