diff options
-rw-r--r-- | src/display.rs | 121 | ||||
-rw-r--r-- | src/lib.rs | 103 | ||||
-rw-r--r-- | src/vex.rs | 1197 | ||||
-rw-r--r-- | src/vex_ops | 273 | ||||
-rw-r--r-- | test/test.rs | 74 |
5 files changed, 1259 insertions, 509 deletions
diff --git a/src/display.rs b/src/display.rs index 8bd2689..f6067fb 100644 --- a/src/display.rs +++ b/src/display.rs @@ -712,6 +712,7 @@ impl fmt::Display for Opcode { &Opcode::VPGATHERQQ => write!(f, "{}", "vpgatherqq"), &Opcode::VPHADDD => write!(f, "{}", "vphaddd"), &Opcode::VPHADDSW => write!(f, "{}", "vphaddsw"), + &Opcode::VPHADDUBSW => write!(f, "{}", "vphaddubsw"), &Opcode::VPHADDW => write!(f, "{}", "vphaddw"), &Opcode::VPHMINPOSUW => write!(f, "{}", "vphminposuw"), &Opcode::VPHSUBD => write!(f, "{}", "vphsubd"), @@ -721,7 +722,6 @@ impl fmt::Display for Opcode { &Opcode::VPINSRD => write!(f, "{}", "vpinsrd"), &Opcode::VPINSRQ => write!(f, "{}", "vpinsrq"), &Opcode::VPINSRW => write!(f, "{}", "vpinsrw"), - &Opcode::VPMADDUBSW => write!(f, "{}", "vpmaddubsw"), &Opcode::VPMADDWD => write!(f, "{}", "vpmaddwd"), &Opcode::VPMASKMOVD => write!(f, "{}", "vpmaskmovd"), &Opcode::VPMASKMOVQ => write!(f, "{}", "vpmaskmovq"), @@ -817,6 +817,64 @@ impl fmt::Display for Opcode { &Opcode::VADDSUBPS => write!(f, "{}", "vaddsubps"), &Opcode::VCVTPD2DQ => write!(f, "{}", "vcvtpd2dq"), &Opcode::VLDDQU => write!(f, "{}", "vlddqu"), + &Opcode::VADDSD => write!(f, "{}", "vaddsd"), + &Opcode::VADDSS => write!(f, "{}", "vaddss"), + &Opcode::VCMPSD => write!(f, "{}", "vcmpsd"), + &Opcode::VCMPSS => write!(f, "{}", "vcmpss"), + &Opcode::VCOMISD => write!(f, "{}", "vcomisd"), + &Opcode::VCOMISS => write!(f, "{}", "vcomiss"), + &Opcode::VCVTSD2SI => write!(f, "{}", "vcvtsd2si"), + &Opcode::VCVTSD2SS => write!(f, "{}", "vcvtsd2ss"), + &Opcode::VCVTSI2SD => write!(f, "{}", "vcvtsi2sd"), + &Opcode::VCVTSI2SS => write!(f, "{}", "vcvtsi2ss"), + &Opcode::VCVTSS2SD => write!(f, "{}", "vcvtss2sd"), + &Opcode::VCVTSS2SI => write!(f, "{}", "vcvtss2si"), + &Opcode::VCVTTSD2SI => write!(f, "{}", "vcvttsd2si"), + &Opcode::VCVTTSS2SI => write!(f, "{}", "vcvttss2si"), + &Opcode::VDIVSD => write!(f, "{}", "vdivsd"), + &Opcode::VDIVSS => write!(f, "{}", "vdivss"), + &Opcode::VFMADD132SD => write!(f, "{}", "vfmadd132sd"), + &Opcode::VFMADD132SS => write!(f, "{}", "vfmadd132ss"), + &Opcode::VFMADD213SD => write!(f, "{}", "vfmadd213sd"), + &Opcode::VFMADD213SS => write!(f, "{}", "vfmadd213ss"), + &Opcode::VFMADD231SD => write!(f, "{}", "vfmadd231sd"), + &Opcode::VFMADD231SS => write!(f, "{}", "vfmadd231ss"), + &Opcode::VFMSUB132SD => write!(f, "{}", "vfmsub132sd"), + &Opcode::VFMSUB132SS => write!(f, "{}", "vfmsub132ss"), + &Opcode::VFMSUB213SD => write!(f, "{}", "vfmsub213sd"), + &Opcode::VFMSUB213SS => write!(f, "{}", "vfmsub213ss"), + &Opcode::VFMSUB231SD => write!(f, "{}", "vfmsub231sd"), + &Opcode::VFMSUB231SS => write!(f, "{}", "vfmsub231ss"), + &Opcode::VFNMADD132SD => write!(f, "{}", "vfnmadd132sd"), + &Opcode::VFNMADD132SS => write!(f, "{}", "vfnmadd132ss"), + &Opcode::VFNMADD213SD => write!(f, "{}", "vfnmadd213sd"), + &Opcode::VFNMADD213SS => write!(f, "{}", "vfnmadd213ss"), + &Opcode::VFNMADD231SD => write!(f, "{}", "vfnmadd231sd"), + &Opcode::VFNMADD231SS => write!(f, "{}", "vfnmadd231ss"), + &Opcode::VFNMSUB132SD => write!(f, "{}", "vfnmsub132sd"), + &Opcode::VFNMSUB132SS => write!(f, "{}", "vfnmsub132ss"), + &Opcode::VFNMSUB213SD => write!(f, "{}", "vfnmsub213sd"), + &Opcode::VFNMSUB213SS => write!(f, "{}", "vfnmsub213ss"), + &Opcode::VFNMSUB231SD => write!(f, "{}", "vfnmsub231sd"), + &Opcode::VFNMSUB231SS => write!(f, "{}", "vfnmsub231ss"), + &Opcode::VMAXSD => write!(f, "{}", "vmaxsd"), + &Opcode::VMAXSS => write!(f, "{}", "vmaxss"), + &Opcode::VMINSD => write!(f, "{}", "vminsd"), + &Opcode::VMINSS => write!(f, "{}", "vminss"), + &Opcode::VMOVSD => write!(f, "{}", "vmovsd"), + &Opcode::VMOVSS => write!(f, "{}", "vmovss"), + &Opcode::VMULSD => write!(f, "{}", "vmulsd"), + &Opcode::VMULSS => write!(f, "{}", "vmulss"), + &Opcode::VRCPSS => write!(f, "{}", "vrcpss"), + &Opcode::VROUNDSD => write!(f, "{}", "vroundsd"), + &Opcode::VROUNDSS => write!(f, "{}", "vroundss"), + &Opcode::VRSQRTSS => write!(f, "{}", "vrsqrtss"), + &Opcode::VSQRTSD => write!(f, "{}", "vsqrtsd"), + &Opcode::VSQRTSS => write!(f, "{}", "vsqrtss"), + &Opcode::VSUBSD => write!(f, "{}", "vsubsd"), + &Opcode::VSUBSS => write!(f, "{}", "vsubss"), + &Opcode::VUCOMISD => write!(f, "{}", "vucomisd"), + &Opcode::VUCOMISS => write!(f, "{}", "vucomiss"), &Opcode::Invalid => write!(f, "{}", "invalid"), } } @@ -830,13 +888,21 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode { Opcode::VADDSUBPS | Opcode::VADDPD | Opcode::VADDPS | + Opcode::VADDSD | + Opcode::VADDSS | Opcode::VADDSUBPD | Opcode::VFMADD132PD | Opcode::VFMADD132PS | + Opcode::VFMADD132SD | + Opcode::VFMADD132SS | Opcode::VFMADD213PD | Opcode::VFMADD213PS | + Opcode::VFMADD213SD | + Opcode::VFMADD213SS | Opcode::VFMADD231PD | Opcode::VFMADD231PS | + Opcode::VFMADD231SD | + Opcode::VFMADD231SS | Opcode::VFMADDSUB132PD | Opcode::VFMADDSUB132PS | Opcode::VFMADDSUB213PD | @@ -845,10 +911,16 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode { Opcode::VFMADDSUB231PS | Opcode::VFMSUB132PD | Opcode::VFMSUB132PS | + Opcode::VFMSUB132SD | + Opcode::VFMSUB132SS | Opcode::VFMSUB213PD | Opcode::VFMSUB213PS | + Opcode::VFMSUB213SD | + Opcode::VFMSUB213SS | Opcode::VFMSUB231PD | Opcode::VFMSUB231PS | + Opcode::VFMSUB231SD | + Opcode::VFMSUB231SS | Opcode::VFMSUBADD132PD | Opcode::VFMSUBADD132PS | Opcode::VFMSUBADD213PD | @@ -857,22 +929,38 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode { Opcode::VFMSUBADD231PS | Opcode::VFNMADD132PD | Opcode::VFNMADD132PS | + Opcode::VFNMADD132SD | + Opcode::VFNMADD132SS | Opcode::VFNMADD213PD | Opcode::VFNMADD213PS | + Opcode::VFNMADD213SD | + Opcode::VFNMADD213SS | Opcode::VFNMADD231PD | Opcode::VFNMADD231PS | + Opcode::VFNMADD231SD | + Opcode::VFNMADD231SS | Opcode::VFNMSUB132PD | Opcode::VFNMSUB132PS | + Opcode::VFNMSUB132SD | + Opcode::VFNMSUB132SS | Opcode::VFNMSUB213PD | Opcode::VFNMSUB213PS | + Opcode::VFNMSUB213SD | + Opcode::VFNMSUB213SS | Opcode::VFNMSUB231PD | Opcode::VFNMSUB231PS | + Opcode::VFNMSUB231SD | + Opcode::VFNMSUB231SS | Opcode::VDIVPD | Opcode::VDIVPS | + Opcode::VDIVSD | + Opcode::VDIVSS | Opcode::VHADDPD | Opcode::VHSUBPD | Opcode::VMULPD | Opcode::VMULPS | + Opcode::VMULSD | + Opcode::VMULSS | Opcode::VPABSB | Opcode::VPABSD | Opcode::VPABSW | @@ -911,6 +999,14 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode { Opcode::VSQRTPS | Opcode::VSUBPD | Opcode::VSUBPS | + Opcode::VSUBSD | + Opcode::VSUBSS | + Opcode::VRCPSS | + Opcode::VROUNDSD | + Opcode::VROUNDSS | + Opcode::VRSQRTSS | + Opcode::VSQRTSD | + Opcode::VSQRTSS | Opcode::VPSADBW | Opcode::VMPSADBW | Opcode::VPHADDD | @@ -919,7 +1015,7 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode { Opcode::VPHSUBD | Opcode::VPHSUBSW | Opcode::VPHSUBW | - Opcode::VPMADDUBSW | + Opcode::VPHADDUBSW | Opcode::VPMADDWD | Opcode::VDPPD | Opcode::VDPPS | @@ -1103,6 +1199,14 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode { Opcode::VCVTPS2PH | Opcode::VCVTTPD2DQ | Opcode::VCVTTPS2DQ | + Opcode::VCVTSD2SI | + Opcode::VCVTSD2SS | + Opcode::VCVTSI2SD | + Opcode::VCVTSI2SS | + Opcode::VCVTSS2SD | + Opcode::VCVTSS2SI | + Opcode::VCVTTSD2SI | + Opcode::VCVTTSS2SI | Opcode::VMOVDDUP | Opcode::VPSHUFLW | Opcode::VBLENDPD | @@ -1148,6 +1252,9 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode { Opcode::VMOVSLDUP | Opcode::VMOVUPD | Opcode::VMOVUPS | + Opcode::VMOVSD | + Opcode::VMOVSS | + Opcode::VPBLENDD | Opcode::VPBLENDVB | Opcode::VPBLENDW | @@ -1334,12 +1441,22 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode { Opcode::SETLE | Opcode::SETG => { write!(out, "{}", colors.data_op(self)) } + Opcode::VCOMISD | + Opcode::VCOMISS | + Opcode::VUCOMISD | + Opcode::VUCOMISS | Opcode::VCMPPD | Opcode::VCMPPS | + Opcode::VCMPSD | + Opcode::VCMPSS | Opcode::VMAXPD | Opcode::VMAXPS | + Opcode::VMAXSD | + Opcode::VMAXSS | Opcode::VMINPD | Opcode::VMINPS | + Opcode::VMINSD | + Opcode::VMINSS | Opcode::VPCMPEQB | Opcode::VPCMPEQD | Opcode::VPCMPEQQ | @@ -250,6 +250,7 @@ impl OperandSpec { OperandSpec::ImmU64 | OperandSpec::RegRRR | OperandSpec::RegMMM | + OperandSpec::RegVex | OperandSpec::AL | OperandSpec::CL | OperandSpec::Nothing => { @@ -272,6 +273,9 @@ impl Operand { OperandSpec::RegMMM => { Operand::Register(inst.modrm_mmm) } + OperandSpec::RegVex => { + Operand::Register(inst.vex_reg) + } OperandSpec::AL => { Operand::Register(RegSpec::al()) } @@ -754,8 +758,14 @@ pub enum Opcode { VCVTPD2DQ, VLDDQU, + VCOMISD, + VCOMISS, + VUCOMISD, + VUCOMISS, VADDPD, VADDPS, + VADDSD, + VADDSS, VADDSUBPD, VAESDEC, VAESDECLAST, @@ -771,6 +781,8 @@ pub enum Opcode { VBROADCASTI128, VBROADCASTSD, VBROADCASTSS, + VCMPSD, + VCMPSS, VCMPPD, VCMPPS, VCVTDQ2PD, @@ -779,11 +791,21 @@ pub enum Opcode { VCVTPH2PS, VCVTPS2DQ, VCVTPS2PD, + VCVTSS2SD, + VCVTSI2SS, + VCVTSI2SD, + VCVTSD2SI, + VCVTSD2SS, VCVTPS2PH, + VCVTSS2SI, VCVTTPD2DQ, VCVTTPS2DQ, + VCVTTSS2SI, + VCVTTSD2SI, VDIVPD, VDIVPS, + VDIVSD, + VDIVSS, VDPPD, VDPPS, VEXTRACTF128, @@ -791,10 +813,16 @@ pub enum Opcode { VEXTRACTPS, VFMADD132PD, VFMADD132PS, + VFMADD132SD, + VFMADD132SS, VFMADD213PD, VFMADD213PS, + VFMADD213SD, + VFMADD213SS, VFMADD231PD, VFMADD231PS, + VFMADD231SD, + VFMADD231SS, VFMADDSUB132PD, VFMADDSUB132PS, VFMADDSUB213PD, @@ -803,10 +831,16 @@ pub enum Opcode { VFMADDSUB231PS, VFMSUB132PD, VFMSUB132PS, + VFMSUB132SD, + VFMSUB132SS, VFMSUB213PD, VFMSUB213PS, + VFMSUB213SD, + VFMSUB213SS, VFMSUB231PD, VFMSUB231PS, + VFMSUB231SD, + VFMSUB231SS, VFMSUBADD132PD, VFMSUBADD132PS, VFMSUBADD213PD, @@ -815,16 +849,28 @@ pub enum Opcode { VFMSUBADD231PS, VFNMADD132PD, VFNMADD132PS, + VFNMADD132SD, + VFNMADD132SS, VFNMADD213PD, VFNMADD213PS, + VFNMADD213SD, + VFNMADD213SS, VFNMADD231PD, VFNMADD231PS, + VFNMADD231SD, + VFNMADD231SS, VFNMSUB132PD, VFNMSUB132PS, + VFNMSUB132SD, + VFNMSUB132SS, VFNMSUB213PD, VFNMSUB213PS, + VFNMSUB213SD, + VFNMSUB213SS, VFNMSUB231PD, VFNMSUB231PS, + VFNMSUB231SD, + VFNMSUB231SS, VGATHERDPD, VGATHERDPS, VGATHERQPD, @@ -839,8 +885,12 @@ pub enum Opcode { VMASKMOVPS, VMAXPD, VMAXPS, + VMAXSD, + VMAXSS, VMINPD, VMINPS, + VMINSD, + VMINSS, VMOVAPD, VMOVAPS, VMOVD, @@ -859,6 +909,8 @@ pub enum Opcode { VMOVNTPD, VMOVNTPS, VMOVQ, + VMOVSS, + VMOVSD, VMOVSHDUP, VMOVSLDUP, VMOVUPD, @@ -866,6 +918,8 @@ pub enum Opcode { VMPSADBW, VMULPD, VMULPS, + VMULSD, + VMULSS, VPABSB, VPABSD, VPABSW, @@ -922,6 +976,7 @@ pub enum Opcode { VPHADDD, VPHADDSW, VPHADDW, + VPHADDUBSW, VPHMINPOSUW, VPHSUBD, VPHSUBSW, @@ -930,7 +985,6 @@ pub enum Opcode { VPINSRD, VPINSRQ, VPINSRW, - VPMADDUBSW, VPMADDWD, VPMASKMOVD, VPMASKMOVQ, @@ -1003,13 +1057,21 @@ pub enum Opcode { VRCPPS, VROUNDPD, VROUNDPS, + VROUNDSD, + VROUNDSS, VRSQRTPS, + VRSQRTSS, + VRCPSS, VSHUFPD, VSHUFPS, VSQRTPD, VSQRTPS, + VSQRTSS, + VSQRTSD, VSUBPD, VSUBPS, + VSUBSD, + VSUBSS, VTESTPD, VTESTPS, VUNPCKHPD, @@ -1043,6 +1105,8 @@ enum OperandSpec { RegRRR, // the register in modrm_mmm (eg modrm mod bits were 11) RegMMM, + // the register selected by vex-vvvv bits + RegVex, // the register `al`. Used for MOVS. AL, // the register `cl`. Used for SHLD and SHRD. @@ -3412,6 +3476,7 @@ pub fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T escapes_are_prefixes_actually(&mut prefixes, &mut alternate_opcode_map); break record; } else { + println!("prefix: {:02x}, extant prefixes: {:?}", b, prefixes); // some prefix seen after we saw rex, but before the 0f escape or an actual // opcode. so we must forget the rex prefix! // this is to handle sequences like 41660f21cf @@ -3419,6 +3484,34 @@ pub fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T // prefix, but since 660f21 is not valid, the opcode is interpreted // as 0f21, where 66 is a prefix, which makes 41 not the last // prefix before the opcode, and it's discarded. + + // 2.3.2 + // Any VEX-encoded instruction with a LOCK prefix preceding VEX will #UD. + // 2.3.3 + // Any VEX-encoded instruction with a 66H, F2H, or F3H prefix preceding VEX + // will #UD. + // 2.3.4 + // Any VEX-encoded instruction with a REX prefix proceeding VEX will #UD. + if b == 0xc5 { + if prefixes.rex().present() || prefixes.lock() || prefixes.operand_size() || prefixes.rep() || prefixes.repnz() { + // rex and then vex is invalid! reject it. + instruction.opcode = Opcode::Invalid; + return Err(()); + } else { + instruction.prefixes = prefixes; + return vex::two_byte_vex(&mut bytes_iter, instruction, length); + } + } else if b == 0xc4 { + if prefixes.rex().present() || prefixes.lock() || prefixes.operand_size() || prefixes.rep() || prefixes.repnz() { + // rex and then vex is invalid! reject it. + instruction.opcode = Opcode::Invalid; + return Err(()); + } else { + instruction.prefixes = prefixes; + return vex::three_byte_vex(&mut bytes_iter, instruction, length); + } + } + prefixes.rex_from(0); escapes_are_prefixes_actually(&mut prefixes, &mut alternate_opcode_map); match b { @@ -3446,14 +3539,6 @@ pub fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T 0x67 => { prefixes.set_address_size(); }, - 0xc4 => { - instruction.prefixes = prefixes; - return vex::three_byte_vex(&mut bytes_iter, instruction, length); - } - 0xc5 => { - instruction.prefixes = prefixes; - return vex::two_byte_vex(&mut bytes_iter, instruction, length); - } 0xf0 => { prefixes.set_lock(); }, @@ -7,6 +7,7 @@ use read_modrm; use read_E; use read_E_xmm; use read_E_ymm; +use read_imm_unsigned; #[derive(Debug)] enum VEXOpcodeMap { @@ -23,8 +24,13 @@ enum VEXOpcodePrefix { PrefixF2, } +#[derive(Debug)] enum VEXOperandCode { Nothing, + VMOVSS_10, + VMOVSD_10, + VMOVSD_11, + VMOVSS_11, E_G_xmm, U_G_xmm, M_G_xmm, @@ -35,37 +41,36 @@ enum VEXOperandCode { E_G_ymm, U_G_ymm, M_G_ymm, + G_E_ymm, G_M_ymm, G_U_ymm, E_V_G_ymm, + E_V_G_xmm, E_xmm_G_ymm_imm8, Ev_G_xmm_imm8, + G_Ex_V_xmm, + G_Ey_V_ymm, G_E_xmm, G_E_xmm_imm8, - G_E_ymm, G_E_ymm_imm8, G_xmm_E_xmm, G_xmm_E_ymm, G_ymm_E_xmm, G_ymm_E_ymm, - V_G_ymm_E_xmm, + G_V_ymm_E_xmm, M_V_G_xmm, M_V_G_ymm, - V15_G_E_xmm, - V15_G_E_ymm, - V15_G_M_xmm, - V15_G_M_ymm, - V_G_E_xmm, - V_G_E_xmm_imm8, - V_G_E_xmm_xmm4, - V_G_E_ymm, - V_G_E_ymm_imm8, - V_G_E_ymm_ymm4, - V_G_M_xmm, - V_G_M_ymm, + G_V_E_xmm, + G_V_E_xmm_imm8, + G_V_E_xmm_xmm4, + G_V_E_ymm, + G_V_E_ymm_imm8, + G_V_E_ymm_ymm4, + G_V_M_xmm, + G_V_M_ymm, V_xmm_G_ymm_E_ymm_imm8, V_ymm_G_ymm_E_xmm_imm8, - V_G_xmm_Ew_imm8, + G_V_xmm_Ew_imm8, Eq_G_xmm, Ed_G_xmm, G_xmm_Ed, @@ -84,9 +89,24 @@ pub(crate) fn three_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: & 0x03 => VEXOpcodePrefix::PrefixF2, _ => { unreachable!("p is two bits"); } }; + let m = vex_byte_one & 0b11111; + println!("m: {:05b}", m); + let m = match m { + 0b00001 => VEXOpcodeMap::Map0F, + 0b00010 => VEXOpcodeMap::Map0F38, + 0b00011 => VEXOpcodeMap::Map0F3A, + _ => { + instruction.opcode = Opcode::Invalid; + return Err(()); + } + }; + instruction.vex_reg = RegSpec { + bank: RegisterBank::X, + num: ((vex_byte_two >> 3) & 0b1111) ^ 0b1111, + }; instruction.prefixes.vex_from_c4(vex_byte_one, vex_byte_two); - read_vex_instruction(VEXOpcodeMap::Map0F, bytes, instruction, &mut length, p); + read_vex_instruction(m, bytes, instruction, &mut length, p); instruction.length = length; Ok(()) } @@ -101,6 +121,10 @@ pub(crate) fn two_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mu 0x03 => VEXOpcodePrefix::PrefixF2, _ => { unreachable!("p is two bits"); } }; + instruction.vex_reg = RegSpec { + bank: RegisterBank::X, + num: ((vex_byte >> 3) & 0b1111) ^ 0b1111, + }; instruction.prefixes.vex_from_c5(vex_byte); read_vex_instruction(VEXOpcodeMap::Map0F, bytes, instruction, &mut length, p); @@ -109,17 +133,71 @@ 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<(), ()> { + println!("operand code: {:?}", operand_code); match operand_code { + VEXOperandCode::VMOVSS_10 | + VEXOperandCode::VMOVSD_10 => { + let modrm = read_modrm(bytes, instruction, 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)?; + instruction.operands[0] = OperandSpec::RegRRR; + match mem_oper { + OperandSpec::RegMMM => { + instruction.operands[1] = OperandSpec::RegVex; + instruction.operands[2] = OperandSpec::RegMMM; + }, + other => { + instruction.operands[1] = other; + } + } + Ok(()) + }, + VEXOperandCode::VMOVSS_11 | + VEXOperandCode::VMOVSD_11 => { + let modrm = read_modrm(bytes, instruction, 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)?; + instruction.operands[1] = OperandSpec::RegRRR; + match mem_oper { + OperandSpec::RegMMM => { + instruction.operands[0] = OperandSpec::RegVex; + instruction.operands[2] = OperandSpec::RegMMM; + }, + other => { + instruction.operands[0] = other; + } + } + Ok(()) + }, VEXOperandCode::Nothing => { Ok(()) }, - op @ VEXOperandCode::V15_G_E_xmm | - op @ VEXOperandCode::V15_G_M_xmm | + VEXOperandCode::Ev_G_xmm_imm8 => { + if instruction.vex_reg.num != 0 { + instruction.opcode = Opcode::Invalid; + return Err(()); + } + let modrm = read_modrm(bytes, instruction, 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)?; + 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 => { + if instruction.vex_reg.num != 0 { + instruction.opcode = Opcode::Invalid; + return Err(()); + } let modrm = read_modrm(bytes, instruction, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); @@ -133,6 +211,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst 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(()); + } let modrm = read_modrm(bytes, instruction, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); @@ -144,9 +226,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst op @ VEXOperandCode::E_G_ymm | op @ VEXOperandCode::U_G_ymm | - op @ VEXOperandCode::M_G_ymm | - op @ VEXOperandCode::V15_G_E_ymm | - op @ VEXOperandCode::V15_G_M_ymm => { + op @ VEXOperandCode::M_G_ymm => { + if instruction.vex_reg.num != 0 { + instruction.opcode = Opcode::Invalid; + return Err(()); + } let modrm = read_modrm(bytes, instruction, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); @@ -159,6 +243,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst 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(()); + } let modrm = read_modrm(bytes, instruction, length)?; instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); @@ -167,8 +255,78 @@ 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)?; + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); + instruction.vex_reg.bank = RegisterBank::Y; + let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = OperandSpec::RegVex; + 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)?; + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); + instruction.vex_reg.bank = RegisterBank::Y; + let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; + instruction.operands[0] = mem_oper; + instruction.operands[1] = OperandSpec::RegVex; + 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)?; + 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)?; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = OperandSpec::RegVex; + instruction.operands[2] = mem_oper; + Ok(()) + } + + op @ VEXOperandCode::E_V_G_xmm | + op @ VEXOperandCode::M_V_G_xmm => { + let modrm = read_modrm(bytes, instruction, 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)?; + instruction.operands[0] = mem_oper; + instruction.operands[1] = OperandSpec::RegVex; + instruction.operands[2] = OperandSpec::RegRRR; + Ok(()) + } + + VEXOperandCode::G_Ex_V_xmm => { + let modrm = read_modrm(bytes, instruction, 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)?; + instruction.sib_index.bank = RegisterBank::X; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = mem_oper; + instruction.operands[2] = OperandSpec::RegVex; + Ok(()) + } + VEXOperandCode::G_Ey_V_ymm => { + let modrm = read_modrm(bytes, instruction, 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)?; + instruction.vex_reg.bank = RegisterBank::Y; + instruction.sib_index.bank = RegisterBank::Y; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = mem_oper; + instruction.operands[2] = OperandSpec::RegVex; + Ok(()) + } - VEXOperandCode::E_V_G_ymm | VEXOperandCode::E_xmm_G_ymm_imm8 | VEXOperandCode::Ev_G_xmm_imm8 | VEXOperandCode::G_E_ymm_imm8 | @@ -176,24 +334,18 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst VEXOperandCode::G_xmm_E_ymm | VEXOperandCode::G_ymm_E_xmm | VEXOperandCode::G_ymm_E_ymm | - VEXOperandCode::M_V_G_xmm | - VEXOperandCode::M_V_G_ymm | - VEXOperandCode::V_G_E_xmm | - VEXOperandCode::V_G_E_xmm_imm8 | - VEXOperandCode::V_G_E_xmm_xmm4 | - VEXOperandCode::V_G_E_ymm | - VEXOperandCode::V_G_E_ymm_imm8 | - VEXOperandCode::V_G_E_ymm_ymm4 | - VEXOperandCode::V_G_M_xmm | - VEXOperandCode::V_G_M_ymm | + VEXOperandCode::G_V_E_xmm_imm8 | + VEXOperandCode::G_V_E_xmm_xmm4 | + VEXOperandCode::G_V_E_ymm_imm8 | + VEXOperandCode::G_V_E_ymm_ymm4 | VEXOperandCode::V_xmm_G_ymm_E_ymm_imm8 | VEXOperandCode::V_ymm_G_ymm_E_xmm_imm8 | VEXOperandCode::Eq_G_xmm | VEXOperandCode::Ed_G_xmm | VEXOperandCode::G_xmm_Ed | VEXOperandCode::G_xmm_Eq | - VEXOperandCode::V_G_ymm_E_xmm | - VEXOperandCode::V_G_xmm_Ew_imm8 => { + VEXOperandCode::G_V_ymm_E_xmm | + VEXOperandCode::G_V_xmm_Ew_imm8 => { Ok(()) // :) } @@ -204,7 +356,8 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & let opc = bytes.next().ok_or(())?; let L = instruction.prefixes.vex().l(); - println!("reading vex instruction from opcode prefix {:?}, L: {}, opc: {:#x}", p, L, opc); + println!("reading vex instruction from opcode prefix {:?}, L: {}, opc: {:#x}, map:{:?}", p, L, opc, opcode_map); + println!("w? {}", instruction.prefixes.vex().w()); // several combinations simply have no instructions. check for those first. let (opcode, operand_code) = match opcode_map { @@ -224,14 +377,14 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::M_G_xmm }), 0x14 => (Opcode::VUNPCKLPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x15 => (Opcode::VUNPCKHPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), // ugh // 0x16 => (Opcode::VMOVHPS, ..), @@ -257,6 +410,8 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::M_G_xmm }), + 0x2e => (Opcode::VUCOMISS, VEXOperandCode::G_E_xmm), + 0x2f => (Opcode::VCOMISS, VEXOperandCode::G_E_xmm), 0x50 => (Opcode::VMOVMSKPS, if L { VEXOperandCode::U_G_ymm } else { @@ -278,19 +433,19 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_xmm }), 0x57 => (Opcode::VXORPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x58 => (Opcode::VADDPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x59 => (Opcode::VMULPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x5A => (Opcode::VCVTPS2PD, if L { VEXOperandCode::G_E_ymm @@ -303,35 +458,35 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_xmm }), 0x5C => (Opcode::VSUBPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x5D => (Opcode::VMINPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x5E => (Opcode::VDIVPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x5F => (Opcode::VMAXPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x77 => (Opcode::VZEROUPPER, VEXOperandCode::Nothing), 0xC2 => (Opcode::VCMPPS, if L { - VEXOperandCode::V_G_E_ymm_imm8 + VEXOperandCode::G_V_E_ymm_imm8 } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0xC6 => (Opcode::VSHUFPS, if L { - VEXOperandCode::V_G_E_ymm_imm8 + VEXOperandCode::G_V_E_ymm_imm8 } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), _ => { instruction.opcode = Opcode::Invalid; @@ -341,6 +496,8 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & }, VEXOpcodePrefix::Prefix66 => { match opc { + 0x0a => (Opcode::VROUNDSS, VEXOperandCode::G_V_E_xmm_imm8), + 0x0b => (Opcode::VROUNDSD, VEXOperandCode::G_V_E_xmm_imm8), 0x10 => (Opcode::VMOVUPD, if L { VEXOperandCode::G_E_ymm } else { @@ -355,7 +512,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_M_xmm + VEXOperandCode::G_V_M_xmm }), 0x13 => (Opcode::VMOVLPD, if L { instruction.opcode = Opcode::Invalid; @@ -364,20 +521,20 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::M_G_xmm }), 0x14 => (Opcode::VUNPCKLPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x15 => (Opcode::VUNPCKHPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x16 => (Opcode::VMOVHPD, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_M_xmm + VEXOperandCode::G_V_M_xmm }), 0x17 => (Opcode::VMOVHPD, if L { instruction.opcode = Opcode::Invalid; @@ -400,6 +557,8 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::M_G_xmm }), + 0x2e => (Opcode::VUCOMISD, VEXOperandCode::G_E_xmm), + 0x2f => (Opcode::VCOMISD, VEXOperandCode::G_E_xmm), 0x50 => (Opcode::VMOVMSKPD, if L { VEXOperandCode::G_U_ymm } else { @@ -411,19 +570,19 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_xmm }), 0x57 => (Opcode::VXORPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x58 => (Opcode::VADDPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x59 => (Opcode::VMULPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x5A => (Opcode::VCVTPD2PS, if L { VEXOperandCode::G_xmm_E_ymm @@ -436,94 +595,94 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_xmm }), 0x5C => (Opcode::VSUBPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x5D => (Opcode::VMINPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x5E => (Opcode::VDIVPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x5F => (Opcode::VMAXPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x60 => (Opcode::VPUNPCKLBW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x61 => (Opcode::VPUNPCKLWD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x62 => (Opcode::VPUNPCKLDQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x63 => (Opcode::VPACKSSWB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x64 => (Opcode::VPCMPGTB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x65 => (Opcode::VPCMPGTW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x66 => (Opcode::VPCMPGTD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x67 => (Opcode::VPACKUSWB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x68 => (Opcode::VPUNPCKHBW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x69 => (Opcode::VPUNPCKHWD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x6A => (Opcode::VPUNPCKHDQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x6B => (Opcode::VPACKSSDW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x6C => (Opcode::VPUNPCKLQDQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x6D => (Opcode::VPUNPCKHQDQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x6E => if instruction.prefixes.vex().w() { (Opcode::VMOVQ, if L { @@ -561,9 +720,9 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_ymm_imm8 }), 0x71 => (Opcode::VPSRLW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }), 0x72 => (Opcode::VPSLLD, if L { VEXOperandCode::G_E_ymm_imm8 @@ -601,29 +760,29 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_ymm_imm8 }), 0x74 => (Opcode::VPCMPEQB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x75 => (Opcode::VPCMPEQW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x76 => (Opcode::VPCMPEQD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x7C => (Opcode::VHADDPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x7D => (Opcode::VHSUBPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x7E => (Opcode::VMOVD, if L { instruction.opcode = Opcode::Invalid; @@ -643,15 +802,15 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::E_G_xmm }), 0xC2 => (Opcode::VCMPPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xC4 => (Opcode::VPINSRW, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_xmm_Ew_imm8 + VEXOperandCode::G_V_xmm_Ew_imm8 }), 0xC5 => (Opcode::VPEXTRW, if L { instruction.opcode = Opcode::Invalid; @@ -660,39 +819,39 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::U_G_xmm_imm8 }), 0xC6 => (Opcode::VSHUFPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xD0 => (Opcode::VADDSUBPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xD1 => (Opcode::VPSRLW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xD2 => (Opcode::VPSRLD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xD3 => (Opcode::VPSRLQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xD4 => (Opcode::VPADDQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xD5 => (Opcode::VPMULLW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xD6 => (Opcode::VMOVQ, if L { instruction.opcode = Opcode::Invalid; @@ -706,65 +865,65 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::U_G_xmm }), 0xD8 => (Opcode::VPSUBUSB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xD9 => (Opcode::VPSUBUSW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xDB => (Opcode::VPAND, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xDC => (Opcode::VPADDUSB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { instruction.opcode = Opcode::Invalid; return Err(()); }), 0xDD => (Opcode::VPADDUSW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xDF => (Opcode::VPANDN, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xE0 => (Opcode::VPAVGB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xE1 => (Opcode::VPSRAW, if L { - VEXOperandCode::V_G_ymm_E_xmm + VEXOperandCode::G_V_ymm_E_xmm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xE2 => (Opcode::VPSRAD, if L { - VEXOperandCode::V_G_ymm_E_xmm + VEXOperandCode::G_V_ymm_E_xmm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xE3 => (Opcode::VPAVGW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xE4 => (Opcode::VPMULHUW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xE5 => (Opcode::VPMULHW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xE6 => (Opcode::VCVTTPD2DQ, if L { VEXOperandCode::G_xmm_E_ymm @@ -777,69 +936,69 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::M_G_xmm }), 0xE8 => (Opcode::VPSUBSB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xE9 => (Opcode::VPSUBSW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xEB => (Opcode::VPOR, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xEC => (Opcode::VPADDSB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xED => (Opcode::VPADDSW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xEE => (Opcode::VPMAXSW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xEF => (Opcode::VPXOR, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xF1 => (Opcode::VPSLLW, if L { - VEXOperandCode::V_G_ymm_E_xmm + VEXOperandCode::G_V_ymm_E_xmm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xF2 => (Opcode::VPSLLD, if L { - VEXOperandCode::V_G_ymm_E_xmm + VEXOperandCode::G_V_ymm_E_xmm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xF3 => (Opcode::VPSLLQ, if L { - VEXOperandCode::V_G_ymm_E_xmm + VEXOperandCode::G_V_ymm_E_xmm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xF4 => (Opcode::VPMULUDQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xF5 => (Opcode::VPMADDWD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xF6 => (Opcode::VPSADBW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xF7 => (Opcode::VMASKMOVDQU, if L { instruction.opcode = Opcode::Invalid; @@ -848,39 +1007,39 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_xmm }), 0xF8 => (Opcode::VPSUBB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xF9 => (Opcode::VPSUBW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xFA => (Opcode::VPSUBD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xFB => (Opcode::VPSUBQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xFC => (Opcode::VPADDB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xFD => (Opcode::VPADDW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xFE => (Opcode::VPADDD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), _ => { instruction.opcode = Opcode::Invalid; @@ -890,30 +1049,56 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } VEXOpcodePrefix::PrefixF2 => { match opc { + 0x10 => (Opcode::VMOVSD, VEXOperandCode::VMOVSD_10), + 0x11 => (Opcode::VMOVSD, VEXOperandCode::VMOVSD_11), 0x12 => (Opcode::VMOVDDUP, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }), + 0x2a => (Opcode::VCVTSI2SD, if instruction.prefixes.vex().w() { + VEXOperandCode::G_V_E_xmm // 64-bit last operand + } else { + VEXOperandCode::G_V_E_xmm // 32-bit last operand + }), + 0x2c => (Opcode::VCVTTSD2SI, if instruction.prefixes.vex().w() { + VEXOperandCode::G_E_xmm // 64-bit + } else { + VEXOperandCode::G_E_xmm // 32-bit + }), + 0x2d => (Opcode::VCVTSD2SI, if instruction.prefixes.vex().w() { + VEXOperandCode::G_E_xmm // 64-bit + } else { + VEXOperandCode::G_E_xmm // 32-bit + }), + 0x51 => (Opcode::VSQRTSD, VEXOperandCode::G_V_E_xmm), + 0x58 => (Opcode::VADDSD, VEXOperandCode::G_V_E_xmm), + 0x59 => (Opcode::VMULSD, VEXOperandCode::G_V_E_xmm), + 0x5a => (Opcode::CVTSD2SS, VEXOperandCode::G_V_E_xmm), + 0x5c => (Opcode::VSUBSD, VEXOperandCode::G_V_E_xmm), + 0x5d => (Opcode::VMINSD, VEXOperandCode::G_V_E_xmm), + 0x5e => (Opcode::VDIVSD, VEXOperandCode::G_V_E_xmm), + 0x5f => (Opcode::VMAXSD, VEXOperandCode::G_V_E_xmm), 0x70 => (Opcode::VPSHUFLW, if L { VEXOperandCode::G_E_ymm_imm8 } else { VEXOperandCode::G_E_xmm_imm8 }), 0x7c => (Opcode::VHADDPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x7d => (Opcode::VHSUBPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), + 0xc2 => (Opcode::VCMPSD, VEXOperandCode::G_V_E_xmm_imm8), 0xd0 => (Opcode::VADDSUBPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xe6 => (Opcode::VCVTPD2DQ, if L { VEXOperandCode::G_xmm_E_ymm @@ -933,13 +1118,41 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } VEXOpcodePrefix::PrefixF3 => { match opc { + 0x10 => (Opcode::VMOVSS, VEXOperandCode::VMOVSS_10), + 0x11 => (Opcode::VMOVSS, VEXOperandCode::VMOVSS_11), 0x12 => (Opcode::VMOVSLDUP, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }), 0x16 => (Opcode::VMOVSHDUP, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }), + 0x2a => (Opcode::VCVTSI2SS, if instruction.prefixes.vex().w() { + VEXOperandCode::G_V_E_xmm // 64-bit last operand + } else { + VEXOperandCode::G_V_E_xmm // 32-bit last operand + }), + 0x2c => (Opcode::VCVTTSS2SI, if instruction.prefixes.vex().w() { + VEXOperandCode::G_E_xmm // 64-bit + } else { + VEXOperandCode::G_E_xmm // 32-bit + }), + 0x2d => (Opcode::VCVTSD2SI, if instruction.prefixes.vex().w() { + VEXOperandCode::G_E_xmm // 64-bit + } else { + VEXOperandCode::G_E_xmm // 32-bit + }), + 0x51 => (Opcode::VSQRTSS, VEXOperandCode::G_V_E_xmm), + 0x52 => (Opcode::VRSQRTSS, VEXOperandCode::G_V_E_xmm), + 0x53 => (Opcode::VRCPSS, VEXOperandCode::G_V_E_xmm), + 0x58 => (Opcode::VADDSS, VEXOperandCode::G_V_E_xmm), + 0x59 => (Opcode::VMULSS, VEXOperandCode::G_V_E_xmm), + 0x5a => (Opcode::VCVTSS2SD, VEXOperandCode::G_V_E_xmm), 0x5b => (Opcode::VCVTTPS2DQ, if L { VEXOperandCode::G_ymm_E_ymm } else { VEXOperandCode::G_xmm_E_xmm }), + 0x5c => (Opcode::VSUBSS, VEXOperandCode::G_V_E_xmm), + 0x5d => (Opcode::VMINSS, VEXOperandCode::G_V_E_xmm), + 0x5e => (Opcode::VDIVSS, VEXOperandCode::G_V_E_xmm), + 0x5f => (Opcode::VMAXSS, VEXOperandCode::G_V_E_xmm), 0x6f => (Opcode::VMOVDQU, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }), 0x70 => (Opcode::VMOVSHDUP, if L { VEXOperandCode::G_E_ymm_imm8 } else { VEXOperandCode::G_E_xmm_imm8 }), 0x7e => (Opcode::VMOVQ, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { VEXOperandCode::G_E_xmm }), 0x7f => (Opcode::VMOVDQU, if L { VEXOperandCode::E_G_ymm } else { VEXOperandCode::E_G_xmm }), + 0xc2 => (Opcode::VCMPSS, VEXOperandCode::G_V_E_xmm_imm8), 0xe6 => (Opcode::VCVTDQ2PD, if L { VEXOperandCode::G_ymm_E_xmm } else { VEXOperandCode::G_xmm_E_xmm }), _ => { instruction.opcode = Opcode::Invalid; @@ -955,186 +1168,186 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & // possibly valid! match opc { 0x00 => (Opcode::VPSHUFB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x01 => (Opcode::VPHADDW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x02 => (Opcode::VPHADDD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x03 => (Opcode::VPHADDSW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), - 0x04 => (Opcode::VPMADDUBSW, if L { - VEXOperandCode::V_G_E_ymm + 0x04 => (Opcode::VPHADDUBSW, if L { + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x05 => (Opcode::VPHSUBW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x06 => (Opcode::VPHSUBD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x07 => (Opcode::VPHSUBSW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x08 => (Opcode::VPSIGNB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x09 => (Opcode::VPSIGNW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x0A => (Opcode::VPSIGND, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x0B => (Opcode::VPMULHRSW, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x0C => (Opcode::VPERMILPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x0D => (Opcode::VPERMILPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x0E => (Opcode::VTESTPS, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x0F => (Opcode::VTESTPD, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x13 => (Opcode::VCVTPH2PS, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x16 => (Opcode::VPERMPS, if L { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm } else { instruction.opcode = Opcode::Invalid; return Err(()); }), 0x17 => (Opcode::VPTEST, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x18 => (Opcode::VBROADCASTSS, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x19 => (Opcode::VBROADCASTSD, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x1A => (Opcode::VBROADCASTF128, if L { - VEXOperandCode::V15_G_M_ymm + VEXOperandCode::G_M_ymm } else { instruction.opcode = Opcode::Invalid; return Err(()); }), 0x1C => (Opcode::VPABSB, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x1D => (Opcode::VPABSW, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x1E => (Opcode::VPABSD, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x20 => (Opcode::VPMOVSXBW, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x21 => (Opcode::VPMOVSXBD, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x22 => (Opcode::VPMOVSXBQ, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x23 => (Opcode::VPMOVSXWD, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x24 => (Opcode::VPMOVSXWQ, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x25 => (Opcode::VPMOVSXDQ, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x28 => (Opcode::VPMULDQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x29 => (Opcode::VPCMPEQQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x2A => (Opcode::VMOVNTDQA, if L { - VEXOperandCode::V15_G_M_ymm + VEXOperandCode::G_M_ymm } else { - VEXOperandCode::V15_G_M_xmm + VEXOperandCode::G_M_xmm }), 0x2C => (Opcode::VMASKMOVPS, if L { - VEXOperandCode::V_G_M_ymm + VEXOperandCode::G_V_M_ymm } else { - VEXOperandCode::V_G_M_xmm + VEXOperandCode::G_V_M_xmm }), 0x2D => (Opcode::VMASKMOVPD, if L { - VEXOperandCode::V_G_M_ymm + VEXOperandCode::G_V_M_ymm } else { - VEXOperandCode::V_G_M_xmm + VEXOperandCode::G_V_M_xmm }), 0x2E => (Opcode::VMASKMOVPS, if L { VEXOperandCode::M_V_G_ymm @@ -1147,146 +1360,146 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::M_V_G_xmm }), 0x30 => (Opcode::VPMOVZXBW, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x31 => (Opcode::VPMOVZXBD, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x32 => (Opcode::VPMOVZXBQ, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x33 => (Opcode::VPMOVZXWD, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x34 => (Opcode::VPMOVZXWQ, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x35 => (Opcode::VPMOVZXDQ, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { instruction.opcode = Opcode::Invalid; return Err(()); }), 0x36 => (Opcode::VPERMD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { instruction.opcode = Opcode::Invalid; return Err(()); }), 0x37 => (Opcode::VPCMPGTQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x39 => (Opcode::VPMINSD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x3B => (Opcode::VPMINUD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x3C => (Opcode::VPMAXSB, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x3D => (Opcode::VPMAXSD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x3F => (Opcode::VPMAXUD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x40 => (Opcode::VPMULLD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x41 => (Opcode::VPHMINPOSUW, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x45 => (Opcode::VPSRLVD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x45 => (Opcode::VPSRLVQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x46 => (Opcode::VPSRAVD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x47 => (Opcode::VPSLLVD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x47 => (Opcode::VPSLLVQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x58 => (Opcode::VPBROADCASTD, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x59 => (Opcode::VPBROADCASTQ, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0x5A => (Opcode::VBROADCASTI128, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { instruction.opcode = Opcode::Invalid; return Err(()); }), 0x78 => (Opcode::VPBROADCASTB, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm }), 0x79 => (Opcode::VPBROADCASTW, if L { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm } else { - VEXOperandCode::V15_G_E_ymm + VEXOperandCode::G_E_ymm }), 0x8C => { if instruction.prefixes.vex().w() { (Opcode::VPMASKMOVD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VPMASKMOVQ, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, @@ -1295,44 +1508,43 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & (Opcode::VPMASKMOVD, if L { VEXOperandCode::E_V_G_ymm } else { - VEXOperandCode::E_V_G_ymm + VEXOperandCode::E_V_G_xmm }) } else { (Opcode::VPMASKMOVQ, if L { VEXOperandCode::E_V_G_ymm } else { - VEXOperandCode::E_V_G_ymm + VEXOperandCode::E_V_G_xmm }) } }, - // TODO 0x90 => { if instruction.prefixes.vex().w() { - (Opcode::VPGATHERDD, if L { - VEXOperandCode::G_E_ymm_imm8 + (Opcode::VPGATHERDQ, if L { + VEXOperandCode::G_Ey_V_ymm } else { - VEXOperandCode::G_E_xmm_imm8 + VEXOperandCode::G_Ex_V_xmm }) } else { - (Opcode::VPGATHERDQ, if L { - VEXOperandCode::G_E_ymm_imm8 + (Opcode::VPGATHERDD, if L { + VEXOperandCode::G_Ey_V_ymm } else { - VEXOperandCode::G_E_xmm_imm8 + VEXOperandCode::G_Ex_V_xmm }) } }, 0x91 => { if instruction.prefixes.vex().w() { - (Opcode::VPGATHERQD, if L { - VEXOperandCode::G_E_ymm_imm8 + (Opcode::VPGATHERQQ, if L { + VEXOperandCode::G_Ey_V_ymm } else { - VEXOperandCode::G_E_xmm_imm8 + VEXOperandCode::G_Ex_V_xmm }) } else { - (Opcode::VPGATHERQQ, if L { - VEXOperandCode::G_E_ymm_imm8 + (Opcode::VPGATHERQD, if L { + VEXOperandCode::G_Ey_V_ymm } else { - VEXOperandCode::G_E_xmm_imm8 + VEXOperandCode::G_Ex_V_xmm }) } }, @@ -1369,302 +1581,362 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & 0x96 => { if instruction.prefixes.vex().w() { (Opcode::VFMADDSUB132PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMADDSUB132PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, 0x97 => { if instruction.prefixes.vex().w() { (Opcode::VFMSUBADD132PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMSUBADD132PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, 0x98 => { if instruction.prefixes.vex().w() { (Opcode::VFMADD132PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMADD132PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0x99 => if instruction.prefixes.vex().w() { + (Opcode::VFMADD132SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFMADD132SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0x9A => { if instruction.prefixes.vex().w() { (Opcode::VFMSUB132PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMSUB132PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0x9B => if instruction.prefixes.vex().w() { + (Opcode::VFMSUB132SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFMSUB132SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0x9C => { if instruction.prefixes.vex().w() { (Opcode::VFNMADD132PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFNMADD132PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0x9D => if instruction.prefixes.vex().w() { + (Opcode::VFNMADD132SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFNMADD132SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0x9E => { if instruction.prefixes.vex().w() { (Opcode::VFNMSUB132PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFNMSUB132PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0x9F => if instruction.prefixes.vex().w() { + (Opcode::VFNMSUB132SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFNMSUB132SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0xA6 => { if instruction.prefixes.vex().w() { (Opcode::VFMADDSUB213PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMADDSUB213PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, 0xA7 => { if instruction.prefixes.vex().w() { (Opcode::VFMSUBADD213PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMSUBADD213PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, 0xA8 => { if instruction.prefixes.vex().w() { (Opcode::VFMADD213PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMADD213PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0xA9 => if instruction.prefixes.vex().w() { + (Opcode::VFMADD231SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFMADD231SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0xAA => { if instruction.prefixes.vex().w() { (Opcode::VFMSUB213PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMSUB213PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0xAB => if instruction.prefixes.vex().w() { + (Opcode::VFMSUB231SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFMSUB231SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0xAC => { if instruction.prefixes.vex().w() { (Opcode::VFNMADD213PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFNMADD213PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0xAD => if instruction.prefixes.vex().w() { + (Opcode::VFNMADD213SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFNMADD213SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0xAE => { if instruction.prefixes.vex().w() { (Opcode::VFNMSUB213PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFNMSUB213PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0xAF => if instruction.prefixes.vex().w() { + (Opcode::VFNMSUB213SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFNMSUB213SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0xB6 => { if instruction.prefixes.vex().w() { (Opcode::VFMADDSUB231PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMADDSUB231PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, 0xB7 => { if instruction.prefixes.vex().w() { (Opcode::VFMSUBADD231PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMSUBADD231PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, 0xB8 => { if instruction.prefixes.vex().w() { (Opcode::VFMADD231PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMADD231PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0xB9 => if instruction.prefixes.vex().w() { + (Opcode::VFMADD231SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFMADD231SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0xBA => { if instruction.prefixes.vex().w() { (Opcode::VFMSUB231PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFMSUB231PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0xBB => if instruction.prefixes.vex().w() { + (Opcode::VFMSUB231SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFMSUB231SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0xBC => { if instruction.prefixes.vex().w() { (Opcode::VFNMADD231PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFNMADD231PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0xBD => if instruction.prefixes.vex().w() { + (Opcode::VFNMADD231SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFNMADD231SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0xBE => { if instruction.prefixes.vex().w() { (Opcode::VFNMSUB231PD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } else { (Opcode::VFNMSUB231PS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm }) } }, + 0xBF => if instruction.prefixes.vex().w() { + (Opcode::VFNMSUB231SD, VEXOperandCode::G_V_E_xmm /* 64bit */) + } else { + (Opcode::VFNMSUB231SS, VEXOperandCode::G_V_E_xmm /* 64bit */) + }, 0xDB => (Opcode::VAESIMC, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V15_G_E_xmm + VEXOperandCode::G_E_xmm }), 0xDC => (Opcode::VAESENC, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xDD => (Opcode::VAESENCLAST, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xDE => (Opcode::VAESDEC, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0xDF => (Opcode::VAESDECLAST, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), _ => { instruction.opcode = Opcode::Invalid; @@ -1694,22 +1966,22 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & return Err(()); }), 0x02 => (Opcode::VPBLENDD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x04 => (Opcode::VPERMILPS, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x05 => (Opcode::VPERMILPD, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { - VEXOperandCode::V_G_E_xmm + VEXOperandCode::G_V_E_xmm }), 0x06 => (Opcode::VPERM2F128, if L { - VEXOperandCode::V_G_E_ymm + VEXOperandCode::G_V_E_ymm } else { instruction.opcode = Opcode::Invalid; return Err(()); @@ -1725,50 +1997,53 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_xmm_imm8 }), 0x0C => (Opcode::VBLENDPS, if L { - VEXOperandCode::V_G_E_ymm_imm8 + VEXOperandCode::G_V_E_ymm_imm8 } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x0D => (Opcode::VBLENDPD, if L { - VEXOperandCode::V_G_E_ymm_imm8 + VEXOperandCode::G_V_E_ymm_imm8 } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x0E => (Opcode::VPBLENDW, if L { - VEXOperandCode::V_G_E_ymm_imm8 + VEXOperandCode::G_V_E_ymm_imm8 } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x0F => (Opcode::VPALIGNR, if L { - VEXOperandCode::V_G_E_ymm_imm8 - } else { - VEXOperandCode::V_G_E_xmm_imm8 - }), - 0x14 => (Opcode::VPEXTRB, if L { - instruction.opcode = Opcode::Invalid; - return Err(()); + VEXOperandCode::G_V_E_ymm_imm8 } else { - VEXOperandCode::Ev_G_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), - 0x15 => (Opcode::VPEXTRW, if L { + 0x14 => (Opcode::VPEXTRB, if L || instruction.prefixes.vex().w() { instruction.opcode = Opcode::Invalid; return Err(()); } else { VEXOperandCode::Ev_G_xmm_imm8 }), - 0x16 => (Opcode::VPEXTRD, if L { + 0x15 => (Opcode::VPEXTRW, if L || instruction.prefixes.vex().w() { instruction.opcode = Opcode::Invalid; return Err(()); } else { - // varies on W VEXOperandCode::Ev_G_xmm_imm8 }), - 0x16 => (Opcode::VPEXTRQ, if L { - instruction.opcode = Opcode::Invalid; - return Err(()); + 0x16 => if instruction.prefixes.vex().w() { + (Opcode::VPEXTRQ, if L { + instruction.opcode = Opcode::Invalid; + return Err(()); + } else { + VEXOperandCode::G_E_ymm_imm8 + }) } else { - VEXOperandCode::G_E_ymm_imm8 - }), + (Opcode::VPEXTRD, if L { + instruction.opcode = Opcode::Invalid; + return Err(()); + } else { + // varies on W + VEXOperandCode::Ev_G_xmm_imm8 + }) + }, 0x17 => (Opcode::VEXTRACTPS, if L { instruction.opcode = Opcode::Invalid; return Err(()); @@ -1776,7 +2051,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & VEXOperandCode::G_E_ymm_imm8 }), 0x18 => (Opcode::VINSERTF128, if L { - VEXOperandCode::V_G_E_ymm_imm8 + VEXOperandCode::G_V_E_ymm_imm8 } else { instruction.opcode = Opcode::Invalid; return Err(()); @@ -1796,25 +2071,25 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x21 => (Opcode::VINSERTPS, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x22 => (Opcode::VPINSRD, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x22 => (Opcode::VPINSRQ, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x38 => (Opcode::VINSERTI128, if L { instruction.opcode = Opcode::Invalid; @@ -1829,15 +2104,15 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & return Err(()); }), 0x40 => (Opcode::VDPPS, if L { - VEXOperandCode::V_G_E_ymm_imm8 + VEXOperandCode::G_V_E_ymm_imm8 } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x41 => (Opcode::VDPPD, if L { instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x42 => (Opcode::VMPSADBW, if L { VEXOperandCode::G_E_ymm_imm8 @@ -1848,28 +2123,28 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & instruction.opcode = Opcode::Invalid; return Err(()); } else { - VEXOperandCode::V_G_E_xmm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 }), 0x46 => (Opcode::VPERM2I128, if L { - VEXOperandCode::V_G_E_ymm_imm8 + VEXOperandCode::G_V_E_ymm_imm8 } else { instruction.opcode = Opcode::Invalid; return Err(()); }), 0x4A => (Opcode::VBLENDVPS, if L { - VEXOperandCode::V_G_E_ymm_ymm4 + VEXOperandCode::G_V_E_ymm_ymm4 } else { - VEXOperandCode::V_G_E_xmm_xmm4 + VEXOperandCode::G_V_E_xmm_xmm4 }), 0x4B => (Opcode::VBLENDVPD, if L { - VEXOperandCode::V_G_E_ymm_ymm4 + VEXOperandCode::G_V_E_ymm_ymm4 } else { - VEXOperandCode::V_G_E_xmm_xmm4 + VEXOperandCode::G_V_E_xmm_xmm4 }), 0x4C => (Opcode::VPBLENDVB, if L { - VEXOperandCode::V_G_E_ymm_ymm4 + VEXOperandCode::G_V_E_ymm_ymm4 } else { - VEXOperandCode::V_G_E_xmm_xmm4 + VEXOperandCode::G_V_E_xmm_xmm4 }), 0x62 => (Opcode::VPCMPISTRM, if L { instruction.opcode = Opcode::Invalid; diff --git a/src/vex_ops b/src/vex_ops new file mode 100644 index 0000000..d2ca692 --- /dev/null +++ b/src/vex_ops @@ -0,0 +1,273 @@ + VMOVDDUP, + VPSHUFLW, + VHADDPS, + VHSUBPS, + VADDSUBPS, + VCVTPD2DQ, + VLDDQU, + + VADDPD, + VADDPS, + VADDSUBPD, + VAESDEC, + VAESDECLAST, + VAESENC, + VAESENCLAST, + VAESIMC, + VAESKEYGENASSIST, + VBLENDPD, + VBLENDPS, + VBLENDVPD, + VBLENDVPS, + VBROADCASTF128, + VBROADCASTI128, + VBROADCASTSD, + VBROADCASTSS, + VCMPPD, + VCMPPS, + VCVTDQ2PD, + VCVTDQ2PS, + VCVTPD2PS, + VCVTPH2PS, + VCVTPS2DQ, + VCVTPS2PD, + VCVTPS2PH, + VCVTTPD2DQ, + VCVTTPS2DQ, + VDIVPD, + VDIVPS, + VDPPD, + VDPPS, + VEXTRACTF128, + VEXTRACTI128, + VEXTRACTPS, + VFMADD132PD, + VFMADD132PS, + VFMADD213PD, + VFMADD213PS, + VFMADD231PD, + VFMADD231PS, + VFMADDSUB132PD, + VFMADDSUB132PS, + VFMADDSUB213PD, + VFMADDSUB213PS, + VFMADDSUB231PD, + VFMADDSUB231PS, + VFMSUB132PD, + VFMSUB132PS, + VFMSUB213PD, + VFMSUB213PS, + VFMSUB231PD, + VFMSUB231PS, + VFMSUBADD132PD, + VFMSUBADD132PS, + VFMSUBADD213PD, + VFMSUBADD213PS, + VFMSUBADD231PD, + VFMSUBADD231PS, + VFNMADD132PD, + VFNMADD132PS, + VFNMADD213PD, + VFNMADD213PS, + VFNMADD231PD, + VFNMADD231PS, + VFNMSUB132PD, + VFNMSUB132PS, + VFNMSUB213PD, + VFNMSUB213PS, + VFNMSUB231PD, + VFNMSUB231PS, + VGATHERDPD, + VGATHERDPS, + VGATHERQPD, + VGATHERQPS, + VHADDPD, + VHSUBPD, + VINSERTF128, + VINSERTI128, + VINSERTPS, + VMASKMOVDQU, + VMASKMOVPD, + VMASKMOVPS, + VMAXPD, + VMAXPS, + VMINPD, + VMINPS, + VMOVAPD, + VMOVAPS, + VMOVD, + VMOVDQA, + VMOVDQU, + VMOVHLPS, + VMOVHPD, + VMOVHPS, + VMOVLHPS, + VMOVLPD, + VMOVLPS, + VMOVMSKPD, + VMOVMSKPS, + VMOVNTDQ, + VMOVNTDQA, + VMOVNTPD, + VMOVNTPS, + VMOVQ, + VMOVSHDUP, + VMOVSLDUP, + VMOVUPD, + VMOVUPS, + VMPSADBW, + VMULPD, + VMULPS, + VPABSB, + VPABSD, + VPABSW, + VPACKSSDW, + VPACKSSWB, + VPACKUSWB, + VPADDB, + VPADDD, + VPADDQ, + VPADDSB, + VPADDSW, + VPADDUSB, + VPADDUSW, + VPADDW, + VPALIGNR, + VPAND, + VPANDN, + VPAVGB, + VPAVGW, + VPBLENDD, + VPBLENDVB, + VPBLENDW, + VPBROADCASTB, + VPBROADCASTD, + VPBROADCASTQ, + VPBROADCASTW, + VPCLMULQDQ, + VPCMPEQB, + VPCMPEQD, + VPCMPEQQ, + VPCMPEQW, + VPCMPGTB, + VPCMPGTD, + VPCMPGTQ, + VPCMPGTW, + VPCMPISTRI, + VPCMPISTRM, + VPERM2F128, + VPERM2I128, + VPERMD, + VPERMILPD, + VPERMILPS, + VPERMPD, + VPERMPS, + VPERMQ, + VPEXTRB, + VPEXTRD, + VPEXTRQ, + VPEXTRW, + VPGATHERDD, + VPGATHERDQ, + VPGATHERQD, + VPGATHERQQ, + VPHADDD, + VPHADDSW, + VPHADDW, + VPHMINPOSUW, + VPHSUBD, + VPHSUBSW, + VPHSUBW, + VPINSRB, + VPINSRD, + VPINSRQ, + VPINSRW, + VPMADDUBSW, + VPMADDWD, + VPMASKMOVD, + VPMASKMOVQ, + VPMAXSB, + VPMAXSD, + VPMAXSW, + VPMAXUD, + VPMINSD, + VPMINUD, + VPMOVMSKB, + VPMOVSXBD, + VPMOVSXBQ, + VPMOVSXBW, + VPMOVSXDQ, + VPMOVSXWD, + VPMOVSXWQ, + VPMOVZXBD, + VPMOVZXBQ, + VPMOVZXBW, + VPMOVZXDQ, + VPMOVZXWD, + VPMOVZXWQ, + VPMULDQ, + VPMULHRSW, + VPMULHUW, + VPMULHW, + VPMULLD, + VPMULLW, + VPMULUDQ, + VPOR, + VPSADBW, + VPSHUFB, + VPSHUFD, + VPSIGNB, + VPSIGND, + VPSIGNW, + VPSLLD, + VPSLLDQ, + VPSLLQ, + VPSLLVD, + VPSLLVQ, + VPSLLW, + VPSRAD, + VPSRAVD, + VPSRAW, + VPSRLD, + VPSRLDQ, + VPSRLQ, + VPSRLVD, + VPSRLVQ, + VPSRLW, + VPSUBB, + VPSUBD, + VPSUBQ, + VPSUBSB, + VPSUBSW, + VPSUBUSB, + VPSUBUSW, + VPSUBW, + VPTEST, + VPUNPCKHBW, + VPUNPCKHDQ, + VPUNPCKHQDQ, + VPUNPCKHWD, + VPUNPCKLBW, + VPUNPCKLDQ, + VPUNPCKLQDQ, + VPUNPCKLWD, + VPXOR, + VRCPPS, + VROUNDPD, + VROUNDPS, + VRSQRTPS, + VSHUFPD, + VSHUFPS, + VSQRTPD, + VSQRTPS, + VSUBPD, + VSUBPS, + VTESTPD, + VTESTPS, + VUNPCKHPD, + VUNPCKHPS, + VUNPCKLPD, + VUNPCKLPS, + VXORPD, + VXORPS, + VZEROUPPER, diff --git a/test/test.rs b/test/test.rs index 8452e89..3b902dc 100644 --- a/test/test.rs +++ b/test/test.rs @@ -297,86 +297,86 @@ fn test_vex() { test_display(&[0xc5, 0xfa, 0x7e, 0x10], "vmovq xmm2, [rax]"); test_display(&[0xc5, 0xfc, 0x10, 0x0f], "vmovups ymm1, [rdi]"); test_display(&[0xc5, 0xfd, 0x10, 0x0f], "vmovupd ymm1, [rdi]"); - test_display(&[0xc5, 0xfe, 0x10, 0x0f], "vmovss ymm1, [rdi]"); + test_display(&[0xc5, 0xfe, 0x10, 0x0f], "vmovss xmm1, [rdi]"); test_display(&[0xc5, 0xff, 0x10, 0xcf], "vmovsd xmm1, xmm0, xmm7"); test_display(&[0xc5, 0xff, 0x10, 0x00], "vmovsd xmm0, [rax]"); test_invalid(&[0x4f, 0xc5, 0xf8, 0x10, 0x00]); test_invalid(&[0xf0, 0xc5, 0xf8, 0x10, 0x00]); - test_display(&[0xc4, 0x02, 0x71, 0x00, 0x00], "vpshufb xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x00, 0x00], "vpshufb ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x00, 0x0f], "vpshufb xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x00, 0x0f], "vpshufb ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x00, 0xcd], "vpshufb xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x00, 0xcd], "vpshufb ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x01, 0x00], "vphaddw xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x01, 0x00], "vphaddw ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x01, 0x0f], "vphaddw xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x01, 0x0f], "vphaddw ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x01, 0xcd], "vphaddw xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x01, 0xcd], "vphaddw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x02, 0x00], "vphaddd xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x02, 0x00], "vphaddd ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x02, 0x0f], "vphaddd xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x02, 0x0f], "vphaddd ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x02, 0xcd], "vphaddd xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x02, 0xcd], "vphaddd ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x03, 0x00], "vphaddsw xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x03, 0x00], "vphaddsw ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x03, 0x0f], "vphaddsw xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x03, 0x0f], "vphaddsw ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x03, 0xcd], "vphaddsw xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x03, 0xcd], "vphaddsw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x04, 0x00], "vphaddubsw xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x04, 0x00], "vphaddubsw ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x04, 0x0f], "vphaddubsw xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x04, 0x0f], "vphaddubsw ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x04, 0xcd], "vphaddubsw xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x04, 0xcd], "vphaddubsw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x05, 0x00], "vphsubw xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x05, 0x00], "vphsubw ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x05, 0x0f], "vphsubw xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x05, 0x0f], "vphsubw ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x05, 0xcd], "vphsubw xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x05, 0xcd], "vphsubw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x06, 0x00], "vphsubd xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x06, 0x00], "vphsubd ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x06, 0x0f], "vphsubd xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x06, 0x0f], "vphsubd ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x06, 0xcd], "vphsubd xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x06, 0xcd], "vphsubd ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x07, 0x00], "vphsubsw xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x07, 0x00], "vphsubsw ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x07, 0x0f], "vphsubsw xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x07, 0x0f], "vphsubsw ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x07, 0xcd], "vphsubsw xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x07, 0xcd], "vphsubsw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x08, 0x00], "vpsignb xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x08, 0x00], "vpsignb ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x08, 0x0f], "vpsignb xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x08, 0x0f], "vpsignb ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x08, 0xcd], "vpsignb xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x08, 0xcd], "vpsignb ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x09, 0x00], "vpsignw xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x09, 0x00], "vpsignw ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x09, 0x0f], "vpsignw xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x09, 0x0f], "vpsignw ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x09, 0xcd], "vpsignw xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x09, 0xcd], "vpsignw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x0a, 0x00], "vpsignd xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x0a, 0x00], "vpsignd ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x0a, 0x0f], "vpsignd xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x0a, 0x0f], "vpsignd ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x0a, 0xcd], "vpsignd xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x0a, 0xcd], "vpsignd ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x0b, 0x00], "vpmulhrsw xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x0b, 0x00], "vpmulhrsw ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x0b, 0x0f], "vpmulhrsw xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x0b, 0x0f], "vpmulhrsw ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x0b, 0xcd], "vpmulhrsw xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x0b, 0xcd], "vpmulhrsw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x0c, 0x00], "vpermilps xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x0c, 0x00], "vpermilps ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x0c, 0x0f], "vpermilps xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x0c, 0x0f], "vpermilps ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x0c, 0xcd], "vpermilps xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x0c, 0xcd], "vpermilps ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x0d, 0x00], "vpermilpd xmm9, xmm1, [r8]"); - test_display(&[0xc4, 0x02, 0x75, 0x0d, 0x00], "vpermilpd ymm9, ymm1, [r8]"); + test_display(&[0xc4, 0x02, 0x71, 0x0d, 0x0f], "vpermilpd xmm9, xmm1, [r15]"); + test_display(&[0xc4, 0x02, 0x75, 0x0d, 0x0f], "vpermilpd ymm9, ymm1, [r15]"); test_display(&[0xc4, 0x02, 0x71, 0x0d, 0xcd], "vpermilpd xmm9, xmm1, xmm13"); test_display(&[0xc4, 0x02, 0x75, 0x0d, 0xcd], "vpermilpd ymm9, ymm1, ymm13"); test_invalid(&[0xc4, 0x02, 0x71, 0x0e, 0x00]); - test_display(&[0xc4, 0x02, 0x79, 0x0e, 0x00], "vtestps xmm8, [r8]"); - test_display(&[0xc4, 0x02, 0x7d, 0x0e, 0x00], "vtestps ymm8, [r8]"); + test_display(&[0xc4, 0x02, 0x79, 0x0e, 0x0f], "vtestps xmm9, [r15]"); + test_display(&[0xc4, 0x02, 0x7d, 0x0e, 0x0f], "vtestps ymm9, [r15]"); test_display(&[0xc4, 0x02, 0x79, 0x0e, 0xcd], "vtestps xmm9, xmm13"); test_display(&[0xc4, 0x02, 0x7d, 0x0e, 0xcd], "vtestps ymm9, ymm13"); test_invalid(&[0xc4, 0x02, 0x71, 0x0f, 0x00]); - test_display(&[0xc4, 0x02, 0x79, 0x0f, 0x00], "vtestpd xmm8, [r8]"); - test_display(&[0xc4, 0x02, 0x7d, 0x0f, 0x00], "vtestpd ymm8, [r8]"); + test_display(&[0xc4, 0x02, 0x79, 0x0f, 0x0f], "vtestpd xmm9, [r15]"); + test_display(&[0xc4, 0x02, 0x7d, 0x0f, 0x0f], "vtestpd ymm9, [r15]"); test_display(&[0xc4, 0x02, 0x79, 0x0f, 0xcd], "vtestpd xmm9, xmm13"); test_display(&[0xc4, 0x02, 0x7d, 0x0f, 0xcd], "vtestpd ymm9, ymm13"); test_display(&[0xc4, 0xe2, 0x65, 0x90, 0x04, 0x51], "vpgatherdd ymm0, [rcx + ymm2 * 2], ymm3"); test_display(&[0xc4, 0xe2, 0xe5, 0x90, 0x04, 0x51], "vpgatherdq ymm0, [rcx + ymm2 * 2], ymm3"); test_display(&[0xc4, 0xe2, 0x65, 0x91, 0x04, 0x51], "vpgatherqd ymm0, [rcx + ymm2 * 2], ymm3"); test_display(&[0xc4, 0xe2, 0xe5, 0x91, 0x04, 0x51], "vpgatherqq ymm0, [rcx + ymm2 * 2], ymm3"); - test_display(&[0xc4, 0x02, 0x09, 0x9d, 0xcd], "vfnmadd132ss xmm9, xmm14, xmm11"); - test_display(&[0xc4, 0x02, 0x89, 0x9d, 0xcd], "vfnmadd132ss xmm9, xmm14, xmm11"); + test_display(&[0xc4, 0x02, 0x09, 0x9d, 0xcd], "vfnmadd132ss xmm9, xmm14, xmm13"); + test_display(&[0xc4, 0x02, 0x89, 0x9d, 0xcd], "vfnmadd132sd xmm9, xmm14, xmm13"); // ... - test_display(&[0xc4, 0xe3, 0x79, 0x14, 0x00, 0xd0], "vpextrb rax, xmm2, 0x0a"); - test_display(&[0xc4, 0xe3, 0x79, 0x14, 0x00, 0x0a], "vpextrb [rax], xmm2, 0x0a"); + test_display(&[0xc4, 0xe3, 0x79, 0x14, 0xd0, 0x0a], "vpextrb rax, xmm2, 0xa"); + test_display(&[0xc4, 0xe3, 0x79, 0x14, 0x10, 0x0a], "vpextrb [rax], xmm2, 0xa"); test_invalid(&[0xc4, 0xe3, 0xf9, 0x14, 0x00, 0xd0]); test_invalid(&[0xc4, 0xe3, 0xf9, 0x14, 0x00, 0x0a]); } |