aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/long_mode/mod.rs27
-rw-r--r--src/long_mode/vex.rs1
-rw-r--r--src/protected_mode/mod.rs23
-rw-r--r--src/protected_mode/vex.rs1
-rw-r--r--src/shared/evex.in2
5 files changed, 53 insertions, 1 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 29a76a8..8d83986 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -7970,6 +7970,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
// lsl is weird. the full register width is written, but only the low 16 bits are used.
if instruction.operands[1] == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::D;
+ } else {
+ instruction.mem_size = 2;
}
instruction.modrm_rrr =
RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present());
@@ -8166,6 +8168,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_rrr.num &= 0b111;
instruction.opcode = Opcode::MOVD;
}
+ if instruction.operands[1] != OperandSpec::RegMMM {
+ if instruction.prefixes.rex().w() {
+ instruction.mem_size = 4;
+ } else {
+ instruction.mem_size = 8;
+ }
+ }
}
OperandCode::ModRM_0x0f0d => {
let modrm = read_modrm(&mut bytes_iter, length)?;
@@ -9138,6 +9147,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
unreachable!("r <= 8");
}
instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ if instruction.operands[0] != OperandSpec::RegMMM {
+ instruction.mem_size = 2;
+ }
}
OperandCode::ModRM_0x0f01 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes);
@@ -9770,6 +9782,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ if instruction.operands[0] != OperandSpec::RegMMM {
+ instruction.mem_size = opwidth;
+ }
instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
instruction.operands[1] = OperandSpec::ImmI8;
@@ -9912,12 +9927,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = OperandSpec::Deref;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operand_count = 2;
+ instruction.mem_size = 1;
}
OperandCode::Yv_DX => {
instruction.modrm_rrr = RegSpec::dx();
instruction.modrm_mmm = RegSpec::rdi();
instruction.operands[0] = OperandSpec::Deref;
instruction.operands[1] = OperandSpec::RegRRR;
+ if instruction.prefixes.operand_size() {
+ instruction.mem_size = 2;
+ } else {
+ instruction.mem_size = 4;
+ }
instruction.operand_count = 2;
}
OperandCode::DX_Xb => {
@@ -9926,6 +9947,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::Deref;
instruction.operand_count = 2;
+ instruction.mem_size = 1;
}
OperandCode::AH => {
instruction.operands[0] = OperandSpec::Nothing;
@@ -9936,6 +9958,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec::rsi();
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::Deref;
+ if instruction.prefixes.operand_size() {
+ instruction.mem_size = 2;
+ } else {
+ instruction.mem_size = 4;
+ }
instruction.operand_count = 2;
}
OperandCode::x87_d8 |
diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs
index ab69e51..31297f7 100644
--- a/src/long_mode/vex.rs
+++ b/src/long_mode/vex.rs
@@ -442,6 +442,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::Nothing => {
+ instruction.operand_count = 0;
Ok(())
},
VEXOperandCode::Ev_G_xmm_imm8 => {
diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs
index 88b41c9..76f3a43 100644
--- a/src/protected_mode/mod.rs
+++ b/src/protected_mode/mod.rs
@@ -7845,6 +7845,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
// lsl is weird. the full register width is written, but only the low 16 bits are used.
if instruction.operands[1] == OperandSpec::RegMMM {
instruction.modrm_mmm.bank = RegisterBank::D;
+ } else {
+ instruction.mem_size = 2;
}
instruction.operand_count = 2;
},
@@ -8013,6 +8015,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
+ if instruction.operands[1] != OperandSpec::RegMMM {
+ instruction.mem_size = 8;
+ }
}
OperandCode::ModRM_0x0f0d => {
let modrm = read_modrm(&mut bytes_iter, length)?;
@@ -8924,6 +8929,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
unreachable!("r <= 8");
}
instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
+ if instruction.operands[0] != OperandSpec::RegMMM {
+ instruction.mem_size = 2;
+ }
}
OperandCode::ModRM_0x0f01 => {
let opwidth = if instruction.prefixes.operand_size() {
@@ -9533,6 +9541,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
+ if instruction.operands[0] != OperandSpec::RegMMM {
+ instruction.mem_size = opwidth;
+ }
instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u32;
instruction.operands[1] = OperandSpec::ImmI8;
@@ -9685,12 +9696,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = OperandSpec::Deref;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operand_count = 2;
+ instruction.mem_size = 1;
}
OperandCode::Yv_DX => {
instruction.modrm_rrr = RegSpec::dx();
instruction.modrm_mmm = RegSpec::edi();
instruction.operands[0] = OperandSpec::Deref;
instruction.operands[1] = OperandSpec::RegRRR;
+ if instruction.prefixes.operand_size() {
+ instruction.mem_size = 2;
+ } else {
+ instruction.mem_size = 4;
+ }
instruction.operand_count = 2;
}
OperandCode::DX_Xb => {
@@ -9699,6 +9716,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::Deref;
instruction.operand_count = 2;
+ instruction.mem_size = 1;
}
OperandCode::AH => {
instruction.operands[0] = OperandSpec::Nothing;
@@ -9709,6 +9727,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_mmm = RegSpec::esi();
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::Deref;
+ if instruction.prefixes.operand_size() {
+ instruction.mem_size = 2;
+ } else {
+ instruction.mem_size = 4;
+ }
instruction.operand_count = 2;
}
OperandCode::x87_d8 |
diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs
index 09379cf..73d10b5 100644
--- a/src/protected_mode/vex.rs
+++ b/src/protected_mode/vex.rs
@@ -438,6 +438,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::Nothing => {
+ instruction.mem_size = 1;
Ok(())
},
VEXOperandCode::Ev_G_xmm_imm8 => {
diff --git a/src/shared/evex.in b/src/shared/evex.in
index e7e0aa1..17c9bb7 100644
--- a/src/shared/evex.in
+++ b/src/shared/evex.in
@@ -53,7 +53,7 @@ pub(crate) fn read_evex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut I
let table_idx = ((m << 2) | p) as usize;
let table = generated::TABLES[table_idx];
if table as *const [_] == &generated::DUMMY[..] as *const [_] {
- panic!("no table for m={}, p={}", m, p);
+ return Err(DecodeError::InvalidOpcode);
}
let mut index_lower = 0;
if instruction.prefixes.evex_unchecked().vex().l() {