aboutsummaryrefslogtreecommitdiff
path: root/src/long_mode/vex.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/long_mode/vex.rs')
-rw-r--r--src/long_mode/vex.rs269
1 files changed, 214 insertions, 55 deletions
diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs
index 893d624..e19621d 100644
--- a/src/long_mode/vex.rs
+++ b/src/long_mode/vex.rs
@@ -7,6 +7,7 @@ use crate::long_mode::DecodeError;
use crate::long_mode::FieldDescription;
use crate::long_mode::RegSpec;
use crate::long_mode::RegisterBank;
+use crate::long_mode::InnerDescription;
use crate::long_mode::Instruction;
use crate::long_mode::Opcode;
use crate::long_mode::read_modrm;
@@ -106,6 +107,7 @@ pub(crate) fn three_byte_vex<
T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>,
S: DescriptionSink<FieldDescription>,
>(words: &mut T, instruction: &mut Instruction, sink: &mut S) -> Result<(), DecodeError> {
+ let vex_start = words.offset() as u32 * 8;
let vex_byte_one = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
let vex_byte_two = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
let p = vex_byte_two & 0x03;
@@ -116,7 +118,29 @@ pub(crate) fn three_byte_vex<
0x03 => VEXOpcodePrefix::PrefixF2,
_ => { unreachable!("p is two bits"); }
};
+ sink.record(
+ vex_start + 8,
+ vex_start + 9,
+ InnerDescription::Misc(match p {
+ VEXOpcodePrefix::None => "vex.p indicates no opcode prefix",
+ VEXOpcodePrefix::Prefix66 => "vex.p indicates opcode prefix 66",
+ VEXOpcodePrefix::PrefixF3 => "vex.p indicates opcode prefix f3",
+ VEXOpcodePrefix::PrefixF2 => "vex.p indicates opcode prefix f2",
+ })
+ .with_id(vex_start)
+ );
let m = vex_byte_one & 0b11111;
+ sink.record(
+ vex_start + 0,
+ vex_start + 4,
+ InnerDescription::Misc(match m {
+ 0b00001 => "vex.mmmmm indicates opcode escape of 0f",
+ 0b00010 => "vex.mmmmm indicates opcode escape of 0f38",
+ 0b00011 => "vex.mmmmm indicates opcode escape of 0f3a",
+ _ => "vex.mmmmm indicates illegal opcode escape and is invalid",
+ })
+ .with_id(vex_start)
+ );
let m = match m {
0b00001 => VEXOpcodeMap::Map0F,
0b00010 => VEXOpcodeMap::Map0F38,
@@ -130,15 +154,81 @@ pub(crate) fn three_byte_vex<
bank: RegisterBank::X,
num: ((vex_byte_two >> 3) & 0b1111) ^ 0b1111,
};
+ sink.record(
+ vex_start + 11,
+ vex_start + 14,
+ InnerDescription::RegisterNumber("vvvv", instruction.regs[3].num, instruction.regs[3])
+ .with_id(vex_start + 2)
+ );
+
+ sink.record(
+ vex_start + 7,
+ vex_start + 7,
+ InnerDescription::Misc(if vex_byte_one & 0b10000000 == 0 {
+ "vex.r extends extends rrr by 0b1000"
+ } else {
+ "vex.r does not alter rrr"
+ })
+ .with_id(vex_start + 1)
+ );
+ sink.record(
+ vex_start + 6,
+ vex_start + 6,
+ InnerDescription::Misc(if vex_byte_one & 0b01000000 == 0 {
+ "vex.x extends extends index reg (if used) by 0b1000"
+ } else {
+ "vex.x does not alter index reg"
+ })
+ .with_id(vex_start + 1)
+ );
+ sink.record(
+ vex_start + 5,
+ vex_start + 5,
+ InnerDescription::Misc(if vex_byte_one & 0b00100000 == 0 {
+ "vex.b extends extends base reg (if used) by 0b1000"
+ } else {
+ "vex.b does not alter base reg"
+ })
+ .with_id(vex_start + 1)
+ );
+ sink.record(
+ vex_start + 10,
+ vex_start + 10,
+ InnerDescription::Misc(if vex_byte_two & 0b100 == 0 {
+ "vex.l selects 128-bit vector sizes"
+ } else {
+ "vex.l selects 256-bit vector sizes"
+ })
+ .with_id(vex_start + 1)
+ );
+ sink.record(
+ vex_start + 15,
+ vex_start + 15,
+ InnerDescription::Misc(if vex_byte_two & 0b10000000 != 0 {
+ "vex.w selects 64-bit operand size"
+ } else {
+ "vex.w leaves default operand size"
+ })
+ .with_id(vex_start + 1)
+ );
+
instruction.prefixes.vex_from_c4(vex_byte_one, vex_byte_two);
- read_vex_instruction(m, words, instruction, p)
+ sink.record(
+ vex_start + 23,
+ vex_start + 23,
+ InnerDescription::Boundary("vex prefix ends/opcode begins")
+ .with_id(vex_start + 23)
+ );
+
+ read_vex_instruction(m, words, instruction, p, sink)
}
pub(crate) fn two_byte_vex<
T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>,
S: DescriptionSink<FieldDescription>,
>(words: &mut T, instruction: &mut Instruction, sink: &mut S) -> Result<(), DecodeError> {
+ let vex_start = words.offset() as u32 * 8;
let vex_byte = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
let p = vex_byte & 0x03;
let p = match p {
@@ -152,12 +242,63 @@ pub(crate) fn two_byte_vex<
bank: RegisterBank::X,
num: ((vex_byte >> 3) & 0b1111) ^ 0b1111,
};
+
+ sink.record(
+ vex_start + 0,
+ vex_start + 1,
+ InnerDescription::Misc(match p {
+ VEXOpcodePrefix::None => "vex.p indicates no opcode prefix",
+ VEXOpcodePrefix::Prefix66 => "vex.p indicates opcode prefix 66",
+ VEXOpcodePrefix::PrefixF3 => "vex.p indicates opcode prefix f3",
+ VEXOpcodePrefix::PrefixF2 => "vex.p indicates opcode prefix f2",
+ })
+ .with_id(vex_start)
+ );
+
+ sink.record(
+ vex_start + 3,
+ vex_start + 6,
+ InnerDescription::RegisterNumber("vvvv", instruction.regs[3].num, instruction.regs[3])
+ .with_id(vex_start + 2)
+ );
+
+ sink.record(
+ vex_start + 2,
+ vex_start + 2,
+ InnerDescription::Misc(if vex_byte & 0b100 == 0 {
+ "vex.r extends extends rrr by 0b1000"
+ } else {
+ "vex.r does not alter rrr"
+ })
+ .with_id(vex_start + 1)
+ );
+ sink.record(
+ vex_start + 7,
+ vex_start + 7,
+ InnerDescription::Misc(if vex_byte & 0b10000000 != 0 {
+ "vex.w selects 64-bit operand size"
+ } else {
+ "vex.w leaves default operand size"
+ })
+ .with_id(vex_start + 1)
+ );
+
instruction.prefixes.vex_from_c5(vex_byte);
- read_vex_instruction(VEXOpcodeMap::Map0F, words, instruction, p)
+ sink.record(
+ vex_start + 15,
+ vex_start + 15,
+ InnerDescription::Boundary("vex prefix ends/opcode begins")
+ .with_id(vex_start + 15)
+ );
+
+ read_vex_instruction(VEXOpcodeMap::Map0F, words, instruction, p, sink)
}
-fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(words: &mut T, instruction: &mut Instruction, operand_code: VEXOperandCode) -> Result<(), DecodeError> {
+fn read_vex_operands<
+ T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>,
+ S: DescriptionSink<FieldDescription>,
+>(words: &mut T, instruction: &mut Instruction, operand_code: VEXOperandCode, sink: &mut S) -> Result<(), DecodeError> {
// println!("operand code: {:?}", operand_code);
match operand_code {
VEXOperandCode::VPS_71 => {
@@ -360,7 +501,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
match mem_oper {
OperandSpec::RegMMM => {
@@ -389,7 +530,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[2] = OperandSpec::RegRRR;
match mem_oper {
OperandSpec::RegMMM => {
@@ -426,7 +567,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
- instruction.operands[2] = read_E_xmm(words, instruction, modrm)?;
+ instruction.operands[2] = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operand_count = 3;
Ok(())
}
@@ -442,7 +583,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
- instruction.operands[2] = read_E_xmm(words, instruction, modrm)?;
+ instruction.operands[2] = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operand_count = 3;
Ok(())
}
@@ -464,7 +605,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E(words, instruction, modrm, 4)?;
+ let mem_oper = read_E(words, instruction, modrm, 4, sink)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.operands[2] = OperandSpec::ImmU8;
@@ -499,7 +640,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E(words, instruction, modrm, 8)?;
+ let mem_oper = read_E(words, instruction, modrm, 8, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -516,7 +657,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E(words, instruction, modrm, 4)?;
+ let mem_oper = read_E(words, instruction, modrm, 4, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -533,7 +674,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E(words, instruction, modrm, 8)?;
+ let mem_oper = read_E(words, instruction, modrm, 8, sink)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
if mem_oper != OperandSpec::RegMMM {
@@ -550,7 +691,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E(words, instruction, modrm, 4)?;
+ let mem_oper = read_E(words, instruction, modrm, 4, sink)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
if mem_oper != OperandSpec::RegMMM {
@@ -567,7 +708,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::D);
- let mem_oper = read_E(words, instruction, modrm, 4)?;
+ let mem_oper = read_E(words, instruction, modrm, 4, sink)?;
if let OperandSpec::RegMMM = mem_oper {
instruction.regs[1].bank = RegisterBank::X;
} else {
@@ -586,7 +727,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Q);
- let mem_oper = read_E(words, instruction, modrm, 4)?;
+ let mem_oper = read_E(words, instruction, modrm, 4, sink)?;
if let OperandSpec::RegMMM = mem_oper {
instruction.regs[1].bank = RegisterBank::X;
} else {
@@ -610,7 +751,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
match (op, mem_oper) {
(VEXOperandCode::E_G_xmm, OperandSpec::RegMMM) => {
/* this is the only accepted operand */
@@ -643,7 +784,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::D);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -660,7 +801,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::D);
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -677,7 +818,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::D);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -696,7 +837,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.imm = read_imm_unsigned(words, 1)?;
@@ -715,7 +856,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
instruction.imm = read_imm_unsigned(words, 1)?;
@@ -735,7 +876,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::D);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -752,7 +893,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::D);
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
if mem_oper != OperandSpec::RegMMM {
return Err(DecodeError::InvalidOperand);
}
@@ -785,7 +926,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
}
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -808,7 +949,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -825,7 +966,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -848,7 +989,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
}
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -871,7 +1012,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -899,7 +1040,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
}
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegRRR;
if mem_oper != OperandSpec::RegMMM {
@@ -927,7 +1068,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
}
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
if mem_oper != OperandSpec::RegMMM {
@@ -947,7 +1088,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
instruction.regs[3].bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -962,7 +1103,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
instruction.regs[3].bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -982,7 +1123,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
instruction.regs[3].bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegRRR;
@@ -999,7 +1140,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
}
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1017,7 +1158,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1037,7 +1178,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E(words, instruction, modrm, 4)?;
+ let mem_oper = read_E(words, instruction, modrm, 4, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1051,7 +1192,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E(words, instruction, modrm, 8)?;
+ let mem_oper = read_E(words, instruction, modrm, 8, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1065,7 +1206,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1082,7 +1223,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
instruction.regs[3].bank = RegisterBank::Y;
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1102,7 +1243,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = mem_oper;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = OperandSpec::RegRRR;
@@ -1117,7 +1258,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.regs[2].bank = RegisterBank::X;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
@@ -1132,7 +1273,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.regs[3].bank = RegisterBank::X;
instruction.regs[2].bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegRRR;
@@ -1148,7 +1289,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.regs[3].bank = RegisterBank::Y;
instruction.regs[2].bank = RegisterBank::Y;
instruction.operands[0] = OperandSpec::RegRRR;
@@ -1174,7 +1315,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), bank);
instruction.regs[3].bank = bank;
- let mem_oper = read_E(words, instruction, modrm, opwidth)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1194,7 +1335,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), bank);
instruction.regs[3].bank = bank;
- let mem_oper = read_E(words, instruction, modrm, opwidth)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.operands[2] = OperandSpec::RegVex;
@@ -1213,7 +1354,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
};
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), bank);
- let mem_oper = read_E(words, instruction, modrm, opwidth)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.imm = read_imm_unsigned(words, 1)?;
@@ -1248,7 +1389,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
};
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), bank);
- let mem_oper = read_E(words, instruction, modrm, opwidth)?;
+ let mem_oper = read_E(words, instruction, modrm, opwidth, sink)?;
instruction.operands[0] = OperandSpec::RegVex;
instruction.operands[1] = mem_oper;
instruction.operand_count = 2;
@@ -1272,7 +1413,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
return Err(DecodeError::InvalidOpcode);
}
};
- let mem_oper = read_E(words, instruction, modrm, 4)?;
+ let mem_oper = read_E(words, instruction, modrm, 4, sink)?;
if let OperandSpec::RegMMM = mem_oper {
return Err(DecodeError::InvalidOperand);
}
@@ -1290,7 +1431,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.imm = read_imm_unsigned(words, 1)?;
@@ -1308,7 +1449,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
let modrm = read_modrm(words)?;
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y);
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = mem_oper;
instruction.imm = read_imm_unsigned(words, 1)?;
@@ -1324,7 +1465,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), RegisterBank::Y);
instruction.regs[3].bank = RegisterBank::Y;
- let mem_oper = read_E_ymm(words, instruction, modrm)?;
+ let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1341,7 +1482,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), RegisterBank::X);
instruction.regs[3].bank = RegisterBank::X;
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1358,7 +1499,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
instruction.regs[0] =
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), RegisterBank::Y);
instruction.regs[3].bank = RegisterBank::Y;
- let mem_oper = read_E_xmm(words, instruction, modrm)?;
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1374,7 +1515,7 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
RegSpec::from_parts((modrm >> 3) & 7,instruction.prefixes.vex_unchecked().x(), RegisterBank::X);
instruction.regs[3].bank = RegisterBank::X;
// TODO: but the memory access is word-sized
- let mem_oper = read_E(words, instruction, modrm, 4)?;
+ let mem_oper = read_E(words, instruction, modrm, 4, sink)?;
instruction.operands[0] = OperandSpec::RegRRR;
instruction.operands[1] = OperandSpec::RegVex;
instruction.operands[2] = mem_oper;
@@ -1406,7 +1547,11 @@ fn read_vex_operands<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as y
}
}
-fn read_vex_instruction<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>>(opcode_map: VEXOpcodeMap, words: &mut T, instruction: &mut Instruction, p: VEXOpcodePrefix) -> Result<(), DecodeError> {
+fn read_vex_instruction<
+ T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>,
+ S: DescriptionSink<FieldDescription>,
+>(opcode_map: VEXOpcodeMap, words: &mut T, instruction: &mut Instruction, p: VEXOpcodePrefix, sink: &mut S) -> Result<(), DecodeError> {
+ let opcode_start = words.offset() as u32 * 8;
let opc = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
// the name of this bit is `L` in the documentation, so use the same name here.
@@ -3455,5 +3600,19 @@ fn read_vex_instruction<T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch a
}
};
instruction.opcode = opcode;
- read_vex_operands(words, instruction, operand_code)
+
+ sink.record(
+ opcode_start,
+ opcode_start + 7,
+ InnerDescription::Opcode(instruction.opcode)
+ .with_id(opcode_start)
+ );
+ sink.record(
+ opcode_start + 7,
+ opcode_start + 7,
+ InnerDescription::Boundary("vex opcode ends/operands begin")
+ .with_id(opcode_start + 7)
+ );
+
+ read_vex_operands(words, instruction, operand_code, sink)
}