From 11ce930421ba8b534024f6695dff8fdfd7e47ff0 Mon Sep 17 00:00:00 2001
From: iximeow <me@iximeow.net>
Date: Sat, 3 Jul 2021 14:41:09 -0700
Subject: support AMD `sev_snp`

---
 src/protected_mode/display.rs |  8 ++++++++
 src/protected_mode/mod.rs     | 37 +++++++++++++++++++++++++++++++++++--
 2 files changed, 43 insertions(+), 2 deletions(-)

(limited to 'src/protected_mode')

diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs
index 3e0079e..ac869aa 100644
--- a/src/protected_mode/display.rs
+++ b/src/protected_mode/display.rs
@@ -1801,6 +1801,10 @@ const MNEMONICS: &[&'static str] = &[
     "vpandnq",
     "vpandd",
     "vpandq",
+    "psmash",
+    "pvalidate",
+    "rmpadjust",
+    "rmpupdate",
 ];
 
 impl Opcode {
@@ -3102,6 +3106,10 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {
             Opcode::INVLPGA |
             Opcode::INVLPGB |
             Opcode::TLBSYNC |
+            Opcode::PSMASH |
+            Opcode::PVALIDATE |
+            Opcode::RMPADJUST |
+            Opcode::RMPUPDATE |
             Opcode::CPUID |
             Opcode::WBINVD |
             Opcode::INVD |
diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs
index 936dc08..0497db6 100644
--- a/src/protected_mode/mod.rs
+++ b/src/protected_mode/mod.rs
@@ -2441,6 +2441,11 @@ pub enum Opcode {
     VPANDNQ,
     VPANDD,
     VPANDQ,
+
+    PSMASH,
+    PVALIDATE,
+    RMPADJUST,
+    RMPUPDATE,
 }
 
 impl PartialEq for Instruction {
@@ -9322,7 +9327,21 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
                         instruction.regs[0] = RegSpec::ecx();
                         instruction.operand_count = 1;
                     } else if m == 6 {
-                        if instruction.prefixes.rep() || instruction.prefixes.repnz() || instruction.prefixes.operand_size() {
+                        if instruction.prefixes.rep() {
+                            if instruction.prefixes.repnz() || instruction.prefixes.operand_size() {
+                                return Err(DecodeError::InvalidOperand);
+                            }
+                            instruction.opcode = Opcode::RMPADJUST;
+                            instruction.operand_count = 0;
+                            return Ok(());
+                        } else if instruction.prefixes.repnz() {
+                            if instruction.prefixes.rep() || instruction.prefixes.operand_size() {
+                                return Err(DecodeError::InvalidOperand);
+                            }
+                            instruction.opcode = Opcode::RMPUPDATE;
+                            instruction.operand_count = 0;
+                            return Ok(());
+                        } else if instruction.prefixes.operand_size() {
                             return Err(DecodeError::InvalidOperand);
                         }
 
@@ -9335,7 +9354,21 @@ fn unlikely_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
                         instruction.regs[1] = RegSpec::edx();
                         instruction.regs[3] = RegSpec::ecx();
                     } else if m == 7 {
-                        if instruction.prefixes.rep() || instruction.prefixes.repnz() || instruction.prefixes.operand_size() {
+                        if instruction.prefixes.rep() {
+                            if instruction.prefixes.repnz() || instruction.prefixes.operand_size() {
+                                return Err(DecodeError::InvalidOperand);
+                            }
+                            instruction.opcode = Opcode::PSMASH;
+                            instruction.operand_count = 0;
+                            return Ok(());
+                        } else if instruction.prefixes.repnz() {
+                            if instruction.prefixes.rep() || instruction.prefixes.operand_size() {
+                                return Err(DecodeError::InvalidOperand);
+                            }
+                            instruction.opcode = Opcode::PVALIDATE;
+                            instruction.operand_count = 0;
+                            return Ok(());
+                        } else if instruction.prefixes.operand_size() {
                             return Err(DecodeError::InvalidOperand);
                         }
 
-- 
cgit v1.1