diff options
Diffstat (limited to 'src/long_mode')
-rw-r--r-- | src/long_mode/display.rs | 26 | ||||
-rw-r--r-- | src/long_mode/mod.rs | 116 | ||||
-rw-r--r-- | src/long_mode/vex.rs | 10 |
3 files changed, 133 insertions, 19 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 8f7bd9b..5c733a2 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -848,6 +848,8 @@ const MNEMONICS: &[&'static str] = &[ "vpalignr", "vandps", "vandpd", + "vorps", + "vorpd", "vandnps", "vandnpd", "vpand", @@ -1285,6 +1287,11 @@ const MNEMONICS: &[&'static str] = &[ // CET "wruss", "wrss", + "incssp", + "saveprevssp", + "setssbsy", + "clrssbsy", + "rstorssp", // TDX "tdcall", @@ -1296,6 +1303,13 @@ const MNEMONICS: &[&'static str] = &[ "tpause", "umonitor", "umwait", + + // UINTR + "uiret", + "testui", + "clui", + "stui", + "senduipi", ]; impl Opcode { @@ -1462,6 +1476,8 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::VDPPD | Opcode::VDPPS | Opcode::VRCPPS | + Opcode::VORPD | + Opcode::VORPS | Opcode::VANDPD | Opcode::VANDPS | Opcode::VANDNPD | @@ -2298,6 +2314,11 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::ENQCMD | Opcode::ENQCMDS | Opcode::PTWRITE | + Opcode::UIRET | + Opcode::TESTUI | + Opcode::CLUI | + Opcode::STUI | + Opcode::SENDUIPI | Opcode::LAR => { write!(out, "{}", colors.platform_op(self)) } Opcode::CRC32 | @@ -2330,6 +2351,11 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::LOADIWKEY | Opcode::WRUSS | Opcode::WRSS | + Opcode::INCSSP | + Opcode::SAVEPREVSSP | + Opcode::SETSSBSY | + Opcode::CLRSSBSY | + Opcode::RSTORSSP | Opcode::AESDEC | Opcode::AESDECLAST | Opcode::AESENC | diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 8e64021..266bd2e 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -1488,6 +1488,8 @@ pub enum Opcode { VPALIGNR, VANDPD, VANDPS, + VORPD, + VORPS, VANDNPD, VANDNPS, VPAND, @@ -1940,6 +1942,11 @@ pub enum Opcode { // CET WRUSS, WRSS, + INCSSP, + SAVEPREVSSP, + SETSSBSY, + CLRSSBSY, + RSTORSSP, // TDX TDCALL, @@ -1951,6 +1958,13 @@ pub enum Opcode { TPAUSE, UMONITOR, UMWAIT, + + // UINTR + UIRET, + TESTUI, + CLUI, + STUI, + SENDUIPI, } #[derive(Debug)] @@ -3109,6 +3123,8 @@ impl InstDecoder { Opcode::VANDPS | Opcode::VANDNPD | Opcode::VANDNPS | + Opcode::VORPD | + Opcode::VORPS | Opcode::VPANDN | Opcode::VPAVGB | Opcode::VPAVGW | @@ -7233,9 +7249,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter 0x1d => { instruction.opcode = Opcode::PF2ID; } - 0x59 => { - instruction.opcode = Opcode::PMULHRW; - } 0x8a => { instruction.opcode = Opcode::PFNACC; } @@ -7293,9 +7306,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter 0xbb => { instruction.opcode = Opcode::PSWAPD; } - 0xbe => { - instruction.opcode = Opcode::PFPNACC; - } 0xbf => { instruction.opcode = Opcode::PAVGUSB; } @@ -7414,9 +7424,10 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::VMXON; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; if instruction.operands[0] == OperandSpec::RegMMM { - // this would be invalid as `vmxon`, so fall back to the parse as - // f3-prefixed rdrand - instruction.opcode = Opcode::RDRAND; + // invalid as `vmxon`, reg-form is `senduipi` + instruction.opcode = Opcode::SENDUIPI; + // and the operand is always a qword register + instruction.modrm_mmm.bank = RegisterBank::Q; } instruction.operand_count = 1; } @@ -8301,20 +8312,69 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else if r == 5 { let mod_bits = modrm >> 6; if mod_bits != 0b11 { - instruction.opcode = Opcode::Invalid; - instruction.operands[0] = OperandSpec::Nothing; - instruction.operand_count = 0; - return Err(DecodeError::InvalidOpcode); + if !instruction.prefixes.rep() { + return Err(DecodeError::InvalidOpcode); + } + instruction.opcode = Opcode::RSTORSSP; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 8, length)?; + instruction.operand_count = 1; + return Ok(()); } let m = modrm & 7; match m { + 0b000 => { + if !instruction.prefixes.rep() || instruction.prefixes.operand_size() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOpcode); + } + instruction.opcode = Opcode::SETSSBSY; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + } + 0b010 => { + if !instruction.prefixes.rep() || instruction.prefixes.operand_size() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOpcode); + } + instruction.opcode = Opcode::SAVEPREVSSP; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + } + 0b100 => { + if instruction.prefixes.rep() { + instruction.opcode = Opcode::UIRET; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + } + } + 0b101 => { + if instruction.prefixes.rep() { + instruction.opcode = Opcode::TESTUI; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + } + } 0b110 => { + if instruction.prefixes.rep() { + instruction.opcode = Opcode::CLUI; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + return Ok(()); + } else if instruction.prefixes.operand_size() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOpcode); + } instruction.opcode = Opcode::RDPKRU; instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; } 0b111 => { + if instruction.prefixes.rep() { + instruction.opcode = Opcode::STUI; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + return Ok(()); + } else if instruction.prefixes.operand_size() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOpcode); + } instruction.opcode = Opcode::WRPKRU; instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; @@ -8509,13 +8569,21 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } + 5 => { + instruction.opcode = Opcode::INCSSP; + let opwidth = if instruction.prefixes.rex().w() { + RegisterBank::Q + } else { + RegisterBank::D + }; + instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); + instruction.operands[0] = OperandSpec::RegMMM; + instruction.operand_count = 1; + } 6 => { instruction.opcode = Opcode::UMONITOR; - instruction.modrm_rrr = RegSpec { - bank: RegisterBank::Q, - num: m + if instruction.prefixes.rex().x() { 0b1000 } else { 0 }, - }; - instruction.operands[0] = OperandSpec::RegRRR; + instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), RegisterBank::Q); + instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } _ => { @@ -8525,7 +8593,17 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } return Ok(()); } else { - return Err(DecodeError::InvalidOperand); + match r { + 6 => { + instruction.opcode = Opcode::CLRSSBSY; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 8, length)?; + instruction.operand_count = 1; + return Ok(()); + } + _ => { + return Err(DecodeError::InvalidOperand); + } + } } } diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index 71a5724..41f5c29 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -952,6 +952,11 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::G_V_E_xmm }), + 0x56 => (Opcode::VORPS, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_xmm + }), 0x57 => (Opcode::VXORPS, if L { VEXOperandCode::G_V_E_ymm } else { @@ -1099,6 +1104,11 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::G_V_E_xmm }), + 0x56 => (Opcode::VORPD, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_xmm + }), 0x57 => (Opcode::VXORPD, if L { VEXOperandCode::G_V_E_ymm } else { |