aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-01-10 22:04:45 -0800
committeriximeow <me@iximeow.net>2020-01-12 16:10:14 -0800
commitb7b781db7a2ba94c816ff5138a713114c39d4034 (patch)
treec974ffbdd16e70677f5ee215d9010f6034571064
parent6f897e655a5f18b28b47542d76ac88d0aebcbc5d (diff)
"fix warnings"
this assists many misdecodes from being totally wrong to only slightly wrong and more clear about it (rrr-selected opcodes or W-bit-selected opcodes were accidentally decoded as the first variant of their opcode) also fixes sillier warnings all over the place, and probably a few incorrectly counted lengths
-rw-r--r--src/display.rs5
-rw-r--r--src/lib.rs152
-rw-r--r--src/vex.rs428
-rw-r--r--test/test.rs7
4 files changed, 360 insertions, 232 deletions
diff --git a/src/display.rs b/src/display.rs
index dd46055..bea5340 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -16,6 +16,7 @@ impl fmt::Display for DecodeError {
DecodeError::InvalidOperand => { write!(f, "invalid operand") },
DecodeError::InvalidPrefixes => { write!(f, "invalid prefixes") },
DecodeError::TooLong => { write!(f, "too long") },
+ DecodeError::IncompleteDecoder => { write!(f, "the decoder is incomplete") },
}
}
}
@@ -641,7 +642,6 @@ impl fmt::Display for Opcode {
&Opcode::ENCLU => write!(f, "enclu"),
&Opcode::RDPKRU => write!(f, "rdpkru"),
&Opcode::WRPKRU => write!(f, "wrpkru"),
- &Opcode::VMOVUPS => write!(f, "vmovups"),
&Opcode::VADDPD => write!(f, "vaddpd"),
&Opcode::VADDPS => write!(f, "vaddps"),
&Opcode::VADDSUBPD => write!(f, "vaddsubpd"),
@@ -1617,7 +1617,6 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode {
Opcode::MOVQ2DQ |
Opcode::MOVSHDUP |
Opcode::MOVUPS |
- Opcode::VMOVUPS |
Opcode::PEXTRW |
Opcode::PINSRW |
Opcode::MOV |
@@ -1908,7 +1907,7 @@ impl <T: std::fmt::Write> ShowContextual<u64, [Option<String>], T> for Instructi
&OperandSpec::RegMMM => {
write!(out, ", ")?;
}
- x @ _ => {
+ _ => {
write!(out, ", byte ")?;
if let Some(prefix) = self.segment_override_for_op(1) {
write!(out, "{}:", prefix)?;
diff --git a/src/lib.rs b/src/lib.rs
index 0bf93ca..f9e2d2d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1227,6 +1227,7 @@ pub enum DecodeError {
InvalidOperand,
InvalidPrefixes,
TooLong,
+ IncompleteDecoder,
}
impl yaxpeax_arch::DecodeError for DecodeError {
@@ -1235,6 +1236,7 @@ impl yaxpeax_arch::DecodeError for DecodeError {
fn bad_operand(&self) -> bool { self == &DecodeError::InvalidOperand }
}
+#[allow(non_camel_case_types)]
#[derive(Debug, Copy, Clone, PartialEq)]
enum OperandSpec {
Nothing,
@@ -2390,7 +2392,13 @@ impl InstDecoder {
return Err(DecodeError::InvalidOpcode);
}
}
- _ => {}
+ other => {
+ if !self.bmi1() {
+ if BMI1.contains(&other) {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+ }
}
Ok(())
}
@@ -2585,6 +2593,7 @@ pub struct PrefixVex {
bits: u8,
}
+#[allow(dead_code)]
impl PrefixVex {
#[inline]
fn b(&self) -> bool { (self.bits & 0x01) == 0x01 }
@@ -4404,7 +4413,7 @@ fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) ->
#[allow(non_snake_case)]
fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
- let modbits = (modrm >> 6);
+ let modbits = modrm >> 6;
let addr_width = if instr.prefixes.address_size() { RegisterBank::D } else { RegisterBank::Q };
let sibbyte = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?;
*length += 1;
@@ -4460,7 +4469,7 @@ fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, m
}
}
} else {
- instr.modrm_mmm = RegSpec::from_parts((sibbyte & 7), instr.prefixes.rex().b(), addr_width);
+ instr.modrm_mmm = RegSpec::from_parts(sibbyte & 7, instr.prefixes.rex().b(), addr_width);
let disp = if modbits == 0b00 {
0
@@ -4496,14 +4505,11 @@ fn read_sib<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, m
#[allow(non_snake_case)]
fn read_M<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> {
- let modbits = (modrm >> 6);
+ let modbits = modrm >> 6;
let addr_width = if instr.prefixes.address_size() { RegisterBank::D } else { RegisterBank::Q };
let mmm = modrm & 7;
let op_spec = if mmm == 4 {
return read_sib(bytes_iter, instr, modrm, length);
-// let (ss, index, base) = octets_of(sibbyte);
-
-// println!("scale: {:b}, index: {:b}, base: {:b}", ss, index, base);
} else if mmm == 5 && modbits == 0b00 {
*length += 4;
let disp = read_num(bytes_iter, 4)? as i32;
@@ -4696,7 +4702,6 @@ pub fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T
}
},
None => {
-// unsafe { unreachable_unchecked(); }
return Err(DecodeError::ExhaustedInput);
}
}
@@ -4718,7 +4723,6 @@ pub fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T
Ok(())
}
pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, length: &mut u8) -> Result<(), DecodeError> {
- let mut bytes_read = 0;
if (operand_code as u8) & 0x40 == 0x40 {
instruction.operands[0] = OperandSpec::RegRRR;
}
@@ -4744,8 +4748,8 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.modrm_rrr =
RegSpec::gp_from_parts(reg, instruction.prefixes.rex().b(), 1, instruction.prefixes.rex().present());
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, 1)?;
- bytes_read = 1;
+ read_imm_unsigned(&mut bytes_iter, 1, length)?;
+ *length += 1;
instruction.operands[1] = OperandSpec::ImmU8;
instruction.operand_count = 2;
} else {
@@ -4762,7 +4766,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec::from_parts(reg, instruction.prefixes.rex().b(), bank);
instruction.imm =
read_imm_ivq(&mut bytes_iter, opwidth, length)?;
- bytes_read = opwidth;
+ *length += opwidth;
instruction.operands[1] = match opwidth {
1 => OperandSpec::ImmI8,
2 => OperandSpec::ImmI16,
@@ -4798,7 +4802,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
bank = RegisterBank::B;
}
};
- modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ modrm = read_modrm(&mut bytes_iter, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), bank);
@@ -4893,7 +4897,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 };
let imm = read_num(&mut bytes_iter, addr_width)?;
*length += addr_width;
- bytes_read = addr_width;
instruction.modrm_rrr =
RegSpec::gp_from_parts(0, instruction.prefixes.rex().b(), opwidth, instruction.prefixes.rex().present());
instruction.disp = imm;
@@ -4920,7 +4923,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
let addr_width = if instruction.prefixes.address_size() { 2 } else { 4 };
let imm = read_num(&mut bytes_iter, addr_width)?;
*length += addr_width;
- bytes_read = addr_width;
instruction.disp = imm;
instruction.operands[0] = if instruction.prefixes.address_size() {
OperandSpec::DispU32
@@ -4932,12 +4934,12 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operand_count = 2;
}
- op @ OperandCode::ModRM_0x80_Eb_Ib |
- op @ OperandCode::ModRM_0x81_Ev_Ivs => {
+ _op @ OperandCode::ModRM_0x80_Eb_Ib |
+ _op @ OperandCode::ModRM_0x81_Ev_Ivs => {
instruction.operands[0] = mem_oper;
let numwidth = if opwidth == 8 { 4 } else { opwidth };
instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
- bytes_read = numwidth;
+ *length = numwidth;
instruction.opcode = base_opcode_map((modrm >> 3) & 7);
instruction.operands[1] = match opwidth {
1 => OperandSpec::ImmI8,
@@ -4948,8 +4950,8 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
};
instruction.operand_count = 2;
},
- op @ OperandCode::ModRM_0xc6_Eb_Ib |
- op @ OperandCode::ModRM_0xc7_Ev_Iv => {
+ _op @ OperandCode::ModRM_0xc6_Eb_Ib |
+ _op @ OperandCode::ModRM_0xc7_Ev_Iv => {
if (modrm & 0b00111000) != 0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand); // Err("Invalid modr/m for opcode 0xc7".to_string());
@@ -4959,7 +4961,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::MOV;
let numwidth = if opwidth == 8 { 4 } else { opwidth };
instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
- bytes_read = numwidth;
instruction.operands[1] = match opwidth {
1 => OperandSpec::ImmI8,
2 => OperandSpec::ImmI16,
@@ -4996,16 +4997,15 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
instruction.operand_count = 2;
},
- op @ OperandCode::ModRM_0xf6 |
- op @ OperandCode::ModRM_0xf7 => {
+ _op @ OperandCode::ModRM_0xf6 |
+ _op @ OperandCode::ModRM_0xf7 => {
instruction.operands[0] = mem_oper;
instruction.operand_count = 1;
- match ((modrm >> 3) & 7) {
+ match (modrm >> 3) & 7 {
0 | 1 => {
instruction.opcode = Opcode::TEST;
let numwidth = if opwidth == 8 { 4 } else { opwidth };
instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
- bytes_read = numwidth;
instruction.operands[1] = match opwidth {
1 => OperandSpec::ImmI8,
2 => OperandSpec::ImmI16,
@@ -5069,8 +5069,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::Gv_Eb => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
- bytes_read = 1;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 1, length)?;
instruction.modrm_rrr =
@@ -5079,8 +5078,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
},
OperandCode::Gv_Ew => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
- bytes_read = 1;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;
instruction.modrm_rrr =
@@ -5089,8 +5087,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
},
OperandCode::Gdq_Ed => {
let opwidth = 8;
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
- bytes_read = 1;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4 /* opwidth */, length)?;
@@ -5109,8 +5106,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 2;
},
OperandCode::E_G_xmm => {
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
- bytes_read = 1;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
instruction.operands[0] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
@@ -5156,8 +5152,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
},
OperandCode::G_E_mm_Ib => {
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
- bytes_read = 1;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
@@ -5170,8 +5165,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 3;
},
OperandCode::G_mm_Ew_Ib => {
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
- bytes_read = 1;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?;
@@ -5192,7 +5186,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec::al();
instruction.imm =
read_imm_signed(&mut bytes_iter, 1, length)? as u64;
- bytes_read = 1;
instruction.operands[1] = OperandSpec::ImmI8;
instruction.operand_count = 2;
}
@@ -5203,7 +5196,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
RegSpec::gp_from_parts(0, false, opwidth, false);
instruction.imm =
read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;
- bytes_read = numwidth;
instruction.operands[1] = match opwidth {
2 => OperandSpec::ImmI16,
4 => OperandSpec::ImmI32,
@@ -5215,8 +5207,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
OperandCode::Ivs => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vd, instruction.prefixes);
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, opwidth)?;
- bytes_read = opwidth;
+ read_imm_unsigned(&mut bytes_iter, opwidth, length)?;
instruction.operands[0] = match opwidth {
2 => OperandSpec::ImmI16,
4 => OperandSpec::ImmI32,
@@ -5229,7 +5220,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = mem_oper;
instruction.opcode = base_opcode_map((modrm >> 3) & 7);
instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
- bytes_read = 2;
instruction.operands[1] = OperandSpec::ImmI8;
instruction.operand_count = 2;
},
@@ -5264,7 +5254,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 3;
}
OperandCode::Ev_Gv_Ib => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.imm =
@@ -5273,7 +5262,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operand_count = 3;
}
OperandCode::Ev_Gv_CL => {
- let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes);
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operands[2] = OperandSpec::CL;
@@ -5291,12 +5279,11 @@ pub fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
Ok(())
}
fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, length: &mut u8) -> Result<(), DecodeError> {
- let mut bytes_read = 0;
match operand_code {
OperandCode::ModRM_0x0f71 => {
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
if modrm & 0xc0 != 0xc0 {
return Err(DecodeError::InvalidOperand);
}
@@ -5325,7 +5312,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
OperandCode::ModRM_0x0f72 => {
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
if modrm & 0xc0 != 0xc0 {
return Err(DecodeError::InvalidOperand);
}
@@ -5354,7 +5341,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
OperandCode::ModRM_0x0f73 => {
instruction.operand_count = 2;
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
if modrm & 0xc0 != 0xc0 {
return Err(DecodeError::InvalidOperand);
}
@@ -5391,7 +5378,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
};
// all these SO FAR are G_E_xmm
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
@@ -5407,7 +5394,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::AESKEYGENASSIST;
// read operands right here right now
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X);
@@ -5415,7 +5402,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?;
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, 1)?;
+ read_imm_unsigned(&mut bytes_iter, 1, length)?;
instruction.operands[2] = OperandSpec::ImmU8;
instruction.operand_count = 3;
}
@@ -5607,8 +5594,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::Ew_Sw => {
let opwidth = 2;
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
- bytes_read = 1;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
// check r
if ((modrm >> 3) & 7) > 5 {
@@ -5631,8 +5617,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
},
OperandCode::Sw_Ew => {
- let opwidth = 2;
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
// check r
if ((modrm >> 3) & 7) > 5 {
@@ -5674,14 +5659,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::Iw => {
instruction.imm =
- read_imm_unsigned(&mut bytes_iter, 2)?;
- bytes_read = 2;
+ read_imm_unsigned(&mut bytes_iter, 2, length)?;
instruction.operands[0] = OperandSpec::ImmU16;
instruction.operand_count = 1;
}
OperandCode::ModRM_0x0f00 => {
instruction.operand_count = 1;
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
let r = (modrm >> 3) & 7;
if r == 0 {
instruction.opcode = Opcode::SLDT;
@@ -5710,7 +5694,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::ModRM_0x0f01 => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
let r = (modrm >> 3) & 7;
if r == 0 {
let mod_bits = modrm >> 6;
@@ -5810,7 +5794,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
} else if r == 3 {
let mod_bits = modrm >> 6;
- let m = modrm & 7;
if mod_bits == 0b11 {
instruction.opcode = Opcode::Invalid;
instruction.operand_count = 0;
@@ -5871,7 +5854,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
}
OperandCode::ModRM_0x0fae => {
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
let r = (modrm >> 3) & 7;
let mod_bits = modrm >> 6;
@@ -5936,7 +5919,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
}
OperandCode::ModRM_0x0fba => {
let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes);
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
let r = (modrm >> 3) & 7;
match r {
0 | 1 | 2 | 3 => {
@@ -5963,7 +5946,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?;
instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;
- bytes_read += 2;
instruction.operands[1] = OperandSpec::ImmI8;
instruction.operand_count = 2;
}
@@ -5986,7 +5968,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
_ => unsafe { unreachable_unchecked() }
};
- let modrm = read_modrm(&mut bytes_iter, instruction, length)?;
+ let modrm = read_modrm(&mut bytes_iter, length)?;
let mut m = modrm & 7;
let mut r = (modrm >> 3) & 7;
if instruction.prefixes.rex().r() {
@@ -6023,7 +6005,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter
instruction.opcode = Opcode::Invalid;
// return Err(()); // Err(format!("unsupported operand code: {:?}", operand_code));
return Err(DecodeError::InvalidOperand);
- // unsafe { unreachable_unchecked(); }
}
};
Ok(())
@@ -6036,34 +6017,9 @@ pub fn decode_one<'b, T: IntoIterator<Item=u8>>(decoder: &InstDecoder, bytes: T,
OperandSpec::Nothing,
OperandSpec::Nothing,
];
- let mut bytes_iter = bytes.into_iter();
+ let bytes_iter = bytes.into_iter();
read_instr(decoder, bytes_iter, instr)
}
-/*
- match read_opcode(&mut bytes_iter, instr) {
- Some(operand_code) => {
- match read_operands(&mut bytes_iter, instr, operand_code) {
- Ok(()) => {
- Some(())
- },
- Err(_reason) => {
-// panic!("Decode error on operand: {:?}", reason);
- // println!("Invalid instruction: {}", reason);
-// return Instruction::invalid()
- None
- }
- }
- }
-// Err(_reason) => {
- None => {
-// panic!("Decode error on opcode: {:?}", reason);
- // println!("Invalid instruction: {}", reason);
-// return Instruction::invalid()
- None
- }
- }
-}
-*/
#[inline]
fn read_num<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u64, DecodeError> {
@@ -6116,13 +6072,11 @@ fn read_imm_signed<T: Iterator<Item=u8>>(bytes: &mut T, num_width: u8, length: &
}
#[inline]
-fn read_imm_unsigned<T: Iterator<Item=u8>>(bytes: &mut T, width: u8) -> Result<u64, DecodeError> {
- read_num(bytes, width)
-}
-
-#[inline]
-fn octets_of(byte: u8) -> (u8, u8, u8) {
- (byte >> 6 & 0b11, (byte >> 3) & 0b111, byte & 0b111)
+fn read_imm_unsigned<T: Iterator<Item=u8>>(bytes: &mut T, width: u8, length: &mut u8) -> Result<u64, DecodeError> {
+ read_num(bytes, width).map(|res| {
+ *length += width;
+ res
+ })
}
#[inline]
@@ -6154,6 +6108,6 @@ fn imm_width_from_prefixes_64(interpretation: SizeCode, prefixes: Prefixes) -> u
}
#[inline]
-fn read_modrm<T: Iterator<Item=u8>>(bytes_iter: &mut T, inst: &mut Instruction, length: &mut u8) -> Result<u8, DecodeError> {
+fn read_modrm<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8) -> Result<u8, DecodeError> {
bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })
}
diff --git a/src/vex.rs b/src/vex.rs
index b59f7d7..cc024bd 100644
--- a/src/vex.rs
+++ b/src/vex.rs
@@ -25,9 +25,16 @@ enum VEXOpcodePrefix {
PrefixF2,
}
+#[allow(non_camel_case_types)]
#[derive(Debug)]
enum VEXOperandCode {
Nothing,
+ VPS_71,
+ VPS_71_L,
+ VPS_72,
+ VPS_72_L,
+ VPS_73,
+ VPS_73_L,
VMOVSS_10,
VMOVSD_10,
VMOVSD_11,
@@ -107,7 +114,7 @@ pub(crate) fn three_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &
};
instruction.prefixes.vex_from_c4(vex_byte_one, vex_byte_two);
- read_vex_instruction(m, bytes, instruction, &mut length, p);
+ read_vex_instruction(m, bytes, instruction, &mut length, p)?;
instruction.length = length;
Ok(())
}
@@ -128,7 +135,7 @@ pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mu
};
instruction.prefixes.vex_from_c5(vex_byte);
- read_vex_instruction(VEXOpcodeMap::Map0F, bytes, instruction, &mut length, p);
+ read_vex_instruction(VEXOpcodeMap::Map0F, bytes, instruction, &mut length, p)?;
instruction.length = length;
Ok(())
}
@@ -136,9 +143,201 @@ pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mu
fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Instruction, length: &mut u8, operand_code: VEXOperandCode) -> Result<(), DecodeError> {
println!("operand code: {:?}", operand_code);
match operand_code {
+ VEXOperandCode::VPS_71 => {
+ let modrm = read_modrm(bytes, length)?;
+ match (modrm >> 3) & 0b111 {
+ 0b010 => {
+ instruction.opcode = Opcode::VPSRLW;
+ }
+ 0b100 => {
+ instruction.opcode = Opcode::VPSRAW;
+ }
+ 0b110 => {
+ instruction.opcode = Opcode::VPSLLW;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+ /*
+ 0x71 => (Opcode::VPSLLW, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ 0x71 => (Opcode::VPSRAW, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ 0x71 => (Opcode::VPSRLW, if L {
+ VEXOperandCode::G_V_E_ymm
+ } else {
+ VEXOperandCode::G_V_E_ymm
+ }),
+ */
+ Err(DecodeError::IncompleteDecoder) // :)
+ }
+ VEXOperandCode::VPS_71_L => {
+ let modrm = read_modrm(bytes, length)?;
+ match (modrm >> 3) & 0b111 {
+ 0b010 => {
+ instruction.opcode = Opcode::VPSRLW;
+ }
+ 0b100 => {
+ instruction.opcode = Opcode::VPSRAW;
+ }
+ 0b110 => {
+ instruction.opcode = Opcode::VPSLLW;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+ /*
+ 0x71 => (Opcode::VPSLLW, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ 0x71 => (Opcode::VPSRAW, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ 0x71 => (Opcode::VPSRLW, if L {
+ VEXOperandCode::G_V_E_ymm
+ } else {
+ VEXOperandCode::G_V_E_ymm
+ }),
+ */
+ Err(DecodeError::IncompleteDecoder) // :)
+ }
+ VEXOperandCode::VPS_72 => {
+ let modrm = read_modrm(bytes, length)?;
+ match (modrm >> 3) & 0b111 {
+ 0b010 => {
+ instruction.opcode = Opcode::VPSRLD;
+ }
+ 0b100 => {
+ instruction.opcode = Opcode::VPSRAD;
+ }
+ 0b110 => {
+ instruction.opcode = Opcode::VPSLLD;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+ /*
+ 0x72 => (Opcode::VPSLLD, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ 0x72 => (Opcode::VPSRAD, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ 0x72 => (Opcode::VPSRLD, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ */
+ Err(DecodeError::IncompleteDecoder) // :)
+ }
+ VEXOperandCode::VPS_72_L => {
+ let modrm = read_modrm(bytes, length)?;
+ match (modrm >> 3) & 0b111 {
+ 0b010 => {
+ instruction.opcode = Opcode::VPSRLD;
+ }
+ 0b100 => {
+ instruction.opcode = Opcode::VPSRAD;
+ }
+ 0b110 => {
+ instruction.opcode = Opcode::VPSLLD;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+ /*
+ 0x72 => (Opcode::VPSLLD, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ 0x72 => (Opcode::VPSRAD, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ 0x72 => (Opcode::VPSRLD, if L {
+ VEXOperandCode::G_E_ymm_imm8
+ } else {
+ VEXOperandCode::G_E_ymm_imm8
+ }),
+ */
+ Err(DecodeError::IncompleteDecoder) // :)
+ }
+ VEXOperandCode::VPS_73 => {
+ let modrm = read_modrm(bytes, length)?;
+ match (modrm >> 3) & 0b111 {
+ 0b010 => {
+ instruction.opcode = Opcode::VPSRLQ;
+ }
+ 0b011 => {
+ instruction.opcode = Opcode::VPSRLDQ;
+ }
+ 0b110 => {
+ instruction.opcode = Opcode::VPSLLQ;
+ }
+ 0b111 => {
+ instruction.opcode = Opcode::VPSLLDQ;
+ }
+ _ => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ }
+ // VEXOperandCode::G_E_xmm_imm8 ? this is reg1, reg2, imm8, but r is used for
+ // picking the opcode. is one of these actually the vex reg?
+ Err(DecodeError::IncompleteDecoder) // :)
+ }
+ VEXOperandCode::VPS_73_L => {
+ let modrm = read_modrm(bytes, length)?;
+ match (modrm >> 3) & 0b111 {
+ 0b000 |
+ 0b001 |
+ 0b100 |
+ 0b101 => {
+ return Err(DecodeError::InvalidOpcode);
+ }
+ 0b010 => {
+ instruction.opcode = Opcode::VPSRLQ;
+ }
+ 0b011 => {
+ instruction.opcode = Opcode::VPSRLDQ;
+ }
+ 0b110 => {
+ instruction.opcode = Opcode::VPSLLQ;
+ }
+ 0b111 => {
+ instruction.opcode = Opcode::VPSLLDQ;
+ }
+ _ => {
+ unreachable!("r is only three bits");
+ }
+ }
+ // VEXOperandCode::G_E_ymm_imm8 ? this is reg1, reg2, imm8, but r is used for
+ // picking the opcode. is one of these actually the vex reg?
+ Err(DecodeError::IncompleteDecoder) // :)
+ }
VEXOperandCode::VMOVSS_10 |
VEXOperandCode::VMOVSD_10 => {
- let modrm = read_modrm(bytes, instruction, length)?;
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
@@ -156,7 +355,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
},
VEXOperandCode::VMOVSS_11 |
VEXOperandCode::VMOVSD_11 => {
- let modrm = read_modrm(bytes, instruction, length)?;
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
@@ -180,26 +379,26 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, instruction, length)?;
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
let mem_oper = read_E(bytes, instruction, modrm, 8, length)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operands[2] = OperandSpec::ImmU8;
- instruction.imm = read_imm_unsigned(bytes, 1)?;
+ instruction.imm = read_imm_unsigned(bytes, 1, length)?;
Ok(())
},
- op @ VEXOperandCode::E_G_xmm |
- op @ VEXOperandCode::U_G_xmm |
- op @ VEXOperandCode::M_G_xmm |
- op @ VEXOperandCode::E_G_xmm_imm8 |
- op @ VEXOperandCode::U_G_xmm_imm8 => {
+ _op @ VEXOperandCode::E_G_xmm |
+ _op @ VEXOperandCode::U_G_xmm |
+ _op @ VEXOperandCode::M_G_xmm |
+ _op @ VEXOperandCode::E_G_xmm_imm8 |
+ _op @ VEXOperandCode::U_G_xmm_imm8 => {
if instruction.vex_reg.num != 0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, instruction, length)?;
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
@@ -208,15 +407,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
- op @ VEXOperandCode::G_M_xmm |
- op @ VEXOperandCode::G_U_xmm |
- op @ VEXOperandCode::G_E_xmm |
- op @ VEXOperandCode::G_E_xmm_imm8 => {
+ _op @ VEXOperandCode::G_M_xmm |
+ _op @ VEXOperandCode::G_U_xmm |
+ _op @ VEXOperandCode::G_E_xmm |
+ _op @ VEXOperandCode::G_E_xmm_imm8 => {
if instruction.vex_reg.num != 0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, instruction, length)?;
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
@@ -225,14 +424,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
- op @ VEXOperandCode::E_G_ymm |
- op @ VEXOperandCode::U_G_ymm |
- op @ VEXOperandCode::M_G_ymm => {
+ _op @ VEXOperandCode::E_G_ymm |
+ _op @ VEXOperandCode::U_G_ymm |
+ _op @ VEXOperandCode::M_G_ymm => {
if instruction.vex_reg.num != 0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, instruction, length)?;
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
@@ -241,14 +440,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
- op @ VEXOperandCode::G_M_ymm |
- op @ VEXOperandCode::G_U_ymm |
- op @ VEXOperandCode::G_E_ymm => {
+ _op @ VEXOperandCode::G_M_ymm |
+ _op @ VEXOperandCode::G_U_ymm |
+ _op @ VEXOperandCode::G_E_ymm => {
if instruction.vex_reg.num != 0 {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOperand);
}
- let modrm = read_modrm(bytes, instruction, length)?;
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
@@ -256,9 +455,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[1] = mem_oper;
Ok(())
}
- op @ VEXOperandCode::G_V_E_ymm |
- op @ VEXOperandCode::G_V_M_ymm => {
- let modrm = read_modrm(bytes, instruction, length)?;
+ _op @ VEXOperandCode::G_V_E_ymm |
+ _op @ VEXOperandCode::G_V_M_ymm => {
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
@@ -268,9 +467,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[2] = mem_oper;
Ok(())
}
- op @ VEXOperandCode::E_V_G_ymm |
- op @ VEXOperandCode::M_V_G_ymm => {
- let modrm = read_modrm(bytes, instruction, length)?;
+ _op @ VEXOperandCode::E_V_G_ymm |
+ _op @ VEXOperandCode::M_V_G_ymm => {
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
instruction.vex_reg.bank = RegisterBank::Y;
@@ -280,9 +479,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
instruction.operands[2] = OperandSpec::RegRRR;
Ok(())
}
- op @ VEXOperandCode::G_V_M_xmm |
- op @ VEXOperandCode::G_V_E_xmm => {
- let modrm = read_modrm(bytes, instruction, length)?;
+ _op @ VEXOperandCode::G_V_M_xmm |
+ _op @ VEXOperandCode::G_V_E_xmm => {
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
@@ -292,9 +491,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
- op @ VEXOperandCode::E_V_G_xmm |
- op @ VEXOperandCode::M_V_G_xmm => {
- let modrm = read_modrm(bytes, instruction, length)?;
+ _op @ VEXOperandCode::E_V_G_xmm |
+ _op @ VEXOperandCode::M_V_G_xmm => {
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
@@ -305,7 +504,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
VEXOperandCode::G_Ex_V_xmm => {
- let modrm = read_modrm(bytes, instruction, length)?;
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);
let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;
@@ -316,7 +515,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
Ok(())
}
VEXOperandCode::G_Ey_V_ymm => {
- let modrm = read_modrm(bytes, instruction, length)?;
+ let modrm = read_modrm(bytes, length)?;
instruction.modrm_rrr =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);
let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?;
@@ -329,7 +528,6 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
}
VEXOperandCode::E_xmm_G_ymm_imm8 |
- VEXOperandCode::Ev_G_xmm_imm8 |
VEXOperandCode::G_E_ymm_imm8 |
VEXOperandCode::G_xmm_E_xmm |
VEXOperandCode::G_xmm_E_ymm |
@@ -347,7 +545,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
VEXOperandCode::G_xmm_Eq |
VEXOperandCode::G_V_ymm_E_xmm |
VEXOperandCode::G_V_xmm_Ew_imm8 => {
- Ok(()) // :)
+ Err(DecodeError::IncompleteDecoder) // :)
}
}
@@ -355,6 +553,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst
fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &mut T, instruction: &mut Instruction, length: &mut u8, p: VEXOpcodePrefix) -> Result<(), DecodeError> {
let opc = bytes.next().ok_or(DecodeError::ExhaustedInput)?;
+
+ // the name of this bit is `L` in the documentation, so use the same name here.
+ #[allow(non_snake_case)]
let L = instruction.prefixes.vex().l();
println!("reading vex instruction from opcode prefix {:?}, L: {}, opc: {:#x}, map:{:?}", p, L, opc, opcode_map);
@@ -710,55 +911,20 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &
} else {
VEXOperandCode::G_E_xmm_imm8
}),
- 0x71 => (Opcode::VPSLLW, if L {
- VEXOperandCode::G_E_ymm_imm8
- } else {
- VEXOperandCode::G_E_ymm_imm8
- }),
- 0x71 => (Opcode::VPSRAW, if L {
- VEXOperandCode::G_E_ymm_imm8
- } else {
- VEXOperandCode::G_E_ymm_imm8
- }),
- 0x71 => (Opcode::VPSRLW, if L {
- VEXOperandCode::G_V_E_ymm
- } else {
- VEXOperandCode::G_V_E_ymm
- }),
- 0x72 => (Opcode::VPSLLD, if L {
- VEXOperandCode::G_E_ymm_imm8
- } else {
- VEXOperandCode::G_E_ymm_imm8
- }),
- 0x72 => (Opcode::VPSRAD, if L {
- VEXOperandCode::G_E_ymm_imm8
- } else {
- VEXOperandCode::G_E_ymm_imm8
- }),
- 0x72 => (Opcode::VPSRLD, if L {
- VEXOperandCode::G_E_ymm_imm8
- } else {
- VEXOperandCode::G_E_ymm_imm8
- }),
- 0x73 => (Opcode::VPSLLDQ, if L {
- VEXOperandCode::G_E_ymm_imm8
- } else {
- VEXOperandCode::G_E_ymm_imm8
- }),
- 0x73 => (Opcode::VPSLLQ, if L {
- VEXOperandCode::G_E_ymm_imm8
+ 0x71 => (Opcode::Invalid, if L {
+ VEXOperandCode::VPS_71_L
} else {
- VEXOperandCode::G_E_ymm_imm8
+ VEXOperandCode::VPS_71
}),
- 0x73 => (Opcode::VPSRLDQ, if L {
- VEXOperandCode::G_E_ymm_imm8
+ 0x72 => (Opcode::Invalid, if L {
+ VEXOperandCode::VPS_72_L
} else {
- VEXOperandCode::G_E_ymm_imm8
+ VEXOperandCode::VPS_72
}),
- 0x73 => (Opcode::VPSRLQ, if L {
- VEXOperandCode::G_E_ymm_imm8
+ 0x73 => (Opcode::Invalid, if L {
+ VEXOperandCode::VPS_73_L
} else {
- VEXOperandCode::G_E_ymm_imm8
+ VEXOperandCode::VPS_73
}),
0x74 => (Opcode::VPCMPEQB, if L {
VEXOperandCode::G_V_E_ymm
@@ -785,18 +951,21 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &
} else {
VEXOperandCode::G_V_E_xmm
}),
- 0x7E => (Opcode::VMOVD, if L {
- instruction.opcode = Opcode::Invalid;
- return Err(DecodeError::InvalidOpcode);
- } else {
- VEXOperandCode::Ed_G_xmm
- }),
- 0x7E => (Opcode::VMOVQ, if L {
- instruction.opcode = Opcode::Invalid;
- return Err(DecodeError::InvalidOpcode);
+ 0x7E => if instruction.prefixes.vex().w() {
+ (Opcode::VMOVQ, if L {
+ instruction.opcode = Opcode::Invalid;
+ return Err(DecodeError::InvalidOpcode);
+ } else {
+ VEXOperandCode::Eq_G_xmm
+ })
} else {
- VEXOperandCode::Eq_G_xmm
- }),
+ (Opcode::VMOVD, if L {
+ instruction.opcode = Opcode::Invalid;
+ return Err(DecodeError::InvalidOpcode);
+ } else {
+ VEXOperandCode::Ed_G_xmm
+ })
+ }
0x7F => (Opcode::VMOVDQA, if L {
VEXOperandCode::E_G_ymm
} else {
@@ -1438,31 +1607,37 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &
} else {
VEXOperandCode::G_E_xmm
}),
- 0x45 => (Opcode::VPSRLVD, if L {
- VEXOperandCode::G_V_E_ymm
- } else {
- VEXOperandCode::G_V_E_xmm
- }),
- 0x45 => (Opcode::VPSRLVQ, if L {
- VEXOperandCode::G_V_E_ymm
+ 0x45 => if instruction.prefixes.vex().w() {
+ (Opcode::VPSRLVQ, if L {
+ VEXOperandCode::G_V_E_ymm
+ } else {
+ VEXOperandCode::G_V_E_xmm
+ })
} else {
- VEXOperandCode::G_V_E_xmm
- }),
+ (Opcode::VPSRLVD, if L {
+ VEXOperandCode::G_V_E_ymm
+ } else {
+ VEXOperandCode::G_V_E_xmm
+ })
+ },
0x46 => (Opcode::VPSRAVD, if L {
VEXOperandCode::G_V_E_ymm
} else {
VEXOperandCode::G_V_E_xmm
}),
- 0x47 => (Opcode::VPSLLVD, if L {
- VEXOperandCode::G_V_E_ymm
- } else {
- VEXOperandCode::G_V_E_xmm
- }),
- 0x47 => (Opcode::VPSLLVQ, if L {
- VEXOperandCode::G_V_E_ymm
+ 0x47 => if instruction.prefixes.vex().w() {
+ (Opcode::VPSLLVQ, if L {
+ VEXOperandCode::G_V_E_ymm
+ } else {
+ VEXOperandCode::G_V_E_xmm
+ })
} else {
- VEXOperandCode::G_V_E_xmm
- }),
+ (Opcode::VPSLLVD, if L {
+ VEXOperandCode::G_V_E_ymm
+ } else {
+ VEXOperandCode::G_V_E_xmm
+ })
+ },
0x58 => (Opcode::VPBROADCASTD, if L {
VEXOperandCode::G_E_ymm
} else {
@@ -2080,18 +2255,21 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &
} else {
VEXOperandCode::G_V_E_xmm_imm8
}),
- 0x22 => (Opcode::VPINSRD, if L {
- instruction.opcode = Opcode::Invalid;
- return Err(DecodeError::InvalidOpcode);
- } else {
- VEXOperandCode::G_V_E_xmm_imm8
- }),
- 0x22 => (Opcode::VPINSRQ, if L {
- instruction.opcode = Opcode::Invalid;
- return Err(DecodeError::InvalidOpcode);
+ 0x22 => if instruction.prefixes.vex().w() {
+ (Opcode::VPINSRQ, if L {
+ instruction.opcode = Opcode::Invalid;
+ return Err(DecodeError::InvalidOpcode);
+ } else {
+ VEXOperandCode::G_V_E_xmm_imm8
+ })
} else {
- VEXOperandCode::G_V_E_xmm_imm8
- }),
+ (Opcode::VPINSRD, if L {
+ instruction.opcode = Opcode::Invalid;
+ return Err(DecodeError::InvalidOpcode);
+ } else {
+ VEXOperandCode::G_V_E_xmm_imm8
+ })
+ },
0x38 => (Opcode::VINSERTI128, if L {
instruction.opcode = Opcode::Invalid;
return Err(DecodeError::InvalidOpcode);
diff --git a/test/test.rs b/test/test.rs
index 96f77be..7726bb7 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -6,6 +6,7 @@ use std::fmt::Write;
use yaxpeax_arch::Decoder;
use yaxpeax_x86::{Instruction, InstDecoder, decode_one};
+#[allow(dead_code)]
fn decode(bytes: &[u8]) -> Option<Instruction> {
let mut instr = Instruction::invalid();
match decode_one(&InstDecoder::default(), bytes.iter().map(|x| *x).take(16).collect::<Vec<u8>>(), &mut instr) {
@@ -14,6 +15,7 @@ fn decode(bytes: &[u8]) -> Option<Instruction> {
}
}
+#[allow(dead_code)]
fn decode_as(decoder: &InstDecoder, bytes: &[u8]) -> Option<Instruction> {
let mut instr = Instruction::invalid();
match decode_one(decoder, bytes.iter().map(|x| *x).take(16).collect::<Vec<u8>>(), &mut instr) {
@@ -105,11 +107,6 @@ fn test_aesni() {
test_invalid_under(&InstDecoder::minimal(), bytes);
}
- fn test_instr_invalid(bytes: &[u8]) {
- test_invalid_under(&InstDecoder::minimal().with_aesni(), bytes);
- test_invalid_under(&InstDecoder::default(), bytes);
- }
-
test_instr(&[0x66, 0x0f, 0x38, 0xdb, 0x0f], "aesimc xmm1, [rdi]");
test_instr(&[0x66, 0x4f, 0x0f, 0x38, 0xdb, 0xcf], "aesimc xmm9, xmm15");