From 620f731301009349aae40f0b172b463fbb6556e7 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 3 Jul 2021 13:38:01 -0700 Subject: add hreset --- src/long_mode/display.rs | 4 ++++ src/long_mode/mod.rs | 25 +++++++++++++++++++++++-- src/protected_mode/display.rs | 4 ++++ src/protected_mode/mod.rs | 23 ++++++++++++++++++++++- test/long_mode/mod.rs | 6 ++++++ test/protected_mode/mod.rs | 6 ++++++ 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 Colorize 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::Address, { + 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 Colorize 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::Address, { + 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"); +} -- cgit v1.1