aboutsummaryrefslogtreecommitdiff
path: root/src/long_mode
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-03-21 02:48:11 -0700
committeriximeow <me@iximeow.net>2021-03-21 02:48:11 -0700
commit5223427b217cc567deb55ea420b8da58aea64d68 (patch)
tree4b8256c45706e3ea94dd7234616a69e79ae45bff /src/long_mode
parent0a3811ec18d2154f050aaf6e611a3d65f467c0cc (diff)
complete CET support, add UINTR, add missing VORP{S,D}, other cleanup
Diffstat (limited to 'src/long_mode')
-rw-r--r--src/long_mode/display.rs26
-rw-r--r--src/long_mode/mod.rs116
-rw-r--r--src/long_mode/vex.rs10
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 {