From a5aa1cab2c050428839afcd4ed6057ec66a6c9cb Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 11 Feb 2023 12:27:01 -0800 Subject: wip --- src/long_mode/mod.rs | 1057 ++++++++++++++++------------- src/long_mode/vex.rs | 1823 +++++++++++++------------------------------------- 2 files changed, 1063 insertions(+), 1817 deletions(-) (limited to 'src/long_mode') diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 671fa02..73f658a 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -264,14 +264,6 @@ impl RegSpec { } #[inline] - fn gp_from_parts_byte(num: u8, extended: bool, rex: bool) -> RegSpec { - RegSpec { - num: num + if extended { 0b1000 } else { 0 }, - bank: if rex { RegisterBank::rB } else { RegisterBank::B } - } - } - - #[inline] fn gp_from_parts_non_byte(num: u8, extended: bool, bank: RegisterBank) -> RegSpec { RegSpec { num: num + if extended { 0b1000 } else { 0 }, @@ -1067,19 +1059,41 @@ const XSAVE: [Opcode; 10] = [ Opcode::XSETBV, ]; +//struct OpcodeBuilder { +// variant_specifier: OpcodeVariantInfo + /// an `x86_64` opcode. there sure are a lot of these. #[allow(non_camel_case_types)] #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[non_exhaustive] #[repr(u32)] pub enum Opcode { - ADD = 0, - OR, - ADC, - SBB, - AND, - SUB, - XOR, +ADD = 0x1000, +ADC = 0x1001, +AND = 0x1002, +BTC = 0x1003, +BTR = 0x1004, +BTS = 0x1005, +CMPXCHG = 0x1006, +CMPXCHG8B = 0x1007, +CMPXCHG16B = 0x1008, +DEC = 0x1009, +INC = 0x100a, +NEG = 0x100b, +NOT = 0x100c, +OR = 0x100d, +SBB = 0x100e, +SUB = 0x100f, +XOR = 0x1010, +XADD = 0x1011, +XCHG = 0x1012, +// ADD = 0, +// OR, +// ADC, +// SBB, +// AND, +// SUB, +// XOR, CMP, ROL = 8, ROR, @@ -1089,12 +1103,12 @@ pub enum Opcode { SHR, SAL, SAR, - Invalid, - XADD, + Invalid = 16, +// XADD, BT, - BTS, - BTC, - BTR, +// BTS, +// BTC, +// BTR, BSF, BSR, TZCNT, @@ -1139,8 +1153,8 @@ pub enum Opcode { MOVSX, MOVSXD, SHRD, - INC, - DEC, +// INC, +// DEC, HLT, CALL, CALLF, @@ -1154,7 +1168,7 @@ pub enum Opcode { PREFETCH0, PREFETCH1, PREFETCH2, - XCHG, +// XCHG, POPF, INT, INTO, @@ -1222,9 +1236,9 @@ pub enum Opcode { DIV, IDIV, MUL, - NEG, - NOT, - CMPXCHG, +// NEG, +// NOT, +// CMPXCHG, SETO, SETNO, SETB, @@ -1949,8 +1963,8 @@ pub enum Opcode { PREFETCHW, RDPID, - CMPXCHG8B, - CMPXCHG16B, +// CMPXCHG8B, +// CMPXCHG16B, VMPTRLD, VMPTRST, @@ -4535,6 +4549,7 @@ pub struct Prefixes { segment: Segment, evex_data: EvexData, vqp_size: RegisterBank, + rb_size: RegisterBank, } /// the `avx512`-related data from an [`evex`](https://en.wikipedia.org/wiki/EVEX_prefix) prefix. @@ -4612,6 +4627,7 @@ impl Prefixes { segment: Segment::DS, evex_data: EvexData { bits: 0 }, vqp_size: RegisterBank::D, + rb_size: RegisterBank::B, } } #[inline] @@ -4681,6 +4697,17 @@ impl Prefixes { #[inline] fn vex_unchecked(&self) -> PrefixVex { PrefixVex { bits: self.rex.bits } } #[inline] + fn vex_invalid(&self) -> bool { + /* + * if instruction.prefixes.rex_unchecked().present() + * || instruction.prefixes.lock() + * || instruction.prefixes.operand_size() + * || instruction.prefixes.rep() + * || instruction.prefixes.repnz() { + */ + (self.bits & 0b1100_1001) > 0 || (self.rex.bits > 0) + } + #[inline] pub fn vex(&self) -> Option { let vex = self.vex_unchecked(); if vex.present() { @@ -4713,6 +4740,7 @@ impl Prefixes { #[inline] fn rex_from(&mut self, bits: u8) { self.rex.bits = bits; + self.rb_size = RegisterBank::rB; } #[inline(always)] @@ -4724,6 +4752,11 @@ impl Prefixes { } } + #[inline(always)] + fn rb_size(&self) -> RegisterBank { + self.rb_size + } + #[inline] fn vex_from_c5(&mut self, bits: u8) { // collect rex bits @@ -4904,20 +4937,13 @@ impl OperandCodeBuilder { } } - #[allow(unused)] - fn special_case_handler_index(&self) -> u16 { - self.bits & 0xff + fn operand_case_handler_index(&self) -> OperandCase { + unsafe { core::mem::transmute(self.bits as u8) } } - const fn special_case(mut self, case: u16) -> Self { + const fn operand_case(mut self, case: OperandCase) -> Self { // leave 0x4000 unset - self.bits |= case & 0xff; - self - } - - const fn operand_case(mut self, case: u16) -> Self { - // leave 0x4000 unset - self.bits |= case & 0xff; + self.bits |= case as u8 as u16; self } @@ -5010,6 +5036,194 @@ impl OperandCodeBuilder { pub struct OperandCodeWrapper { code: OperandCode } #[allow(non_camel_case_types)] +#[derive(Debug, PartialEq, Copy, Clone)] +#[repr(u8)] +enum OperandCase { + Internal = 0, // handled internally and completely by embedded rules. + Gv_M = 1, // "internal", but must be distinguished from Gv_Ev + Nothing = 2, // no operands. this is distinct from `Internal`: `Internal` may specify one or two operands depending on embedded rules. + SingleMMMOper = 3, // one operand, disregard rrr bits of modrm. + BaseOpWithI8 = 4, + BaseOpWithIv = 5, + MovI8 = 6, + MovIv = 7, + BitwiseWithI8 = 8, +// BitwiseWithIv = 9, + ShiftBy1_b, + ShiftBy1_v, + BitwiseByCL, + ModRM_0x8f, + ModRM_0xf6_0xf7, + ModRM_0xfe, + ModRM_0xff, + Gv_Eb, + Gv_Ew, + Gdq_Ed, + I_3, + E_G_xmm, + G_M_xmm, + G_E_xmm, + G_E_xmm_Ib, + AL_Ibs, + AX_Ivd, + Ivs, + ModRM_0x83, + Ed_G_xmm, + G_Ed_xmm, + + /* + Nothing = Nothing, + Eb_R0 = SingleMMMOper, + Ev = SingleMMMOper, + ModRM_0x80_Eb_Ib = BaseOpWithI8, + ModRM_0x81_Ev_Ivs = BaseOpWithIv, + ModRM_0xc6_Eb_Ib = MovI8, + ModRM_0xc7_Ev_Iv = MovIv, + ModRM_0xc0_Eb_Ib = BitwiseWithI8, + ModRM_0xc1_Ev_Ib = BitwiseWithIv, + ModRM_0xd0_Eb_1 = ShiftBy1_b, + ModRM_0xd1_Ev_1 = ShiftBy1_v, + ModRM_0x8f_Ev = ModRM_0x8f, + ModRM_0xd2_Eb_CL = BitwiseByCL, + ModRM_0xd3_Ev_CL = BitwiseByCL, + ModRM_0xf6 = ModRM_0xf6_0xf7, + ModRM_0xf7 = ModRM_0xf6_0xf7, + ModRM_0xfe_Eb = ModRM_0xfe, + ModRM_0xff_Ev = ModRM_0xff, + Gv_Eb = Gv_Eb, + Gv_Ew = Gv_Ew, + Gdq_Ed = Gdq_Ed, + I_3 = I_3, + E_G_xmm = E_G_xmm, + G_M_xmm = G_M_xmm, + G_E_xmm = G_E_xmm, + G_E_xmm_Ib = G_E_xmm_Ib, + AL_Ibs = AL_Ibs, + AX_Ivd = AX_Ivd, + Ivs = Ivs, + ModRM_0x83_Ev_Ibs = ModRM_0x83, + + Ed_G_xmm = Ed_G_xmm, + + G_Ed_xmm = G_Ed_xmm, + */ + + Ib, + x87_d8, + x87_d9, + x87_da, + x87_db, + x87_dc, + x87_dd, + x87_de, + x87_df, + AL_Ib, + AX_Ib, + Ib_AL, + Ib_AX, + Gv_Ew_LSL, + Gdq_Ev, + Gv_Ev_Ib, + Gv_Ev_Iv, + AX_DX, + AL_DX, + DX_AX, + DX_AL, + MOVQ_f30f, + Yv_Xv, + Gd_Ed, + Mdq_Gdq, + Md_Gd, + AL_Ob, + AL_Xb, + AX_Ov, + G_xmm_E_mm, + G_xmm_U_mm, + U_mm_G_xmm, + Rv_Gmm_Ib, + G_xmm_Edq, + G_xmm_Eq, + G_mm_E_xmm, + Gd_U_xmm, + Gv_E_xmm, + G_xmm_Ew_Ib, + G_E_xmm_Ub, + G_U_xmm_Ub, + G_U_xmm, + M_G_xmm, + G_E_mm, + G_U_mm, + E_G_mm, + Edq_G_mm, + Edq_G_xmm, + G_mm_Edq, + G_mm_E, + Ev_Gv_Ib, + Ev_Gv_CL, + G_mm_U_mm, + G_Mq_mm, + G_mm_Ew_Ib, + G_E_q, + E_G_q, + CVT_AA, + CVT_DA, + Rq_Cq_0, + Rq_Dq_0, + Cq_Rq_0, + Dq_Rq_0, + FS, + GS, + Yb_DX, + Yv_DX, + DX_Xb, + DX_Xv, + AH, + AX_Xv, + Ew_Sw, + Fw, + I_1, + Iw, + Iw_Ib, + Ob_AL, + Ov_AX, + Sw_Ew, + Yb_AL, + Yb_Xb, + Yv_AX, + INV_Gv_M, + PMOVX_G_E_xmm, + PMOVX_E_G_xmm, + G_Ev_xmm_Ib, + G_E_mm_Ib, + MOVDIR64B, + M_Gv, + ModRM_0x0f00, + ModRM_0x0f01, + ModRM_0x0f0d, + ModRM_0x0f0f, + ModRM_0x0f12, + ModRM_0x0f16, + ModRM_0x0f18, + ModRM_0x0f71, + ModRM_0x0f72, + ModRM_0x0f73, + ModRM_0x0fae, + ModRM_0x0fba, + ModRM_0x0fc7, + ModRM_0x660f78, + ModRM_0xf20f78, + ModRM_0xf30f1e, + ModRM_0xf30f38d8, + ModRM_0xf30f38dc, + ModRM_0xf30f38dd, + ModRM_0xf30f38de, + ModRM_0xf30f38df, + ModRM_0xf30f38fa, + ModRM_0xf30f38fb, + ModRM_0xf30f3af0, +} + +#[allow(non_camel_case_types)] // might be able to pack these into a u8, but with `Operand` being u16 as well now there's little // point. table entries will have a padding byte per record already. // @@ -5028,81 +5242,81 @@ pub struct OperandCodeWrapper { code: OperandCode } #[repr(u16)] #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum OperandCode { - Ivs = OperandCodeBuilder::new().special_case(25).bits(), - I_3 = OperandCodeBuilder::new().special_case(18).bits(), - Nothing = OperandCodeBuilder::new().special_case(6).bits(), - Ib = OperandCodeBuilder::new().with_imm(false, 0).special_case(32).bits(), - Ibs = OperandCodeBuilder::new().with_imm(true, 0).special_case(33).bits(), - Jvds = OperandCodeBuilder::new().with_imm(true, 1).special_case(32).bits(), - Yv_Xv = OperandCodeBuilder::new().special_case(50).bits(), - - x87_d8 = OperandCodeBuilder::new().special_case(32).bits(), - x87_d9 = OperandCodeBuilder::new().special_case(33).bits(), - x87_da = OperandCodeBuilder::new().special_case(34).bits(), - x87_db = OperandCodeBuilder::new().special_case(35).bits(), - x87_dc = OperandCodeBuilder::new().special_case(36).bits(), - x87_dd = OperandCodeBuilder::new().special_case(37).bits(), - x87_de = OperandCodeBuilder::new().special_case(38).bits(), - x87_df = OperandCodeBuilder::new().special_case(39).bits(), + Ivs = OperandCodeBuilder::new().operand_case(OperandCase::Ivs).bits(), + I_3 = OperandCodeBuilder::new().operand_case(OperandCase::I_3).bits(), + Nothing = OperandCodeBuilder::new().operand_case(OperandCase::Nothing).bits(), + Ib = OperandCodeBuilder::new().with_imm(false, 0).operand_case(OperandCase::Ib).bits(), + Ibs = OperandCodeBuilder::new().with_imm(true, 0).operand_case(OperandCase::Internal).bits(), + Jvds = OperandCodeBuilder::new().with_imm(true, 1).operand_case(OperandCase::Internal).bits(), + Yv_Xv = OperandCodeBuilder::new().operand_case(OperandCase::Yv_Xv).bits(), + + x87_d8 = OperandCodeBuilder::new().operand_case(OperandCase::x87_d8).bits(), + x87_d9 = OperandCodeBuilder::new().operand_case(OperandCase::x87_d9).bits(), + x87_da = OperandCodeBuilder::new().operand_case(OperandCase::x87_da).bits(), + x87_db = OperandCodeBuilder::new().operand_case(OperandCase::x87_db).bits(), + x87_dc = OperandCodeBuilder::new().operand_case(OperandCase::x87_dc).bits(), + x87_dd = OperandCodeBuilder::new().operand_case(OperandCase::x87_dd).bits(), + x87_de = OperandCodeBuilder::new().operand_case(OperandCase::x87_de).bits(), + x87_df = OperandCodeBuilder::new().operand_case(OperandCase::x87_df).bits(), Eb_R0 = OperandCodeBuilder::new() .read_modrm() .read_E() .byte_operands() - .operand_case(0) + .operand_case(OperandCase::SingleMMMOper) .bits(), - AL_Ib = OperandCodeBuilder::new().special_case(33).with_imm(false, 0).bits(), - AX_Ib = OperandCodeBuilder::new().special_case(34).with_imm(false, 0).bits(), - Ib_AL = OperandCodeBuilder::new().special_case(35).with_imm(false, 0).bits(), - Ib_AX = OperandCodeBuilder::new().special_case(36).with_imm(false, 0).bits(), - AX_DX = OperandCodeBuilder::new().special_case(44).bits(), - AL_DX = OperandCodeBuilder::new().special_case(45).bits(), - DX_AX = OperandCodeBuilder::new().special_case(46).bits(), - DX_AL = OperandCodeBuilder::new().special_case(47).bits(), - MOVQ_f30f = OperandCodeBuilder::new().special_case(48).bits(), - -// Unsupported = OperandCodeBuilder::new().special_case(49).bits(), - - ModRM_0x0f00 = OperandCodeBuilder::new().read_modrm().special_case(40).bits(), - ModRM_0x0f01 = OperandCodeBuilder::new().read_modrm().special_case(41).bits(), - ModRM_0x0f0d = OperandCodeBuilder::new().read_modrm().special_case(42).bits(), - ModRM_0x0f0f = OperandCodeBuilder::new().read_modrm().special_case(65).bits(), // 3dnow - ModRM_0x0fae = OperandCodeBuilder::new().read_modrm().special_case(43).bits(), - ModRM_0x0fba = OperandCodeBuilder::new().read_modrm().special_case(44).bits(), -// ModRM_0xf30fae = OperandCodeBuilder::new().read_modrm().special_case(46).bits(), -// ModRM_0x660fae = OperandCodeBuilder::new().read_modrm().special_case(47).bits(), -// ModRM_0xf30fc7 = OperandCodeBuilder::new().read_modrm().special_case(48).bits(), -// ModRM_0x660f38 = OperandCodeBuilder::new().read_modrm().special_case(49).bits(), -// ModRM_0xf20f38 = OperandCodeBuilder::new().read_modrm().special_case(50).bits(), -// ModRM_0xf30f38 = OperandCodeBuilder::new().read_modrm().special_case(51).bits(), - ModRM_0xf30f38d8 = OperandCodeBuilder::new().read_modrm().special_case(45).bits(), - ModRM_0xf30f38dc = OperandCodeBuilder::new().read_modrm().special_case(46).bits(), - ModRM_0xf30f38dd = OperandCodeBuilder::new().read_modrm().special_case(47).bits(), - ModRM_0xf30f38de = OperandCodeBuilder::new().read_modrm().special_case(48).bits(), - ModRM_0xf30f38df = OperandCodeBuilder::new().read_modrm().special_case(49).bits(), - ModRM_0xf30f38fa = OperandCodeBuilder::new().read_modrm().special_case(50).bits(), - ModRM_0xf30f38fb = OperandCodeBuilder::new().read_modrm().special_case(51).bits(), - ModRM_0xf30f3af0 = OperandCodeBuilder::new().read_modrm().special_case(52).bits(), -// ModRM_0x660f3a = OperandCodeBuilder::new().read_modrm().special_case(52).bits(), -// ModRM_0x0f38 = OperandCodeBuilder::new().read_modrm().special_case(53).bits(), -// ModRM_0x0f3a = OperandCodeBuilder::new().read_modrm().special_case(54).bits(), - ModRM_0x0f71 = OperandCodeBuilder::new().read_modrm().special_case(55).bits(), - ModRM_0x0f72 = OperandCodeBuilder::new().read_modrm().special_case(56).bits(), - ModRM_0x0f73 = OperandCodeBuilder::new().read_modrm().special_case(57).bits(), - ModRM_0xf20f78 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(), - ModRM_0x660f78 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), - ModRM_0xf30f1e = OperandCodeBuilder::new().special_case(60).bits(), -// ModRM_0x660f72 = OperandCodeBuilder::new().read_modrm().special_case(61).bits(), -// ModRM_0x660f73 = OperandCodeBuilder::new().read_modrm().special_case(62).bits(), -// ModRM_0x660fc7 = OperandCodeBuilder::new().read_modrm().special_case(63).bits(), - ModRM_0x0fc7 = OperandCodeBuilder::new().read_modrm().special_case(64).bits(), + AL_Ib = OperandCodeBuilder::new().operand_case(OperandCase::AL_Ib).with_imm(false, 0).bits(), + AX_Ib = OperandCodeBuilder::new().operand_case(OperandCase::AX_Ib).with_imm(false, 0).bits(), + Ib_AL = OperandCodeBuilder::new().operand_case(OperandCase::Ib_AL).with_imm(false, 0).bits(), + Ib_AX = OperandCodeBuilder::new().operand_case(OperandCase::Ib_AX).with_imm(false, 0).bits(), + AX_DX = OperandCodeBuilder::new().operand_case(OperandCase::AX_DX).bits(), + AL_DX = OperandCodeBuilder::new().operand_case(OperandCase::AL_DX).bits(), + DX_AX = OperandCodeBuilder::new().operand_case(OperandCase::DX_AX).bits(), + DX_AL = OperandCodeBuilder::new().operand_case(OperandCase::DX_AL).bits(), + MOVQ_f30f = OperandCodeBuilder::new().operand_case(OperandCase::MOVQ_f30f).bits(), + +// Unsupported = OperandCodeBuilder::new().operand_case(49).bits(), + + ModRM_0x0f00 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0f00).bits(), + ModRM_0x0f01 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0f01).bits(), + ModRM_0x0f0d = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0f0d).bits(), + ModRM_0x0f0f = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0f0f).bits(), // 3dnow + ModRM_0x0fae = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0fae).bits(), + ModRM_0x0fba = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0fba).bits(), +// ModRM_0xf30fae = OperandCodeBuilder::new().read_modrm().operand_case(46).bits(), +// ModRM_0x660fae = OperandCodeBuilder::new().read_modrm().operand_case(47).bits(), +// ModRM_0xf30fc7 = OperandCodeBuilder::new().read_modrm().operand_case(48).bits(), +// ModRM_0x660f38 = OperandCodeBuilder::new().read_modrm().operand_case(49).bits(), +// ModRM_0xf20f38 = OperandCodeBuilder::new().read_modrm().operand_case(50).bits(), +// ModRM_0xf30f38 = OperandCodeBuilder::new().read_modrm().operand_case(51).bits(), + ModRM_0xf30f38d8 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0xf30f38d8).bits(), + ModRM_0xf30f38dc = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0xf30f38dc).bits(), + ModRM_0xf30f38dd = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0xf30f38dd).bits(), + ModRM_0xf30f38de = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0xf30f38de).bits(), + ModRM_0xf30f38df = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0xf30f38df).bits(), + ModRM_0xf30f38fa = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0xf30f38fa).bits(), + ModRM_0xf30f38fb = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0xf30f38fb).bits(), + ModRM_0xf30f3af0 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0xf30f3af0).bits(), +// ModRM_0x660f3a = OperandCodeBuilder::new().read_modrm().operand_case(52).bits(), +// ModRM_0x0f38 = OperandCodeBuilder::new().read_modrm().operand_case(53).bits(), +// ModRM_0x0f3a = OperandCodeBuilder::new().read_modrm().operand_case(54).bits(), + ModRM_0x0f71 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0f71).bits(), + ModRM_0x0f72 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0f72).bits(), + ModRM_0x0f73 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0f73).bits(), + ModRM_0xf20f78 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0xf20f78).bits(), + ModRM_0x660f78 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x660f78).bits(), + ModRM_0xf30f1e = OperandCodeBuilder::new().operand_case(OperandCase::ModRM_0xf30f1e).bits(), +// ModRM_0x660f72 = OperandCodeBuilder::new().read_modrm().operand_case(61).bits(), +// ModRM_0x660f73 = OperandCodeBuilder::new().read_modrm().operand_case(62).bits(), +// ModRM_0x660fc7 = OperandCodeBuilder::new().read_modrm().operand_case(63).bits(), + ModRM_0x0fc7 = OperandCodeBuilder::new().read_modrm().operand_case(OperandCase::ModRM_0x0fc7).bits(), // xmmword? ModRM_0x0f12 = OperandCodeBuilder::new() .read_modrm() .op0_is_rrr_and_embedded_instructions() .read_E() .reg_mem() - .operand_case(65) + .operand_case(OperandCase::ModRM_0x0f12) .bits(), // xmmword? ModRM_0x0f16 = OperandCodeBuilder::new() @@ -5110,109 +5324,109 @@ enum OperandCode { .op0_is_rrr_and_embedded_instructions() .read_E() .reg_mem() - .operand_case(66) + .operand_case(OperandCase::ModRM_0x0f16) .bits(), // encode immediates? ModRM_0xc0_Eb_Ib = OperandCodeBuilder::new() .read_modrm() .read_E() .byte_operands() - .operand_case(5) + .operand_case(OperandCase::BitwiseWithI8) .bits(), ModRM_0xc1_Ev_Ib = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(5) + .operand_case(OperandCase::BitwiseWithI8) .bits(), ModRM_0xd0_Eb_1 = OperandCodeBuilder::new() .read_modrm() .read_E() .byte_operands() - .operand_case(7) + .operand_case(OperandCase::ShiftBy1_b) .bits(), ModRM_0xd1_Ev_1 = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(7) + .operand_case(OperandCase::ShiftBy1_v) .bits(), ModRM_0xd2_Eb_CL = OperandCodeBuilder::new() .read_modrm() .read_E() .byte_operands() - .operand_case(9) + .operand_case(OperandCase::BitwiseByCL) .bits(), ModRM_0xd3_Ev_CL = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(9) + .operand_case(OperandCase::BitwiseByCL) .bits(), ModRM_0x80_Eb_Ib = OperandCodeBuilder::new() .read_modrm() .read_E() .with_imm(false, 0) .byte_operands() - .operand_case(1) + .operand_case(OperandCase::BaseOpWithI8) .bits(), ModRM_0x83_Ev_Ibs = OperandCodeBuilder::new() .read_modrm() .read_E() .with_imm(false, 0) - .operand_case(26) + .operand_case(OperandCase::ModRM_0x83) .bits(), // this would be Eb_Ivs, 0x8e ModRM_0x81_Ev_Ivs = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(2) + .operand_case(OperandCase::BaseOpWithIv) .bits(), ModRM_0xc6_Eb_Ib = OperandCodeBuilder::new() .read_modrm() .read_E() .byte_operands() - .operand_case(3) + .operand_case(OperandCase::MovI8) .bits(), ModRM_0xc7_Ev_Iv = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(4) + .operand_case(OperandCase::MovIv) .bits(), ModRM_0xfe_Eb = OperandCodeBuilder::new() .read_modrm() .read_E() .byte_operands() - .operand_case(13) + .operand_case(OperandCase::ModRM_0xfe) .bits(), ModRM_0x8f_Ev = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(8) + .operand_case(OperandCase::ModRM_0x8f) .bits(), // gap, 0x94 ModRM_0xff_Ev = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(14) + .operand_case(OperandCase::ModRM_0xff) .bits(), ModRM_0x0f18 = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(58) + .operand_case(OperandCase::ModRM_0x0f18) .bits(), ModRM_0xf6 = OperandCodeBuilder::new() .read_modrm() .read_E() .byte_operands() - .operand_case(11) + .operand_case(OperandCase::ModRM_0xf6_0xf7) .bits(), ModRM_0xf7 = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(11) + .operand_case(OperandCase::ModRM_0xf6_0xf7) .bits(), Ev = OperandCodeBuilder::new() .read_modrm() .read_E() - .operand_case(0) + .operand_case(OperandCase::SingleMMMOper) .bits(), Zv_R0 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_R, 0).bits(), Zv_R1 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_R, 1).bits(), @@ -5246,120 +5460,98 @@ enum OperandCode { Zv_Ivq_R5 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_Ivq_R, 5).bits(), Zv_Ivq_R6 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_Ivq_R, 6).bits(), Zv_Ivq_R7 = OperandCodeBuilder::new().op0_is_rrr_and_Z_operand(ZOperandCategory::Zv_Ivq_R, 7).bits(), - Gv_Eb = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(15).bits(), - Gv_Ew = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(16).bits(), - Gv_Ew_LSL = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(37).bits(), - Gdq_Ed = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(17).bits(), - Gd_Ed = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().operand_case(51).bits(), - Md_Gd = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().operand_case(52).bits(), + Gv_Eb = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::Gv_Eb).bits(), + Gv_Ew = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::Gv_Ew).bits(), + Gv_Ew_LSL = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::Gv_Ew_LSL).bits(), + Gdq_Ed = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::Gdq_Ed).bits(), + Gd_Ed = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().operand_case(OperandCase::Gd_Ed).bits(), + Md_Gd = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().operand_case(OperandCase::Md_Gd).bits(), // Edq_Gdq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().operand_case(49).bits(), - Gdq_Ev = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(40).bits(), - Mdq_Gdq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(51).bits(), - G_E_xmm_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(22).bits(), - G_E_xmm_Ub = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(60).bits(), - G_U_xmm_Ub = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(61).bits(), - AL_Ob = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(50).bits(), - AL_Xb = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(52).bits(), - AX_Ov = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(53).bits(), - AL_Ibs = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().with_imm(false, 0).byte_operands().operand_case(23).bits(), - AX_Ivd = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(24).bits(), - - Eb_Gb = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().byte_operands().only_modrm_operands().mem_reg().bits(), - Ev_Gv = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().only_modrm_operands().mem_reg().bits(), - Gb_Eb = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().byte_operands().only_modrm_operands().reg_mem().bits(), - Gv_Ev = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().only_modrm_operands().reg_mem().bits(), - Gv_M = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().only_modrm_operands().reg_mem().operand_case(25).bits(), - MOVDIR64B = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(108).bits(), - M_Gv = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(109).bits(), - Gv_Ev_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().with_imm(false, 0).reg_mem().operand_case(40).bits(), - Gv_Ev_Iv = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(41).bits(), - Rv_Gmm_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_modrm().read_E().reg_mem().operand_case(55).bits(), + Gdq_Ev = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::Gdq_Ev).bits(), + Mdq_Gdq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::Mdq_Gdq).bits(), + G_E_xmm_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::G_E_xmm_Ib).bits(), + G_E_xmm_Ub = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::G_E_xmm_Ub).bits(), + G_U_xmm_Ub = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::G_U_xmm_Ub).bits(), + AL_Ob = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::AL_Ob).bits(), + AL_Xb = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::AL_Xb).bits(), + AX_Ov = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::AX_Ov).bits(), + AL_Ibs = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().with_imm(false, 0).byte_operands().operand_case(OperandCase::AL_Ibs).bits(), + AX_Ivd = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::AX_Ivd).bits(), + + Eb_Gb = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().byte_operands().only_modrm_operands().mem_reg().operand_case(OperandCase::Internal).bits(), + Ev_Gv = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().only_modrm_operands().mem_reg().operand_case(OperandCase::Internal).bits(), + Gb_Eb = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().byte_operands().only_modrm_operands().reg_mem().operand_case(OperandCase::Internal).bits(), + Gv_Ev = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().only_modrm_operands().reg_mem().operand_case(OperandCase::Internal).bits(), + Gv_M = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().only_modrm_operands().reg_mem().operand_case(OperandCase::Gv_M).bits(), + MOVDIR64B = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::MOVDIR64B).bits(), + M_Gv = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::M_Gv).bits(), + Gv_Ev_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().with_imm(false, 0).reg_mem().operand_case(OperandCase::Gv_Ev_Ib).bits(), + Gv_Ev_Iv = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::Gv_Ev_Iv).bits(), + Rv_Gmm_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_modrm().read_E().reg_mem().operand_case(OperandCase::Rv_Gmm_Ib).bits(), // gap, 0x9a - G_xmm_E_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(53).bits(), - G_xmm_U_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(54).bits(), - U_mm_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(55).bits(), - G_xmm_Edq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(56).bits(), - G_xmm_Eq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(57).bits(), - G_mm_E_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(58).bits(), - Gd_U_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(59).bits(), - Gv_E_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(60).bits(), + G_xmm_E_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_xmm_E_mm).bits(), + G_xmm_U_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_xmm_U_mm).bits(), + U_mm_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(OperandCase::U_mm_G_xmm).bits(), + G_xmm_Edq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_xmm_Edq).bits(), + G_xmm_Eq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_xmm_Eq).bits(), + G_mm_E_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_mm_E_xmm).bits(), + Gd_U_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::Gd_U_xmm).bits(), + Gv_E_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::Gv_E_xmm).bits(), //= 0x816f, // mirror G_xmm_Edq, but also read an immediate - G_xmm_Ew_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(61).bits(), - G_U_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(62).bits(), - G_M_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(20).bits(), - G_E_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(21).bits(), - E_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(19).bits(), - G_Ed_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(31).bits(), - Ed_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(29).bits(), - M_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(63).bits(), - G_E_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(64).bits(), - G_U_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(65).bits(), - E_G_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(66).bits(), - Edq_G_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(67).bits(), - Edq_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(68).bits(), - G_mm_Edq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(69).bits(), - G_mm_E = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(70).bits(), - Ev_Gv_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(71).bits(), - Ev_Gv_CL = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(72).bits(), - G_mm_U_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(73).bits(), - G_Mq_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(74).bits(), - G_mm_Ew_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(75).bits(), - G_E_q = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(76).bits(), - E_G_q = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(77).bits(), - CVT_AA = OperandCodeBuilder::new().special_case(77).bits(), - CVT_DA = OperandCodeBuilder::new().special_case(78).bits(), - Rq_Cq_0 = OperandCodeBuilder::new().special_case(79).bits(), - Rq_Dq_0 = OperandCodeBuilder::new().special_case(80).bits(), - Cq_Rq_0 = OperandCodeBuilder::new().special_case(81).bits(), - Dq_Rq_0 = OperandCodeBuilder::new().special_case(82).bits(), - FS = OperandCodeBuilder::new().special_case(83).bits(), - GS = OperandCodeBuilder::new().special_case(84).bits(), - Yb_DX = OperandCodeBuilder::new().special_case(85).bits(), - Yv_DX = OperandCodeBuilder::new().special_case(86).bits(), - DX_Xb = OperandCodeBuilder::new().special_case(87).bits(), - DX_Xv = OperandCodeBuilder::new().special_case(88).bits(), - AH = OperandCodeBuilder::new().special_case(89).bits(), - AX_Xv = OperandCodeBuilder::new().special_case(90).bits(), - Ew_Sw = OperandCodeBuilder::new().special_case(91).bits(), - Fw = OperandCodeBuilder::new().special_case(92).bits(), - I_1 = OperandCodeBuilder::new().special_case(93).bits(), - Iw = OperandCodeBuilder::new().special_case(94).bits(), - Iw_Ib = OperandCodeBuilder::new().special_case(95).bits(), - Ob_AL = OperandCodeBuilder::new().special_case(96).bits(), - Ov_AX = OperandCodeBuilder::new().special_case(97).bits(), - Sw_Ew = OperandCodeBuilder::new().special_case(98).bits(), - Yb_AL = OperandCodeBuilder::new().special_case(99).bits(), - Yb_Xb = OperandCodeBuilder::new().special_case(100).bits(), - Yv_AX = OperandCodeBuilder::new().special_case(101).bits(), - INV_Gv_M = OperandCodeBuilder::new().special_case(102).bits(), - PMOVX_G_E_xmm = OperandCodeBuilder::new().operand_case(103).bits(), - PMOVX_E_G_xmm = OperandCodeBuilder::new().operand_case(104).bits(), - G_Ev_xmm_Ib = OperandCodeBuilder::new().operand_case(105).bits(), - G_E_mm_Ib = OperandCodeBuilder::new().operand_case(106).bits(), + G_xmm_Ew_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_xmm_Ew_Ib).bits(), + G_U_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_U_xmm).bits(), + G_M_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_M_xmm).bits(), + G_E_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_E_xmm).bits(), + E_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(OperandCase::E_G_xmm).bits(), + G_Ed_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_Ed_xmm).bits(), + Ed_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(OperandCase::Ed_G_xmm).bits(), + M_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(OperandCase::M_G_xmm).bits(), + G_E_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_E_mm).bits(), + G_U_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_U_mm).bits(), + E_G_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(OperandCase::E_G_mm).bits(), + Edq_G_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(OperandCase::Edq_G_mm).bits(), + Edq_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(OperandCase::Edq_G_xmm).bits(), + G_mm_Edq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(OperandCase::G_mm_Edq).bits(), + G_mm_E = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(OperandCase::G_mm_E).bits(), + Ev_Gv_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::Ev_Gv_Ib).bits(), + Ev_Gv_CL = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::Ev_Gv_CL).bits(), + G_mm_U_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_mm_U_mm).bits(), + G_Mq_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(OperandCase::G_Mq_mm).bits(), + G_mm_Ew_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::G_mm_Ew_Ib).bits(), + G_E_q = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::G_E_q).bits(), + E_G_q = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(OperandCase::E_G_q).bits(), + CVT_AA = OperandCodeBuilder::new().operand_case(OperandCase::CVT_AA).bits(), + CVT_DA = OperandCodeBuilder::new().operand_case(OperandCase::CVT_DA).bits(), + Rq_Cq_0 = OperandCodeBuilder::new().operand_case(OperandCase::Rq_Cq_0).bits(), + Rq_Dq_0 = OperandCodeBuilder::new().operand_case(OperandCase::Rq_Dq_0).bits(), + Cq_Rq_0 = OperandCodeBuilder::new().operand_case(OperandCase::Cq_Rq_0).bits(), + Dq_Rq_0 = OperandCodeBuilder::new().operand_case(OperandCase::Dq_Rq_0).bits(), + FS = OperandCodeBuilder::new().operand_case(OperandCase::FS).bits(), + GS = OperandCodeBuilder::new().operand_case(OperandCase::GS).bits(), + Yb_DX = OperandCodeBuilder::new().operand_case(OperandCase::Yb_DX).bits(), + Yv_DX = OperandCodeBuilder::new().operand_case(OperandCase::Yv_DX).bits(), + DX_Xb = OperandCodeBuilder::new().operand_case(OperandCase::DX_Xb).bits(), + DX_Xv = OperandCodeBuilder::new().operand_case(OperandCase::DX_Xv).bits(), + AH = OperandCodeBuilder::new().operand_case(OperandCase::AH).bits(), + AX_Xv = OperandCodeBuilder::new().operand_case(OperandCase::AX_Xv).bits(), + Ew_Sw = OperandCodeBuilder::new().operand_case(OperandCase::Ew_Sw).bits(), + Fw = OperandCodeBuilder::new().operand_case(OperandCase::Fw).bits(), + I_1 = OperandCodeBuilder::new().operand_case(OperandCase::I_1).bits(), + Iw = OperandCodeBuilder::new().operand_case(OperandCase::Iw).bits(), + Iw_Ib = OperandCodeBuilder::new().operand_case(OperandCase::Iw_Ib).bits(), + Ob_AL = OperandCodeBuilder::new().operand_case(OperandCase::Ob_AL).bits(), + Ov_AX = OperandCodeBuilder::new().operand_case(OperandCase::Ov_AX).bits(), + Sw_Ew = OperandCodeBuilder::new().operand_case(OperandCase::Sw_Ew).bits(), + Yb_AL = OperandCodeBuilder::new().operand_case(OperandCase::Yb_AL).bits(), + Yb_Xb = OperandCodeBuilder::new().operand_case(OperandCase::Yb_Xb).bits(), + Yv_AX = OperandCodeBuilder::new().operand_case(OperandCase::Yv_AX).bits(), + INV_Gv_M = OperandCodeBuilder::new().operand_case(OperandCase::INV_Gv_M).bits(), + PMOVX_G_E_xmm = OperandCodeBuilder::new().operand_case(OperandCase::PMOVX_G_E_xmm).bits(), + PMOVX_E_G_xmm = OperandCodeBuilder::new().operand_case(OperandCase::PMOVX_E_G_xmm).bits(), + G_Ev_xmm_Ib = OperandCodeBuilder::new().operand_case(OperandCase::G_Ev_xmm_Ib).bits(), + G_E_mm_Ib = OperandCodeBuilder::new().operand_case(OperandCase::G_E_mm_Ib).bits(), } -const LOCKABLE_INSTRUCTIONS: &[Opcode] = &[ - Opcode::ADD, - Opcode::ADC, - Opcode::AND, - Opcode::BTC, - Opcode::BTR, - Opcode::BTS, - Opcode::CMPXCHG, - Opcode::CMPXCHG8B, - Opcode::CMPXCHG16B, - Opcode::DEC, - Opcode::INC, - Opcode::NEG, - Opcode::NOT, - Opcode::OR, - Opcode::SBB, - Opcode::SUB, - Opcode::XOR, - Opcode::XADD, - Opcode::XCHG, -]; - fn base_opcode_map(v: u8) -> Opcode { match v { 0 => Opcode::ADD, @@ -6773,7 +6965,7 @@ fn read_with_annotations< read_operands(decoder, words, instruction, record, sink)?; if instruction.prefixes.lock() { - if !LOCKABLE_INSTRUCTIONS.contains(&instruction.opcode) || !instruction.operands[0].is_memory() { + if (instruction.opcode as u32) < 0x1000 || !instruction.operands[0].is_memory() { return Err(DecodeError::InvalidPrefixes); } } @@ -6785,7 +6977,7 @@ fn read_avx_prefixed< T: Reader<::Address, ::Word>, S: DescriptionSink, >(b: u8, words: &mut T, instruction: &mut Instruction, sink: &mut S) -> Result<(), DecodeError> { - if instruction.prefixes.rex_unchecked().present() || instruction.prefixes.lock() || instruction.prefixes.operand_size() || instruction.prefixes.rep() || instruction.prefixes.repnz() { + if instruction.prefixes.vex_invalid() { // rex and then vex is invalid! reject it. return Err(DecodeError::InvalidPrefixes); } @@ -6892,11 +7084,7 @@ fn read_operands< instruction.mem_size = bank as u8; bank } else { - let bank = if instruction.prefixes.rex_unchecked().present() { - RegisterBank::rB - } else { - RegisterBank::B - }; + let bank = instruction.prefixes.rb_size(); instruction.regs[0].bank = bank; instruction.mem_size = 1; bank @@ -6958,11 +7146,7 @@ fn read_operands< instruction.mem_size = bank as u8; opwidth = bank as u8; } else { - bank = if instruction.prefixes.rex_unchecked().present() { - RegisterBank::rB - } else { - RegisterBank::B - }; + bank = instruction.prefixes.rb_size(); instruction.mem_size = 1; opwidth = 1; }; @@ -7112,7 +7296,10 @@ fn read_operands< 2 => { // these are Zb_Ib_R instruction.regs[0] = - RegSpec::gp_from_parts_byte(reg, instruction.prefixes.rex_unchecked().b(), instruction.prefixes.rex_unchecked().present()); + RegSpec { + num: reg + if instruction.prefixes.rex_unchecked().b() { 0b1000 } else { 0 }, + bank: instruction.prefixes.rb_size() + }; sink.record( opcode_start, opcode_start + 2, @@ -7178,12 +7365,14 @@ fn read_operands< } // match operand_code { - match operand_code.special_case_handler_index() { - 0 => { + match operand_code.operand_case_handler_index() { + OperandCase::Internal | OperandCase::Gv_M => { + } + OperandCase::SingleMMMOper => { instruction.operands[0] = mem_oper; instruction.operand_count = 1; }, - 1 => { + OperandCase::BaseOpWithI8 => { instruction.opcode = base_opcode_map((modrm >> 3) & 7); instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::ImmI8; @@ -7201,7 +7390,7 @@ fn read_operands< .with_id(words.offset() as u32 * 8 - 8) ); } - 2 => { + OperandCase::BaseOpWithIv => { instruction.operands[0] = mem_oper; instruction.opcode = base_opcode_map((modrm >> 3) & 7); sink.record( @@ -7234,7 +7423,7 @@ fn read_operands< } }; }, - 3 => { + OperandCase::MovI8 => { if (modrm & 0b00111000) != 0 { if modrm == 0xf8 { instruction.opcode = Opcode::XABORT; @@ -7270,7 +7459,7 @@ fn read_operands< ); } - 4 => { + OperandCase::MovIv => { if (modrm & 0b00111000) != 0 { if modrm == 0xf8 { instruction.opcode = Opcode::XBEGIN; @@ -7323,7 +7512,7 @@ fn read_operands< .with_id(modrm_start + 8) ); }, - 5 => { + OperandCase::BitwiseWithI8 => { instruction.operands[0] = mem_oper; instruction.opcode = bitwise_opcode_map((modrm >> 3) & 7); sink.record( @@ -7342,7 +7531,8 @@ fn read_operands< instruction.imm = num; instruction.operands[1] = OperandSpec::ImmI8; } - 7 => { + OperandCase::ShiftBy1_v | + OperandCase::ShiftBy1_b => { instruction.operands[0] = mem_oper; instruction.opcode = bitwise_opcode_map((modrm >> 3) & 7); sink.record( @@ -7361,7 +7551,7 @@ fn read_operands< instruction.imm = num; instruction.operands[1] = OperandSpec::ImmI8; } - 9 => { + OperandCase::BitwiseByCL => { instruction.operands[0] = mem_oper; instruction.opcode = bitwise_opcode_map((modrm >> 3) & 7); sink.record( @@ -7379,7 +7569,7 @@ fn read_operands< ); instruction.operands[1] = OperandSpec::RegRRR; }, - 11 => { + OperandCase::ModRM_0xf6_0xf7 => { instruction.operands[0] = mem_oper; const TABLE: [Opcode; 8] = [ Opcode::TEST, Opcode::TEST, Opcode::NOT, Opcode::NEG, @@ -7414,7 +7604,7 @@ fn read_operands< instruction.operand_count = 1; } }, - 13 => { + OperandCase::ModRM_0xfe => { instruction.operands[0] = mem_oper; let r = (modrm >> 3) & 7; if r >= 2 { @@ -7438,7 +7628,7 @@ fn read_operands< ); instruction.operand_count = 1; } - 14 => { + OperandCase::ModRM_0xff => { instruction.operands[0] = mem_oper; let r = (modrm >> 3) & 7; if r == 7 { @@ -7491,12 +7681,8 @@ fn read_operands< instruction.opcode = opcode; instruction.operand_count = 1; } - 15 => { - let w = if instruction.prefixes.rex_unchecked().present() { - RegisterBank::rB - } else { - RegisterBank::B - }; + OperandCase::Gv_Eb => { + let w = instruction.prefixes.rb_size(); instruction.mem_size = 1; let bank = instruction.prefixes.vqp_size(); let modrm = read_modrm(words)?; @@ -7515,7 +7701,7 @@ fn read_operands< } instruction.operand_count = 2; } - 16 => { + OperandCase::Gv_Ew => { let w = RegisterBank::W; instruction.mem_size = 2; let bank = instruction.prefixes.vqp_size(); @@ -7535,7 +7721,7 @@ fn read_operands< } instruction.operand_count = 2; }, - 17 => { + OperandCase::Gdq_Ed => { let modrm = read_modrm(words)?; instruction.operands[1] = read_E(words, instruction, modrm, RegisterBank::D, sink)?; @@ -7549,7 +7735,7 @@ fn read_operands< .with_id(modrm_start as u32 + 3) ); }, - 19 => { + OperandCase::E_G_xmm => { instruction.regs[0].bank = RegisterBank::X; instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; @@ -7566,11 +7752,11 @@ fn read_operands< instruction.mem_size = 16; } }, - op @ 20 | - op @ 21 => { + op @ OperandCase::G_M_xmm | + op @ OperandCase::G_E_xmm => { instruction.regs[0].bank = RegisterBank::X; if instruction.operands[1] == OperandSpec::RegMMM { - if op == 20 { + if op == OperandCase::G_M_xmm { sink.record( modrm_start + 6, modrm_start + 7, @@ -7596,7 +7782,7 @@ fn read_operands< } } }, - 22 => { + OperandCase::G_E_xmm_Ib => { let modrm = read_modrm(words)?; instruction.operands[1] = read_E_xmm(words, instruction, modrm, sink)?; @@ -7628,7 +7814,7 @@ fn read_operands< instruction.operands[2] = OperandSpec::ImmI8; instruction.operand_count = 3; }, - 23 => { + OperandCase::AL_Ibs => { instruction.regs[0] = RegSpec::al(); sink.record( @@ -7639,7 +7825,7 @@ fn read_operands< ); instruction.operands[1] = OperandSpec::ImmI8; } - 24 => { + OperandCase::AX_Ivd => { let bank = instruction.prefixes.vqp_size(); let numwidth = if bank as u8 == 8 { 4 } else { bank as u8 }; instruction.regs[0] = @@ -7665,7 +7851,7 @@ fn read_operands< .with_id(words.offset() as u32 * 8 - numwidth as u32 * 8 + 1) ); } - 25 => { + OperandCase::Ivs => { let opwidth = imm_width_from_prefixes_64(SizeCode::vd, instruction.prefixes); instruction.imm = read_imm_unsigned(words, opwidth)?; @@ -7683,7 +7869,7 @@ fn read_operands< ); instruction.operand_count = 1; }, - 26 => { + OperandCase::ModRM_0x83 => { instruction.operands[0] = mem_oper; instruction.opcode = base_opcode_map((modrm >> 3) & 7); sink.record( @@ -7694,7 +7880,7 @@ fn read_operands< ); instruction.operands[1] = OperandSpec::ImmI8; }, - 18 => { + OperandCase::I_3 => { sink.record( modrm_start - 8, modrm_start - 1, @@ -7705,7 +7891,7 @@ fn read_operands< instruction.operands[0] = OperandSpec::ImmU8; instruction.operand_count = 1; } - 6 => { + OperandCase::Nothing => { if instruction.opcode == Opcode::Invalid { return Err(DecodeError::InvalidOpcode); } @@ -7719,7 +7905,7 @@ fn read_operands< instruction.operand_count = 0; return Ok(()); }, - 29 => { + OperandCase::Ed_G_xmm => { instruction.regs[0].bank = RegisterBank::X; instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; @@ -7737,7 +7923,7 @@ fn read_operands< instruction.mem_size = 4; } }, - 8 => { + OperandCase::ModRM_0x8f => { instruction.operands[0] = mem_oper; let r = (modrm >> 3) & 7; if r >= 1 { @@ -7769,7 +7955,7 @@ fn read_operands< } instruction.operand_count = 1; } - 31 => { + OperandCase::G_Ed_xmm => { instruction.regs[0].bank = RegisterBank::X; instruction.operand_count = 2; if instruction.operands[1] == OperandSpec::RegMMM { @@ -7779,21 +7965,7 @@ fn read_operands< instruction.mem_size = 4; } }, - _ => { - let operand_code: OperandCode = unsafe { core::mem::transmute(operand_code.bits()) }; - unlikely_operands(decoder, words, instruction, operand_code, mem_oper, sink)?; - } - }; - - Ok(()) -} -#[inline(never)] -fn unlikely_operands< - T: Reader<::Address, ::Word>, - S: DescriptionSink ->(decoder: &InstDecoder, words: &mut T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, sink: &mut S) -> Result<(), DecodeError> { - match operand_code { - OperandCode::G_E_mm_Ib => { + OperandCase::G_E_mm_Ib => { let modrm = read_modrm(words)?; instruction.operands[1] = read_E_mm(words, instruction, modrm, sink)?; @@ -7807,7 +7979,7 @@ fn unlikely_operands< instruction.operands[2] = OperandSpec::ImmI8; instruction.operand_count = 3; } - OperandCode::G_Ev_xmm_Ib => { + OperandCase::G_Ev_xmm_Ib => { let modrm = read_modrm(words)?; instruction.operands[1] = read_E_xmm(words, instruction, modrm, sink)?; @@ -7831,7 +8003,7 @@ fn unlikely_operands< instruction.operands[2] = OperandSpec::ImmI8; instruction.operand_count = 3; } - OperandCode::PMOVX_E_G_xmm => { + OperandCase::PMOVX_E_G_xmm => { let modrm = read_modrm(words)?; instruction.regs[0] = @@ -7850,7 +8022,7 @@ fn unlikely_operands< } } } - OperandCode::PMOVX_G_E_xmm => { + OperandCase::PMOVX_G_E_xmm => { let modrm = read_modrm(words)?; instruction.regs[0] = @@ -7871,7 +8043,7 @@ fn unlikely_operands< } } } - OperandCode::INV_Gv_M => { + OperandCase::INV_Gv_M => { let modrm = read_modrm(words)?; if modrm >= 0xc0 { return Err(DecodeError::InvalidOperand); @@ -7893,7 +8065,7 @@ fn unlikely_operands< instruction.mem_size = 16; } } - OperandCode::G_U_xmm_Ub => { + OperandCase::G_U_xmm_Ub => { let modrm = read_modrm(words)?; instruction.operands[1] = read_E_xmm(words, instruction, modrm, sink)?; @@ -7907,7 +8079,7 @@ fn unlikely_operands< instruction.operands[2] = OperandSpec::ImmU8; instruction.operand_count = 3; } - OperandCode::ModRM_0xf20f78 => { + OperandCase::ModRM_0xf20f78 => { instruction.opcode = Opcode::INSERTQ; let modrm = read_modrm(words)?; @@ -7930,7 +8102,7 @@ fn unlikely_operands< instruction.operands[3] = OperandSpec::ImmInDispField; instruction.operand_count = 4; } - OperandCode::ModRM_0x660f78 => { + OperandCase::ModRM_0x660f78 => { instruction.opcode = Opcode::EXTRQ; let modrm = read_modrm(words)?; @@ -7955,7 +8127,7 @@ fn unlikely_operands< instruction.operand_count = 3; } - OperandCode::ModRM_0xf30f1e => { + OperandCase::ModRM_0xf30f1e => { let modrm = read_modrm(words)?; match modrm { 0xfa => { @@ -7984,7 +8156,7 @@ fn unlikely_operands< } }; } - OperandCode::G_E_xmm_Ub => { + OperandCase::G_E_xmm_Ub => { let modrm = read_modrm(words)?; instruction.operands[1] = read_E_xmm(words, instruction, modrm, sink)?; @@ -7998,7 +8170,7 @@ fn unlikely_operands< instruction.operands[2] = OperandSpec::ImmU8; instruction.operand_count = 3; } - OperandCode::Gd_Ed => { + OperandCase::Gd_Ed => { instruction.regs[0].bank = RegisterBank::D; if mem_oper == OperandSpec::RegMMM { instruction.regs[1].bank = RegisterBank::D; @@ -8007,7 +8179,7 @@ fn unlikely_operands< } instruction.operands[1] = mem_oper; } - OperandCode::Md_Gd => { + OperandCase::Md_Gd => { instruction.regs[0].bank = RegisterBank::D; if mem_oper == OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); @@ -8016,7 +8188,7 @@ fn unlikely_operands< instruction.operands[0] = mem_oper; } /* - OperandCode::Edq_Gdq => { + OperandCase::Edq_Gdq => { let bank = if instruction.prefixes.rex_unchecked().w() { RegisterBank::Q } else { @@ -8032,18 +8204,18 @@ fn unlikely_operands< instruction.operand_count = 2; } */ - OperandCode::G_U_xmm => { + OperandCase::G_U_xmm => { instruction.regs[0].bank = RegisterBank::X; if mem_oper != OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); } instruction.regs[1].bank = RegisterBank::X; }, - OperandCode::Gv_Ev_Ib => { + OperandCase::Gv_Ev_Ib => { instruction.operands[2] = OperandSpec::ImmI8; instruction.operand_count = 3; } - OperandCode::Gv_Ev_Iv => { + OperandCase::Gv_Ev_Iv => { let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); let numwidth = if opwidth == 8 { 4 } else { opwidth }; instruction.imm = @@ -8056,7 +8228,7 @@ fn unlikely_operands< }; instruction.operand_count = 3; } - OperandCode::Ev_Gv_Ib => { + OperandCase::Ev_Gv_Ib => { instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; instruction.imm = @@ -8064,14 +8236,14 @@ fn unlikely_operands< instruction.operands[2] = OperandSpec::ImmI8; instruction.operand_count = 3; } - OperandCode::Ev_Gv_CL => { + OperandCase::Ev_Gv_CL => { instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; instruction.operands[2] = OperandSpec::RegVex; instruction.regs[3] = RegSpec::cl(); instruction.operand_count = 3; } - OperandCode::G_mm_Ew_Ib => { + OperandCase::G_mm_Ew_Ib => { let modrm = read_modrm(words)?; instruction.operands[1] = read_E(words, instruction, modrm, RegisterBank::D, sink)?; @@ -8087,7 +8259,7 @@ fn unlikely_operands< instruction.operands[2] = OperandSpec::ImmI8; instruction.operand_count = 3; } - OperandCode::G_E_mm => { + OperandCase::G_E_mm => { instruction.regs[0].bank = RegisterBank::MM; instruction.regs[0].num &= 0b111; if mem_oper == OperandSpec::RegMMM { @@ -8101,7 +8273,7 @@ fn unlikely_operands< } } }, - OperandCode::G_U_mm => { + OperandCase::G_U_mm => { instruction.regs[0].bank = RegisterBank::D; if mem_oper != OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); @@ -8109,7 +8281,7 @@ fn unlikely_operands< instruction.regs[1].bank = RegisterBank::MM; instruction.regs[1].num &= 0b111; }, - OperandCode::Gv_Ew_LSL => { + OperandCase::Gv_Ew_LSL => { let opwidth = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); let modrm = read_modrm(words)?; @@ -8123,7 +8295,7 @@ fn unlikely_operands< instruction.regs[0] = RegSpec::gp_from_parts_non_byte((modrm >> 3) & 7, instruction.prefixes.rex_unchecked().r(), opwidth); }, - OperandCode::Gdq_Ev => { + OperandCase::Gdq_Ev => { let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); let modrm = read_modrm(words)?; @@ -8143,14 +8315,14 @@ fn unlikely_operands< RegSpec::gp_from_parts_non_byte((modrm >> 3) & 7, instruction.prefixes.rex_unchecked().r(), regbank); instruction.operand_count = 2; }, - op @ OperandCode::AL_Ob | - op @ OperandCode::AX_Ov => { + op @ OperandCase::AL_Ob | + op @ OperandCase::AX_Ov => { match op { - OperandCode::AL_Ob => { + OperandCase::AL_Ob => { instruction.mem_size = 1; instruction.regs[0] = RegSpec::al(); } - OperandCode::AX_Ov => { + OperandCase::AX_Ov => { let b = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.mem_size = b as u8; instruction.regs[0].num = 0; @@ -8170,14 +8342,14 @@ fn unlikely_operands< }; instruction.operand_count = 2; } - op @ OperandCode::Ob_AL | - op @ OperandCode::Ov_AX => { + op @ OperandCase::Ob_AL | + op @ OperandCase::Ov_AX => { match op { - OperandCode::Ob_AL => { + OperandCase::Ob_AL => { instruction.mem_size = 1; instruction.regs[0] = RegSpec::al(); } - OperandCode::Ov_AX => { + OperandCase::Ov_AX => { let b = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.mem_size = b as u8; instruction.regs[0].num = 0; @@ -8198,24 +8370,24 @@ fn unlikely_operands< instruction.operands[1] = OperandSpec::RegRRR; instruction.operand_count = 2; } - OperandCode::I_1 => { + OperandCase::I_1 => { instruction.imm = 1; instruction.operands[0] = OperandSpec::ImmU8; instruction.operand_count = 1; } /* - OperandCode::Unsupported => { + OperandCase::Unsupported => { return Err(DecodeError::IncompleteDecoder); } */ - OperandCode::Iw_Ib => { + OperandCase::Iw_Ib => { instruction.disp = read_num(words, 2)? as u64; instruction.imm = read_num(words, 1)? as u64; instruction.operands[0] = OperandSpec::ImmInDispField; instruction.operands[1] = OperandSpec::ImmU8; instruction.operand_count = 2; } - OperandCode::Fw => { + OperandCase::Fw => { if instruction.prefixes.rex_unchecked().w() { instruction.opcode = Opcode::IRETQ; } else if instruction.prefixes.operand_size() { @@ -8225,7 +8397,7 @@ fn unlikely_operands< } instruction.operand_count = 0; } - OperandCode::Mdq_Gdq => { + OperandCase::Mdq_Gdq => { let bank = if instruction.prefixes.rex_unchecked().w() { RegisterBank::Q } else { RegisterBank::D }; let modrm = read_modrm(words)?; @@ -8241,7 +8413,7 @@ fn unlikely_operands< instruction.operand_count = 2; } - OperandCode::G_mm_U_mm => { + OperandCase::G_mm_U_mm => { instruction.regs[0].bank = RegisterBank::MM; if mem_oper != OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); @@ -8251,7 +8423,7 @@ fn unlikely_operands< instruction.regs[0].num &= 0b111; instruction.operand_count = 2; }, - OperandCode::E_G_q => { + OperandCase::E_G_q => { if instruction.prefixes.operand_size() { return Err(DecodeError::InvalidOpcode); } @@ -8267,7 +8439,7 @@ fn unlikely_operands< instruction.mem_size = 8; } } - OperandCode::G_E_q => { + OperandCase::G_E_q => { if instruction.prefixes.operand_size() { return Err(DecodeError::InvalidOpcode); } @@ -8283,7 +8455,7 @@ fn unlikely_operands< instruction.mem_size = 8; } } - OperandCode::G_Mq_mm => { + OperandCase::G_Mq_mm => { instruction.operands[1] = instruction.operands[0]; instruction.operands[0] = mem_oper; instruction.regs[0].bank = RegisterBank::MM; @@ -8295,7 +8467,7 @@ fn unlikely_operands< instruction.regs[0].num &= 0b111; instruction.operand_count = 2; }, - OperandCode::MOVQ_f30f => { + OperandCase::MOVQ_f30f => { // if rex.w is set, the f3 prefix no longer applies and this becomes an 0f7e movq, // rather than f30f7e movq. // @@ -8325,7 +8497,7 @@ fn unlikely_operands< } } } - OperandCode::ModRM_0x0f0d => { + OperandCase::ModRM_0x0f0d => { let modrm = read_modrm(words)?; let r = (modrm >> 3) & 0b111; @@ -8345,7 +8517,7 @@ fn unlikely_operands< } instruction.operand_count = 1; } - OperandCode::ModRM_0x0f0f => { + OperandCase::ModRM_0x0f0f => { // 3dnow instructions are WILD, the opcode is encoded as an imm8 trailing the // instruction. @@ -8436,7 +8608,7 @@ fn unlikely_operands< } } } - OperandCode::ModRM_0x0fc7 => { + OperandCase::ModRM_0x0fc7 => { if instruction.prefixes.repnz() { let modrm = read_modrm(words)?; let is_reg = (modrm & 0xc0) == 0xc0; @@ -8656,7 +8828,7 @@ fn unlikely_operands< let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.operands[0] = read_E(words, instruction, modrm, bank, sink)?; }, - OperandCode::ModRM_0x0f71 => { + OperandCase::ModRM_0x0f71 => { if instruction.prefixes.rep() || instruction.prefixes.repnz() { return Err(DecodeError::InvalidOperand); } @@ -8693,7 +8865,7 @@ fn unlikely_operands< instruction.imm = read_imm_signed(words, 1)? as u64; instruction.operands[1] = OperandSpec::ImmU8; }, - OperandCode::ModRM_0x0f72 => { + OperandCase::ModRM_0x0f72 => { if instruction.prefixes.rep() || instruction.prefixes.repnz() { return Err(DecodeError::InvalidOperand); } @@ -8730,7 +8902,7 @@ fn unlikely_operands< instruction.imm = read_imm_signed(words, 1)? as u64; instruction.operands[1] = OperandSpec::ImmU8; }, - OperandCode::ModRM_0x0f73 => { + OperandCase::ModRM_0x0f73 => { if instruction.prefixes.rep() || instruction.prefixes.repnz() { return Err(DecodeError::InvalidOperand); } @@ -8776,7 +8948,7 @@ fn unlikely_operands< instruction.imm = read_imm_signed(words, 1)? as u64; instruction.operands[1] = OperandSpec::ImmU8; }, - OperandCode::ModRM_0xf30f38d8 => { + OperandCase::ModRM_0xf30f38d8 => { let modrm = read_modrm(words)?; let r = (modrm >> 3) & 7; match r { @@ -8821,8 +8993,8 @@ fn unlikely_operands< } } } - OperandCode::ModRM_0xf30f38dc => { - read_operands(decoder, words, instruction, OperandCode::G_E_xmm, sink)?; + OperandCase::ModRM_0xf30f38dc => { +// read_operands(decoder, words, instruction, OperandCode::G_E_xmm, sink)?; if let OperandSpec::RegMMM = instruction.operands[1] { instruction.opcode = Opcode::LOADIWKEY; } else { @@ -8830,8 +9002,8 @@ fn unlikely_operands< instruction.opcode = Opcode::AESENC128KL; } } - OperandCode::ModRM_0xf30f38dd => { - read_operands(decoder, words, instruction, OperandCode::G_E_xmm, sink)?; + OperandCase::ModRM_0xf30f38dd => { +// read_operands(decoder, words, instruction, OperandCode::G_E_xmm, sink)?; if let OperandSpec::RegMMM = instruction.operands[1] { return Err(DecodeError::InvalidOperand); } else { @@ -8839,8 +9011,8 @@ fn unlikely_operands< instruction.opcode = Opcode::AESDEC128KL; } } - OperandCode::ModRM_0xf30f38de => { - read_operands(decoder, words, instruction, OperandCode::G_E_xmm, sink)?; + OperandCase::ModRM_0xf30f38de => { +// read_operands(decoder, words, instruction, OperandCode::G_E_xmm, sink)?; if let OperandSpec::RegMMM = instruction.operands[1] { return Err(DecodeError::InvalidOperand); } else { @@ -8848,8 +9020,8 @@ fn unlikely_operands< instruction.opcode = Opcode::AESENC256KL; } } - OperandCode::ModRM_0xf30f38df => { - read_operands(decoder, words, instruction, OperandCode::G_E_xmm, sink)?; + OperandCase::ModRM_0xf30f38df => { +// read_operands(decoder, words, instruction, OperandCode::G_E_xmm, sink)?; if let OperandSpec::RegMMM = instruction.operands[1] { return Err(DecodeError::InvalidOperand); } else { @@ -8857,19 +9029,19 @@ fn unlikely_operands< instruction.opcode = Opcode::AESDEC256KL; } } - OperandCode::ModRM_0xf30f38fa => { + OperandCase::ModRM_0xf30f38fa => { instruction.opcode = Opcode::ENCODEKEY128; - read_operands(decoder, words, instruction, OperandCode::G_U_xmm, sink)?; +// read_operands(decoder, words, instruction, OperandCode::G_U_xmm, sink)?; instruction.regs[0].bank = RegisterBank::D; instruction.regs[1].bank = RegisterBank::D; } - OperandCode::ModRM_0xf30f38fb => { + OperandCase::ModRM_0xf30f38fb => { instruction.opcode = Opcode::ENCODEKEY256; - read_operands(decoder, words, instruction, OperandCode::G_U_xmm, sink)?; +// read_operands(decoder, words, instruction, OperandCode::G_U_xmm, sink)?; instruction.regs[0].bank = RegisterBank::D; instruction.regs[1].bank = RegisterBank::D; } - OperandCode::ModRM_0xf30f3af0 => { + OperandCase::ModRM_0xf30f3af0 => { let modrm = words.next().ok().ok_or(DecodeError::ExhaustedInput)?; if modrm & 0xc0 != 0xc0 { return Err(DecodeError::InvalidOpcode); @@ -8879,7 +9051,7 @@ fn unlikely_operands< instruction.imm = read_num(words, 1)?; instruction.operands[0] = OperandSpec::ImmU8; } - OperandCode::G_mm_Edq => { + OperandCase::G_mm_Edq => { instruction.regs[0].bank = RegisterBank::MM; instruction.regs[0].num &= 0b111; if mem_oper == OperandSpec::RegMMM { @@ -8890,7 +9062,7 @@ fn unlikely_operands< } } } - OperandCode::G_mm_E => { + OperandCase::G_mm_E => { instruction.regs[0].bank = RegisterBank::MM; instruction.regs[0].num &= 0b111; if mem_oper == OperandSpec::RegMMM { @@ -8900,7 +9072,7 @@ fn unlikely_operands< instruction.mem_size = 8; } } - OperandCode::Edq_G_mm => { + OperandCase::Edq_G_mm => { instruction.operands[1] = instruction.operands[0]; instruction.operands[0] = mem_oper; instruction.regs[0].bank = RegisterBank::MM; @@ -8919,7 +9091,7 @@ fn unlikely_operands< } } } - OperandCode::Edq_G_xmm => { + OperandCase::Edq_G_xmm => { instruction.operands[1] = instruction.operands[0]; instruction.operands[0] = mem_oper; instruction.regs[0].bank = RegisterBank::X; @@ -8940,7 +9112,7 @@ fn unlikely_operands< } } } - OperandCode::E_G_mm => { + OperandCase::E_G_mm => { instruction.operands[1] = instruction.operands[0]; instruction.operands[0] = mem_oper; instruction.regs[0].bank = RegisterBank::MM; @@ -8953,7 +9125,7 @@ fn unlikely_operands< } } /* - OperandCode::G_xmm_Ed => { + OperandCase::G_xmm_Ed => { instruction.operands[1] = mem_oper; instruction.regs[0].bank = RegisterBank::X; if mem_oper == OperandSpec::RegMMM { @@ -8961,7 +9133,7 @@ fn unlikely_operands< } }, */ - OperandCode::G_xmm_Edq => { + OperandCase::G_xmm_Edq => { instruction.regs[0].bank = RegisterBank::X; if mem_oper == OperandSpec::RegMMM { if instruction.prefixes.rex_unchecked().w() { @@ -8971,7 +9143,7 @@ fn unlikely_operands< } } }, - OperandCode::G_xmm_Ew_Ib => { + OperandCase::G_xmm_Ew_Ib => { instruction.operands[2] = OperandSpec::ImmU8; instruction.operand_count = 3; instruction.imm = @@ -8983,7 +9155,7 @@ fn unlikely_operands< instruction.mem_size = 2; } }, - OperandCode::G_xmm_Eq => { + OperandCase::G_xmm_Eq => { instruction.regs[0].bank = RegisterBank::X; if mem_oper == OperandSpec::RegMMM { instruction.regs[1].bank = RegisterBank::Q; @@ -8991,7 +9163,7 @@ fn unlikely_operands< instruction.mem_size = 8; } }, - OperandCode::G_mm_E_xmm => { + OperandCase::G_mm_E_xmm => { instruction.regs[0].bank = RegisterBank::MM; instruction.regs[0].num &= 0b111; if mem_oper == OperandSpec::RegMMM { @@ -9000,14 +9172,14 @@ fn unlikely_operands< instruction.mem_size = 16; } }, - op @ OperandCode::G_xmm_U_mm | - op @ OperandCode::G_xmm_E_mm => { + op @ OperandCase::G_xmm_U_mm | + op @ OperandCase::G_xmm_E_mm => { instruction.regs[0].bank = RegisterBank::X; if mem_oper == OperandSpec::RegMMM { instruction.regs[1].bank = RegisterBank::MM; instruction.regs[1].num &= 0b111; } else { - if op == OperandCode::G_xmm_U_mm { + if op == OperandCase::G_xmm_U_mm { return Err(DecodeError::InvalidOperand); } else { if instruction.prefixes.rex_unchecked().w() { @@ -9018,7 +9190,7 @@ fn unlikely_operands< } } }, - OperandCode::Rv_Gmm_Ib => { + OperandCase::Rv_Gmm_Ib => { instruction.operands[2] = OperandSpec::ImmU8; instruction.operand_count = 3; instruction.imm = @@ -9031,7 +9203,7 @@ fn unlikely_operands< return Err(DecodeError::InvalidOperand); } } - OperandCode::U_mm_G_xmm => { + OperandCase::U_mm_G_xmm => { instruction.regs[1].bank = RegisterBank::X; if mem_oper == OperandSpec::RegMMM { instruction.regs[0].bank = RegisterBank::MM; @@ -9041,7 +9213,7 @@ fn unlikely_operands< } } // sure hope these aren't backwards huh - OperandCode::AL_Xb => { + OperandCase::AL_Xb => { instruction.regs[0] = RegSpec::al(); if instruction.prefixes.address_size() { instruction.regs[1] = RegSpec::esi(); @@ -9053,7 +9225,7 @@ fn unlikely_operands< instruction.mem_size = 1; instruction.operand_count = 2; } - OperandCode::Yb_Xb => { + OperandCase::Yb_Xb => { if instruction.prefixes.address_size() { instruction.operands[0] = OperandSpec::Deref_edi; instruction.operands[1] = OperandSpec::Deref_esi; @@ -9064,7 +9236,7 @@ fn unlikely_operands< instruction.mem_size = 1; instruction.operand_count = 2; } - OperandCode::Yb_AL => { + OperandCase::Yb_AL => { instruction.regs[0] = RegSpec::al(); if instruction.prefixes.address_size() { instruction.regs[1] = RegSpec::edi(); @@ -9076,7 +9248,7 @@ fn unlikely_operands< instruction.mem_size = 1; instruction.operand_count = 2; } - OperandCode::AX_Xv => { + OperandCase::AX_Xv => { let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.regs[0].num = 0; instruction.regs[0].bank = bank; @@ -9088,7 +9260,7 @@ fn unlikely_operands< instruction.operands[1] = OperandSpec::Deref; instruction.mem_size = bank as u8; } - OperandCode::Yv_AX => { + OperandCase::Yv_AX => { let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.regs[0].num = 0; instruction.regs[0].bank = bank; @@ -9101,7 +9273,7 @@ fn unlikely_operands< instruction.operands[1] = OperandSpec::RegRRR; instruction.mem_size = bank as u8; } - OperandCode::Yv_Xv => { + OperandCase::Yv_Xv => { let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.mem_size = bank as u8; if instruction.prefixes.address_size() { @@ -9112,7 +9284,7 @@ fn unlikely_operands< instruction.operands[1] = OperandSpec::Deref_rsi; } } - OperandCode::ModRM_0x0f12 => { + OperandCase::ModRM_0x0f12 => { instruction.regs[0].bank = RegisterBank::X; instruction.operands[1] = mem_oper; if instruction.operands[1] == OperandSpec::RegMMM { @@ -9130,7 +9302,7 @@ fn unlikely_operands< } } } - OperandCode::ModRM_0x0f16 => { + OperandCase::ModRM_0x0f16 => { instruction.regs[0].bank = RegisterBank::X; instruction.operands[1] = mem_oper; if instruction.operands[1] == OperandSpec::RegMMM { @@ -9148,7 +9320,7 @@ fn unlikely_operands< } } } - OperandCode::ModRM_0x0f18 => { + OperandCase::ModRM_0x0f18 => { let rrr = instruction.regs[0].num & 0b111; instruction.operands[0] = mem_oper; instruction.operand_count = 1; @@ -9168,21 +9340,21 @@ fn unlikely_operands< instruction.mem_size = 64; } } - OperandCode::Gd_U_xmm => { + OperandCase::Gd_U_xmm => { if instruction.operands[1] != OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); } instruction.regs[0].bank = RegisterBank::D; instruction.regs[1].bank = RegisterBank::X; } - OperandCode::Gv_E_xmm => { + OperandCase::Gv_E_xmm => { if instruction.operands[1] == OperandSpec::RegMMM { instruction.regs[1].bank = RegisterBank::X; } else { instruction.mem_size = 4; } } - OperandCode::M_G_xmm => { + OperandCase::M_G_xmm => { instruction.operands[1] = instruction.operands[0]; instruction.operands[0] = mem_oper; if instruction.operands[0] == OperandSpec::RegMMM { @@ -9198,7 +9370,7 @@ fn unlikely_operands< } instruction.regs[0].bank = RegisterBank::X; } - OperandCode::Ew_Sw => { + OperandCase::Ew_Sw => { let modrm = read_modrm(words)?; // check r @@ -9222,7 +9394,7 @@ fn unlikely_operands< instruction.mem_size = 2; } }, - OperandCode::Sw_Ew => { + OperandCase::Sw_Ew => { let modrm = read_modrm(words)?; // check r @@ -9256,7 +9428,7 @@ fn unlikely_operands< instruction.mem_size = 2; } }, - OperandCode::CVT_AA => { + OperandCase::CVT_AA => { let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; @@ -9267,7 +9439,7 @@ fn unlikely_operands< _ => { unreachable!("invalid operation width"); }, } } - OperandCode::CVT_DA => { + OperandCase::CVT_DA => { let bank = bank_from_prefixes_64(SizeCode::vqp, instruction.prefixes); instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; @@ -9278,11 +9450,11 @@ fn unlikely_operands< _ => { unreachable!("invalid operation width"); }, } } - OperandCode::Ib => { + OperandCase::Ib => { instruction.operands[0] = OperandSpec::ImmU8; instruction.operand_count = 1; } - OperandCode::Iw => { + OperandCase::Iw => { instruction.imm = read_imm_unsigned(words, 2)?; instruction.operands[0] = OperandSpec::ImmU16; @@ -9293,7 +9465,7 @@ fn unlikely_operands< } instruction.operand_count = 1; } - OperandCode::ModRM_0x0f00 => { + OperandCase::ModRM_0x0f00 => { instruction.operand_count = 1; let modrm = read_modrm(words)?; let r = (modrm >> 3) & 7; @@ -9326,7 +9498,7 @@ fn unlikely_operands< instruction.mem_size = 2; } } - OperandCode::ModRM_0x0f01 => { + OperandCase::ModRM_0x0f01 => { let bank = bank_from_prefixes_64(SizeCode::vq, instruction.prefixes); let modrm = read_modrm(words)?; let r = (modrm >> 3) & 7; @@ -9732,7 +9904,7 @@ fn unlikely_operands< unreachable!("r <= 8"); } } - OperandCode::ModRM_0x0fae => { + OperandCase::ModRM_0x0fae => { let modrm = read_modrm(words)?; let r = (modrm >> 3) & 7; let m = modrm & 7; @@ -9960,7 +10132,7 @@ fn unlikely_operands< instruction.operands[0] = read_M(words, instruction, modrm, sink)?; } } - OperandCode::ModRM_0x0fba => { + OperandCase::ModRM_0x0fba => { let bank = bank_from_prefixes_64(SizeCode::vq, instruction.prefixes); let modrm = read_modrm(words)?; let r = (modrm >> 3) & 7; @@ -9994,10 +10166,10 @@ fn unlikely_operands< instruction.operands[1] = OperandSpec::ImmI8; instruction.operand_count = 2; } - op @ OperandCode::Rq_Cq_0 | - op @ OperandCode::Rq_Dq_0 | - op @ OperandCode::Cq_Rq_0 | - op @ OperandCode::Dq_Rq_0 => { + op @ OperandCase::Rq_Cq_0 | + op @ OperandCase::Rq_Dq_0 | + op @ OperandCase::Cq_Rq_0 | + op @ OperandCase::Dq_Rq_0 => { let modrm = read_modrm(words)?; let mut m = modrm & 7; let mut r = (modrm >> 3) & 7; @@ -10009,15 +10181,15 @@ fn unlikely_operands< } let bank = match op { - OperandCode::Rq_Cq_0 | - OperandCode::Cq_Rq_0 => { + OperandCase::Rq_Cq_0 | + OperandCase::Cq_Rq_0 => { if r != 0 && r != 2 && r != 3 && r != 4 && r != 8 { return Err(DecodeError::InvalidOperand); } RegisterBank::CR }, - OperandCode::Rq_Dq_0 | - OperandCode::Dq_Rq_0 => { + OperandCase::Rq_Dq_0 | + OperandCase::Dq_Rq_0 => { if r > 7 { return Err(DecodeError::InvalidOperand); } @@ -10026,10 +10198,10 @@ fn unlikely_operands< _ => unsafe { unreachable_unchecked() } }; let (rrr, mmm) = match op { - OperandCode::Rq_Cq_0 | - OperandCode::Rq_Dq_0 => (1, 0), - OperandCode::Cq_Rq_0 | - OperandCode::Dq_Rq_0 => (0, 1), + OperandCase::Rq_Cq_0 | + OperandCase::Rq_Dq_0 => (1, 0), + OperandCase::Cq_Rq_0 | + OperandCase::Dq_Rq_0 => (0, 1), _ => unsafe { unreachable_unchecked() } }; @@ -10041,45 +10213,45 @@ fn unlikely_operands< instruction.operands[rrr] = OperandSpec::RegRRR; instruction.operand_count = 2; } - OperandCode::FS => { + OperandCase::FS => { instruction.regs[0] = RegSpec::fs(); instruction.operands[0] = OperandSpec::RegRRR; instruction.operand_count = 1; } - OperandCode::GS => { + OperandCase::GS => { instruction.regs[0] = RegSpec::gs(); instruction.operands[0] = OperandSpec::RegRRR; instruction.operand_count = 1; } - OperandCode::AL_Ib => { + OperandCase::AL_Ib => { instruction.regs[0] = RegSpec::al(); instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::ImmU8; instruction.operand_count = 2; } - OperandCode::AX_Ib => { + OperandCase::AX_Ib => { instruction.regs[0].num = 0; instruction.regs[0].bank = bank_from_prefixes_64(SizeCode::vd, instruction.prefixes); instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::ImmU8; instruction.operand_count = 2; } - OperandCode::Ib_AL => { + OperandCase::Ib_AL => { instruction.regs[0] = RegSpec::al(); instruction.operands[0] = OperandSpec::ImmU8; instruction.operands[1] = OperandSpec::RegRRR; instruction.operand_count = 2; } - OperandCode::Ib_AX => { + OperandCase::Ib_AX => { instruction.regs[0].num = 0; instruction.regs[0].bank = bank_from_prefixes_64(SizeCode::vd, instruction.prefixes); instruction.operands[0] = OperandSpec::ImmU8; instruction.operands[1] = OperandSpec::RegRRR; instruction.operand_count = 2; } - OperandCode::AX_DX => { + OperandCase::AX_DX => { instruction.regs[0].num = 0; instruction.regs[0].bank = bank_from_prefixes_64(SizeCode::vd, instruction.prefixes); instruction.regs[1] = RegSpec::dx(); @@ -10087,14 +10259,14 @@ fn unlikely_operands< instruction.operands[1] = OperandSpec::RegMMM; instruction.operand_count = 2; } - OperandCode::AL_DX => { + OperandCase::AL_DX => { instruction.regs[0] = RegSpec::al(); instruction.regs[1] = RegSpec::dx(); instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegMMM; instruction.operand_count = 2; } - OperandCode::DX_AX => { + OperandCase::DX_AX => { instruction.regs[0].num = 0; instruction.regs[0].bank = bank_from_prefixes_64(SizeCode::vd, instruction.prefixes); instruction.regs[1] = RegSpec::dx(); @@ -10102,14 +10274,14 @@ fn unlikely_operands< instruction.operands[1] = OperandSpec::RegRRR; instruction.operand_count = 2; } - OperandCode::DX_AL => { + OperandCase::DX_AL => { instruction.regs[0] = RegSpec::al(); instruction.regs[1] = RegSpec::dx(); instruction.operands[0] = OperandSpec::RegMMM; instruction.operands[1] = OperandSpec::RegRRR; instruction.operand_count = 2; } - OperandCode::Yb_DX => { + OperandCase::Yb_DX => { instruction.regs[0] = RegSpec::dl(); instruction.regs[1] = RegSpec::rdi(); instruction.operands[0] = OperandSpec::Deref; @@ -10117,7 +10289,7 @@ fn unlikely_operands< instruction.operand_count = 2; instruction.mem_size = 1; } - OperandCode::Yv_DX => { + OperandCase::Yv_DX => { instruction.regs[0] = RegSpec::dx(); instruction.regs[1] = RegSpec::rdi(); instruction.operands[0] = OperandSpec::Deref; @@ -10129,7 +10301,7 @@ fn unlikely_operands< } instruction.operand_count = 2; } - OperandCode::DX_Xb => { + OperandCase::DX_Xb => { instruction.regs[0] = RegSpec::dl(); instruction.regs[1] = RegSpec::rsi(); instruction.operands[0] = OperandSpec::RegRRR; @@ -10137,11 +10309,11 @@ fn unlikely_operands< instruction.operand_count = 2; instruction.mem_size = 1; } - OperandCode::AH => { + OperandCase::AH => { instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; } - OperandCode::DX_Xv => { + OperandCase::DX_Xv => { instruction.regs[0] = RegSpec::dx(); instruction.regs[1] = RegSpec::rsi(); instruction.operands[0] = OperandSpec::RegRRR; @@ -10153,17 +10325,17 @@ fn unlikely_operands< } instruction.operand_count = 2; } - OperandCode::x87_d8 | - OperandCode::x87_d9 | - OperandCode::x87_da | - OperandCode::x87_db | - OperandCode::x87_dc | - OperandCode::x87_dd | - OperandCode::x87_de | - OperandCode::x87_df => { - return decode_x87(words, instruction, operand_code, sink); - } - OperandCode::MOVDIR64B => { + OperandCase::x87_d8 | + OperandCase::x87_d9 | + OperandCase::x87_da | + OperandCase::x87_db | + OperandCase::x87_dc | + OperandCase::x87_dd | + OperandCase::x87_de | + OperandCase::x87_df => { + return decode_x87(words, instruction, operand_code.operand_case_handler_index(), sink); + } + OperandCase::MOVDIR64B => { // at this point we've done a read as if it was Gv_M (`lea` operands). because the // first operand is actually a memory address, and this is the only x86 instruction // other than movs to have two memory operands, the first operand has to be sized by @@ -10178,7 +10350,7 @@ fn unlikely_operands< instruction.regs[0].bank = RegisterBank::Q; }; } - OperandCode::M_Gv => { + OperandCase::M_Gv => { // `lea` operands (`Gv_M`) opportunistically reject a register form of `mmm` early, but // leaves `M_Gv` to test memory-ness of the `mmm` operand directly. also, swap // operands. @@ -10189,17 +10361,6 @@ fn unlikely_operands< instruction.operands[1] = instruction.operands[0]; instruction.operands[0] = temp; } - _ => { - // TODO: this should be unreachable - safe to panic now? - // can't simply delete this arm because the non-unlikely operands are handled outside - // here, and some operands are entirely decoded before reaching match in the first - // place. - // perhaps fully-decoded operands could be a return here? they would be jump table - // entries anyway, so no extra space for the dead arms. - instruction.operands[0] = OperandSpec::Nothing; - instruction.operand_count = 0; - return Err(DecodeError::InvalidOperand); - } }; Ok(()) } @@ -10207,7 +10368,7 @@ fn unlikely_operands< fn decode_x87< T: Reader<::Address, ::Word>, S: DescriptionSink, ->(words: &mut T, instruction: &mut Instruction, operand_code: OperandCode, sink: &mut S) -> Result<(), DecodeError> { +>(words: &mut T, instruction: &mut Instruction, operand_code: OperandCase, sink: &mut S) -> Result<(), DecodeError> { sink.record( words.offset() as u32 * 8 - 8, words.offset() as u32 * 8 - 1, @@ -10244,7 +10405,7 @@ fn decode_x87< let r = (modrm >> 3) & 0b111; let (opcode, x87_operands) = match operand_code { - OperandCode::x87_d8 => { + OperandCase::x87_d8 => { match r { 0 => (Opcode::FADD, OperandCodeX87::St_Edst), 1 => (Opcode::FMUL, OperandCodeX87::St_Edst), @@ -10257,7 +10418,7 @@ fn decode_x87< _ => { unreachable!("impossible r"); } } } - OperandCode::x87_d9 => { + OperandCase::x87_d9 => { match r { 0 => (Opcode::FLD, OperandCodeX87::St_Edst), 1 => { @@ -10356,7 +10517,7 @@ fn decode_x87< _ => { unreachable!("impossible r"); } } } - OperandCode::x87_da => { + OperandCase::x87_da => { if modrm >= 0xc0 { match r { 0 => (Opcode::FCMOVB, OperandCodeX87::St_Est), @@ -10385,7 +10546,7 @@ fn decode_x87< } } } - OperandCode::x87_db => { + OperandCase::x87_db => { if modrm >= 0xc0 { match r { 0 => (Opcode::FCMOVNB, OperandCodeX87::St_Est), @@ -10425,7 +10586,7 @@ fn decode_x87< } } - OperandCode::x87_dc => { + OperandCase::x87_dc => { // mod=11 swaps operand order for some instructions if modrm >= 0xc0 { match r { @@ -10453,7 +10614,7 @@ fn decode_x87< } } } - OperandCode::x87_dd => { + OperandCase::x87_dd => { if modrm >= 0xc0 { match r { 0 => (Opcode::FFREE, OperandCodeX87::Est), @@ -10480,7 +10641,7 @@ fn decode_x87< } } } - OperandCode::x87_de => { + OperandCase::x87_de => { if modrm >= 0xc0 { match r { 0 => (Opcode::FADDP, OperandCodeX87::Est_St), @@ -10515,7 +10676,7 @@ fn decode_x87< } } } - OperandCode::x87_df => { + OperandCase::x87_df => { if modrm >= 0xc0 { match r { 0 => (Opcode::FFREEP, OperandCodeX87::Est), diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index 24ff2a8..89e253c 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -36,36 +36,29 @@ enum VEXOpcodePrefix { enum VEXOperandCode { Nothing, VPS_71, - VPS_71_L, VPS_72, - VPS_72_L, VPS_73, - VPS_73_L, VMOVSS_10, VMOVSD_10, VMOVSD_11, VMOVSS_11, VMOVLPS_12, VMOVHPS_16, - E_G_xmm, M_G_xmm, G_M_xmm, G_U_xmm, Gd_U_xmm, E_G_xmm_imm8, Ud_G_xmm_imm8, - Ud_G_xmm, - Ud_G_ymm, - E_G_ymm, + Ud_G_xyLmm, + M_G_xyLmm, M_G_ymm, G_E_ymm, G_M_ymm, Gd_U_ymm, E_xmm_G_ymm_imm8, Ev_G_xmm_imm8, - G_Ex_V_xmm, - G_Ey_V_xmm, - G_Ey_V_ymm, + G_ExyL_V_xyLmm, G_E_xmm, G_E_xmm_imm8, G_E_ymm_imm8, @@ -79,6 +72,11 @@ enum VEXOperandCode { M_V_G_ymm, G_V_xmm_Ed, G_V_xmm_Eq, + G_V_E_xyLmm, + G_E_xyLmm, + E_G_xyLmm, + G_E_xyLmm_imm8, + G_V_E_xyLmm_imm8, G_V_E_xmm, G_V_E_xmm_imm8, G_V_E_xmm_xmm4, @@ -146,7 +144,6 @@ pub(crate) fn three_byte_vex< 0b00010 => VEXOpcodeMap::Map0F38, 0b00011 => VEXOpcodeMap::Map0F3A, _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } }; @@ -296,6 +293,7 @@ pub(crate) fn two_byte_vex< read_vex_instruction(VEXOpcodeMap::Map0F, words, instruction, p, sink) } +#[inline] fn read_vex_operands< T: Reader<::Address, ::Word>, S: DescriptionSink, @@ -305,59 +303,35 @@ fn read_vex_operands< VEXOperandCode::VPS_71 => { let modrm = read_modrm(words)?; if modrm & 0xc0 != 0xc0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } - match (modrm >> 3) & 0b111 { - 0b010 => { - instruction.opcode = Opcode::VPSRLW; - } - 0b100 => { - instruction.opcode = Opcode::VPSRAW; - } - 0b110 => { - instruction.opcode = Opcode::VPSLLW; - } - _ => { - return Err(DecodeError::InvalidOpcode); - } - } - instruction.regs[0] = - RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X); - instruction.regs[3].bank = RegisterBank::X; - instruction.operands[0] = OperandSpec::RegVex; - instruction.operands[1] = OperandSpec::RegRRR; - instruction.imm = read_imm_unsigned(words, 1)?; - instruction.operands[2] = OperandSpec::ImmI8; - instruction.operand_count = 3; - Ok(()) - } - VEXOperandCode::VPS_71_L => { - let modrm = read_modrm(words)?; - if modrm & 0xc0 != 0xc0 { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOperand); + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + + let bank = if L { + RegisterBank::Y + } else { + RegisterBank::X + }; + + let rrr = (modrm >> 3) & 0b111; + + if rrr == 0b001 && L { + return Err(DecodeError::InvalidOpcode); } - match (modrm >> 3) & 0b111 { - 0b001 => { - instruction.opcode = Opcode::VPSLLW; - } - 0b010 => { - instruction.opcode = Opcode::VPSRLW; - } - 0b100 => { - instruction.opcode = Opcode::VPSRAW; - } - 0b110 => { - instruction.opcode = Opcode::VPSLLW; - } + + instruction.opcode = match rrr { + 0b001 => Opcode::VPSLLW, + 0b010 => Opcode::VPSRLW, + 0b100 => Opcode::VPSRAW, + 0b110 => Opcode::VPSLLW, _ => { return Err(DecodeError::InvalidOpcode); } - } + }; instruction.regs[0] = - RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y); - instruction.regs[3].bank = RegisterBank::Y; + RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), bank); + instruction.regs[3].bank = bank; instruction.operands[0] = OperandSpec::RegVex; instruction.operands[1] = OperandSpec::RegRRR; instruction.imm = read_imm_unsigned(words, 1)?; @@ -368,39 +342,18 @@ fn read_vex_operands< VEXOperandCode::VPS_72 => { let modrm = read_modrm(words)?; if modrm & 0xc0 != 0xc0 { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOperand); - } - match (modrm >> 3) & 0b111 { - 0b010 => { - instruction.opcode = Opcode::VPSRLD; - } - 0b100 => { - instruction.opcode = Opcode::VPSRAD; - } - 0b110 => { - instruction.opcode = Opcode::VPSLLD; - } - _ => { - return Err(DecodeError::InvalidOpcode); - } - } - instruction.regs[0] = - RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X); - instruction.regs[3].bank = RegisterBank::X; - instruction.operands[0] = OperandSpec::RegVex; - instruction.operands[1] = OperandSpec::RegRRR; - instruction.imm = read_imm_unsigned(words, 1)?; - instruction.operands[2] = OperandSpec::ImmI8; - instruction.operand_count = 3; - Ok(()) - } - VEXOperandCode::VPS_72_L => { - let modrm = read_modrm(words)?; - if modrm & 0xc0 != 0xc0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } + + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + + let bank = if L { + RegisterBank::Y + } else { + RegisterBank::X + }; + match (modrm >> 3) & 0b111 { 0b010 => { instruction.opcode = Opcode::VPSRLD; @@ -416,8 +369,8 @@ fn read_vex_operands< } } instruction.regs[0] = - RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y); - instruction.regs[3].bank = RegisterBank::Y; + RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), bank); + instruction.regs[3].bank = bank; instruction.operands[0] = OperandSpec::RegVex; instruction.operands[1] = OperandSpec::RegRRR; instruction.imm = read_imm_unsigned(words, 1)?; @@ -428,9 +381,18 @@ fn read_vex_operands< VEXOperandCode::VPS_73 => { let modrm = read_modrm(words)?; if modrm & 0xc0 != 0xc0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } + + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + + let bank = if L { + RegisterBank::Y + } else { + RegisterBank::X + }; + match (modrm >> 3) & 0b111 { 0b010 => { instruction.opcode = Opcode::VPSRLQ; @@ -449,47 +411,8 @@ fn read_vex_operands< } } instruction.regs[0] = - RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X); - instruction.regs[3].bank = RegisterBank::X; - instruction.operands[0] = OperandSpec::RegVex; - instruction.operands[1] = OperandSpec::RegRRR; - instruction.imm = read_imm_unsigned(words, 1)?; - instruction.operands[2] = OperandSpec::ImmI8; - instruction.operand_count = 3; - Ok(()) - } - VEXOperandCode::VPS_73_L => { - let modrm = read_modrm(words)?; - if modrm & 0xc0 != 0xc0 { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOperand); - } - match (modrm >> 3) & 0b111 { - 0b000 | - 0b001 | - 0b100 | - 0b101 => { - return Err(DecodeError::InvalidOpcode); - } - 0b010 => { - instruction.opcode = Opcode::VPSRLQ; - } - 0b011 => { - instruction.opcode = Opcode::VPSRLDQ; - } - 0b110 => { - instruction.opcode = Opcode::VPSLLQ; - } - 0b111 => { - instruction.opcode = Opcode::VPSLLDQ; - } - _ => { - unreachable!("r is only three bits"); - } - } - instruction.regs[0] = - RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Y); - instruction.regs[3].bank = RegisterBank::Y; + RegSpec::from_parts(modrm & 7, instruction.prefixes.vex_unchecked().r(), bank); + instruction.regs[3].bank = bank; instruction.operands[0] = OperandSpec::RegVex; instruction.operands[1] = OperandSpec::RegRRR; instruction.imm = read_imm_unsigned(words, 1)?; @@ -512,7 +435,6 @@ fn read_vex_operands< }, other => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } if instruction.opcode == Opcode::VMOVSS { @@ -541,7 +463,6 @@ fn read_vex_operands< }, other => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } if instruction.opcode == Opcode::VMOVSS { @@ -591,7 +512,6 @@ fn read_vex_operands< VEXOperandCode::Nothing => { if instruction.opcode == Opcode::VZEROUPPER || instruction.opcode == Opcode::VZEROALL { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } } @@ -600,7 +520,6 @@ fn read_vex_operands< }, VEXOperandCode::Ev_G_xmm_imm8 => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -635,7 +554,6 @@ fn read_vex_operands< }, VEXOperandCode::G_xmm_Eq => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -652,7 +570,6 @@ fn read_vex_operands< } VEXOperandCode::G_xmm_Ed => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -669,7 +586,6 @@ fn read_vex_operands< } VEXOperandCode::Eq_G_xmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -686,7 +602,6 @@ fn read_vex_operands< } VEXOperandCode::Ed_G_xmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -703,7 +618,6 @@ fn read_vex_operands< } VEXOperandCode::VCVT_Gd_Ed_xmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -722,7 +636,6 @@ fn read_vex_operands< } VEXOperandCode::VCVT_Gq_Eq_xmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -743,27 +656,21 @@ fn read_vex_operands< instruction.operand_count = 2; Ok(()) } - op @ VEXOperandCode::E_G_xmm | - op @ VEXOperandCode::M_G_xmm => { + VEXOperandCode::M_G_xyLmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } + // the name of this bit is `L` in the documentation, so use the same name here. + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + let bank = if L { RegisterBank::Y } else { RegisterBank::X }; + 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, sink)?; - match (op, mem_oper) { - (VEXOperandCode::E_G_xmm, OperandSpec::RegMMM) => { - /* this is the only accepted operand */ - } - (VEXOperandCode::M_G_xmm, OperandSpec::RegMMM) => { - return Err(DecodeError::InvalidOperand); - } - (VEXOperandCode::M_G_xmm, _) | // otherwise it's memory-constrained and a memory operand - (_, _) => { // ... or unconstrained - /* and this is always accepted */ - } + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), bank); + let mem_oper = read_E(words, instruction, modrm, bank, sink)?; + if mem_oper == OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); } if mem_oper != OperandSpec::RegMMM { if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS { @@ -777,32 +684,42 @@ fn read_vex_operands< instruction.operand_count = 2; Ok(()) } - VEXOperandCode::Ud_G_xmm => { + VEXOperandCode::M_G_xmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; instruction.regs[0] = - RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::D); + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm, sink)?; - if mem_oper != OperandSpec::RegMMM { + if mem_oper == OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); } - instruction.operands[0] = OperandSpec::RegRRR; - instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } + } + instruction.operands[0] = mem_oper; + instruction.operands[1] = OperandSpec::RegRRR; instruction.operand_count = 2; Ok(()) } - VEXOperandCode::Ud_G_ymm => { + VEXOperandCode::Ud_G_xyLmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } + // the name of this bit is `L` in the documentation, so use the same name here. + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + let bank = if L { RegisterBank::Y } else { RegisterBank::X }; + 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, sink)?; + let mem_oper = read_E(words, instruction, modrm, bank, sink)?; if mem_oper != OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); } @@ -813,7 +730,6 @@ fn read_vex_operands< } VEXOperandCode::Ud_G_xmm_imm8 => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -832,7 +748,6 @@ fn read_vex_operands< } VEXOperandCode::E_G_xmm_imm8 => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -851,7 +766,6 @@ fn read_vex_operands< } VEXOperandCode::E_xmm_G_ymm_imm8 => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -871,7 +785,6 @@ fn read_vex_operands< VEXOperandCode::Gd_U_xmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -888,7 +801,6 @@ fn read_vex_operands< } VEXOperandCode::Gd_U_ymm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -908,7 +820,6 @@ fn read_vex_operands< op @ VEXOperandCode::G_U_xmm | op @ VEXOperandCode::G_E_xmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -944,7 +855,6 @@ fn read_vex_operands< } VEXOperandCode::G_xmm_E_xmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -961,7 +871,6 @@ fn read_vex_operands< } VEXOperandCode::G_xmm_E_ymm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -979,7 +888,6 @@ fn read_vex_operands< op @ VEXOperandCode::G_ymm_M_xmm | op @ VEXOperandCode::G_ymm_E_xmm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -1007,7 +915,6 @@ fn read_vex_operands< } VEXOperandCode::G_ymm_E_ymm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -1023,10 +930,8 @@ fn read_vex_operands< Ok(()) } - op @ VEXOperandCode::E_G_ymm | op @ VEXOperandCode::M_G_ymm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -1054,7 +959,6 @@ fn read_vex_operands< op @ VEXOperandCode::G_M_ymm | op @ VEXOperandCode::G_E_ymm => { if instruction.regs[3].num != 0 { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; @@ -1155,6 +1059,107 @@ fn read_vex_operands< instruction.operand_count = 3; Ok(()) } + VEXOperandCode::E_G_xyLmm => { + if instruction.regs[3].num != 0 { + return Err(DecodeError::InvalidOperand); + } + // the name of this bit is `L` in the documentation, so use the same name here. + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + let bank = if L { RegisterBank::Y } else { RegisterBank::X }; + + let modrm = read_modrm(words)?; + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), bank); + let mem_oper = read_E(words, instruction, modrm, bank, sink)?; + if mem_oper != OperandSpec::RegMMM { + if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } + } + instruction.operands[0] = mem_oper; + instruction.operands[1] = OperandSpec::RegRRR; + + instruction.operand_count = 2; + Ok(()) + } + VEXOperandCode::G_V_E_xyLmm_imm8 => { + // the name of this bit is `L` in the documentation, so use the same name here. + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + let bank = if L { RegisterBank::Y } else { RegisterBank::X }; + + let modrm = read_modrm(words)?; + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), bank); + let mem_oper = read_E(words, instruction, modrm, bank, sink)?; + instruction.regs[3].bank = bank; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = OperandSpec::RegVex; + instruction.operands[2] = mem_oper; + instruction.imm = read_imm_unsigned(words, 1)?; + instruction.operands[3] = OperandSpec::ImmU8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } + instruction.operand_count = 4; + Ok(()) + } + VEXOperandCode::G_E_xyLmm => { + if instruction.regs[3].num != 0 { + return Err(DecodeError::InvalidOperand); + } + // the name of this bit is `L` in the documentation, so use the same name here. + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + let bank = if L { RegisterBank::Y } else { RegisterBank::X }; + + let modrm = read_modrm(words)?; + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), bank); + let mem_oper = read_E(words, instruction, modrm, bank, sink)?; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + if [Opcode::VBROADCASTSS, Opcode::VUCOMISS, Opcode::VCOMISS].contains(&instruction.opcode) { + instruction.mem_size = 4; + } else if [Opcode::VMOVDDUP, Opcode::VUCOMISD, Opcode::VCOMISD, Opcode::VCVTPS2PD, Opcode::VMOVQ].contains(&instruction.opcode) { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + }; + } + instruction.operand_count = 2; + Ok(()) + } + VEXOperandCode::G_V_E_xyLmm => { + let modrm = read_modrm(words)?; + // the name of this bit is `L` in the documentation, so use the same name here. + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + let bank = if L { RegisterBank::Y } else { RegisterBank::X }; + + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), bank); + let mem_oper = read_E(words, instruction, modrm, bank, sink)?; + instruction.regs[3].bank = bank; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = OperandSpec::RegVex; + instruction.operands[2] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + if [Opcode::VSQRTSS, Opcode::VADDSS, Opcode::VMULSS, Opcode::VSUBSS, Opcode::VMINSS, Opcode::VDIVSS, Opcode::VMAXSS].contains(&instruction.opcode) { + instruction.mem_size = 4; + } else if [Opcode::VSQRTSD, Opcode::VADDSD, Opcode::VMULSD, Opcode::VSUBSD, Opcode::VMINSD, Opcode::VDIVSD, Opcode::VMAXSD].contains(&instruction.opcode) { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } + } + instruction.operand_count = 3; + Ok(()) + } VEXOperandCode::G_V_E_xmm => { let modrm = read_modrm(words)?; instruction.regs[0] = @@ -1255,44 +1260,21 @@ fn read_vex_operands< Ok(()) } - VEXOperandCode::G_Ex_V_xmm => { - 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, sink)?; - instruction.regs[2].bank = RegisterBank::X; - instruction.operands[0] = OperandSpec::RegRRR; - instruction.operands[1] = mem_oper; - instruction.operands[2] = OperandSpec::RegVex; - if mem_oper != OperandSpec::RegMMM { - instruction.mem_size = 4; - } - instruction.operand_count = 3; - Ok(()) - } - VEXOperandCode::G_Ey_V_xmm => { - 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, sink)?; - instruction.regs[3].bank = RegisterBank::X; - instruction.regs[2].bank = RegisterBank::Y; - instruction.operands[0] = OperandSpec::RegRRR; - instruction.operands[1] = mem_oper; - instruction.operands[2] = OperandSpec::RegVex; - if mem_oper != OperandSpec::RegMMM { - instruction.mem_size = 4; - } - instruction.operand_count = 3; - Ok(()) - } - VEXOperandCode::G_Ey_V_ymm => { + VEXOperandCode::G_ExyL_V_xyLmm => { + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + + let bank = if L { + RegisterBank::Y + } else { + RegisterBank::X + }; + 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, sink)?; - instruction.regs[3].bank = RegisterBank::Y; - instruction.regs[2].bank = RegisterBank::Y; + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), bank); + let mem_oper = read_E(words, instruction, modrm, bank, sink)?; + instruction.regs[2].bank = bank; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; instruction.operands[2] = OperandSpec::RegVex; @@ -1379,7 +1361,6 @@ fn read_vex_operands< Opcode::BLSI } _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } }; @@ -1410,7 +1391,6 @@ fn read_vex_operands< Opcode::VSTMXCSR } _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } }; @@ -1425,10 +1405,44 @@ fn read_vex_operands< instruction.operand_count = 1; Ok(()) } - VEXOperandCode::G_E_xmm_imm8 => { + VEXOperandCode::G_E_xyLmm_imm8 => { if instruction.regs[3].num != 0 { return Err(DecodeError::InvalidOperand); } + + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + + let bank = if L { + RegisterBank::Y + } else { + RegisterBank::X + }; + + let modrm = read_modrm(words)?; + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), bank); + let mem_oper = read_E(words, instruction, modrm, bank, sink)?; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = mem_oper; + instruction.imm = read_imm_unsigned(words, 1)?; + instruction.operands[2] = OperandSpec::ImmU8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } + instruction.operand_count = 3; + Ok(()) + } + VEXOperandCode::G_E_xmm_imm8 => { + if instruction.regs[3].num != 0 { + return Err(DecodeError::InvalidOperand); + } + + #[allow(non_snake_case)] + let L = instruction.prefixes.vex_unchecked().l(); + if L { + return Err(DecodeError::InvalidOperand); + } let modrm = read_modrm(words)?; instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X); @@ -1548,6 +1562,7 @@ fn read_vex_operands< } } +#[inline] fn read_vex_instruction< T: Reader<::Address, ::Word>, S: DescriptionSink, @@ -1568,52 +1583,32 @@ fn read_vex_instruction< match p { VEXOpcodePrefix::None => { match opc { - 0x10 => (Opcode::VMOVUPS, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }), - 0x11 => (Opcode::VMOVUPS, if L { VEXOperandCode::E_G_ymm } else { VEXOperandCode::E_G_xmm }), + 0x10 => (Opcode::VMOVUPS, VEXOperandCode::G_E_xyLmm), + 0x11 => (Opcode::VMOVUPS, VEXOperandCode::E_G_xyLmm), 0x12 => (Opcode::Invalid, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::VMOVLPS_12 }), 0x13 => (Opcode::VMOVLPS, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::M_G_xmm }), - 0x14 => (Opcode::VUNPCKLPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x15 => (Opcode::VUNPCKHPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x14 => (Opcode::VUNPCKLPS, VEXOperandCode::G_V_E_xyLmm), + 0x15 => (Opcode::VUNPCKHPS, VEXOperandCode::G_V_E_xyLmm), 0x16 => (Opcode::Invalid, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::VMOVHPS_16 }), 0x17 => (Opcode::VMOVHPS, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::M_G_xmm }), - 0x28 => (Opcode::VMOVAPS, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x29 => (Opcode::VMOVAPS, if L { - VEXOperandCode::E_G_ymm - } else { - VEXOperandCode::E_G_xmm - }), + 0x28 => (Opcode::VMOVAPS, VEXOperandCode::G_E_xyLmm), + 0x29 => (Opcode::VMOVAPS, VEXOperandCode::E_G_xyLmm), 0x2B => (Opcode::VMOVNTPS, if L { VEXOperandCode::M_G_ymm } else { @@ -1621,86 +1616,26 @@ fn read_vex_instruction< }), 0x2e => (Opcode::VUCOMISS, VEXOperandCode::G_E_xmm), 0x2f => (Opcode::VCOMISS, VEXOperandCode::G_E_xmm), - 0x50 => (Opcode::VMOVMSKPS, if L { - VEXOperandCode::Ud_G_ymm - } else { - VEXOperandCode::Ud_G_xmm - }), - 0x51 => (Opcode::VSQRTPS, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x52 => (Opcode::VRSQRTPS, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x53 => (Opcode::VRCPPS, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x54 => (Opcode::VANDPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x55 => (Opcode::VANDNPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x56 => (Opcode::VORPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x57 => (Opcode::VXORPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x58 => (Opcode::VADDPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x59 => (Opcode::VMULPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x50 => (Opcode::VMOVMSKPS, VEXOperandCode::Ud_G_xyLmm), + 0x51 => (Opcode::VSQRTPS, VEXOperandCode::G_E_xyLmm), + 0x52 => (Opcode::VRSQRTPS, VEXOperandCode::G_E_xyLmm), + 0x53 => (Opcode::VRCPPS, VEXOperandCode::G_E_xyLmm), + 0x54 => (Opcode::VANDPS, VEXOperandCode::G_V_E_xyLmm), + 0x55 => (Opcode::VANDNPS, VEXOperandCode::G_V_E_xyLmm), + 0x56 => (Opcode::VORPS, VEXOperandCode::G_V_E_xyLmm), + 0x57 => (Opcode::VXORPS, VEXOperandCode::G_V_E_xyLmm), + 0x58 => (Opcode::VADDPS, VEXOperandCode::G_V_E_xyLmm), + 0x59 => (Opcode::VMULPS, VEXOperandCode::G_V_E_xyLmm), 0x5A => (Opcode::VCVTPS2PD, if L { VEXOperandCode::G_ymm_E_xmm } else { VEXOperandCode::G_E_xmm }), - 0x5B => (Opcode::VCVTDQ2PS, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x5C => (Opcode::VSUBPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x5D => (Opcode::VMINPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x5E => (Opcode::VDIVPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x5F => (Opcode::VMAXPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x5B => (Opcode::VCVTDQ2PS, VEXOperandCode::G_E_xyLmm), + 0x5C => (Opcode::VSUBPS, VEXOperandCode::G_V_E_xyLmm), + 0x5D => (Opcode::VMINPS, VEXOperandCode::G_V_E_xyLmm), + 0x5E => (Opcode::VDIVPS, VEXOperandCode::G_V_E_xyLmm), + 0x5F => (Opcode::VMAXPS, VEXOperandCode::G_V_E_xyLmm), 0x77 => if L { (Opcode::VZEROALL, VEXOperandCode::Nothing) } else { @@ -1711,18 +1646,9 @@ fn read_vex_instruction< } else { VEXOperandCode::MXCSR }), - 0xC2 => (Opcode::VCMPPS, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), - 0xC6 => (Opcode::VSHUFPS, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), + 0xC2 => (Opcode::VCMPPS, VEXOperandCode::G_V_E_xyLmm_imm8), + 0xC6 => (Opcode::VSHUFPS, VEXOperandCode::G_V_E_xyLmm_imm8), _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -1731,64 +1657,33 @@ fn read_vex_instruction< 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 { - VEXOperandCode::G_E_xmm - }), - 0x11 => (Opcode::VMOVUPD, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), + 0x10 => (Opcode::VMOVUPD, VEXOperandCode::G_E_xyLmm), + 0x11 => (Opcode::VMOVUPD, VEXOperandCode::G_E_xyLmm), 0x12 => (Opcode::VMOVLPD, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_M_xmm }), 0x13 => (Opcode::VMOVLPD, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::M_G_xmm }), - 0x14 => (Opcode::VUNPCKLPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x15 => (Opcode::VUNPCKHPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x14 => (Opcode::VUNPCKLPD, VEXOperandCode::G_V_E_xyLmm), + 0x15 => (Opcode::VUNPCKHPD, VEXOperandCode::G_V_E_xyLmm), 0x16 => (Opcode::VMOVHPD, if L { return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_M_xmm }), 0x17 => (Opcode::VMOVHPD, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::M_G_xmm }), - 0x28 => (Opcode::VMOVAPD, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x29 => (Opcode::VMOVAPD, if L { - VEXOperandCode::E_G_ymm - } else { - VEXOperandCode::E_G_xmm - }), - 0x2B => (Opcode::VMOVNTPD, if L { - VEXOperandCode::M_G_ymm - } else { - VEXOperandCode::M_G_xmm - }), + 0x28 => (Opcode::VMOVAPD, VEXOperandCode::G_E_xyLmm), + 0x29 => (Opcode::VMOVAPD, VEXOperandCode::E_G_xyLmm), + 0x2B => (Opcode::VMOVNTPD, VEXOperandCode::M_G_xyLmm), 0x2e => (Opcode::VUCOMISD, VEXOperandCode::G_E_xmm), 0x2f => (Opcode::VCOMISD, VEXOperandCode::G_E_xmm), 0x50 => (Opcode::VMOVMSKPD, if L { @@ -1796,253 +1691,87 @@ fn read_vex_instruction< } else { VEXOperandCode::Gd_U_xmm }), - 0x51 => (Opcode::VSQRTPD, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x54 => (Opcode::VANDPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x55 => (Opcode::VANDNPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x56 => (Opcode::VORPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x57 => (Opcode::VXORPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x58 => (Opcode::VADDPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x59 => (Opcode::VMULPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x51 => (Opcode::VSQRTPD, VEXOperandCode::G_E_xyLmm), + 0x54 => (Opcode::VANDPD, VEXOperandCode::G_V_E_xyLmm), + 0x55 => (Opcode::VANDNPD, VEXOperandCode::G_V_E_xyLmm), + 0x56 => (Opcode::VORPD, VEXOperandCode::G_V_E_xyLmm), + 0x57 => (Opcode::VXORPD, VEXOperandCode::G_V_E_xyLmm), + 0x58 => (Opcode::VADDPD, VEXOperandCode::G_V_E_xyLmm), + 0x59 => (Opcode::VMULPD, VEXOperandCode::G_V_E_xyLmm), 0x5A => (Opcode::VCVTPD2PS, if L { VEXOperandCode::G_xmm_E_ymm } else { VEXOperandCode::G_xmm_E_xmm }), - 0x5B => (Opcode::VCVTPS2DQ, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x5C => (Opcode::VSUBPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x5D => (Opcode::VMINPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x5E => (Opcode::VDIVPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x5F => (Opcode::VMAXPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x60 => (Opcode::VPUNPCKLBW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x61 => (Opcode::VPUNPCKLWD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x62 => (Opcode::VPUNPCKLDQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x63 => (Opcode::VPACKSSWB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x64 => (Opcode::VPCMPGTB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x65 => (Opcode::VPCMPGTW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x66 => (Opcode::VPCMPGTD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x67 => (Opcode::VPACKUSWB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x68 => (Opcode::VPUNPCKHBW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x69 => (Opcode::VPUNPCKHWD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x6A => (Opcode::VPUNPCKHDQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x6B => (Opcode::VPACKSSDW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x6C => (Opcode::VPUNPCKLQDQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x6D => (Opcode::VPUNPCKHQDQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x5B => (Opcode::VCVTPS2DQ, VEXOperandCode::G_E_xyLmm), + 0x5C => (Opcode::VSUBPD, VEXOperandCode::G_V_E_xyLmm), + 0x5D => (Opcode::VMINPD, VEXOperandCode::G_V_E_xyLmm), + 0x5E => (Opcode::VDIVPD, VEXOperandCode::G_V_E_xyLmm), + 0x5F => (Opcode::VMAXPD, VEXOperandCode::G_V_E_xyLmm), + 0x60 => (Opcode::VPUNPCKLBW, VEXOperandCode::G_V_E_xyLmm), + 0x61 => (Opcode::VPUNPCKLWD, VEXOperandCode::G_V_E_xyLmm), + 0x62 => (Opcode::VPUNPCKLDQ, VEXOperandCode::G_V_E_xyLmm), + 0x63 => (Opcode::VPACKSSWB, VEXOperandCode::G_V_E_xyLmm), + 0x64 => (Opcode::VPCMPGTB, VEXOperandCode::G_V_E_xyLmm), + 0x65 => (Opcode::VPCMPGTW, VEXOperandCode::G_V_E_xyLmm), + 0x66 => (Opcode::VPCMPGTD, VEXOperandCode::G_V_E_xyLmm), + 0x67 => (Opcode::VPACKUSWB, VEXOperandCode::G_V_E_xyLmm), + 0x68 => (Opcode::VPUNPCKHBW, VEXOperandCode::G_V_E_xyLmm), + 0x69 => (Opcode::VPUNPCKHWD, VEXOperandCode::G_V_E_xyLmm), + 0x6A => (Opcode::VPUNPCKHDQ, VEXOperandCode::G_V_E_xyLmm), + 0x6B => (Opcode::VPACKSSDW, VEXOperandCode::G_V_E_xyLmm), + 0x6C => (Opcode::VPUNPCKLQDQ, VEXOperandCode::G_V_E_xyLmm), + 0x6D => (Opcode::VPUNPCKHQDQ, VEXOperandCode::G_V_E_xyLmm), 0x6E => if instruction.prefixes.vex_unchecked().w() { (Opcode::VMOVQ, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_xmm_Eq }) } else { (Opcode::VMOVD, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_xmm_Ed }) }, - 0x6F => (Opcode::VMOVDQA, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x70 => (Opcode::VPSHUFD, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_xmm_imm8 - }), - 0x71 => (Opcode::Invalid, if L { - VEXOperandCode::VPS_71_L - } else { - VEXOperandCode::VPS_71 - }), - 0x72 => (Opcode::Invalid, if L { - VEXOperandCode::VPS_72_L - } else { - VEXOperandCode::VPS_72 - }), - 0x73 => (Opcode::Invalid, if L { - VEXOperandCode::VPS_73_L - } else { - VEXOperandCode::VPS_73 - }), - 0x74 => (Opcode::VPCMPEQB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x75 => (Opcode::VPCMPEQW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x76 => (Opcode::VPCMPEQD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x7C => (Opcode::VHADDPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x7D => (Opcode::VHSUBPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x6F => (Opcode::VMOVDQA, VEXOperandCode::G_E_xyLmm), + 0x70 => (Opcode::VPSHUFD, VEXOperandCode::G_E_xyLmm_imm8), + 0x71 => (Opcode::Invalid, VEXOperandCode::VPS_71), + 0x72 => (Opcode::Invalid, VEXOperandCode::VPS_72), + 0x73 => (Opcode::Invalid, VEXOperandCode::VPS_73), + 0x74 => (Opcode::VPCMPEQB, VEXOperandCode::G_V_E_xyLmm), + 0x75 => (Opcode::VPCMPEQW, VEXOperandCode::G_V_E_xyLmm), + 0x76 => (Opcode::VPCMPEQD, VEXOperandCode::G_V_E_xyLmm), + 0x7C => (Opcode::VHADDPD, VEXOperandCode::G_V_E_xyLmm), + 0x7D => (Opcode::VHSUBPD, VEXOperandCode::G_V_E_xyLmm), 0x7E => if instruction.prefixes.vex_unchecked().w() { (Opcode::VMOVQ, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Eq_G_xmm }) } else { (Opcode::VMOVD, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Ed_G_xmm }) } - 0x7F => (Opcode::VMOVDQA, if L { - VEXOperandCode::E_G_ymm - } else { - VEXOperandCode::E_G_xmm - }), - 0xC2 => (Opcode::VCMPPD, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), + 0x7F => (Opcode::VMOVDQA, VEXOperandCode::E_G_xyLmm), + 0xC2 => (Opcode::VCMPPD, VEXOperandCode::G_V_E_xyLmm_imm8), 0xC4 => (Opcode::VPINSRW, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_xmm_Ev_imm8 }), 0xC5 => (Opcode::VPEXTRW, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Ud_G_xmm_imm8 }), - 0xC6 => (Opcode::VSHUFPD, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), - 0xD0 => (Opcode::VADDSUBPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0xC6 => (Opcode::VSHUFPD, VEXOperandCode::G_V_E_xyLmm_imm8), + 0xD0 => (Opcode::VADDSUBPD, VEXOperandCode::G_V_E_xyLmm), 0xD1 => (Opcode::VPSRLW, if L { VEXOperandCode::G_V_ymm_E_xmm } else { @@ -2058,72 +1787,23 @@ fn read_vex_instruction< } else { VEXOperandCode::G_V_E_xmm }), - 0xD4 => (Opcode::VPADDQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xD5 => (Opcode::VPMULLW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0xD4 => (Opcode::VPADDQ, VEXOperandCode::G_V_E_xyLmm), + 0xD5 => (Opcode::VPMULLW, VEXOperandCode::G_V_E_xyLmm), 0xD6 => (Opcode::VMOVQ, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), - 0xD7 => (Opcode::VPMOVMSKB, if L { - VEXOperandCode::Ud_G_ymm - } else { - VEXOperandCode::Ud_G_xmm - }), - 0xD8 => (Opcode::VPSUBUSB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xD9 => (Opcode::VPSUBUSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xDA => (Opcode::VPMINUB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xDB => (Opcode::VPAND, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xDC => (Opcode::VPADDUSB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xDD => (Opcode::VPADDUSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xDE => (Opcode::VPMAXUB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xDF => (Opcode::VPANDN, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xE0 => (Opcode::VPAVGB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0xD7 => (Opcode::VPMOVMSKB, VEXOperandCode::Ud_G_xyLmm), + 0xD8 => (Opcode::VPSUBUSB, VEXOperandCode::G_V_E_xyLmm), + 0xD9 => (Opcode::VPSUBUSW, VEXOperandCode::G_V_E_xyLmm), + 0xDA => (Opcode::VPMINUB, VEXOperandCode::G_V_E_xyLmm), + 0xDB => (Opcode::VPAND, VEXOperandCode::G_V_E_xyLmm), + 0xDC => (Opcode::VPADDUSB, VEXOperandCode::G_V_E_xyLmm), + 0xDD => (Opcode::VPADDUSW, VEXOperandCode::G_V_E_xyLmm), + 0xDE => (Opcode::VPMAXUB, VEXOperandCode::G_V_E_xyLmm), + 0xDF => (Opcode::VPANDN, VEXOperandCode::G_V_E_xyLmm), + 0xE0 => (Opcode::VPAVGB, VEXOperandCode::G_V_E_xyLmm), 0xE1 => (Opcode::VPSRAW, if L { VEXOperandCode::G_V_ymm_E_xmm } else { @@ -2134,71 +1814,23 @@ fn read_vex_instruction< } else { VEXOperandCode::G_V_E_xmm }), - 0xE3 => (Opcode::VPAVGW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xE4 => (Opcode::VPMULHUW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xE5 => (Opcode::VPMULHW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0xE3 => (Opcode::VPAVGW, VEXOperandCode::G_V_E_xyLmm), + 0xE4 => (Opcode::VPMULHUW, VEXOperandCode::G_V_E_xyLmm), + 0xE5 => (Opcode::VPMULHW, VEXOperandCode::G_V_E_xyLmm), 0xE6 => (Opcode::VCVTTPD2DQ, if L { VEXOperandCode::G_xmm_E_ymm } else { VEXOperandCode::G_E_xmm }), - 0xE7 => (Opcode::VMOVNTDQ, if L { - VEXOperandCode::M_G_ymm - } else { - VEXOperandCode::M_G_xmm - }), - 0xE8 => (Opcode::VPSUBSB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xE9 => (Opcode::VPSUBSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xEA => (Opcode::VPMINSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xEB => (Opcode::VPOR, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xEC => (Opcode::VPADDSB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xED => (Opcode::VPADDSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xEE => (Opcode::VPMAXSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xEF => (Opcode::VPXOR, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0xE7 => (Opcode::VMOVNTDQ, VEXOperandCode::M_G_xyLmm), + 0xE8 => (Opcode::VPSUBSB, VEXOperandCode::G_V_E_xyLmm), + 0xE9 => (Opcode::VPSUBSW, VEXOperandCode::G_V_E_xyLmm), + 0xEA => (Opcode::VPMINSW, VEXOperandCode::G_V_E_xyLmm), + 0xEB => (Opcode::VPOR, VEXOperandCode::G_V_E_xyLmm), + 0xEC => (Opcode::VPADDSB, VEXOperandCode::G_V_E_xyLmm), + 0xED => (Opcode::VPADDSW, VEXOperandCode::G_V_E_xyLmm), + 0xEE => (Opcode::VPMAXSW, VEXOperandCode::G_V_E_xyLmm), + 0xEF => (Opcode::VPXOR, VEXOperandCode::G_V_E_xyLmm), 0xF1 => (Opcode::VPSLLW, if L { VEXOperandCode::G_V_ymm_E_xmm } else { @@ -2214,64 +1846,22 @@ fn read_vex_instruction< } else { VEXOperandCode::G_V_E_xmm }), - 0xF4 => (Opcode::VPMULUDQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xF5 => (Opcode::VPMADDWD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xF6 => (Opcode::VPSADBW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0xF4 => (Opcode::VPMULUDQ, VEXOperandCode::G_V_E_xyLmm), + 0xF5 => (Opcode::VPMADDWD, VEXOperandCode::G_V_E_xyLmm), + 0xF6 => (Opcode::VPSADBW, VEXOperandCode::G_V_E_xyLmm), 0xF7 => (Opcode::VMASKMOVDQU, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_U_xmm }), - 0xF8 => (Opcode::VPSUBB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xF9 => (Opcode::VPSUBW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xFA => (Opcode::VPSUBD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xFB => (Opcode::VPSUBQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xFC => (Opcode::VPADDB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xFD => (Opcode::VPADDW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xFE => (Opcode::VPADDD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0xF8 => (Opcode::VPSUBB, VEXOperandCode::G_V_E_xyLmm), + 0xF9 => (Opcode::VPSUBW, VEXOperandCode::G_V_E_xyLmm), + 0xFA => (Opcode::VPSUBD, VEXOperandCode::G_V_E_xyLmm), + 0xFB => (Opcode::VPSUBQ, VEXOperandCode::G_V_E_xyLmm), + 0xFC => (Opcode::VPADDB, VEXOperandCode::G_V_E_xyLmm), + 0xFD => (Opcode::VPADDW, VEXOperandCode::G_V_E_xyLmm), + 0xFE => (Opcode::VPADDD, VEXOperandCode::G_V_E_xyLmm), _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -2280,11 +1870,7 @@ fn read_vex_instruction< 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 - }), + 0x12 => (Opcode::VMOVDDUP, VEXOperandCode::G_E_xyLmm), 0x2a => (Opcode::VCVTSI2SD, if instruction.prefixes.vex_unchecked().w() { VEXOperandCode::G_V_xmm_Eq // 64-bit last operand } else { @@ -2308,27 +1894,11 @@ fn read_vex_instruction< 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::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x7d => (Opcode::VHSUBPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x70 => (Opcode::VPSHUFLW, VEXOperandCode::G_E_xyLmm_imm8), + 0x7c => (Opcode::VHADDPS, VEXOperandCode::G_V_E_xyLmm), + 0x7d => (Opcode::VHSUBPS, VEXOperandCode::G_V_E_xyLmm), 0xc2 => (Opcode::VCMPSD, VEXOperandCode::G_V_E_xmm_imm8), - 0xd0 => (Opcode::VADDSUBPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0xd0 => (Opcode::VADDSUBPS, VEXOperandCode::G_V_E_xyLmm), 0xe6 => (Opcode::VCVTPD2DQ, if L { VEXOperandCode::G_xmm_E_ymm } else { @@ -2340,7 +1910,6 @@ fn read_vex_instruction< VEXOperandCode::G_M_xmm }), _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -2378,17 +1947,12 @@ fn read_vex_instruction< 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::VPSHUFHW, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_xmm_imm8 - }), - 0x7e => (Opcode::VMOVQ, if L { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), - 0x7f => (Opcode::VMOVDQU, if L { VEXOperandCode::E_G_ymm } else { VEXOperandCode::E_G_xmm }), + 0x70 => (Opcode::VPSHUFHW, VEXOperandCode::G_E_xyLmm_imm8), + 0x7e => (Opcode::VMOVQ, if L { return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), + 0x7f => (Opcode::VMOVDQU, VEXOperandCode::E_G_xyLmm), 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; return Err(DecodeError::InvalidOpcode); } } @@ -2400,107 +1964,33 @@ fn read_vex_instruction< if let VEXOpcodePrefix::Prefix66 = p { // possibly valid! match opc { - 0x00 => (Opcode::VPSHUFB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x01 => (Opcode::VPHADDW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x02 => (Opcode::VPHADDD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x03 => (Opcode::VPHADDSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x04 => (Opcode::VPMADDUBSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x05 => (Opcode::VPHSUBW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x06 => (Opcode::VPHSUBD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x07 => (Opcode::VPHSUBSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x08 => (Opcode::VPSIGNB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x09 => (Opcode::VPSIGNW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x0A => (Opcode::VPSIGND, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x0B => (Opcode::VPMULHRSW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x0C => (Opcode::VPERMILPS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x0D => (Opcode::VPERMILPD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x0E => (Opcode::VTESTPS, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x0F => (Opcode::VTESTPD, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x13 => (Opcode::VCVTPH2PS, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), + 0x00 => (Opcode::VPSHUFB, VEXOperandCode::G_V_E_xyLmm), + 0x01 => (Opcode::VPHADDW, VEXOperandCode::G_V_E_xyLmm), + 0x02 => (Opcode::VPHADDD, VEXOperandCode::G_V_E_xyLmm), + 0x03 => (Opcode::VPHADDSW, VEXOperandCode::G_V_E_xyLmm), + 0x04 => (Opcode::VPMADDUBSW, VEXOperandCode::G_V_E_xyLmm), + 0x05 => (Opcode::VPHSUBW, VEXOperandCode::G_V_E_xyLmm), + 0x06 => (Opcode::VPHSUBD, VEXOperandCode::G_V_E_xyLmm), + 0x07 => (Opcode::VPHSUBSW, VEXOperandCode::G_V_E_xyLmm), + 0x08 => (Opcode::VPSIGNB, VEXOperandCode::G_V_E_xyLmm), + 0x09 => (Opcode::VPSIGNW, VEXOperandCode::G_V_E_xyLmm), + 0x0A => (Opcode::VPSIGND, VEXOperandCode::G_V_E_xyLmm), + 0x0B => (Opcode::VPMULHRSW, VEXOperandCode::G_V_E_xyLmm), + 0x0C => (Opcode::VPERMILPS, VEXOperandCode::G_V_E_xyLmm), + 0x0D => (Opcode::VPERMILPD, VEXOperandCode::G_V_E_xyLmm), + 0x0E => (Opcode::VTESTPS, VEXOperandCode::G_E_xyLmm), + 0x0F => (Opcode::VTESTPD, VEXOperandCode::G_E_xyLmm), + 0x13 => (Opcode::VCVTPH2PS, VEXOperandCode::G_E_xyLmm), 0x16 => (Opcode::VPERMPS, if L { if instruction.prefixes.vex_unchecked().w() { return Err(DecodeError::InvalidOpcode); } VEXOperandCode::G_V_E_ymm } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), - 0x17 => (Opcode::VPTEST, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), + 0x17 => (Opcode::VPTEST, VEXOperandCode::G_E_xyLmm), 0x18 => if instruction.prefixes.vex_unchecked().w() { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { (Opcode::VBROADCASTSS, if L { @@ -2510,7 +2000,6 @@ fn read_vex_instruction< }) }, 0x19 => if instruction.prefixes.vex_unchecked().w() { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { (Opcode::VBROADCASTSD, if L { @@ -2522,24 +2011,11 @@ fn read_vex_instruction< 0x1A => (Opcode::VBROADCASTF128, if L { VEXOperandCode::G_ymm_M_xmm } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), - 0x1C => (Opcode::VPABSB, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x1D => (Opcode::VPABSW, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x1E => (Opcode::VPABSD, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), + 0x1C => (Opcode::VPABSB, VEXOperandCode::G_E_xyLmm), + 0x1D => (Opcode::VPABSW, VEXOperandCode::G_E_xyLmm), + 0x1E => (Opcode::VPABSD, VEXOperandCode::G_E_xyLmm), 0x20 => (Opcode::VPMOVSXBW, if L { VEXOperandCode::G_ymm_E_xmm } else { @@ -2570,26 +2046,14 @@ fn read_vex_instruction< } else { VEXOperandCode::G_E_xmm }), - 0x28 => (Opcode::VPMULDQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x29 => (Opcode::VPCMPEQQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x28 => (Opcode::VPMULDQ, VEXOperandCode::G_V_E_xyLmm), + 0x29 => (Opcode::VPCMPEQQ, VEXOperandCode::G_V_E_xyLmm), 0x2A => (Opcode::VMOVNTDQA, if L { VEXOperandCode::G_M_ymm } else { VEXOperandCode::G_M_xmm }), - 0x2B => (Opcode::VPACKUSDW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x2B => (Opcode::VPACKUSDW, VEXOperandCode::G_V_E_xyLmm), 0x2C => (Opcode::VMASKMOVPS, if L { VEXOperandCode::G_V_M_ymm } else { @@ -2643,77 +2107,27 @@ fn read_vex_instruction< 0x36 => (Opcode::VPERMD, if L { VEXOperandCode::G_V_E_ymm } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), - 0x37 => (Opcode::VPCMPGTQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x38 => (Opcode::VPMINSB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x39 => (Opcode::VPMINSD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x3A => (Opcode::VPMINUW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x3B => (Opcode::VPMINUD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x3C => (Opcode::VPMAXSB, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x3D => (Opcode::VPMAXSD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x3E => (Opcode::VPMAXUW, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x3F => (Opcode::VPMAXUD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0x40 => (Opcode::VPMULLD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0x37 => (Opcode::VPCMPGTQ, VEXOperandCode::G_V_E_xyLmm), + 0x38 => (Opcode::VPMINSB, VEXOperandCode::G_V_E_xyLmm), + 0x39 => (Opcode::VPMINSD, VEXOperandCode::G_V_E_xyLmm), + 0x3A => (Opcode::VPMINUW, VEXOperandCode::G_V_E_xyLmm), + 0x3B => (Opcode::VPMINUD, VEXOperandCode::G_V_E_xyLmm), + 0x3C => (Opcode::VPMAXSB, VEXOperandCode::G_V_E_xyLmm), + 0x3D => (Opcode::VPMAXSD, VEXOperandCode::G_V_E_xyLmm), + 0x3E => (Opcode::VPMAXUW, VEXOperandCode::G_V_E_xyLmm), + 0x3F => (Opcode::VPMAXUD, VEXOperandCode::G_V_E_xyLmm), + 0x40 => (Opcode::VPMULLD, VEXOperandCode::G_V_E_xyLmm), 0x41 => (Opcode::VPHMINPOSUW, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), 0x45 => if instruction.prefixes.vex_unchecked().w() { - (Opcode::VPSRLVQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }) + (Opcode::VPSRLVQ, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VPSRLVD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }) + (Opcode::VPSRLVD, VEXOperandCode::G_V_E_xyLmm) }, 0x46 => (Opcode::VPSRAVD, if L { if instruction.prefixes.vex_unchecked().w() { @@ -2727,35 +2141,18 @@ fn read_vex_instruction< VEXOperandCode::G_V_E_xmm }), 0x47 => if instruction.prefixes.vex_unchecked().w() { - (Opcode::VPSLLVQ, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }) + (Opcode::VPSLLVQ, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VPSLLVD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }) + (Opcode::VPSLLVD, VEXOperandCode::G_V_E_xyLmm) }, - 0x58 => (Opcode::VPBROADCASTD, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), - 0x59 => (Opcode::VPBROADCASTQ, if L { - VEXOperandCode::G_E_ymm - } else { - VEXOperandCode::G_E_xmm - }), + 0x58 => (Opcode::VPBROADCASTD, VEXOperandCode::G_E_xyLmm), + 0x59 => (Opcode::VPBROADCASTQ, VEXOperandCode::G_E_xyLmm), 0x5A => (Opcode::VBROADCASTI128, if L { if instruction.prefixes.vex_unchecked().w() { return Err(DecodeError::InvalidOpcode); } VEXOperandCode::G_ymm_M_xmm } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), 0x78 => (Opcode::VPBROADCASTB, if L { @@ -2800,107 +2197,51 @@ fn read_vex_instruction< }, 0x90 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VPGATHERDQ, if L { - VEXOperandCode::G_Ey_V_ymm - } else { - VEXOperandCode::G_Ex_V_xmm - }) + (Opcode::VPGATHERDQ, VEXOperandCode::G_ExyL_V_xyLmm) } else { - (Opcode::VPGATHERDD, if L { - VEXOperandCode::G_Ey_V_ymm - } else { - VEXOperandCode::G_Ex_V_xmm - }) + (Opcode::VPGATHERDD, VEXOperandCode::G_ExyL_V_xyLmm) } }, 0x91 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VPGATHERQQ, if L { - VEXOperandCode::G_Ey_V_ymm - } else { - VEXOperandCode::G_Ex_V_xmm - }) + (Opcode::VPGATHERQQ, VEXOperandCode::G_ExyL_V_xyLmm) } else { - (Opcode::VPGATHERQD, if L { - VEXOperandCode::G_Ey_V_xmm - } else { - VEXOperandCode::G_Ex_V_xmm - }) + (Opcode::VPGATHERQD, VEXOperandCode::G_ExyL_V_xyLmm) } }, 0x92 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VGATHERDPD, if L { - VEXOperandCode::G_Ey_V_ymm - } else { - VEXOperandCode::G_Ex_V_xmm - }) + (Opcode::VGATHERDPD, VEXOperandCode::G_ExyL_V_xyLmm) } else { - (Opcode::VGATHERDPS, if L { - VEXOperandCode::G_Ey_V_ymm - } else { - VEXOperandCode::G_Ex_V_xmm - }) + (Opcode::VGATHERDPS, VEXOperandCode::G_ExyL_V_xyLmm) } }, 0x93 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VGATHERQPD, if L { - VEXOperandCode::G_Ey_V_ymm - } else { - VEXOperandCode::G_Ex_V_xmm - }) + (Opcode::VGATHERQPD, VEXOperandCode::G_ExyL_V_xyLmm) } else { - (Opcode::VGATHERQPS, if L { - VEXOperandCode::G_Ey_V_ymm - } else { - VEXOperandCode::G_Ex_V_xmm - }) + (Opcode::VGATHERQPS, VEXOperandCode::G_ExyL_V_xyLmm) } }, 0x96 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMADDSUB132PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADDSUB132PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMADDSUB132PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADDSUB132PS, VEXOperandCode::G_V_E_xyLmm) } }, 0x97 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMSUBADD132PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUBADD132PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMSUBADD132PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUBADD132PS, VEXOperandCode::G_V_E_xyLmm) } }, 0x98 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMADD132PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADD132PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMADD132PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADD132PS, VEXOperandCode::G_V_E_xyLmm) } }, 0x99 => if instruction.prefixes.vex_unchecked().w() { @@ -2910,17 +2251,9 @@ fn read_vex_instruction< }, 0x9A => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMSUB132PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUB132PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMSUB132PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUB132PS, VEXOperandCode::G_V_E_xyLmm) } }, 0x9B => if instruction.prefixes.vex_unchecked().w() { @@ -2930,17 +2263,9 @@ fn read_vex_instruction< }, 0x9C => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFNMADD132PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMADD132PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFNMADD132PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMADD132PS, VEXOperandCode::G_V_E_xyLmm) } }, 0x9D => if instruction.prefixes.vex_unchecked().w() { @@ -2950,17 +2275,9 @@ fn read_vex_instruction< }, 0x9E => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFNMSUB132PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMSUB132PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFNMSUB132PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMSUB132PS, VEXOperandCode::G_V_E_xyLmm) } }, 0x9F => if instruction.prefixes.vex_unchecked().w() { @@ -2970,47 +2287,23 @@ fn read_vex_instruction< }, 0xA6 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMADDSUB213PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADDSUB213PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMADDSUB213PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADDSUB213PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xA7 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMSUBADD213PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUBADD213PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMSUBADD213PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUBADD213PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xA8 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMADD213PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADD213PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMADD213PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADD213PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xA9 => if instruction.prefixes.vex_unchecked().w() { @@ -3020,17 +2313,9 @@ fn read_vex_instruction< }, 0xAA => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMSUB213PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUB213PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMSUB213PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUB213PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xAB => if instruction.prefixes.vex_unchecked().w() { @@ -3040,17 +2325,9 @@ fn read_vex_instruction< }, 0xAC => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFNMADD213PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMADD213PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFNMADD213PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMADD213PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xAD => if instruction.prefixes.vex_unchecked().w() { @@ -3060,17 +2337,9 @@ fn read_vex_instruction< }, 0xAE => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFNMSUB213PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMSUB213PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFNMSUB213PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMSUB213PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xAF => if instruction.prefixes.vex_unchecked().w() { @@ -3080,47 +2349,23 @@ fn read_vex_instruction< }, 0xB6 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMADDSUB231PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADDSUB231PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMADDSUB231PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADDSUB231PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xB7 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMSUBADD231PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUBADD231PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMSUBADD231PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUBADD231PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xB8 => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMADD231PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADD231PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMADD231PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMADD231PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xB9 => if instruction.prefixes.vex_unchecked().w() { @@ -3130,17 +2375,9 @@ fn read_vex_instruction< }, 0xBA => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFMSUB231PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUB231PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFMSUB231PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFMSUB231PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xBB => if instruction.prefixes.vex_unchecked().w() { @@ -3150,17 +2387,9 @@ fn read_vex_instruction< }, 0xBC => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFNMADD231PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMADD231PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFNMADD231PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMADD231PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xBD => if instruction.prefixes.vex_unchecked().w() { @@ -3170,17 +2399,9 @@ fn read_vex_instruction< }, 0xBE => { if instruction.prefixes.vex_unchecked().w() { - (Opcode::VFNMSUB231PD, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMSUB231PD, VEXOperandCode::G_V_E_xyLmm) } else { - (Opcode::VFNMSUB231PS, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_ymm - }) + (Opcode::VFNMSUB231PS, VEXOperandCode::G_V_E_xyLmm) } }, 0xBF => if instruction.prefixes.vex_unchecked().w() { @@ -3189,114 +2410,83 @@ fn read_vex_instruction< (Opcode::VFNMSUB231SS, VEXOperandCode::G_V_E_xmm /* 64bit */) }, 0xDB => (Opcode::VAESIMC, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), - 0xDC => (Opcode::VAESENC, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xDD => (Opcode::VAESENCLAST, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xDE => (Opcode::VAESDEC, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), - 0xDF => (Opcode::VAESDECLAST, if L { - VEXOperandCode::G_V_E_ymm - } else { - VEXOperandCode::G_V_E_xmm - }), + 0xDC => (Opcode::VAESENC, VEXOperandCode::G_V_E_xyLmm), + 0xDD => (Opcode::VAESENCLAST, VEXOperandCode::G_V_E_xyLmm), + 0xDE => (Opcode::VAESDEC, VEXOperandCode::G_V_E_xyLmm), + 0xDF => (Opcode::VAESDECLAST, VEXOperandCode::G_V_E_xyLmm), 0xF7 => (Opcode::SHLX, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_V }), _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } } else if let VEXOpcodePrefix::PrefixF2 = p { match opc { 0xF5 => (Opcode::PDEP, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E }), 0xF6 => (Opcode::MULX, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E }), 0xF7 => (Opcode::SHRX, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_V }), _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } } else if let VEXOpcodePrefix::PrefixF3 = p { match opc { 0xF5 => (Opcode::PEXT, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E }), 0xF7 => (Opcode::SARX, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_V }), _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } } else { match opc { 0xF2 => (Opcode::ANDN, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E }), 0xF3 => (Opcode::Invalid, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::BMI1_F3 }), 0xF5 => (Opcode::BZHI, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_V }), 0xF7 => (Opcode::BEXTR, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_V }), _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } @@ -3312,7 +2502,6 @@ fn read_vex_instruction< } VEXOperandCode::G_E_ymm_imm8 } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), 0x01 => (Opcode::VPERMPD, if L { @@ -3321,101 +2510,49 @@ fn read_vex_instruction< } VEXOperandCode::G_E_ymm_imm8 } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), - 0x02 => (Opcode::VPBLENDD, if L { - if instruction.prefixes.vex_unchecked().w() { - return Err(DecodeError::InvalidOpcode); - } - VEXOperandCode::G_V_E_ymm_imm8 - } else { - if instruction.prefixes.vex_unchecked().w() { - return Err(DecodeError::InvalidOpcode); - } - VEXOperandCode::G_V_E_xmm_imm8 - }), - 0x04 => (Opcode::VPERMILPS, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_xmm_imm8 - }), - 0x05 => (Opcode::VPERMILPD, if L { - VEXOperandCode::G_E_ymm_imm8 + 0x02 => (Opcode::VPBLENDD, if instruction.prefixes.vex_unchecked().w() { + return Err(DecodeError::InvalidOpcode); } else { - VEXOperandCode::G_E_xmm_imm8 + VEXOperandCode::G_V_E_xyLmm_imm8 }), + 0x04 => (Opcode::VPERMILPS, VEXOperandCode::G_E_xyLmm_imm8), + 0x05 => (Opcode::VPERMILPD, VEXOperandCode::G_E_xyLmm_imm8), 0x06 => (Opcode::VPERM2F128, if L { if instruction.prefixes.vex_unchecked().w() { return Err(DecodeError::InvalidOpcode); } VEXOperandCode::G_V_E_ymm_imm8 } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), - 0x08 => (Opcode::VROUNDPS, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_xmm_imm8 - }), - 0x09 => (Opcode::VROUNDPD, if L { - VEXOperandCode::G_E_ymm_imm8 - } else { - VEXOperandCode::G_E_xmm_imm8 - }), - 0x0A => (Opcode::VROUNDSS, if L { - VEXOperandCode::G_V_E_xmm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), - 0x0B => (Opcode::VROUNDSD, if L { - VEXOperandCode::G_V_E_xmm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), - 0x0C => (Opcode::VBLENDPS, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), - 0x0D => (Opcode::VBLENDPD, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), - 0x0E => (Opcode::VPBLENDW, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), - 0x0F => (Opcode::VPALIGNR, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), + 0x08 => (Opcode::VROUNDPS, VEXOperandCode::G_E_xyLmm_imm8), + 0x09 => (Opcode::VROUNDPD, VEXOperandCode::G_E_xyLmm_imm8), + 0x0A => (Opcode::VROUNDSS, VEXOperandCode::G_V_E_xyLmm_imm8), + 0x0B => (Opcode::VROUNDSD, VEXOperandCode::G_V_E_xyLmm_imm8), + 0x0C => (Opcode::VBLENDPS, VEXOperandCode::G_V_E_xyLmm_imm8), + 0x0D => (Opcode::VBLENDPD, VEXOperandCode::G_V_E_xyLmm_imm8), + 0x0E => (Opcode::VPBLENDW, VEXOperandCode::G_V_E_xyLmm_imm8), + 0x0F => (Opcode::VPALIGNR, VEXOperandCode::G_V_E_xyLmm_imm8), 0x14 => (Opcode::VPEXTRB, if L || instruction.prefixes.vex_unchecked().w() { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Ev_G_xmm_imm8 }), 0x15 => (Opcode::VPEXTRW, if L || instruction.prefixes.vex_unchecked().w() { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Ev_G_xmm_imm8 }), 0x16 => if instruction.prefixes.vex_unchecked().w() { (Opcode::VPEXTRQ, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Ev_G_xmm_imm8 }) } else { (Opcode::VPEXTRD, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { // varies on W @@ -3423,30 +2560,25 @@ fn read_vex_instruction< }) }, 0x17 => (Opcode::VEXTRACTPS, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::Ev_G_xmm_imm8 }), 0x18 => if instruction.prefixes.vex_unchecked().w() { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { (Opcode::VINSERTF128, if L { VEXOperandCode::G_ymm_V_ymm_E_xmm_imm8 } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }) }, 0x19 => if instruction.prefixes.vex_unchecked().w() { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { (Opcode::VEXTRACTF128, if L { VEXOperandCode::E_xmm_G_ymm_imm8 } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }) }, @@ -3456,27 +2588,23 @@ fn read_vex_instruction< VEXOperandCode::E_G_xmm_imm8 }), 0x20 => (Opcode::VPINSRB, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_xmm_Ev_imm8 }), 0x21 => (Opcode::VINSERTPS, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm_imm8 }), 0x22 => if instruction.prefixes.vex_unchecked().w() { (Opcode::VPINSRQ, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_xmm_Ev_imm8 }) } else { (Opcode::VPINSRD, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_xmm_Ev_imm8 @@ -3485,33 +2613,21 @@ fn read_vex_instruction< 0x38 => (Opcode::VINSERTI128, if L { VEXOperandCode::G_ymm_V_ymm_E_xmm_imm8 } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), 0x39 => (Opcode::VEXTRACTI128, if L { VEXOperandCode::E_xmm_G_ymm_imm8 } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), - 0x40 => (Opcode::VDPPS, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), + 0x40 => (Opcode::VDPPS, VEXOperandCode::G_V_E_xyLmm_imm8), 0x41 => (Opcode::VDPPD, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm_imm8 }), - 0x42 => (Opcode::VMPSADBW, if L { - VEXOperandCode::G_V_E_ymm_imm8 - } else { - VEXOperandCode::G_V_E_xmm_imm8 - }), + 0x42 => (Opcode::VMPSADBW, VEXOperandCode::G_V_E_xyLmm_imm8), 0x44 => (Opcode::VPCLMULQDQ, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_V_E_xmm_imm8 @@ -3522,7 +2638,6 @@ fn read_vex_instruction< } VEXOperandCode::G_V_E_ymm_imm8 } else { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); }), 0x4A => (Opcode::VBLENDVPS, if L { @@ -3536,7 +2651,6 @@ fn read_vex_instruction< VEXOperandCode::G_V_E_xmm_xmm4 }), 0x4C => if instruction.prefixes.vex_unchecked().w() { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { (Opcode::VPBLENDVB, if L { @@ -3545,57 +2659,28 @@ fn read_vex_instruction< VEXOperandCode::G_V_E_xmm_xmm4 }) }, - 0x60 => (Opcode::VPCMPESTRM, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } else { - VEXOperandCode::G_E_xmm_imm8 - }), - 0x61 => (Opcode::VPCMPESTRI, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } else { - VEXOperandCode::G_E_xmm_imm8 - }), - 0x62 => (Opcode::VPCMPISTRM, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } else { - VEXOperandCode::G_E_xmm_imm8 - }), - 0x63 => (Opcode::VPCMPISTRI, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } else { - VEXOperandCode::G_E_xmm_imm8 - }), - 0xDF => (Opcode::VAESKEYGENASSIST, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } else { - VEXOperandCode::G_E_xmm_imm8 - }), + 0x60 => (Opcode::VPCMPESTRM, VEXOperandCode::G_E_xmm_imm8), + 0x61 => (Opcode::VPCMPESTRI, VEXOperandCode::G_E_xmm_imm8), + 0x62 => (Opcode::VPCMPISTRM, VEXOperandCode::G_E_xmm_imm8), + 0x63 => (Opcode::VPCMPISTRI, VEXOperandCode::G_E_xmm_imm8), + 0xDF => (Opcode::VAESKEYGENASSIST, VEXOperandCode::G_E_xmm_imm8), _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } } else if let VEXOpcodePrefix::PrefixF2 = p { match opc { 0xF0 => (Opcode::RORX, if L { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_Ib }), _ => { - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } } else { // the only VEX* 0f3a instructions have an implied 66 prefix. - instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } } -- cgit v1.1