aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-07-03 13:38:01 -0700
committeriximeow <me@iximeow.net>2021-07-03 13:38:01 -0700
commit620f731301009349aae40f0b172b463fbb6556e7 (patch)
tree234ea5ac8f2cbc692121a53761e2cf965f7391a4
parentf883f8d99519e745e5dcb239112365c04f90457b (diff)
add hreset
-rw-r--r--src/long_mode/display.rs4
-rw-r--r--src/long_mode/mod.rs25
-rw-r--r--src/protected_mode/display.rs4
-rw-r--r--src/protected_mode/mod.rs23
-rw-r--r--test/long_mode/mod.rs6
-rw-r--r--test/protected_mode/mod.rs6
6 files changed, 65 insertions, 3 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs
index 5f74a3e..b9e4a92 100644
--- a/src/long_mode/display.rs
+++ b/src/long_mode/display.rs
@@ -1350,6 +1350,9 @@ const MNEMONICS: &[&'static str] = &[
"encodekey256",
"loadiwkey",
+ // unsure
+ "hreset",
+
// 3dnow
"femms",
"pi2fw",
@@ -3202,6 +3205,7 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {
Opcode::ENCODEKEY128 |
Opcode::ENCODEKEY256 |
Opcode::LOADIWKEY |
+ Opcode::HRESET |
Opcode::WRUSS |
Opcode::WRSS |
Opcode::INCSSP |
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 254ccc7..b00a9ff 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -585,7 +585,7 @@ impl Operand {
OperandSpec::Nothing => {
Operand::Nothing
}
- // the register in regs[0]
+ // the register in modrm_rrr
OperandSpec::RegRRR => {
Operand::Register(inst.regs[0])
}
@@ -2067,6 +2067,9 @@ pub enum Opcode {
ENCODEKEY256,
LOADIWKEY,
+ // unsure
+ HRESET,
+
// 3dnow
FEMMS,
PI2FW,
@@ -4828,6 +4831,7 @@ enum OperandCode {
ModRM_0xf30f38df = OperandCodeBuilder::new().read_modrm().special_case(49).bits(),
ModRM_0xf30f38fa = OperandCodeBuilder::new().read_modrm().special_case(50).bits(),
ModRM_0xf30f38fb = OperandCodeBuilder::new().read_modrm().special_case(51).bits(),
+ ModRM_0xf30f3af0 = OperandCodeBuilder::new().read_modrm().special_case(52).bits(),
// ModRM_0x660f3a = OperandCodeBuilder::new().read_modrm().special_case(52).bits(),
// ModRM_0x0f38 = OperandCodeBuilder::new().read_modrm().special_case(53).bits(),
// ModRM_0x0f3a = OperandCodeBuilder::new().read_modrm().special_case(54).bits(),
@@ -6933,7 +6937,14 @@ fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {
}
fn read_0f3a_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {
- if prefixes.rep() || prefixes.repnz() {
+ if prefixes.rep() {
+ return match opcode {
+ 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::HRESET), OperandCode::ModRM_0xf30f3af0),
+ _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ };
+ }
+
+ if prefixes.repnz() {
return OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing);
}
@@ -8707,6 +8718,16 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0].bank = RegisterBank::D;
instruction.regs[1].bank = RegisterBank::D;
}
+ OperandCode::ModRM_0xf30f3af0 => {
+ let modrm = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
+ if modrm & 0xc0 != 0xc0 {
+ return Err(DecodeError::InvalidOpcode);
+ // invalid
+ }
+ instruction.opcode = Opcode::HRESET;
+ instruction.imm = read_num(words, 1)?;
+ instruction.operands[0] = OperandSpec::ImmU8;
+ }
OperandCode::G_mm_Edq => {
instruction.regs[0].bank = RegisterBank::MM;
instruction.regs[0].num &= 0b111;
diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs
index 4f784d6..83d3b56 100644
--- a/src/protected_mode/display.rs
+++ b/src/protected_mode/display.rs
@@ -1351,6 +1351,9 @@ const MNEMONICS: &[&'static str] = &[
"encodekey256",
"loadiwkey",
+ // unsure
+ "hreset",
+
// 3dnow
"femms",
"pi2fw",
@@ -3215,6 +3218,7 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {
Opcode::ENCODEKEY128 |
Opcode::ENCODEKEY256 |
Opcode::LOADIWKEY |
+ Opcode::HRESET |
Opcode::WRUSS |
Opcode::WRSS |
Opcode::INCSSP |
diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs
index b7387d9..c9a2de0 100644
--- a/src/protected_mode/mod.rs
+++ b/src/protected_mode/mod.rs
@@ -1996,6 +1996,9 @@ pub enum Opcode {
ENCODEKEY256,
LOADIWKEY,
+ // unsure
+ HRESET,
+
// 3dnow
FEMMS,
PI2FW,
@@ -4676,6 +4679,7 @@ enum OperandCode {
ModRM_0xf30f38df = OperandCodeBuilder::new().read_modrm().special_case(49).bits(),
ModRM_0xf30f38fa = OperandCodeBuilder::new().read_modrm().special_case(50).bits(),
ModRM_0xf30f38fb = OperandCodeBuilder::new().read_modrm().special_case(51).bits(),
+ ModRM_0xf30f3af0 = OperandCodeBuilder::new().read_modrm().special_case(52).bits(),
// ModRM_0x660f3a = OperandCodeBuilder::new().read_modrm().special_case(52).bits(),
// ModRM_0x0f38 = OperandCodeBuilder::new().read_modrm().special_case(53).bits(),
// ModRM_0x0f3a = OperandCodeBuilder::new().read_modrm().special_case(54).bits(),
@@ -6806,7 +6810,14 @@ fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {
}
fn read_0f3a_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {
- if prefixes.rep() || prefixes.repnz() {
+ if prefixes.rep() {
+ return match opcode {
+ 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::HRESET), OperandCode::ModRM_0xf30f3af0),
+ _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
+ };
+ }
+
+ if prefixes.repnz() {
return OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing);
}
@@ -8521,6 +8532,16 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0].bank = RegisterBank::D;
instruction.regs[1].bank = RegisterBank::D;
}
+ OperandCode::ModRM_0xf30f3af0 => {
+ let modrm = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
+ if modrm & 0xc0 != 0xc0 {
+ return Err(DecodeError::InvalidOpcode);
+ // invalid
+ }
+ instruction.opcode = Opcode::HRESET;
+ instruction.imm = read_num(words, 1)?;
+ instruction.operands[0] = OperandSpec::ImmU8;
+ }
OperandCode::G_mm_Ed => {
instruction.regs[0].bank = RegisterBank::MM;
instruction.regs[0].num &= 0b111;
diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs
index 98fc8b6..0e28ea3 100644
--- a/test/long_mode/mod.rs
+++ b/test/long_mode/mod.rs
@@ -3315,3 +3315,9 @@ fn test_tsxldtrk() {
test_display(&[0xf2, 0x0f, 0x01, 0xe8], "xsusldtrk");
test_display(&[0xf2, 0x0f, 0x01, 0xe9], "xresldtrk");
}
+
+// some test cases are best just lifted from llvm or gcc.
+#[test]
+fn from_llvm() {
+ test_display(&[0xf3, 0x0f, 0x3a, 0xf0, 0xc0, 0x01], "hreset 0x1");
+}
diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs
index 9221e7d..90b53a6 100644
--- a/test/protected_mode/mod.rs
+++ b/test/protected_mode/mod.rs
@@ -3025,3 +3025,9 @@ fn test_tsxldtrk() {
test_display(&[0xf2, 0x0f, 0x01, 0xe8], "xsusldtrk");
test_display(&[0xf2, 0x0f, 0x01, 0xe9], "xresldtrk");
}
+
+// some test cases are best just lifted from llvm or gcc.
+#[test]
+fn from_llvm() {
+ test_display(&[0xf3, 0x0f, 0x3a, 0xf0, 0xc0, 0x01], "hreset 0x1");
+}