aboutsummaryrefslogtreecommitdiff
path: root/src/long_mode/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/long_mode/mod.rs')
-rw-r--r--src/long_mode/mod.rs26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 79e5b39..73570c1 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -659,6 +659,7 @@ pub enum Opcode {
BLSMSK,
BLSR,
VMCLEAR,
+ VMXON,
VMCALL,
VMLAUNCH,
VMRESUME,
@@ -5111,6 +5112,13 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T,
Opcode::PUSH,
Opcode::Invalid
][((modrm >> 3) & 7) as usize];
+ if instruction.operands[0] == OperandSpec::RegMMM {
+ if opcode == Opcode::CALL || opcode == Opcode::JMP {
+ instruction.modrm_mmm.bank = RegisterBank::Q;
+ } else if opcode == Opcode::CALLF || opcode == Opcode::JMPF {
+ return Err(DecodeError::InvalidOperand);
+ }
+ }
instruction.opcode = opcode;
instruction.operand_count = 1;
}
@@ -5643,6 +5651,24 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
},
+ OperandCode::ModRM_0xf30fc7 => {
+ let modrm = read_modrm(&mut bytes_iter, length)?;
+
+ let r = (modrm >> 3) & 7;
+ match r {
+ 6 => {
+ instruction.opcode = Opcode::VMXON;
+ instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 1 /* doesn't matter, something using this width is invalid */, length)?;
+ if instruction.operands[0] == OperandSpec::RegMMM {
+ return Err(DecodeError::InvalidOperand);
+ }
+ instruction.operand_count = 1;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+ },
OperandCode::G_mm_Edq => {
instruction.operands[1] = mem_oper;
instruction.modrm_rrr.bank = RegisterBank::MM;