diff options
author | iximeow <me@iximeow.net> | 2021-03-21 01:02:00 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2021-03-21 01:21:55 -0700 |
commit | a493b4d267c4fb6a042cf071301c8885196b4a91 (patch) | |
tree | 9be24cf43e2fef9f48d6f88e0b7716eb5f66ccca | |
parent | 0c8dccaf591748e6acb9b437d69ba028e59a73cf (diff) |
rewrite 0f-based instruction handling
this is... a more significant rewrite than i expected yaxpeax-x86 to
ever need. it turns out that capstone is extremely permissive about
duplicative 66/f2/f3 prefixes to the point that the implemented prefex
handling was unsalvageable.
while this replaces the *0f* opcode tables, i haven't profiled these
changes. it's possible this is a net improvement for single-byte
opcodes, it could be a net loss. code size may be severely impacted.
there is still work to do.
but this in total gets very close to iced/xed/zydis parity, far more
than before.
also adds several small extensions, gfni, 3dnow, enqcmd, invpcid, some
of cet, and a few missing avx instructions.
-rw-r--r-- | src/long_mode/display.rs | 52 | ||||
-rw-r--r-- | src/long_mode/mod.rs | 4061 | ||||
-rw-r--r-- | src/long_mode/vex.rs | 20 | ||||
-rw-r--r-- | test/long_mode/display.rs | 3 | ||||
-rw-r--r-- | test/long_mode/mod.rs | 194 |
5 files changed, 2262 insertions, 2068 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index df7237d..3e38d8d 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -570,6 +570,10 @@ const MNEMONICS: &[&'static str] = &[ "movnti", "movntps", "movntpd", + "extrq", + "insertq", + "movntss", + "movntsd", "movntq", "movntdq", "mulps", @@ -842,6 +846,10 @@ const MNEMONICS: &[&'static str] = &[ "vpaddusw", "vpaddw", "vpalignr", + "vandps", + "vandpd", + "vandnps", + "vandnpd", "vpand", "vpandn", "vpavgb", @@ -1086,6 +1094,8 @@ const MNEMONICS: &[&'static str] = &[ "vmsave", "vmrun", "invlpga", + "invlpgb", + "tlbsync", "movbe", "adcx", "adox", @@ -1248,15 +1258,33 @@ const MNEMONICS: &[&'static str] = &[ "pfacc", "pfcmpeq", "pfmul", + "pfmulhrw", "pfrcpit2", "pfnacc", - "pswapd", "pfpnacc", + "pswapd", "pavgusb", // ENQCMD "enqcmd", "enqcmds", + + // INVPCID, + "invept", + "invvpid", + "invpcid", + + // PTWRITE + "ptwrite", + + // GFNI + "gf2p8affineqb", + "gf2p8affineinvqb", + "gf2p8mulb", + + // CET + "wruss", + "wrss", ]; impl Opcode { @@ -1423,6 +1451,10 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::VDPPD | Opcode::VDPPS | Opcode::VRCPPS | + Opcode::VANDPD | + Opcode::VANDPS | + Opcode::VANDNPD | + Opcode::VANDNPS | Opcode::VPAND | Opcode::VPANDN | Opcode::VPOR | @@ -1480,10 +1512,11 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::PFSUBR | Opcode::PFACC | Opcode::PFMUL | + Opcode::PFMULHRW | Opcode::PFRCPIT2 | Opcode::PFNACC | - Opcode::PSWAPD | Opcode::PFPNACC | + Opcode::PSWAPD | Opcode::PAVGUSB | Opcode::XADD| Opcode::DIV | @@ -1845,9 +1878,11 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::PEXTRB | Opcode::PEXTRD | Opcode::PEXTRQ | + Opcode::EXTRQ | Opcode::PINSRB | Opcode::PINSRD | Opcode::PINSRQ | + Opcode::INSERTQ | Opcode::VPINSRB | Opcode::VPINSRD | Opcode::VPINSRQ | @@ -1899,6 +1934,8 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::MOVNTI | Opcode::MOVNTPS | Opcode::MOVNTPD | + Opcode::MOVNTSS | + Opcode::MOVNTSD | Opcode::MOVNTQ | Opcode::MOVNTDQ | Opcode::MOVSD | @@ -2173,8 +2210,13 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::LMSW | Opcode::SWAPGS | Opcode::RDTSCP | + Opcode::INVEPT | + Opcode::INVVPID | + Opcode::INVPCID | Opcode::INVLPG | Opcode::INVLPGA | + Opcode::INVLPGB | + Opcode::TLBSYNC | Opcode::CPUID | Opcode::WBINVD | Opcode::INVD | @@ -2237,6 +2279,7 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::CLZERO | Opcode::ENQCMD | Opcode::ENQCMDS | + Opcode::PTWRITE | Opcode::LAR => { write!(out, "{}", colors.platform_op(self)) } Opcode::CRC32 | @@ -2253,6 +2296,9 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::FFREEP | Opcode::FDECSTP | Opcode::FINCSTP | + Opcode::GF2P8MULB | + Opcode::GF2P8AFFINEQB | + Opcode::GF2P8AFFINEINVQB | Opcode::AESDEC128KL | Opcode::AESDEC256KL | Opcode::AESDECWIDE128KL | @@ -2264,6 +2310,8 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color Opcode::ENCODEKEY128 | Opcode::ENCODEKEY256 | Opcode::LOADIWKEY | + Opcode::WRUSS | + Opcode::WRSS | Opcode::AESDEC | Opcode::AESDECLAST | Opcode::AESENC | diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 15a1318..9410b2b 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -46,16 +46,6 @@ impl Hash for RegSpec { } } -// This is only to select alternate opcode maps for the 0f escape byte. -// This often could be treated as a size prefix but in some cases selects -// an entirely different operation. -#[derive(Debug)] -enum OpcodeMap { - Map66, - MapF2, - MapF3, -} - #[derive(Debug)] pub enum ConditionCode { O, @@ -491,7 +481,7 @@ impl OperandSpec { OperandSpec::RegMMM | OperandSpec::RegVex | OperandSpec::Reg4 | - OperandSpec::EnterFrameSize | + OperandSpec::ImmInDispField | OperandSpec::Nothing => { false } @@ -526,7 +516,7 @@ impl Operand { OperandSpec::ImmU32 => Operand::ImmediateU32(inst.imm as u32), OperandSpec::ImmI64 => Operand::ImmediateI64(inst.imm as i64), OperandSpec::ImmU64 => Operand::ImmediateU64(inst.imm as u64), - OperandSpec::EnterFrameSize => Operand::ImmediateU16(inst.disp as u16), + OperandSpec::ImmInDispField => Operand::ImmediateU16(inst.disp as u16), OperandSpec::DispU32 => Operand::DisplacementU32(inst.disp as u32), OperandSpec::DispU64 => Operand::DisplacementU64(inst.disp as u64), OperandSpec::Deref => { @@ -892,7 +882,6 @@ const XSAVE: [Opcode; 10] = [ ]; // TODO: -// PTWRITE // TPAUSE // UMONITOR // UMWAIT @@ -1223,6 +1212,10 @@ pub enum Opcode { MOVNTI, MOVNTPS, MOVNTPD, + EXTRQ, + INSERTQ, + MOVNTSS, + MOVNTSD, MOVNTQ, MOVNTDQ, MULPS, @@ -1497,6 +1490,10 @@ pub enum Opcode { VPADDUSW, VPADDW, VPALIGNR, + VANDPD, + VANDPS, + VANDNPD, + VANDNPS, VPAND, VPANDN, VPAVGB, @@ -1744,6 +1741,8 @@ pub enum Opcode { VMSAVE, VMRUN, INVLPGA, + INVLPGB, + TLBSYNC, MOVBE, @@ -1918,15 +1917,33 @@ pub enum Opcode { PFACC, PFCMPEQ, PFMUL, + PFMULHRW, PFRCPIT2, PFNACC, - PSWAPD, PFPNACC, + PSWAPD, PAVGUSB, // ENQCMD ENQCMD, ENQCMDS, + + // INVPCID + INVEPT, + INVVPID, + INVPCID, + + // PTWRITE + PTWRITE, + + // GFNI + GF2P8AFFINEQB, + GF2P8AFFINEINVQB, + GF2P8MULB, + + // CET + WRUSS, + WRSS, } #[derive(Debug)] @@ -1992,7 +2009,9 @@ enum OperandSpec { ImmU64, // ENTER is a two-immediate instruction, where the first immediate is stored in the disp field. // for this case, a second immediate-style operand is needed. - EnterFrameSize, + // turns out `insertq` and `extrq` are also two-immediate instructions, so this is generalized + // to cover them too. + ImmInDispField, DispU32, DispU64, Deref, @@ -2832,6 +2851,15 @@ impl InstDecoder { return Err(DecodeError::InvalidOpcode); } } + Opcode::EXTRQ | + Opcode::INSERTQ | + Opcode::MOVNTSS | + Opcode::MOVNTSD => { + if !self.sse4a() { + inst.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + } Opcode::CRC32 | Opcode::PCMPESTRI | Opcode::PCMPESTRM | @@ -3070,6 +3098,10 @@ impl InstDecoder { Opcode::VPADDW | Opcode::VPALIGNR | Opcode::VPAND | + Opcode::VANDPD | + Opcode::VANDPS | + Opcode::VANDNPD | + Opcode::VANDNPS | Opcode::VPANDN | Opcode::VPAVGB | Opcode::VPAVGW | @@ -3623,21 +3655,23 @@ impl Prefixes { #[inline] pub fn rep(&self) -> bool { self.bits & 0x30 == 0x10 } #[inline] - fn set_rep(&mut self) { self.bits = (self.bits & 0xcf) | 0x10 } + fn set_rep(&mut self) { self.bits = (self.bits & 0xcf) | 0x10; } #[inline] pub fn repz(&self) -> bool { self.bits & 0x30 == 0x20 } #[inline] - fn set_repz(&mut self) { self.bits = (self.bits & 0xcf) | 0x20 } + fn set_repz(&mut self) { self.bits = (self.bits & 0xcf) | 0x20; } #[inline] pub fn repnz(&self) -> bool { self.bits & 0x30 == 0x30 } #[inline] - fn set_repnz(&mut self) { self.bits = (self.bits & 0xcf) | 0x30 } + fn set_repnz(&mut self) { self.bits = (self.bits & 0xcf) | 0x30; } #[inline] pub fn rep_any(&self) -> bool { self.bits & 0x30 != 0x00 } #[inline] fn operand_size(&self) -> bool { self.bits & 0x1 == 1 } #[inline] - fn set_operand_size(&mut self) { self.bits = self.bits | 0x1 } + fn set_operand_size(&mut self) { self.bits = self.bits | 0x1; } + #[inline] + fn unset_operand_size(&mut self) { self.bits = self.bits & !0x1; } #[inline] fn address_size(&self) -> bool { self.bits & 0x2 == 2 } #[inline] @@ -3965,24 +3999,33 @@ enum OperandCode { 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_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_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_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_0x660f12 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(), - ModRM_0x660f16 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), - ModRM_0x660f71 = OperandCodeBuilder::new().read_modrm().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_0xf20f78 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(), + ModRM_0x660f78 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), +// ModRM_0x660f12 = OperandCodeBuilder::new().read_modrm().special_case(58).bits(), +// ModRM_0x660f16 = OperandCodeBuilder::new().read_modrm().special_case(59).bits(), +// ModRM_0x660f71 = OperandCodeBuilder::new().read_modrm().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(), // xmmword? ModRM_0x0f12 = OperandCodeBuilder::new() @@ -4156,10 +4199,15 @@ enum OperandCode { 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(), + 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_mm_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().with_imm(false, 0).reg_mem().operand_case(29).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(), @@ -4172,6 +4220,7 @@ enum OperandCode { 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(), Gb_Eb_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().with_imm(false, 0).byte_operands().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(), @@ -4279,1115 +4328,6 @@ const BITWISE_OPCODE_MAP: [Opcode; 8] = [ Opcode::SAR ]; -const OPCODE_660F_MAP: [OpcodeRecord; 256] = [ - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x10 - OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPD), OperandCode::E_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f12), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPD), OperandCode::M_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKLPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKHPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::ModRM_0x660f16), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::M_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x20 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPD), OperandCode::E_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTPI2PD), OperandCode::G_xmm_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTPD), OperandCode::M_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPD2PI), OperandCode::G_mm_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTPD2PI), OperandCode::G_mm_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::COMISD), OperandCode::G_E_xmm), -// 0x30 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f38), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f3a), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x40 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x50 - OpcodeRecord(Interpretation::Instruction(Opcode::MOVMSKPD), OperandCode::Gd_U_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::SQRTPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::ANDPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::ANDNPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::ORPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::XORPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::ADDPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MULPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTPD2PS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2DQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::SUBPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MINPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::DIVPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MAXPD), OperandCode::G_E_xmm), -// 0x60 - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLBW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLWD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLDQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSWB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PACKUSWB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHBW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHWD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHDQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSDW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLQDQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHQDQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::G_xmm_Eq), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQA), OperandCode::G_E_xmm), -// 0x70 - OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFD), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f71), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f72), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f73), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::HADDPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::HSUBPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::Edq_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQA), OperandCode::E_G_xmm), -// 0x80 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x90 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xa0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660fae), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xb0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xc0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CMPPD), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::PINSRW), OperandCode::G_xmm_Ed_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::SHUFPD), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660fc7), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xd0 - OpcodeRecord(Interpretation::Instruction(Opcode::ADDSUBPD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRLW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRLD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRLQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMULLW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::E_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMOVMSKB), OperandCode::Gd_U_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMINUB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PAND), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMAXUB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PANDN), OperandCode::G_E_xmm), -// 0xe0 - OpcodeRecord(Interpretation::Instruction(Opcode::PAVGB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRAW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRAD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PAVGW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMULHUW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMULHW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPD2DQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTDQ), OperandCode::M_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMINSW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::POR), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDSB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDSW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMAXSW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PXOR), OperandCode::G_E_xmm), -// 0xf0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::PSLLW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSLLD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSLLQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMULUDQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMADDWD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSADBW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MASKMOVDQU), OperandCode::G_U_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDB), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDW), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDQ), OperandCode::G_E_xmm), -]; - -const OPCODE_F20F_MAP: [OpcodeRecord; 256] = [ - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x10 - OpcodeRecord(Interpretation::Instruction(Opcode::MOVSD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVSD), OperandCode::E_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVDDUP), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x20 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTSI2SD), OperandCode::G_xmm_Edq), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTTSD2SI), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTSD2SI), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x30 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf20f38), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x40 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x50 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::SQRTSD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::ADDSD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MULSD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTSD2SS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::SUBSD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MINSD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::DIVSD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MAXSD), OperandCode::G_E_xmm), -// 0x60 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x70 - OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFLW), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::HADDPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::HSUBPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x80 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x90 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xa0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xb0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xc0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CMPSD), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xd0 - OpcodeRecord(Interpretation::Instruction(Opcode::ADDSUBPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQ2Q), OperandCode::U_mm_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xe0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTPD2DQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xf0 - OpcodeRecord(Interpretation::Instruction(Opcode::LDDQU), OperandCode::G_M_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -]; - -const OPCODE_F30F_MAP: [OpcodeRecord; 256] = [ - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x10 - OpcodeRecord(Interpretation::Instruction(Opcode::MOVSS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVSS), OperandCode::E_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVSLDUP), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVSHDUP), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x20 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTSI2SS), OperandCode::G_xmm_Edq), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTTSS2SI), OperandCode::Gv_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTSS2SI), OperandCode::Gv_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x30 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x40 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x50 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::SQRTSS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::RSQRTSS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::RCPSS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::ADDSS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MULSS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTSS2SD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPS2DQ), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::SUBSS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MINSS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::DIVSS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MAXSS), OperandCode::G_E_xmm), -// 0x60 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQU), OperandCode::G_E_xmm), -// 0x70 - OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFHW), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::MOVQ_f30f), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQU), OperandCode::E_G_xmm), -// 0x80 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0x90 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xa0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30fae), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xb0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::POPCNT), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::LZCNT), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xc0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CMPSS), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30fc7), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xd0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ2DQ), OperandCode::G_xmm_U_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xe0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTDQ2PD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -// 0xf0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), -]; - -const OPCODE_0F_MAP: [OpcodeRecord; 256] = [ - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), - OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew), - OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::SYSCALL), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::CLTS), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::SYSRET), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::INVD), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::WBINVD), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::UD2), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0d), - OpcodeRecord(Interpretation::Instruction(Opcode::FEMMS), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0f), -// 0x10 - OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPS), OperandCode::E_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f12), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPS), OperandCode::M_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKLPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKHPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f16), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPS), OperandCode::M_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f18), - OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), -// 0x20 - OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Cq_0), - OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Dq_0), - OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Cq_Rq_0), - OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Dq_Rq_0), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPS), OperandCode::E_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTPI2PS), OperandCode::G_xmm_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTPS), OperandCode::M_G_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPS2PI), OperandCode::G_mm_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2PI), OperandCode::G_mm_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::COMISS), OperandCode::G_E_xmm), - -// 0x30 - OpcodeRecord(Interpretation::Instruction(Opcode::WRMSR), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::RDTSC), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::RDMSR), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::RDPMC), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::SYSENTER), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::SYSEXIT), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::GETSEC), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f38), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f3a), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - -// 0x40 - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVO), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNO), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVB), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNB), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVZ), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNZ), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNA), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVA), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVS), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNS), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVP), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNP), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVL), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVGE), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVLE), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::CMOVG), OperandCode::Gv_Ev), - -// 0x50 - OpcodeRecord(Interpretation::Instruction(Opcode::MOVMSKPS), OperandCode::Gd_U_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::SQRTPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::RSQRTPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::RCPPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::ANDPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::ANDNPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::ORPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::XORPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::ADDPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MULPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2PD), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::CVTDQ2PS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::SUBPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MINPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::DIVPS), OperandCode::G_E_xmm), - OpcodeRecord(Interpretation::Instruction(Opcode::MAXPS), OperandCode::G_E_xmm), - -// 0x60 - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLBW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLWD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLDQ), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSWB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PACKUSWB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHBW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHWD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHDQ), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSDW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::G_mm_Edq), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::G_mm_E), - -// 0x70 - OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFW), OperandCode::G_E_mm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f71), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f72), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f73), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::EMMS), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::VMREAD), OperandCode::E_G_q), - OpcodeRecord(Interpretation::Instruction(Opcode::VMWRITE), OperandCode::G_E_q), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::Edq_G_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::E_G_mm), - -// 0x80 - OpcodeRecord(Interpretation::Instruction(Opcode::JO), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JNO), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JB), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JNB), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JZ), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JNZ), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JNA), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JA), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JS), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JNS), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JP), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JNP), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JL), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JGE), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JLE), OperandCode::Jvds), - OpcodeRecord(Interpretation::Instruction(Opcode::JG), OperandCode::Jvds), - -// 0x90 - OpcodeRecord(Interpretation::Instruction(Opcode::SETO), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETNO), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETB), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETAE), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETZ), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETNZ), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETBE), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETA), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETS), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETNS), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETP), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETNP), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETL), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETGE), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETLE), OperandCode::Eb_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::SETG), OperandCode::Eb_R0), - -// 0xa0 - OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::FS), - OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::FS), - OpcodeRecord(Interpretation::Instruction(Opcode::CPUID), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::BT), OperandCode::Ev_Gv), - OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_CL), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::GS), - OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::GS), - OpcodeRecord(Interpretation::Instruction(Opcode::RSM), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::BTS), OperandCode::Ev_Gv), - OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_CL), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fae), - OpcodeRecord(Interpretation::Instruction(Opcode::IMUL), OperandCode::Gv_Ev), - -// 0xb0 - OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb), - OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv), - OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M), - OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::Ev_Gv), - OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M), - OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // JMPE, ITANIUM - OpcodeRecord(Interpretation::Instruction(Opcode::UD1), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fba), - OpcodeRecord(Interpretation::Instruction(Opcode::BTC), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::TZCNT), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::BSR), OperandCode::Gv_Ev), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_b), OperandCode::Gv_Eb), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_w), OperandCode::Gv_Ew), - -// 0xc0 - OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Eb_Gb), - OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Ev_Gv), - OpcodeRecord(Interpretation::Instruction(Opcode::CMPPS), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTI), OperandCode::Mdq_Gdq), - OpcodeRecord(Interpretation::Instruction(Opcode::PINSRW), OperandCode::G_mm_Ew_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::Rv_Gmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::SHUFPS), OperandCode::G_E_xmm_Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fc7), - OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R0), - OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R1), - OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R2), - OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R3), - OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R4), - OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R5), - OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R6), - OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R7), - -// 0xd0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRLW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRLD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRLQ), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDQ), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMULLW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::PMOVMSKB), OperandCode::G_U_mm), - - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMINUB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PAND), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMAXUB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PANDN), OperandCode::G_E_mm), - -// 0xe0 - OpcodeRecord(Interpretation::Instruction(Opcode::PAVGB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRAW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSRAD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PAVGW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMULHUW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMULHW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTQ), OperandCode::G_Md_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMINSW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::POR), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDSB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDSW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMAXSW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PXOR), OperandCode::G_E_mm), -// 0xf0 - OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::PSLLW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSLLD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSLLQ), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMULUDQ), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PMADDWD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSADBW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::MASKMOVQ), OperandCode::G_mm_U_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PSUBQ), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDB), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDW), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::PADDD), OperandCode::G_E_mm), - OpcodeRecord(Interpretation::Instruction(Opcode::UD0), OperandCode::Gdq_Ed), -]; - #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum Interpretation { Instruction(Opcode), @@ -5627,7 +4567,7 @@ const OPCODES: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xd3_Ev_CL), OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - OpcodeRecord(Interpretation::Instruction(Opcode::SALC), OperandCode::Nothing), + OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // XLAT OpcodeRecord(Interpretation::Instruction(Opcode::XLAT), OperandCode::Nothing), // x86 d8 @@ -5697,9 +4637,19 @@ pub(self) fn read_E<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instru } } #[allow(non_snake_case)] +pub(self) fn read_E_mm<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> { + if modrm >= 0b11000000 { + instr.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; + Ok(OperandSpec::RegMMM) + } else { + read_M(bytes_iter, instr, modrm, length) + } +} +#[allow(non_snake_case)] pub(self) fn read_E_st<T: Iterator<Item=u8>>(bytes_iter: &mut T, instr: &mut Instruction, modrm: u8, length: &mut u8) -> Result<OperandSpec, DecodeError> { if modrm >= 0b11000000 { - read_modrm_reg(instr, modrm, RegisterBank::ST) + instr.modrm_mmm = RegSpec { bank: RegisterBank::ST, num: modrm & 7 }; + Ok(OperandSpec::RegMMM) } else { read_M(bytes_iter, instr, modrm, length) } @@ -5909,9 +4859,1315 @@ fn width_to_gp_reg_bank(width: u8, rex: bool) -> RegisterBank { } } +fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { + // seems like f2 takes priority, then f3, then 66, then "no prefix". for SOME instructions an + // invalid prefix is in fact an invalid instruction. so just duplicate for the four kinds of + // opcode lists. + if prefixes.repnz() { + match opcode { + 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), + 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), + 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew), + 0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL), + 0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x05 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSCALL), OperandCode::Nothing), + 0x06 => OpcodeRecord(Interpretation::Instruction(Opcode::CLTS), OperandCode::Nothing), + 0x07 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSRET), OperandCode::Nothing), + 0x08 => OpcodeRecord(Interpretation::Instruction(Opcode::INVD), OperandCode::Nothing), + 0x09 => OpcodeRecord(Interpretation::Instruction(Opcode::WBINVD), OperandCode::Nothing), + 0x0a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x0b => OpcodeRecord(Interpretation::Instruction(Opcode::UD2), OperandCode::Nothing), + 0x0c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x0d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0d), + 0x0e => OpcodeRecord(Interpretation::Instruction(Opcode::FEMMS), OperandCode::Nothing), + 0x0f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0f), + + 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSD), OperandCode::G_E_xmm), + 0x11 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSD), OperandCode::E_G_xmm), + 0x12 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDDUP), OperandCode::G_E_xmm), + 0x13 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x18 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f18), + 0x19 => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1a => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1b => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1f => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), +// 0x20 + 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Cq_0), + 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Dq_0), + 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Cq_Rq_0), + 0x23 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Dq_Rq_0), + 0x24 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x25 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x26 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x27 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x28 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x29 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x2a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSI2SD), OperandCode::G_xmm_Edq), + 0x2b => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTSD), OperandCode::M_G_xmm), + 0x2c => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTSD2SI), OperandCode::G_E_xmm), + 0x2d => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSD2SI), OperandCode::G_E_xmm), + 0x2e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x2f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + + 0x30 => OpcodeRecord(Interpretation::Instruction(Opcode::WRMSR), OperandCode::Nothing), + 0x31 => OpcodeRecord(Interpretation::Instruction(Opcode::RDTSC), OperandCode::Nothing), + 0x32 => OpcodeRecord(Interpretation::Instruction(Opcode::RDMSR), OperandCode::Nothing), + 0x33 => OpcodeRecord(Interpretation::Instruction(Opcode::RDPMC), OperandCode::Nothing), + 0x34 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSENTER), OperandCode::Nothing), + 0x35 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSEXIT), OperandCode::Nothing), + 0x36 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x37 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x38 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // handled before getting to `read_0f_opcode` + 0x39 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // handled before getting to `read_0f_opcode` + 0x3b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + + 0x40 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVO), OperandCode::Gv_Ev), + 0x41 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNO), OperandCode::Gv_Ev), + 0x42 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVB), OperandCode::Gv_Ev), + 0x43 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNB), OperandCode::Gv_Ev), + 0x44 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVZ), OperandCode::Gv_Ev), + 0x45 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNZ), OperandCode::Gv_Ev), + 0x46 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNA), OperandCode::Gv_Ev), + 0x47 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVA), OperandCode::Gv_Ev), + 0x48 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVS), OperandCode::Gv_Ev), + 0x49 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNS), OperandCode::Gv_Ev), + 0x4a => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVP), OperandCode::Gv_Ev), + 0x4b => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNP), OperandCode::Gv_Ev), + 0x4c => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVL), OperandCode::Gv_Ev), + 0x4d => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVGE), OperandCode::Gv_Ev), + 0x4e => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVLE), OperandCode::Gv_Ev), + 0x4f => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVG), OperandCode::Gv_Ev), + + 0x50 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x51 => OpcodeRecord(Interpretation::Instruction(Opcode::SQRTSD), OperandCode::G_E_xmm), + 0x52 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x53 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x54 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x55 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x56 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x57 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x58 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDSD), OperandCode::G_E_xmm), + 0x59 => OpcodeRecord(Interpretation::Instruction(Opcode::MULSD), OperandCode::G_E_xmm), + 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSD2SS), OperandCode::G_E_xmm), + 0x5b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x5c => OpcodeRecord(Interpretation::Instruction(Opcode::SUBSD), OperandCode::G_E_xmm), + 0x5d => OpcodeRecord(Interpretation::Instruction(Opcode::MINSD), OperandCode::G_E_xmm), + 0x5e => OpcodeRecord(Interpretation::Instruction(Opcode::DIVSD), OperandCode::G_E_xmm), + 0x5f => OpcodeRecord(Interpretation::Instruction(Opcode::MAXSD), OperandCode::G_E_xmm), + + 0x60 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x61 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x62 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x63 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x64 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x65 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x66 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x67 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x68 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x69 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + + 0x70 => OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFLW), OperandCode::G_E_xmm_Ib), + 0x71 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // no f2-0f71 instructions, so we can stop early + 0x72 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // no f2-0f72 instructions, so we can stop early + 0x73 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // no f2-0f73 instructions, so we can stop early + 0x74 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x75 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x76 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x77 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x78 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf20f78), + 0x79 => OpcodeRecord(Interpretation::Instruction(Opcode::INSERTQ), OperandCode::G_U_xmm), + 0x7a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7c => OpcodeRecord(Interpretation::Instruction(Opcode::HADDPS), OperandCode::G_E_xmm), + 0x7d => OpcodeRecord(Interpretation::Instruction(Opcode::HSUBPS), OperandCode::G_E_xmm), + 0x7e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0x80 + 0x80 => OpcodeRecord(Interpretation::Instruction(Opcode::JO), OperandCode::Jvds), + 0x81 => OpcodeRecord(Interpretation::Instruction(Opcode::JNO), OperandCode::Jvds), + 0x82 => OpcodeRecord(Interpretation::Instruction(Opcode::JB), OperandCode::Jvds), + 0x83 => OpcodeRecord(Interpretation::Instruction(Opcode::JNB), OperandCode::Jvds), + 0x84 => OpcodeRecord(Interpretation::Instruction(Opcode::JZ), OperandCode::Jvds), + 0x85 => OpcodeRecord(Interpretation::Instruction(Opcode::JNZ), OperandCode::Jvds), + 0x86 => OpcodeRecord(Interpretation::Instruction(Opcode::JNA), OperandCode::Jvds), + 0x87 => OpcodeRecord(Interpretation::Instruction(Opcode::JA), OperandCode::Jvds), + 0x88 => OpcodeRecord(Interpretation::Instruction(Opcode::JS), OperandCode::Jvds), + 0x89 => OpcodeRecord(Interpretation::Instruction(Opcode::JNS), OperandCode::Jvds), + 0x8a => OpcodeRecord(Interpretation::Instruction(Opcode::JP), OperandCode::Jvds), + 0x8b => OpcodeRecord(Interpretation::Instruction(Opcode::JNP), OperandCode::Jvds), + 0x8c => OpcodeRecord(Interpretation::Instruction(Opcode::JL), OperandCode::Jvds), + 0x8d => OpcodeRecord(Interpretation::Instruction(Opcode::JGE), OperandCode::Jvds), + 0x8e => OpcodeRecord(Interpretation::Instruction(Opcode::JLE), OperandCode::Jvds), + 0x8f => OpcodeRecord(Interpretation::Instruction(Opcode::JG), OperandCode::Jvds), + +// 0x90 + 0x90 => OpcodeRecord(Interpretation::Instruction(Opcode::SETO), OperandCode::Eb_R0), + 0x91 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNO), OperandCode::Eb_R0), + 0x92 => OpcodeRecord(Interpretation::Instruction(Opcode::SETB), OperandCode::Eb_R0), + 0x93 => OpcodeRecord(Interpretation::Instruction(Opcode::SETAE), OperandCode::Eb_R0), + 0x94 => OpcodeRecord(Interpretation::Instruction(Opcode::SETZ), OperandCode::Eb_R0), + 0x95 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNZ), OperandCode::Eb_R0), + 0x96 => OpcodeRecord(Interpretation::Instruction(Opcode::SETBE), OperandCode::Eb_R0), + 0x97 => OpcodeRecord(Interpretation::Instruction(Opcode::SETA), OperandCode::Eb_R0), + 0x98 => OpcodeRecord(Interpretation::Instruction(Opcode::SETS), OperandCode::Eb_R0), + 0x99 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNS), OperandCode::Eb_R0), + 0x9a => OpcodeRecord(Interpretation::Instruction(Opcode::SETP), OperandCode::Eb_R0), + 0x9b => OpcodeRecord(Interpretation::Instruction(Opcode::SETNP), OperandCode::Eb_R0), + 0x9c => OpcodeRecord(Interpretation::Instruction(Opcode::SETL), OperandCode::Eb_R0), + 0x9d => OpcodeRecord(Interpretation::Instruction(Opcode::SETGE), OperandCode::Eb_R0), + 0x9e => OpcodeRecord(Interpretation::Instruction(Opcode::SETLE), OperandCode::Eb_R0), + 0x9f => OpcodeRecord(Interpretation::Instruction(Opcode::SETG), OperandCode::Eb_R0), + +// 0xa0 + 0xa0 => OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::FS), + 0xa1 => OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::FS), + 0xa2 => OpcodeRecord(Interpretation::Instruction(Opcode::CPUID), OperandCode::Nothing), + 0xa3 => OpcodeRecord(Interpretation::Instruction(Opcode::BT), OperandCode::Ev_Gv), + 0xa4 => OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_Ib), + 0xa5 => OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_CL), + 0xa6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xa7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xa8 => OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::GS), + 0xa9 => OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::GS), + 0xaa => OpcodeRecord(Interpretation::Instruction(Opcode::RSM), OperandCode::Nothing), + 0xab => OpcodeRecord(Interpretation::Instruction(Opcode::BTS), OperandCode::Ev_Gv), + 0xac => OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_Ib), + 0xad => OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_CL), + 0xae => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fae), + 0xaf => OpcodeRecord(Interpretation::Instruction(Opcode::IMUL), OperandCode::Gv_Ev), + +// 0xb0 + 0xb0 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb), + 0xb1 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv), + 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M), + 0xb3 => OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::Ev_Gv), + 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M), + 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M), + 0xb6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb), + 0xb7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew), + 0xb8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xb9 => OpcodeRecord(Interpretation::Instruction(Opcode::UD1), OperandCode::Gv_Ev), + 0xba => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fba), + 0xbb => OpcodeRecord(Interpretation::Instruction(Opcode::BTC), OperandCode::Ev_Gv), + 0xbc => OpcodeRecord(Interpretation::Instruction(Opcode::BSF), OperandCode::Gv_Ev), + 0xbd => OpcodeRecord(Interpretation::Instruction(Opcode::BSR), OperandCode::Gv_Ev), + 0xbe => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_b), OperandCode::Gv_Eb), + 0xbf => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_w), OperandCode::Gv_Ew), +// 0xc0 + 0xc0 => OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Eb_Gb), + 0xc1 => OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Ev_Gv), + 0xc2 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPSD), OperandCode::G_E_xmm_Ib), + 0xc3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xc4 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xc5 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xc6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xc7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fc7), // cmpxchg permits an f2 prefix, which is the only reason this entry is not `Nothing` + 0xc8 => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R0), + 0xc9 => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R1), + 0xca => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R2), + 0xcb => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R3), + 0xcc => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R4), + 0xcd => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R5), + 0xce => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R6), + 0xcf => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R7), + + 0xd0 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDSUBPS), OperandCode::G_E_xmm), + 0xd1 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd2 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd4 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd5 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQ2Q), OperandCode::U_mm_G_xmm), + 0xd7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd9 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xda => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xdb => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xdc => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xdd => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xde => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xdf => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0xe0 + 0xe0 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe1 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe2 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe4 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe5 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe6 => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPD2DQ), OperandCode::G_E_xmm), + 0xe7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe9 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xea => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xeb => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xec => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xed => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xee => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xef => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + + 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::LDDQU), OperandCode::G_M_xmm), + 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf2 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf4 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf5 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf9 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfa => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfb => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfc => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfd => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfe => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xff => OpcodeRecord(Interpretation::Instruction(Opcode::UD0), OperandCode::Gd_Ed), + } + } else if prefixes.rep() { + match opcode { + 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), + 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), + 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew), + 0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL), + 0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x05 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSCALL), OperandCode::Nothing), + 0x06 => OpcodeRecord(Interpretation::Instruction(Opcode::CLTS), OperandCode::Nothing), + 0x07 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSRET), OperandCode::Nothing), + 0x08 => OpcodeRecord(Interpretation::Instruction(Opcode::INVD), OperandCode::Nothing), + 0x09 => OpcodeRecord(Interpretation::Instruction(Opcode::WBINVD), OperandCode::Nothing), + 0x0a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x0b => OpcodeRecord(Interpretation::Instruction(Opcode::UD2), OperandCode::Nothing), + 0x0c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x0d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0d), + 0x0e => OpcodeRecord(Interpretation::Instruction(Opcode::FEMMS), OperandCode::Nothing), + 0x0f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0f), + + 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSS), OperandCode::G_E_xmm), + 0x11 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSS), OperandCode::E_G_xmm), + 0x12 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSLDUP), OperandCode::G_E_xmm), + 0x13 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSHDUP), OperandCode::G_E_xmm), + 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x18 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f18), + 0x19 => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1a => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1b => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1f => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + + 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Cq_0), + 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Dq_0), + 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Cq_Rq_0), + 0x23 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Dq_Rq_0), + 0x24 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x25 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x26 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x27 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x28 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x29 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x2a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSI2SS), OperandCode::G_xmm_Edq), + 0x2b => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTSS), OperandCode::M_G_xmm), + 0x2c => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTSS2SI), OperandCode::Gv_E_xmm), + 0x2d => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSS2SI), OperandCode::Gv_E_xmm), + 0x2e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x2f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + + 0x30 => OpcodeRecord(Interpretation::Instruction(Opcode::WRMSR), OperandCode::Nothing), + 0x31 => OpcodeRecord(Interpretation::Instruction(Opcode::RDTSC), OperandCode::Nothing), + 0x32 => OpcodeRecord(Interpretation::Instruction(Opcode::RDMSR), OperandCode::Nothing), + 0x33 => OpcodeRecord(Interpretation::Instruction(Opcode::RDPMC), OperandCode::Nothing), + 0x34 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSENTER), OperandCode::Nothing), + 0x35 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSEXIT), OperandCode::Nothing), + 0x36 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x37 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x38 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // handled before getting to `read_0f_opcode` + 0x39 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // handled before getting to `read_0f_opcode` + 0x3b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + + 0x40 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVO), OperandCode::Gv_Ev), + 0x41 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNO), OperandCode::Gv_Ev), + 0x42 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVB), OperandCode::Gv_Ev), + 0x43 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNB), OperandCode::Gv_Ev), + 0x44 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVZ), OperandCode::Gv_Ev), + 0x45 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNZ), OperandCode::Gv_Ev), + 0x46 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNA), OperandCode::Gv_Ev), + 0x47 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVA), OperandCode::Gv_Ev), + 0x48 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVS), OperandCode::Gv_Ev), + 0x49 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNS), OperandCode::Gv_Ev), + 0x4a => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVP), OperandCode::Gv_Ev), + 0x4b => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNP), OperandCode::Gv_Ev), + 0x4c => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVL), OperandCode::Gv_Ev), + 0x4d => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVGE), OperandCode::Gv_Ev), + 0x4e => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVLE), OperandCode::Gv_Ev), + 0x4f => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVG), OperandCode::Gv_Ev), +// 0x50 + 0x50 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x51 => OpcodeRecord(Interpretation::Instruction(Opcode::SQRTSS), OperandCode::G_E_xmm), + 0x52 => OpcodeRecord(Interpretation::Instruction(Opcode::RSQRTSS), OperandCode::G_E_xmm), + 0x53 => OpcodeRecord(Interpretation::Instruction(Opcode::RCPSS), OperandCode::G_E_xmm), + 0x54 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x55 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x56 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x57 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x58 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDSS), OperandCode::G_E_xmm), + 0x59 => OpcodeRecord(Interpretation::Instruction(Opcode::MULSS), OperandCode::G_E_xmm), + 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSS2SD), OperandCode::G_E_xmm), + 0x5b => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPS2DQ), OperandCode::G_E_xmm), + 0x5c => OpcodeRecord(Interpretation::Instruction(Opcode::SUBSS), OperandCode::G_E_xmm), + 0x5d => OpcodeRecord(Interpretation::Instruction(Opcode::MINSS), OperandCode::G_E_xmm), + 0x5e => OpcodeRecord(Interpretation::Instruction(Opcode::DIVSS), OperandCode::G_E_xmm), + 0x5f => OpcodeRecord(Interpretation::Instruction(Opcode::MAXSS), OperandCode::G_E_xmm), +// 0x60 + 0x60 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x61 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x62 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x63 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x64 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x65 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x66 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x67 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x68 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x69 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6f => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQU), OperandCode::G_E_xmm), +// 0x70 + 0x70 => OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFHW), OperandCode::G_E_xmm_Ib), + 0x71 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // no f3-0f71 instructions, so we can stop early + 0x72 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // no f3-0f72 instructions, so we can stop early + 0x73 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // no f3-0f73 instructions, so we can stop early + 0x74 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x75 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x76 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x77 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x78 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x79 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7e => OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::MOVQ_f30f), + 0x7f => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQU), OperandCode::E_G_xmm), +// 0x80 + 0x80 => OpcodeRecord(Interpretation::Instruction(Opcode::JO), OperandCode::Jvds), + 0x81 => OpcodeRecord(Interpretation::Instruction(Opcode::JNO), OperandCode::Jvds), + 0x82 => OpcodeRecord(Interpretation::Instruction(Opcode::JB), OperandCode::Jvds), + 0x83 => OpcodeRecord(Interpretation::Instruction(Opcode::JNB), OperandCode::Jvds), + 0x84 => OpcodeRecord(Interpretation::Instruction(Opcode::JZ), OperandCode::Jvds), + 0x85 => OpcodeRecord(Interpretation::Instruction(Opcode::JNZ), OperandCode::Jvds), + 0x86 => OpcodeRecord(Interpretation::Instruction(Opcode::JNA), OperandCode::Jvds), + 0x87 => OpcodeRecord(Interpretation::Instruction(Opcode::JA), OperandCode::Jvds), + 0x88 => OpcodeRecord(Interpretation::Instruction(Opcode::JS), OperandCode::Jvds), + 0x89 => OpcodeRecord(Interpretation::Instruction(Opcode::JNS), OperandCode::Jvds), + 0x8a => OpcodeRecord(Interpretation::Instruction(Opcode::JP), OperandCode::Jvds), + 0x8b => OpcodeRecord(Interpretation::Instruction(Opcode::JNP), OperandCode::Jvds), + 0x8c => OpcodeRecord(Interpretation::Instruction(Opcode::JL), OperandCode::Jvds), + 0x8d => OpcodeRecord(Interpretation::Instruction(Opcode::JGE), OperandCode::Jvds), + 0x8e => OpcodeRecord(Interpretation::Instruction(Opcode::JLE), OperandCode::Jvds), + 0x8f => OpcodeRecord(Interpretation::Instruction(Opcode::JG), OperandCode::Jvds), + +// 0x90 + 0x90 => OpcodeRecord(Interpretation::Instruction(Opcode::SETO), OperandCode::Eb_R0), + 0x91 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNO), OperandCode::Eb_R0), + 0x92 => OpcodeRecord(Interpretation::Instruction(Opcode::SETB), OperandCode::Eb_R0), + 0x93 => OpcodeRecord(Interpretation::Instruction(Opcode::SETAE), OperandCode::Eb_R0), + 0x94 => OpcodeRecord(Interpretation::Instruction(Opcode::SETZ), OperandCode::Eb_R0), + 0x95 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNZ), OperandCode::Eb_R0), + 0x96 => OpcodeRecord(Interpretation::Instruction(Opcode::SETBE), OperandCode::Eb_R0), + 0x97 => OpcodeRecord(Interpretation::Instruction(Opcode::SETA), OperandCode::Eb_R0), + 0x98 => OpcodeRecord(Interpretation::Instruction(Opcode::SETS), OperandCode::Eb_R0), + 0x99 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNS), OperandCode::Eb_R0), + 0x9a => OpcodeRecord(Interpretation::Instruction(Opcode::SETP), OperandCode::Eb_R0), + 0x9b => OpcodeRecord(Interpretation::Instruction(Opcode::SETNP), OperandCode::Eb_R0), + 0x9c => OpcodeRecord(Interpretation::Instruction(Opcode::SETL), OperandCode::Eb_R0), + 0x9d => OpcodeRecord(Interpretation::Instruction(Opcode::SETGE), OperandCode::Eb_R0), + 0x9e => OpcodeRecord(Interpretation::Instruction(Opcode::SETLE), OperandCode::Eb_R0), + 0x9f => OpcodeRecord(Interpretation::Instruction(Opcode::SETG), OperandCode::Eb_R0), + +// 0xa0 + 0xa0 => OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::FS), + 0xa1 => OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::FS), + 0xa2 => OpcodeRecord(Interpretation::Instruction(Opcode::CPUID), OperandCode::Nothing), + 0xa3 => OpcodeRecord(Interpretation::Instruction(Opcode::BT), OperandCode::Ev_Gv), + 0xa4 => OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_Ib), + 0xa5 => OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_CL), + 0xa6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xa7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xa8 => OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::GS), + 0xa9 => OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::GS), + 0xaa => OpcodeRecord(Interpretation::Instruction(Opcode::RSM), OperandCode::Nothing), + 0xab => OpcodeRecord(Interpretation::Instruction(Opcode::BTS), OperandCode::Ev_Gv), + 0xac => OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_Ib), + 0xad => OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_CL), + 0xae => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fae), + 0xaf => OpcodeRecord(Interpretation::Instruction(Opcode::IMUL), OperandCode::Gv_Ev), + +// 0xb0 + 0xb0 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb), + 0xb1 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv), + 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M), + 0xb3 => OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::Ev_Gv), + 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M), + 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M), + 0xb6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb), + 0xb7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew), + 0xb8 => OpcodeRecord(Interpretation::Instruction(Opcode::POPCNT), OperandCode::Gv_Ev), + 0xb9 => OpcodeRecord(Interpretation::Instruction(Opcode::UD1), OperandCode::Gv_Ev), + 0xba => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fba), + 0xbb => OpcodeRecord(Interpretation::Instruction(Opcode::BTC), OperandCode::Ev_Gv), + 0xbc => OpcodeRecord(Interpretation::Instruction(Opcode::TZCNT), OperandCode::Gv_Ev), + 0xbd => OpcodeRecord(Interpretation::Instruction(Opcode::LZCNT), OperandCode::Gv_Ev), + 0xbe => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_b), OperandCode::Gv_Eb), + 0xbf => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_w), OperandCode::Gv_Ew), +// 0xc0 + 0xc0 => OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Eb_Gb), + 0xc1 => OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Ev_Gv), + 0xc2 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPSS), OperandCode::G_E_xmm_Ib), + 0xc3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xc4 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xc5 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xc6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xc7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fc7), + 0xc8 => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R0), + 0xc9 => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R1), + 0xca => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R2), + 0xcb => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R3), + 0xcc => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R4), + 0xcd => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R5), + 0xce => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R6), + 0xcf => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R7), + + 0xd0 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd1 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd2 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd4 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd5 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ2DQ), OperandCode::G_xmm_U_mm), + 0xd7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd9 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xda => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xdb => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xdc => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xdd => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xde => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xdf => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0xe0 + 0xe0 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe1 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe2 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe4 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe5 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe6 => OpcodeRecord(Interpretation::Instruction(Opcode::CVTDQ2PD), OperandCode::G_E_xmm), + 0xe7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe9 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xea => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xeb => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xec => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xed => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xee => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xef => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), +// 0xf0 + 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf2 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf4 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf5 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf9 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfa => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfb => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfc => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfd => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xfe => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xff => OpcodeRecord(Interpretation::Instruction(Opcode::UD0), OperandCode::Gd_Ed), + } + } else if prefixes.operand_size() { + match opcode { + 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), + 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), + 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew), + 0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL), + 0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x05 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSCALL), OperandCode::Nothing), + 0x06 => OpcodeRecord(Interpretation::Instruction(Opcode::CLTS), OperandCode::Nothing), + 0x07 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSRET), OperandCode::Nothing), + 0x08 => OpcodeRecord(Interpretation::Instruction(Opcode::INVD), OperandCode::Nothing), + 0x09 => OpcodeRecord(Interpretation::Instruction(Opcode::WBINVD), OperandCode::Nothing), + 0x0a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x0b => OpcodeRecord(Interpretation::Instruction(Opcode::UD2), OperandCode::Nothing), + 0x0c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x0d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0d), + 0x0e => OpcodeRecord(Interpretation::Instruction(Opcode::FEMMS), OperandCode::Nothing), + 0x0f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0f), + + 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPD), OperandCode::G_E_xmm), + 0x11 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPD), OperandCode::E_G_xmm), + 0x12 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPD), OperandCode::G_M_xmm), + 0x13 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPD), OperandCode::M_G_xmm), + 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKLPD), OperandCode::G_E_xmm), + 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKHPD), OperandCode::G_E_xmm), + 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::G_M_xmm), + 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::M_G_xmm), + 0x18 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f18), + 0x19 => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1a => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1b => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1f => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + + 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Cq_0), + 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Dq_0), + 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Cq_Rq_0), + 0x23 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Dq_Rq_0), + 0x24 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x25 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x26 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x27 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x28 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPD), OperandCode::G_E_xmm), + 0x29 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPD), OperandCode::E_G_xmm), + 0x2a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPI2PD), OperandCode::G_xmm_E_mm), + 0x2b => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTPD), OperandCode::M_G_xmm), + 0x2c => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPD2PI), OperandCode::G_mm_E_xmm), + 0x2d => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPD2PI), OperandCode::G_mm_E_xmm), + 0x2e => OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISD), OperandCode::G_E_xmm), + 0x2f => OpcodeRecord(Interpretation::Instruction(Opcode::COMISD), OperandCode::G_E_xmm), + + 0x30 => OpcodeRecord(Interpretation::Instruction(Opcode::WRMSR), OperandCode::Nothing), + 0x31 => OpcodeRecord(Interpretation::Instruction(Opcode::RDTSC), OperandCode::Nothing), + 0x32 => OpcodeRecord(Interpretation::Instruction(Opcode::RDMSR), OperandCode::Nothing), + 0x33 => OpcodeRecord(Interpretation::Instruction(Opcode::RDPMC), OperandCode::Nothing), + 0x34 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSENTER), OperandCode::Nothing), + 0x35 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSEXIT), OperandCode::Nothing), + 0x36 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x37 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x38 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // handled before getting to `read_0f_opcode` + 0x39 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // handled before getting to `read_0f_opcode` + 0x3b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + + 0x40 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVO), OperandCode::Gv_Ev), + 0x41 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNO), OperandCode::Gv_Ev), + 0x42 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVB), OperandCode::Gv_Ev), + 0x43 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNB), OperandCode::Gv_Ev), + 0x44 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVZ), OperandCode::Gv_Ev), + 0x45 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNZ), OperandCode::Gv_Ev), + 0x46 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNA), OperandCode::Gv_Ev), + 0x47 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVA), OperandCode::Gv_Ev), + 0x48 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVS), OperandCode::Gv_Ev), + 0x49 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNS), OperandCode::Gv_Ev), + 0x4a => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVP), OperandCode::Gv_Ev), + 0x4b => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNP), OperandCode::Gv_Ev), + 0x4c => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVL), OperandCode::Gv_Ev), + 0x4d => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVGE), OperandCode::Gv_Ev), + 0x4e => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVLE), OperandCode::Gv_Ev), + 0x4f => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVG), OperandCode::Gv_Ev), + 0x50 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVMSKPD), OperandCode::Gd_U_xmm), + 0x51 => OpcodeRecord(Interpretation::Instruction(Opcode::SQRTPD), OperandCode::G_E_xmm), + 0x52 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x53 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x54 => OpcodeRecord(Interpretation::Instruction(Opcode::ANDPD), OperandCode::G_E_xmm), + 0x55 => OpcodeRecord(Interpretation::Instruction(Opcode::ANDNPD), OperandCode::G_E_xmm), + 0x56 => OpcodeRecord(Interpretation::Instruction(Opcode::ORPD), OperandCode::G_E_xmm), + 0x57 => OpcodeRecord(Interpretation::Instruction(Opcode::XORPD), OperandCode::G_E_xmm), + 0x58 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDPD), OperandCode::G_E_xmm), + 0x59 => OpcodeRecord(Interpretation::Instruction(Opcode::MULPD), OperandCode::G_E_xmm), + 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPD2PS), OperandCode::G_E_xmm), + 0x5b => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2DQ), OperandCode::G_E_xmm), + 0x5c => OpcodeRecord(Interpretation::Instruction(Opcode::SUBPD), OperandCode::G_E_xmm), + 0x5d => OpcodeRecord(Interpretation::Instruction(Opcode::MINPD), OperandCode::G_E_xmm), + 0x5e => OpcodeRecord(Interpretation::Instruction(Opcode::DIVPD), OperandCode::G_E_xmm), + 0x5f => OpcodeRecord(Interpretation::Instruction(Opcode::MAXPD), OperandCode::G_E_xmm), + 0x60 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLBW), OperandCode::G_E_xmm), + 0x61 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLWD), OperandCode::G_E_xmm), + 0x62 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLDQ), OperandCode::G_E_xmm), + 0x63 => OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSWB), OperandCode::G_E_xmm), + 0x64 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTB), OperandCode::G_E_xmm), + 0x65 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTW), OperandCode::G_E_xmm), + 0x66 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTD), OperandCode::G_E_xmm), + 0x67 => OpcodeRecord(Interpretation::Instruction(Opcode::PACKUSWB), OperandCode::G_E_xmm), + 0x68 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHBW), OperandCode::G_E_xmm), + 0x69 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHWD), OperandCode::G_E_xmm), + 0x6a => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHDQ), OperandCode::G_E_xmm), + 0x6b => OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSDW), OperandCode::G_E_xmm), + 0x6c => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLQDQ), OperandCode::G_E_xmm), + 0x6d => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHQDQ), OperandCode::G_E_xmm), + 0x6e => OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::G_xmm_Eq), + 0x6f => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQA), OperandCode::G_E_xmm), + 0x70 => OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFD), OperandCode::G_E_xmm_Ib), + 0x71 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f71), + 0x72 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f72), + 0x73 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f73), + 0x74 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQB), OperandCode::G_E_xmm), + 0x75 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQW), OperandCode::G_E_xmm), + 0x76 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQD), OperandCode::G_E_xmm), + 0x77 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x78 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f78), + 0x79 => OpcodeRecord(Interpretation::Instruction(Opcode::EXTRQ), OperandCode::G_U_xmm), + 0x7a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7c => OpcodeRecord(Interpretation::Instruction(Opcode::HADDPD), OperandCode::G_E_xmm), + 0x7d => OpcodeRecord(Interpretation::Instruction(Opcode::HSUBPD), OperandCode::G_E_xmm), + 0x7e => OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::Edq_G_xmm), + 0x7f => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQA), OperandCode::E_G_xmm), +// 0x80 + 0x80 => OpcodeRecord(Interpretation::Instruction(Opcode::JO), OperandCode::Jvds), + 0x81 => OpcodeRecord(Interpretation::Instruction(Opcode::JNO), OperandCode::Jvds), + 0x82 => OpcodeRecord(Interpretation::Instruction(Opcode::JB), OperandCode::Jvds), + 0x83 => OpcodeRecord(Interpretation::Instruction(Opcode::JNB), OperandCode::Jvds), + 0x84 => OpcodeRecord(Interpretation::Instruction(Opcode::JZ), OperandCode::Jvds), + 0x85 => OpcodeRecord(Interpretation::Instruction(Opcode::JNZ), OperandCode::Jvds), + 0x86 => OpcodeRecord(Interpretation::Instruction(Opcode::JNA), OperandCode::Jvds), + 0x87 => OpcodeRecord(Interpretation::Instruction(Opcode::JA), OperandCode::Jvds), + 0x88 => OpcodeRecord(Interpretation::Instruction(Opcode::JS), OperandCode::Jvds), + 0x89 => OpcodeRecord(Interpretation::Instruction(Opcode::JNS), OperandCode::Jvds), + 0x8a => OpcodeRecord(Interpretation::Instruction(Opcode::JP), OperandCode::Jvds), + 0x8b => OpcodeRecord(Interpretation::Instruction(Opcode::JNP), OperandCode::Jvds), + 0x8c => OpcodeRecord(Interpretation::Instruction(Opcode::JL), OperandCode::Jvds), + 0x8d => OpcodeRecord(Interpretation::Instruction(Opcode::JGE), OperandCode::Jvds), + 0x8e => OpcodeRecord(Interpretation::Instruction(Opcode::JLE), OperandCode::Jvds), + 0x8f => OpcodeRecord(Interpretation::Instruction(Opcode::JG), OperandCode::Jvds), + +// 0x90 + 0x90 => OpcodeRecord(Interpretation::Instruction(Opcode::SETO), OperandCode::Eb_R0), + 0x91 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNO), OperandCode::Eb_R0), + 0x92 => OpcodeRecord(Interpretation::Instruction(Opcode::SETB), OperandCode::Eb_R0), + 0x93 => OpcodeRecord(Interpretation::Instruction(Opcode::SETAE), OperandCode::Eb_R0), + 0x94 => OpcodeRecord(Interpretation::Instruction(Opcode::SETZ), OperandCode::Eb_R0), + 0x95 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNZ), OperandCode::Eb_R0), + 0x96 => OpcodeRecord(Interpretation::Instruction(Opcode::SETBE), OperandCode::Eb_R0), + 0x97 => OpcodeRecord(Interpretation::Instruction(Opcode::SETA), OperandCode::Eb_R0), + 0x98 => OpcodeRecord(Interpretation::Instruction(Opcode::SETS), OperandCode::Eb_R0), + 0x99 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNS), OperandCode::Eb_R0), + 0x9a => OpcodeRecord(Interpretation::Instruction(Opcode::SETP), OperandCode::Eb_R0), + 0x9b => OpcodeRecord(Interpretation::Instruction(Opcode::SETNP), OperandCode::Eb_R0), + 0x9c => OpcodeRecord(Interpretation::Instruction(Opcode::SETL), OperandCode::Eb_R0), + 0x9d => OpcodeRecord(Interpretation::Instruction(Opcode::SETGE), OperandCode::Eb_R0), + 0x9e => OpcodeRecord(Interpretation::Instruction(Opcode::SETLE), OperandCode::Eb_R0), + 0x9f => OpcodeRecord(Interpretation::Instruction(Opcode::SETG), OperandCode::Eb_R0), + +// 0xa0 + 0xa0 => OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::FS), + 0xa1 => OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::FS), + 0xa2 => OpcodeRecord(Interpretation::Instruction(Opcode::CPUID), OperandCode::Nothing), + 0xa3 => OpcodeRecord(Interpretation::Instruction(Opcode::BT), OperandCode::Ev_Gv), + 0xa4 => OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_Ib), + 0xa5 => OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_CL), + 0xa6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xa7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xa8 => OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::GS), + 0xa9 => OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::GS), + 0xaa => OpcodeRecord(Interpretation::Instruction(Opcode::RSM), OperandCode::Nothing), + 0xab => OpcodeRecord(Interpretation::Instruction(Opcode::BTS), OperandCode::Ev_Gv), + 0xac => OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_Ib), + 0xad => OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_CL), + 0xae => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fae), + 0xaf => OpcodeRecord(Interpretation::Instruction(Opcode::IMUL), OperandCode::Gv_Ev), + +// 0xb0 + 0xb0 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb), + 0xb1 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv), + 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M), + 0xb3 => OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::Ev_Gv), + 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M), + 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M), + 0xb6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb), + 0xb7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew), + 0xb8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xb9 => OpcodeRecord(Interpretation::Instruction(Opcode::UD1), OperandCode::Gv_Ev), + 0xba => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fba), + 0xbb => OpcodeRecord(Interpretation::Instruction(Opcode::BTC), OperandCode::Ev_Gv), + 0xbc => OpcodeRecord(Interpretation::Instruction(Opcode::BSF), OperandCode::Gv_Ev), + 0xbd => OpcodeRecord(Interpretation::Instruction(Opcode::BSR), OperandCode::Gv_Ev), + 0xbe => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_b), OperandCode::Gv_Eb), + 0xbf => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_w), OperandCode::Gv_Ew), +// 0xc0 + 0xc0 => OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Eb_Gb), + 0xc1 => OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Ev_Gv), + 0xc2 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPPD), OperandCode::G_E_xmm_Ib), + 0xc3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xc4 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRW), OperandCode::G_xmm_Ed_Ib), + 0xc5 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::G_U_xmm_Ub), + 0xc6 => OpcodeRecord(Interpretation::Instruction(Opcode::SHUFPD), OperandCode::G_E_xmm_Ib), + 0xc7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fc7), + 0xc8 => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R0), + 0xc9 => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R1), + 0xca => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R2), + 0xcb => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R3), + 0xcc => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R4), + 0xcd => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R5), + 0xce => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R6), + 0xcf => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R7), +// 0xd0 + 0xd0 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDSUBPD), OperandCode::G_E_xmm), + 0xd1 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRLW), OperandCode::G_E_xmm), + 0xd2 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRLD), OperandCode::G_E_xmm), + 0xd3 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRLQ), OperandCode::G_E_xmm), + 0xd4 => OpcodeRecord(Interpretation::Instruction(Opcode::PADDQ), OperandCode::G_E_xmm), + 0xd5 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULLW), OperandCode::G_E_xmm), + 0xd6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::E_G_xmm), + 0xd7 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVMSKB), OperandCode::Gd_U_xmm), + 0xd8 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSB), OperandCode::G_E_xmm), + 0xd9 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSW), OperandCode::G_E_xmm), + 0xda => OpcodeRecord(Interpretation::Instruction(Opcode::PMINUB), OperandCode::G_E_xmm), + 0xdb => OpcodeRecord(Interpretation::Instruction(Opcode::PAND), OperandCode::G_E_xmm), + 0xdc => OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSB), OperandCode::G_E_xmm), + 0xdd => OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSW), OperandCode::G_E_xmm), + 0xde => OpcodeRecord(Interpretation::Instruction(Opcode::PMAXUB), OperandCode::G_E_xmm), + 0xdf => OpcodeRecord(Interpretation::Instruction(Opcode::PANDN), OperandCode::G_E_xmm), +// 0xe0 + 0xe0 => OpcodeRecord(Interpretation::Instruction(Opcode::PAVGB), OperandCode::G_E_xmm), + 0xe1 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRAW), OperandCode::G_E_xmm), + 0xe2 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRAD), OperandCode::G_E_xmm), + 0xe3 => OpcodeRecord(Interpretation::Instruction(Opcode::PAVGW), OperandCode::G_E_xmm), + 0xe4 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULHUW), OperandCode::G_E_xmm), + 0xe5 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULHW), OperandCode::G_E_xmm), + 0xe6 => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPD2DQ), OperandCode::G_E_xmm), + 0xe7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTDQ), OperandCode::M_G_xmm), + 0xe8 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSB), OperandCode::G_E_xmm), + 0xe9 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSW), OperandCode::G_E_xmm), + 0xea => OpcodeRecord(Interpretation::Instruction(Opcode::PMINSW), OperandCode::G_E_xmm), + 0xeb => OpcodeRecord(Interpretation::Instruction(Opcode::POR), OperandCode::G_E_xmm), + 0xec => OpcodeRecord(Interpretation::Instruction(Opcode::PADDSB), OperandCode::G_E_xmm), + 0xed => OpcodeRecord(Interpretation::Instruction(Opcode::PADDSW), OperandCode::G_E_xmm), + 0xee => OpcodeRecord(Interpretation::Instruction(Opcode::PMAXSW), OperandCode::G_E_xmm), + 0xef => OpcodeRecord(Interpretation::Instruction(Opcode::PXOR), OperandCode::G_E_xmm), +// 0xf0 + 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::PSLLW), OperandCode::G_E_xmm), + 0xf2 => OpcodeRecord(Interpretation::Instruction(Opcode::PSLLD), OperandCode::G_E_xmm), + 0xf3 => OpcodeRecord(Interpretation::Instruction(Opcode::PSLLQ), OperandCode::G_E_xmm), + 0xf4 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULUDQ), OperandCode::G_E_xmm), + 0xf5 => OpcodeRecord(Interpretation::Instruction(Opcode::PMADDWD), OperandCode::G_E_xmm), + 0xf6 => OpcodeRecord(Interpretation::Instruction(Opcode::PSADBW), OperandCode::G_E_xmm), + 0xf7 => OpcodeRecord(Interpretation::Instruction(Opcode::MASKMOVDQU), OperandCode::G_U_xmm), + 0xf8 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBB), OperandCode::G_E_xmm), + 0xf9 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBW), OperandCode::G_E_xmm), + 0xfa => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBD), OperandCode::G_E_xmm), + 0xfb => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBQ), OperandCode::G_E_xmm), + 0xfc => OpcodeRecord(Interpretation::Instruction(Opcode::PADDB), OperandCode::G_E_xmm), + 0xfd => OpcodeRecord(Interpretation::Instruction(Opcode::PADDW), OperandCode::G_E_xmm), + 0xfe => OpcodeRecord(Interpretation::Instruction(Opcode::PADDD), OperandCode::G_E_xmm), + 0xff => OpcodeRecord(Interpretation::Instruction(Opcode::UD0), OperandCode::Gd_Ed), + } + } else { + match opcode { + 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), + 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), + 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew), + 0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL), + 0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x05 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSCALL), OperandCode::Nothing), + 0x06 => OpcodeRecord(Interpretation::Instruction(Opcode::CLTS), OperandCode::Nothing), + 0x07 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSRET), OperandCode::Nothing), + 0x08 => OpcodeRecord(Interpretation::Instruction(Opcode::INVD), OperandCode::Nothing), + 0x09 => OpcodeRecord(Interpretation::Instruction(Opcode::WBINVD), OperandCode::Nothing), + 0x0a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x0b => OpcodeRecord(Interpretation::Instruction(Opcode::UD2), OperandCode::Nothing), + 0x0c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x0d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0d), + 0x0e => OpcodeRecord(Interpretation::Instruction(Opcode::FEMMS), OperandCode::Nothing), + 0x0f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0f), + + 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPS), OperandCode::G_E_xmm), + 0x11 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPS), OperandCode::E_G_xmm), + 0x12 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f12), + 0x13 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPS), OperandCode::M_G_xmm), + 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKLPS), OperandCode::G_E_xmm), + 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKHPS), OperandCode::G_E_xmm), + 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f16), + 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPS), OperandCode::M_G_xmm), + 0x18 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f18), + 0x19 => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1a => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1b => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + 0x1f => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), + + 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Cq_0), + 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Rq_Dq_0), + 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Cq_Rq_0), + 0x23 => OpcodeRecord(Interpretation::Instruction(Opcode::MOV), OperandCode::Dq_Rq_0), + 0x24 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x25 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x26 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x27 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x28 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPS), OperandCode::G_E_xmm), + 0x29 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVAPS), OperandCode::E_G_xmm), + 0x2a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPI2PS), OperandCode::G_xmm_E_mm), + 0x2b => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTPS), OperandCode::M_G_xmm), + 0x2c => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPS2PI), OperandCode::G_mm_E_xmm), + 0x2d => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2PI), OperandCode::G_mm_E_xmm), + 0x2e => OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISS), OperandCode::G_E_xmm), + 0x2f => OpcodeRecord(Interpretation::Instruction(Opcode::COMISS), OperandCode::G_E_xmm), +// 0x30 + 0x30 => OpcodeRecord(Interpretation::Instruction(Opcode::WRMSR), OperandCode::Nothing), + 0x31 => OpcodeRecord(Interpretation::Instruction(Opcode::RDTSC), OperandCode::Nothing), + 0x32 => OpcodeRecord(Interpretation::Instruction(Opcode::RDMSR), OperandCode::Nothing), + 0x33 => OpcodeRecord(Interpretation::Instruction(Opcode::RDPMC), OperandCode::Nothing), + 0x34 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSENTER), OperandCode::Nothing), + 0x35 => OpcodeRecord(Interpretation::Instruction(Opcode::SYSEXIT), OperandCode::Nothing), + 0x36 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x37 => OpcodeRecord(Interpretation::Instruction(Opcode::GETSEC), OperandCode::Nothing), + 0x38 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // handled before getting to `read_0f_opcode` + 0x39 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // handled before getting to `read_0f_opcode` + 0x3b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x3f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + +// 0x40 + 0x40 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVO), OperandCode::Gv_Ev), + 0x41 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNO), OperandCode::Gv_Ev), + 0x42 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVB), OperandCode::Gv_Ev), + 0x43 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNB), OperandCode::Gv_Ev), + 0x44 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVZ), OperandCode::Gv_Ev), + 0x45 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNZ), OperandCode::Gv_Ev), + 0x46 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNA), OperandCode::Gv_Ev), + 0x47 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVA), OperandCode::Gv_Ev), + 0x48 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVS), OperandCode::Gv_Ev), + 0x49 => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNS), OperandCode::Gv_Ev), + 0x4a => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVP), OperandCode::Gv_Ev), + 0x4b => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVNP), OperandCode::Gv_Ev), + 0x4c => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVL), OperandCode::Gv_Ev), + 0x4d => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVGE), OperandCode::Gv_Ev), + 0x4e => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVLE), OperandCode::Gv_Ev), + 0x4f => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVG), OperandCode::Gv_Ev), + +// 0x50 + 0x50 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVMSKPS), OperandCode::Gd_U_xmm), + 0x51 => OpcodeRecord(Interpretation::Instruction(Opcode::SQRTPS), OperandCode::G_E_xmm), + 0x52 => OpcodeRecord(Interpretation::Instruction(Opcode::RSQRTPS), OperandCode::G_E_xmm), + 0x53 => OpcodeRecord(Interpretation::Instruction(Opcode::RCPPS), OperandCode::G_E_xmm), + 0x54 => OpcodeRecord(Interpretation::Instruction(Opcode::ANDPS), OperandCode::G_E_xmm), + 0x55 => OpcodeRecord(Interpretation::Instruction(Opcode::ANDNPS), OperandCode::G_E_xmm), + 0x56 => OpcodeRecord(Interpretation::Instruction(Opcode::ORPS), OperandCode::G_E_xmm), + 0x57 => OpcodeRecord(Interpretation::Instruction(Opcode::XORPS), OperandCode::G_E_xmm), + 0x58 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDPS), OperandCode::G_E_xmm), + 0x59 => OpcodeRecord(Interpretation::Instruction(Opcode::MULPS), OperandCode::G_E_xmm), + 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2PD), OperandCode::G_E_xmm), + 0x5b => OpcodeRecord(Interpretation::Instruction(Opcode::CVTDQ2PS), OperandCode::G_E_xmm), + 0x5c => OpcodeRecord(Interpretation::Instruction(Opcode::SUBPS), OperandCode::G_E_xmm), + 0x5d => OpcodeRecord(Interpretation::Instruction(Opcode::MINPS), OperandCode::G_E_xmm), + 0x5e => OpcodeRecord(Interpretation::Instruction(Opcode::DIVPS), OperandCode::G_E_xmm), + 0x5f => OpcodeRecord(Interpretation::Instruction(Opcode::MAXPS), OperandCode::G_E_xmm), + +// 0x60 + 0x60 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLBW), OperandCode::G_E_mm), + 0x61 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLWD), OperandCode::G_E_mm), + 0x62 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKLDQ), OperandCode::G_E_mm), + 0x63 => OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSWB), OperandCode::G_E_mm), + 0x64 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTB), OperandCode::G_E_mm), + 0x65 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTW), OperandCode::G_E_mm), + 0x66 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTD), OperandCode::G_E_mm), + 0x67 => OpcodeRecord(Interpretation::Instruction(Opcode::PACKUSWB), OperandCode::G_E_mm), + 0x68 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHBW), OperandCode::G_E_mm), + 0x69 => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHWD), OperandCode::G_E_mm), + 0x6a => OpcodeRecord(Interpretation::Instruction(Opcode::PUNPCKHDQ), OperandCode::G_E_mm), + 0x6b => OpcodeRecord(Interpretation::Instruction(Opcode::PACKSSDW), OperandCode::G_E_mm), + 0x6c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x6e => OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::G_mm_Edq), + 0x6f => OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::G_mm_E), + +// 0x70 + 0x70 => OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFW), OperandCode::G_E_mm_Ib), + 0x71 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f71), + 0x72 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f72), + 0x73 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f73), + 0x74 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQB), OperandCode::G_E_mm), + 0x75 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQW), OperandCode::G_E_mm), + 0x76 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQD), OperandCode::G_E_mm), + 0x77 => OpcodeRecord(Interpretation::Instruction(Opcode::EMMS), OperandCode::Nothing), + 0x78 => OpcodeRecord(Interpretation::Instruction(Opcode::VMREAD), OperandCode::E_G_q), + 0x79 => OpcodeRecord(Interpretation::Instruction(Opcode::VMWRITE), OperandCode::G_E_q), + 0x7a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7d => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0x7e => OpcodeRecord(Interpretation::Instruction(Opcode::MOVD), OperandCode::Edq_G_mm), + 0x7f => OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::E_G_mm), + +// 0x80 + 0x80 => OpcodeRecord(Interpretation::Instruction(Opcode::JO), OperandCode::Jvds), + 0x81 => OpcodeRecord(Interpretation::Instruction(Opcode::JNO), OperandCode::Jvds), + 0x82 => OpcodeRecord(Interpretation::Instruction(Opcode::JB), OperandCode::Jvds), + 0x83 => OpcodeRecord(Interpretation::Instruction(Opcode::JNB), OperandCode::Jvds), + 0x84 => OpcodeRecord(Interpretation::Instruction(Opcode::JZ), OperandCode::Jvds), + 0x85 => OpcodeRecord(Interpretation::Instruction(Opcode::JNZ), OperandCode::Jvds), + 0x86 => OpcodeRecord(Interpretation::Instruction(Opcode::JNA), OperandCode::Jvds), + 0x87 => OpcodeRecord(Interpretation::Instruction(Opcode::JA), OperandCode::Jvds), + 0x88 => OpcodeRecord(Interpretation::Instruction(Opcode::JS), OperandCode::Jvds), + 0x89 => OpcodeRecord(Interpretation::Instruction(Opcode::JNS), OperandCode::Jvds), + 0x8a => OpcodeRecord(Interpretation::Instruction(Opcode::JP), OperandCode::Jvds), + 0x8b => OpcodeRecord(Interpretation::Instruction(Opcode::JNP), OperandCode::Jvds), + 0x8c => OpcodeRecord(Interpretation::Instruction(Opcode::JL), OperandCode::Jvds), + 0x8d => OpcodeRecord(Interpretation::Instruction(Opcode::JGE), OperandCode::Jvds), + 0x8e => OpcodeRecord(Interpretation::Instruction(Opcode::JLE), OperandCode::Jvds), + 0x8f => OpcodeRecord(Interpretation::Instruction(Opcode::JG), OperandCode::Jvds), + +// 0x90 + 0x90 => OpcodeRecord(Interpretation::Instruction(Opcode::SETO), OperandCode::Eb_R0), + 0x91 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNO), OperandCode::Eb_R0), + 0x92 => OpcodeRecord(Interpretation::Instruction(Opcode::SETB), OperandCode::Eb_R0), + 0x93 => OpcodeRecord(Interpretation::Instruction(Opcode::SETAE), OperandCode::Eb_R0), + 0x94 => OpcodeRecord(Interpretation::Instruction(Opcode::SETZ), OperandCode::Eb_R0), + 0x95 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNZ), OperandCode::Eb_R0), + 0x96 => OpcodeRecord(Interpretation::Instruction(Opcode::SETBE), OperandCode::Eb_R0), + 0x97 => OpcodeRecord(Interpretation::Instruction(Opcode::SETA), OperandCode::Eb_R0), + 0x98 => OpcodeRecord(Interpretation::Instruction(Opcode::SETS), OperandCode::Eb_R0), + 0x99 => OpcodeRecord(Interpretation::Instruction(Opcode::SETNS), OperandCode::Eb_R0), + 0x9a => OpcodeRecord(Interpretation::Instruction(Opcode::SETP), OperandCode::Eb_R0), + 0x9b => OpcodeRecord(Interpretation::Instruction(Opcode::SETNP), OperandCode::Eb_R0), + 0x9c => OpcodeRecord(Interpretation::Instruction(Opcode::SETL), OperandCode::Eb_R0), + 0x9d => OpcodeRecord(Interpretation::Instruction(Opcode::SETGE), OperandCode::Eb_R0), + 0x9e => OpcodeRecord(Interpretation::Instruction(Opcode::SETLE), OperandCode::Eb_R0), + 0x9f => OpcodeRecord(Interpretation::Instruction(Opcode::SETG), OperandCode::Eb_R0), + +// 0xa0 + 0xa0 => OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::FS), + 0xa1 => OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::FS), + 0xa2 => OpcodeRecord(Interpretation::Instruction(Opcode::CPUID), OperandCode::Nothing), + 0xa3 => OpcodeRecord(Interpretation::Instruction(Opcode::BT), OperandCode::Ev_Gv), + 0xa4 => OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_Ib), + 0xa5 => OpcodeRecord(Interpretation::Instruction(Opcode::SHLD), OperandCode::Ev_Gv_CL), + 0xa6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xa7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xa8 => OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::GS), + 0xa9 => OpcodeRecord(Interpretation::Instruction(Opcode::POP), OperandCode::GS), + 0xaa => OpcodeRecord(Interpretation::Instruction(Opcode::RSM), OperandCode::Nothing), + 0xab => OpcodeRecord(Interpretation::Instruction(Opcode::BTS), OperandCode::Ev_Gv), + 0xac => OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_Ib), + 0xad => OpcodeRecord(Interpretation::Instruction(Opcode::SHRD), OperandCode::Ev_Gv_CL), + 0xae => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fae), + 0xaf => OpcodeRecord(Interpretation::Instruction(Opcode::IMUL), OperandCode::Gv_Ev), + +// 0xb0 + 0xb0 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb), + 0xb1 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv), + 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M), + 0xb3 => OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::Ev_Gv), + 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M), + 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M), + 0xb6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb), + 0xb7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew), + 0xb8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // JMPE, ITANIUM + 0xb9 => OpcodeRecord(Interpretation::Instruction(Opcode::UD1), OperandCode::Gv_Ev), + 0xba => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fba), + 0xbb => OpcodeRecord(Interpretation::Instruction(Opcode::BTC), OperandCode::Ev_Gv), + 0xbc => OpcodeRecord(Interpretation::Instruction(Opcode::BSF), OperandCode::Gv_Ev), + 0xbd => OpcodeRecord(Interpretation::Instruction(Opcode::BSR), OperandCode::Gv_Ev), + 0xbe => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_b), OperandCode::Gv_Eb), + 0xbf => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSX_w), OperandCode::Gv_Ew), + +// 0xc0 + 0xc0 => OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Eb_Gb), + 0xc1 => OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Ev_Gv), + 0xc2 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPPS), OperandCode::G_E_xmm_Ib), + 0xc3 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTI), OperandCode::Mdq_Gdq), + 0xc4 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRW), OperandCode::G_mm_Ew_Ib), + 0xc5 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::Rv_Gmm_Ib), + 0xc6 => OpcodeRecord(Interpretation::Instruction(Opcode::SHUFPS), OperandCode::G_E_xmm_Ib), + 0xc7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fc7), + 0xc8 => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R0), + 0xc9 => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R1), + 0xca => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R2), + 0xcb => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R3), + 0xcc => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R4), + 0xcd => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R5), + 0xce => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R6), + 0xcf => OpcodeRecord(Interpretation::Instruction(Opcode::BSWAP), OperandCode::Zv_R7), + +// 0xd0 + 0xd0 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd1 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRLW), OperandCode::G_E_mm), + 0xd2 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRLD), OperandCode::G_E_mm), + 0xd3 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRLQ), OperandCode::G_E_mm), + 0xd4 => OpcodeRecord(Interpretation::Instruction(Opcode::PADDQ), OperandCode::G_E_mm), + 0xd5 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULLW), OperandCode::G_E_mm), + 0xd6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xd7 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVMSKB), OperandCode::G_U_mm), + 0xd8 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSB), OperandCode::G_E_mm), + 0xd9 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSW), OperandCode::G_E_mm), + 0xda => OpcodeRecord(Interpretation::Instruction(Opcode::PMINUB), OperandCode::G_E_mm), + 0xdb => OpcodeRecord(Interpretation::Instruction(Opcode::PAND), OperandCode::G_E_mm), + 0xdc => OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSB), OperandCode::G_E_mm), + 0xdd => OpcodeRecord(Interpretation::Instruction(Opcode::PADDUSW), OperandCode::G_E_mm), + 0xde => OpcodeRecord(Interpretation::Instruction(Opcode::PMAXUB), OperandCode::G_E_mm), + 0xdf => OpcodeRecord(Interpretation::Instruction(Opcode::PANDN), OperandCode::G_E_mm), + +// 0xe0 + 0xe0 => OpcodeRecord(Interpretation::Instruction(Opcode::PAVGB), OperandCode::G_E_mm), + 0xe1 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRAW), OperandCode::G_E_mm), + 0xe2 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRAD), OperandCode::G_E_mm), + 0xe3 => OpcodeRecord(Interpretation::Instruction(Opcode::PAVGW), OperandCode::G_E_mm), + 0xe4 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULHUW), OperandCode::G_E_mm), + 0xe5 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULHW), OperandCode::G_E_mm), + 0xe6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xe7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTQ), OperandCode::G_Md_mm), + 0xe8 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSB), OperandCode::G_E_mm), + 0xe9 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSW), OperandCode::G_E_mm), + 0xea => OpcodeRecord(Interpretation::Instruction(Opcode::PMINSW), OperandCode::G_E_mm), + 0xeb => OpcodeRecord(Interpretation::Instruction(Opcode::POR), OperandCode::G_E_mm), + 0xec => OpcodeRecord(Interpretation::Instruction(Opcode::PADDSB), OperandCode::G_E_mm), + 0xed => OpcodeRecord(Interpretation::Instruction(Opcode::PADDSW), OperandCode::G_E_mm), + 0xee => OpcodeRecord(Interpretation::Instruction(Opcode::PMAXSW), OperandCode::G_E_mm), + 0xef => OpcodeRecord(Interpretation::Instruction(Opcode::PXOR), OperandCode::G_E_mm), +// 0xf0 + 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::PSLLW), OperandCode::G_E_mm), + 0xf2 => OpcodeRecord(Interpretation::Instruction(Opcode::PSLLD), OperandCode::G_E_mm), + 0xf3 => OpcodeRecord(Interpretation::Instruction(Opcode::PSLLQ), OperandCode::G_E_mm), + 0xf4 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULUDQ), OperandCode::G_E_mm), + 0xf5 => OpcodeRecord(Interpretation::Instruction(Opcode::PMADDWD), OperandCode::G_E_mm), + 0xf6 => OpcodeRecord(Interpretation::Instruction(Opcode::PSADBW), OperandCode::G_E_mm), + 0xf7 => OpcodeRecord(Interpretation::Instruction(Opcode::MASKMOVQ), OperandCode::G_mm_U_mm), + 0xf8 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBB), OperandCode::G_E_mm), + 0xf9 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBW), OperandCode::G_E_mm), + 0xfa => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBD), OperandCode::G_E_mm), + 0xfb => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBQ), OperandCode::G_E_mm), + 0xfc => OpcodeRecord(Interpretation::Instruction(Opcode::PADDB), OperandCode::G_E_mm), + 0xfd => OpcodeRecord(Interpretation::Instruction(Opcode::PADDW), OperandCode::G_E_mm), + 0xfe => OpcodeRecord(Interpretation::Instruction(Opcode::PADDD), OperandCode::G_E_mm), + 0xff => OpcodeRecord(Interpretation::Instruction(Opcode::UD0), OperandCode::Gd_Ed), + } + } +} + +fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { + if prefixes.rep() { + return match opcode { + 0xd8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38d8), + 0xdc => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38dc), + 0xdd => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38dd), + 0xde => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38de), + 0xdf => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38df), + 0xf6 => OpcodeRecord(Interpretation::Instruction(Opcode::ADOX), OperandCode::Gv_Ev), + 0xf8 => { + prefixes.unset_operand_size(); + OpcodeRecord(Interpretation::Instruction(Opcode::ENQCMDS), OperandCode::Gv_M) + }, + 0xfa => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38fa), + 0xfb => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38fb), + _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + }; + } + + if prefixes.repnz() { + return match opcode { + 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::CRC32), OperandCode::Gv_Eb), + 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::CRC32), OperandCode::Gdq_Ev), + 0xf8 => { + prefixes.unset_operand_size(); + OpcodeRecord(Interpretation::Instruction(Opcode::ENQCMD), OperandCode::Gv_M) + }, + _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + }; + } + + if prefixes.operand_size() { + // leave operand size present for `movbe` + if opcode != 0xf0 && opcode != 0xf1 { + prefixes.unset_operand_size(); + } + + return match opcode { + 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFB), OperandCode::G_E_xmm), + 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::PHADDW), OperandCode::G_E_xmm), + 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::PHADDD), OperandCode::G_E_xmm), + 0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::PHADDSW), OperandCode::G_E_xmm), + 0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::PMADDUBSW), OperandCode::G_E_xmm), + 0x05 => OpcodeRecord(Interpretation::Instruction(Opcode::PHSUBW), OperandCode::G_E_xmm), + 0x06 => OpcodeRecord(Interpretation::Instruction(Opcode::PHSUBD), OperandCode::G_E_xmm), + 0x07 => OpcodeRecord(Interpretation::Instruction(Opcode::PHSUBSW), OperandCode::G_E_xmm), + 0x08 => OpcodeRecord(Interpretation::Instruction(Opcode::PSIGNB), OperandCode::G_E_xmm), + 0x09 => OpcodeRecord(Interpretation::Instruction(Opcode::PSIGNW), OperandCode::G_E_xmm), + 0x0a => OpcodeRecord(Interpretation::Instruction(Opcode::PSIGND), OperandCode::G_E_xmm), + 0x0b => OpcodeRecord(Interpretation::Instruction(Opcode::PMULHRSW), OperandCode::G_E_xmm), + 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::PBLENDVB), OperandCode::G_E_xmm), + 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::BLENDVPS), OperandCode::G_E_xmm), + 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::BLENDVPD), OperandCode::G_E_xmm), + 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::PTEST), OperandCode::G_E_xmm), + 0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::PABSB), OperandCode::G_E_xmm), + 0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::PABSW), OperandCode::G_E_xmm), + 0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::PABSD), OperandCode::G_E_xmm), + 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXBW), OperandCode::G_E_xmm), + 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXBD), OperandCode::G_E_xmm), + 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXBQ), OperandCode::G_E_xmm), + 0x23 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXWD), OperandCode::G_E_xmm), + 0x24 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXWQ), OperandCode::G_E_xmm), + 0x25 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXDQ), OperandCode::G_E_xmm), + 0x28 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULDQ), OperandCode::G_E_xmm), + 0x29 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQQ), OperandCode::G_E_xmm), + 0x2a => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTDQA), OperandCode::G_M_xmm), + 0x2b => OpcodeRecord(Interpretation::Instruction(Opcode::PACKUSDW), OperandCode::G_E_xmm), + 0x30 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXBW), OperandCode::G_E_xmm), + 0x31 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXBD), OperandCode::G_E_xmm), + 0x32 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXBQ), OperandCode::G_E_xmm), + 0x33 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXWD), OperandCode::G_E_xmm), + 0x34 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXWQ), OperandCode::G_E_xmm), + 0x35 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXDQ), OperandCode::G_E_xmm), + 0x37 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTQ), OperandCode::G_E_xmm), + 0x38 => OpcodeRecord(Interpretation::Instruction(Opcode::PMINSB), OperandCode::G_E_xmm), + 0x39 => OpcodeRecord(Interpretation::Instruction(Opcode::PMINSD), OperandCode::G_E_xmm), + 0x3a => OpcodeRecord(Interpretation::Instruction(Opcode::PMINUW), OperandCode::G_E_xmm), + 0x3b => OpcodeRecord(Interpretation::Instruction(Opcode::PMINUD), OperandCode::G_E_xmm), + 0x3c => OpcodeRecord(Interpretation::Instruction(Opcode::PMAXSB), OperandCode::G_E_xmm), + 0x3d => OpcodeRecord(Interpretation::Instruction(Opcode::PMAXSD), OperandCode::G_E_xmm), + 0x3e => OpcodeRecord(Interpretation::Instruction(Opcode::PMAXUW), OperandCode::G_E_xmm), + 0x3f => OpcodeRecord(Interpretation::Instruction(Opcode::PMAXUD), OperandCode::G_E_xmm), + 0x40 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULLD), OperandCode::G_E_xmm), + 0x41 => OpcodeRecord(Interpretation::Instruction(Opcode::PHMINPOSUW), OperandCode::G_E_xmm), + 0x80 => OpcodeRecord(Interpretation::Instruction(Opcode::INVEPT), OperandCode::Gv_M), + 0x81 => OpcodeRecord(Interpretation::Instruction(Opcode::INVVPID), OperandCode::Gv_M), + 0x82 => OpcodeRecord(Interpretation::Instruction(Opcode::INVPCID), OperandCode::Gv_M), + 0xcf => OpcodeRecord(Interpretation::Instruction(Opcode::GF2P8MULB), OperandCode::G_E_xmm), + 0xdb => OpcodeRecord(Interpretation::Instruction(Opcode::AESIMC), OperandCode::G_E_xmm), + 0xdc => OpcodeRecord(Interpretation::Instruction(Opcode::AESENC), OperandCode::G_E_xmm), + 0xdd => OpcodeRecord(Interpretation::Instruction(Opcode::AESENCLAST), OperandCode::G_E_xmm), + 0xde => OpcodeRecord(Interpretation::Instruction(Opcode::AESDEC), OperandCode::G_E_xmm), + 0xdf => OpcodeRecord(Interpretation::Instruction(Opcode::AESDECLAST), OperandCode::G_E_xmm), + 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVBE), OperandCode::Gv_M), + 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVBE), OperandCode::M_Gv), + 0xf5 => OpcodeRecord(Interpretation::Instruction(Opcode::WRUSS), OperandCode::Mdq_Gdq), + 0xf6 => OpcodeRecord(Interpretation::Instruction(Opcode::ADCX), OperandCode::Gv_Ev), + 0xf8 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDIR64B), OperandCode::MOVDIR64B), + _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + }; + } else { + return match opcode { + // TODO: straggler? 0x0f => Opcode::PALIGNR, + // PALIGNR + // OperandCode::G_E_mm_Ib + 0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFB), OperandCode::G_E_mm), + 0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::PHADDW), OperandCode::G_E_mm), + 0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::PHADDD), OperandCode::G_E_mm), + 0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::PHADDSW), OperandCode::G_E_mm), + 0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::PMADDUBSW), OperandCode::G_E_mm), + 0x05 => OpcodeRecord(Interpretation::Instruction(Opcode::PHSUBW), OperandCode::G_E_mm), + 0x06 => OpcodeRecord(Interpretation::Instruction(Opcode::PHSUBD), OperandCode::G_E_mm), + 0x07 => OpcodeRecord(Interpretation::Instruction(Opcode::PHSUBSW), OperandCode::G_E_mm), + 0x08 => OpcodeRecord(Interpretation::Instruction(Opcode::PSIGNB), OperandCode::G_E_mm), + 0x09 => OpcodeRecord(Interpretation::Instruction(Opcode::PSIGNW), OperandCode::G_E_mm), + 0x0a => OpcodeRecord(Interpretation::Instruction(Opcode::PSIGND), OperandCode::G_E_mm), + 0x0b => OpcodeRecord(Interpretation::Instruction(Opcode::PMULHRSW), OperandCode::G_E_mm), + 0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::PABSB), OperandCode::G_E_mm), + 0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::PABSW), OperandCode::G_E_mm), + 0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::PABSD), OperandCode::G_E_mm), + 0xc8 => OpcodeRecord(Interpretation::Instruction(Opcode::SHA1NEXTE), OperandCode::G_E_xmm), + 0xc9 => OpcodeRecord(Interpretation::Instruction(Opcode::SHA1MSG1), OperandCode::G_E_xmm), + 0xca => OpcodeRecord(Interpretation::Instruction(Opcode::SHA1MSG2), OperandCode::G_E_xmm), + 0xcb => OpcodeRecord(Interpretation::Instruction(Opcode::SHA256RNDS2), OperandCode::G_E_xmm), + 0xcc => OpcodeRecord(Interpretation::Instruction(Opcode::SHA256MSG1), OperandCode::G_E_xmm), + 0xcd => OpcodeRecord(Interpretation::Instruction(Opcode::SHA256MSG2), OperandCode::G_E_xmm), + 0xf0 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVBE), OperandCode::Gv_M), + 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVBE), OperandCode::M_Gv), + 0xf6 => OpcodeRecord(Interpretation::Instruction(Opcode::WRSS), OperandCode::Mdq_Gdq), + // TODO: always 32-bit mov, be careful about memory size + 0xf9 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDIRI), OperandCode::Md_Gd), + _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + }; + } +} + +fn read_0f3a_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { + if prefixes.rep() || prefixes.repnz() { + return OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing); + } + + if prefixes.operand_size() { + if opcode == 0x16 && prefixes.rex().w() { + return OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRQ), OperandCode::G_E_xmm_Ib); + } else if opcode == 0x22 && prefixes.rex().w() { + return OpcodeRecord(Interpretation::Instruction(Opcode::PINSRQ), OperandCode::G_E_xmm_Ib); + } + + return match opcode { + 0x08 => OpcodeRecord(Interpretation::Instruction(Opcode::ROUNDPS), OperandCode::G_E_xmm_Ib), + 0x09 => OpcodeRecord(Interpretation::Instruction(Opcode::ROUNDPD), OperandCode::G_E_xmm_Ib), + 0x0a => OpcodeRecord(Interpretation::Instruction(Opcode::ROUNDSS), OperandCode::G_E_xmm_Ib), + 0x0b => OpcodeRecord(Interpretation::Instruction(Opcode::ROUNDSD), OperandCode::G_E_xmm_Ib), + 0x0c => OpcodeRecord(Interpretation::Instruction(Opcode::BLENDPS), OperandCode::G_E_xmm_Ib), + 0x0d => OpcodeRecord(Interpretation::Instruction(Opcode::BLENDPD), OperandCode::G_E_xmm_Ib), + 0x0e => OpcodeRecord(Interpretation::Instruction(Opcode::PBLENDW), OperandCode::G_E_xmm_Ib), + 0x0f => OpcodeRecord(Interpretation::Instruction(Opcode::PALIGNR), OperandCode::G_E_xmm_Ib), + 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRB), OperandCode::G_E_xmm_Ib), + 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::G_E_xmm_Ib), + 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRD), OperandCode::G_E_xmm_Ib), + 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::EXTRACTPS), OperandCode::G_E_xmm_Ib), + 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRB), OperandCode::G_E_xmm_Ib), + 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::INSERTPS), OperandCode::G_E_xmm_Ib), + 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRD), OperandCode::G_E_xmm_Ib), + 0x40 => OpcodeRecord(Interpretation::Instruction(Opcode::DPPS), OperandCode::G_E_xmm_Ib), + 0x41 => OpcodeRecord(Interpretation::Instruction(Opcode::DPPD), OperandCode::G_E_xmm_Ib), + 0x42 => OpcodeRecord(Interpretation::Instruction(Opcode::MPSADBW), OperandCode::G_E_xmm_Ib), + 0x44 => OpcodeRecord(Interpretation::Instruction(Opcode::PCLMULQDQ), OperandCode::G_E_xmm_Ib), + 0x60 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPESTRM), OperandCode::G_E_xmm_Ib), + 0x61 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPESTRI), OperandCode::G_E_xmm_Ib), + 0x62 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPISTRM), OperandCode::G_E_xmm_Ib), + 0x63 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPISTRI), OperandCode::G_E_xmm_Ib), + 0xcc => OpcodeRecord(Interpretation::Instruction(Opcode::SHA1RNDS4), OperandCode::G_E_xmm_Ib), + 0xce => OpcodeRecord(Interpretation::Instruction(Opcode::GF2P8AFFINEQB), OperandCode::G_E_xmm_Ub), + 0xcf => OpcodeRecord(Interpretation::Instruction(Opcode::GF2P8AFFINEINVQB), OperandCode::G_E_xmm_Ub), + 0xdf => OpcodeRecord(Interpretation::Instruction(Opcode::AESKEYGENASSIST), OperandCode::G_E_xmm_Ub), + _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + }; + } + + return match opcode { + 0xcc => OpcodeRecord(Interpretation::Instruction(Opcode::SHA1RNDS4), OperandCode::G_E_xmm_Ub), + 0x0f => OpcodeRecord(Interpretation::Instruction(Opcode::PALIGNR), OperandCode::G_E_mm_Ib), + _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), + }; +} + fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction) -> Result<(), DecodeError> { let mut length = 0u8; - let mut alternate_opcode_map: Option<OpcodeMap> = None; // use core::intrinsics::unlikely; let mut prefixes = Prefixes::new(0); @@ -5921,156 +6177,106 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in instruction.sib_index = RegSpec::rax(); instruction.mem_size = 0; - fn escapes_are_prefixes_actually(prefixes: &mut Prefixes, opc_map: &mut Option<OpcodeMap>) { - match opc_map { - Some(OpcodeMap::Map66) => { - prefixes.set_operand_size(); - }, - Some(OpcodeMap::MapF2) => { - prefixes.set_repnz(); - }, - Some(OpcodeMap::MapF3) => { - prefixes.set_rep(); - }, - None => {} - } - *opc_map = None; - } - let record: OpcodeRecord = loop { -// let operand_code = loop { - match bytes_iter.next() { - Some(b) => { + let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?; + length += 1; + if length >= 15 { + return Err(DecodeError::TooLong); + } + let record = OPCODES[b as usize]; + if (b & 0xf0) == 0x40 { + prefixes.rex_from(b); + } else if b == 0x0f { + let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?; + length += 1; + if b == 0x38 { + let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?; length += 1; - if length >= 15 { - return Err(DecodeError::TooLong); - } - let record = OPCODES[b as usize]; - if (b & 0xf0) == 0x40 { - prefixes.rex_from(b); - } else if b == 0x0f { - let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?; - length += 1; - let record = match alternate_opcode_map { - Some(opcode_map) => { - let rec = match opcode_map { - OpcodeMap::Map66 => { - OPCODE_660F_MAP[b as usize] - }, - OpcodeMap::MapF2 => { - OPCODE_F20F_MAP[b as usize] - }, - OpcodeMap::MapF3 => { - OPCODE_F30F_MAP[b as usize] - }, - }; - if rec == OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing) { - escapes_are_prefixes_actually(&mut prefixes, &mut Some(opcode_map)); - OPCODE_0F_MAP[b as usize] - } else { - rec - } - }, - None => { - OPCODE_0F_MAP[b as usize] - } - }; - - break record; - } else if let Interpretation::Instruction(_) = record.0 { - escapes_are_prefixes_actually(&mut prefixes, &mut alternate_opcode_map); - break record; + break read_0f38_opcode(b, &mut prefixes); + } else if b == 0x3a { + let b = bytes_iter.next().ok_or(DecodeError::ExhaustedInput)?; + length += 1; + break read_0f3a_opcode(b, &mut prefixes); + } else { + break read_0f_opcode(b, &mut prefixes); + } + } else if let Interpretation::Instruction(_) = record.0 { + break record; + } else { + // some prefix seen after we saw rex, but before the 0f escape or an actual + // opcode. so we must forget the rex prefix! + // this is to handle sequences like 41660f21cf + // where if 660f21 were a valid opcode, 41 would apply a rex.b + // prefix, but since 660f21 is not valid, the opcode is interpreted + // as 0f21, where 66 is a prefix, which makes 41 not the last + // prefix before the opcode, and it's discarded. + + // 2.3.2 + // Any VEX-encoded instruction with a LOCK prefix preceding VEX will #UD. + // 2.3.3 + // Any VEX-encoded instruction with a 66H, F2H, or F3H prefix preceding VEX + // will #UD. + // 2.3.4 + // Any VEX-encoded instruction with a REX prefix proceeding VEX will #UD. + if b == 0xc5 { + if prefixes.rex().present() || prefixes.lock() || prefixes.operand_size() || prefixes.rep() || prefixes.repnz() { + // rex and then vex is invalid! reject it. + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidPrefixes); } else { - // some prefix seen after we saw rex, but before the 0f escape or an actual - // opcode. so we must forget the rex prefix! - // this is to handle sequences like 41660f21cf - // where if 660f21 were a valid opcode, 41 would apply a rex.b - // prefix, but since 660f21 is not valid, the opcode is interpreted - // as 0f21, where 66 is a prefix, which makes 41 not the last - // prefix before the opcode, and it's discarded. - - // 2.3.2 - // Any VEX-encoded instruction with a LOCK prefix preceding VEX will #UD. - // 2.3.3 - // Any VEX-encoded instruction with a 66H, F2H, or F3H prefix preceding VEX - // will #UD. - // 2.3.4 - // Any VEX-encoded instruction with a REX prefix proceeding VEX will #UD. - if b == 0xc5 { - if prefixes.rex().present() || prefixes.lock() || prefixes.operand_size() || prefixes.rep() || prefixes.repnz() { - // rex and then vex is invalid! reject it. - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidPrefixes); - } else { - instruction.prefixes = prefixes; - vex::two_byte_vex(&mut bytes_iter, instruction, length)?; + instruction.prefixes = prefixes; + vex::two_byte_vex(&mut bytes_iter, instruction, length)?; - if decoder != &InstDecoder::default() { - decoder.revise_instruction(instruction)?; - } - return Ok(()); - } - } else if b == 0xc4 { - if prefixes.rex().present() || prefixes.lock() || prefixes.operand_size() || prefixes.rep() || prefixes.repnz() { - // rex and then vex is invalid! reject it. - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidPrefixes); - } else { - instruction.prefixes = prefixes; - vex::three_byte_vex(&mut bytes_iter, instruction, length)?; - if decoder != &InstDecoder::default() { - decoder.revise_instruction(instruction)?; - } - return Ok(()); - } + if decoder != &InstDecoder::default() { + decoder.revise_instruction(instruction)?; } - - prefixes.rex_from(0); - match b { - 0x26 => { -// prefixes.set_es(); - }, - 0x2e => { -// prefixes.set_cs(); - }, - 0x36 => { -// prefixes.set_ss(); - }, - 0x3e => { -// prefixes.set_ds(); - }, - 0x64 => { - prefixes.set_fs(); - }, - 0x65 => { - prefixes.set_gs(); - }, - 0x66 => { - escapes_are_prefixes_actually(&mut prefixes, &mut alternate_opcode_map); - alternate_opcode_map = Some(OpcodeMap::Map66); - }, - 0x67 => { - prefixes.set_address_size(); - instruction.modrm_mmm.bank = RegisterBank::D; - instruction.sib_index.bank = RegisterBank::D; - }, - 0xf0 => { - prefixes.set_lock(); - }, - 0xf2 => { - escapes_are_prefixes_actually(&mut prefixes, &mut alternate_opcode_map); - alternate_opcode_map = Some(OpcodeMap::MapF2); - }, - 0xf3 => { - escapes_are_prefixes_actually(&mut prefixes, &mut alternate_opcode_map); - alternate_opcode_map = Some(OpcodeMap::MapF3); - }, - _ => { unsafe { unreachable_unchecked(); } } + return Ok(()); + } + } else if b == 0xc4 { + if prefixes.rex().present() || prefixes.lock() || prefixes.operand_size() || prefixes.rep() || prefixes.repnz() { + // rex and then vex is invalid! reject it. + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidPrefixes); + } else { + instruction.prefixes = prefixes; + vex::three_byte_vex(&mut bytes_iter, instruction, length)?; + if decoder != &InstDecoder::default() { + decoder.revise_instruction(instruction)?; } + return Ok(()); } - }, - None => { - return Err(DecodeError::ExhaustedInput); + } + + prefixes.rex_from(0); + match b { + 0x26 | + 0x2e | + 0x36 | + 0x3e =>{ /* no-op in amd64 */ }, + 0x64 => { + prefixes.set_fs(); + }, + 0x65 => { + prefixes.set_gs(); + }, + 0x66 => { + prefixes.set_operand_size(); + }, + 0x67 => { + prefixes.set_address_size(); + instruction.modrm_mmm.bank = RegisterBank::D; + instruction.sib_index.bank = RegisterBank::D; + }, + 0xf0 => { + prefixes.set_lock(); + }, + 0xf2 => { + prefixes.set_repnz(); + }, + 0xf3 => { + prefixes.set_rep(); + }, + _ => { unsafe { unreachable_unchecked(); } } } } }; @@ -6248,6 +6454,10 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction.modrm_rrr.num = ((modrm >> 3) & 7) + if instruction.prefixes.rex().r() { 0b1000 } else { 0 }; mem_oper = if modrm >= 0b11000000 { + // special-case here to handle `lea`. there *is* an `M_Gv` but it's only for a + // reversed-operands `movbe` and fairly unlikely. that case is handled in + // `unlikely_operands`. TODO: maybe this could just be a bit in `operand_code` for + // "memory-only mmm"? if operand_code.bits() == (OperandCode::Gv_M as u16) { return Err(DecodeError::InvalidOperand); } @@ -6604,6 +6814,115 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, } fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, length: &mut u8) -> Result<(), DecodeError> { match operand_code { + OperandCode::G_U_xmm_Ub => { + let modrm = read_modrm(&mut bytes_iter, length)?; + + instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; + if instruction.operands[1] != OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::D); + instruction.imm = + read_num(&mut bytes_iter, 1)? as u8 as u64; + *length += 1; + instruction.operands[2] = OperandSpec::ImmU8; + instruction.operand_count = 3; + } + OperandCode::ModRM_0xf20f78 => { + instruction.opcode = Opcode::INSERTQ; + + let modrm = read_modrm(&mut bytes_iter, length)?; + + if modrm < 0b11_000_000 { + return Err(DecodeError::InvalidOperand); + } + + instruction.operands[0] = OperandSpec::RegRRR; + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); + instruction.operands[1] = OperandSpec::RegMMM; + instruction.modrm_mmm = + RegSpec::from_parts(modrm & 7, instruction.prefixes.rex().r(), RegisterBank::X); + instruction.imm = + read_num(&mut bytes_iter, 1)? as u8 as u64; + instruction.disp = + read_num(&mut bytes_iter, 1)? as u8 as u64; + *length += 2; + instruction.operands[2] = OperandSpec::ImmU8; + instruction.operands[3] = OperandSpec::ImmInDispField; + instruction.operand_count = 4; + } + OperandCode::ModRM_0x660f78 => { + instruction.opcode = Opcode::EXTRQ; + + let modrm = read_modrm(&mut bytes_iter, length)?; + + if modrm < 0b11_000_000 { + return Err(DecodeError::InvalidOperand); + } + + if modrm >= 0b11_001_000 { + return Err(DecodeError::InvalidOperand); + } + + instruction.operands[0] = OperandSpec::RegMMM; + instruction.modrm_mmm = + RegSpec::from_parts(modrm & 7, instruction.prefixes.rex().r(), RegisterBank::X); + instruction.imm = + read_num(&mut bytes_iter, 1)? as u8 as u64; + instruction.disp = + read_num(&mut bytes_iter, 1)? as u8 as u64; + *length += 2; + instruction.operands[1] = OperandSpec::ImmU8; + instruction.operands[2] = OperandSpec::ImmInDispField; + instruction.operand_count = 3; + + } + OperandCode::G_E_xmm_Ub => { + let modrm = read_modrm(&mut bytes_iter, length)?; + + instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); + instruction.imm = + read_num(&mut bytes_iter, 1)? as u8 as u64; + *length += 1; + instruction.operands[2] = OperandSpec::ImmU8; + instruction.operand_count = 3; + } + OperandCode::Gd_Ed => { + instruction.modrm_rrr.bank = RegisterBank::D; + if mem_oper == OperandSpec::RegMMM { + instruction.modrm_mmm.bank = RegisterBank::D; + } + instruction.operands[1] = mem_oper; + instruction.operand_count = 2; + } + OperandCode::Md_Gd => { + instruction.modrm_rrr.bank = RegisterBank::D; + if mem_oper == OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + instruction.operands[1] = instruction.operands[0]; + instruction.operands[0] = mem_oper; + instruction.operand_count = 2; + } + OperandCode::Edq_Gdq => { + let bank = if instruction.prefixes.rex().w() { + RegisterBank::Q + } else { + RegisterBank::D + }; + + instruction.modrm_rrr.bank = bank; + if mem_oper == OperandSpec::RegMMM { + instruction.modrm_mmm.bank = bank; + } + instruction.operands[1] = instruction.operands[0]; + instruction.operands[0] = mem_oper; + instruction.operand_count = 2; + } OperandCode::G_U_xmm => { instruction.modrm_rrr.bank = RegisterBank::X; if mem_oper != OperandSpec::RegMMM { @@ -6771,7 +7090,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter OperandCode::Iw_Ib => { instruction.disp = read_num(&mut bytes_iter, 2)? as u64; instruction.imm = read_num(&mut bytes_iter, 1)? as u64; - instruction.operands[0] = OperandSpec::EnterFrameSize; + instruction.operands[0] = OperandSpec::ImmInDispField; instruction.operands[1] = OperandSpec::ImmU8; instruction.operand_count = 2; *length += 3; @@ -6887,205 +7206,230 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operand_count = 1; } OperandCode::ModRM_0x0f0f => { + // 3dnow instructions are WILD, the opcode is encoded as an imm8 trailing the + // instruction. + + let modrm = read_modrm(&mut bytes_iter, length)?; + instruction.operands[1] = read_E_mm(&mut bytes_iter, instruction, modrm, length)?; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec { bank: RegisterBank::MM, num: (modrm >> 3) & 7 }; + let opcode = read_modrm(&mut bytes_iter, length)?; match opcode { 0x0c => { instruction.opcode = Opcode::PI2FW; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0x0d => { instruction.opcode = Opcode::PI2FD; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0x1c => { instruction.opcode = Opcode::PF2IW; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0x1d => { instruction.opcode = Opcode::PF2ID; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0x59 => { instruction.opcode = Opcode::PMULHRW; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); + } + 0x8a => { + instruction.opcode = Opcode::PFNACC; + } + 0x8e => { + instruction.opcode = Opcode::PFPNACC; } 0x90 => { instruction.opcode = Opcode::PFCMPGE; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0x94 => { instruction.opcode = Opcode::PFMIN; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0x96 => { instruction.opcode = Opcode::PFRCP; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0x97 => { instruction.opcode = Opcode::PFRSQRT; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0x9a => { instruction.opcode = Opcode::PFSUB; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0x9e => { instruction.opcode = Opcode::PFADD; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xa0 => { instruction.opcode = Opcode::PFCMPGT; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xa4 => { instruction.opcode = Opcode::PFMAX; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xa6 => { instruction.opcode = Opcode::PFRCPIT1; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xa7 => { instruction.opcode = Opcode::PFRSQIT1; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xaa => { instruction.opcode = Opcode::PFSUBR; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xae => { instruction.opcode = Opcode::PFACC; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xb0 => { instruction.opcode = Opcode::PFCMPEQ; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xb4 => { instruction.opcode = Opcode::PFMUL; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xb6 => { instruction.opcode = Opcode::PFRCPIT2; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } - 0xba => { - instruction.opcode = Opcode::PFNACC; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); + 0xb7 => { + instruction.opcode = Opcode::PMULHRW; } 0xbb => { instruction.opcode = Opcode::PSWAPD; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xbe => { instruction.opcode = Opcode::PFPNACC; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } 0xbf => { instruction.opcode = Opcode::PAVGUSB; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm, length); } _ => { return Err(DecodeError::InvalidOpcode); } } } - OperandCode::ModRM_0x0f38 => { - let opcode = read_modrm(&mut bytes_iter, length)?; - - let high = opcode >> 4; - let low = opcode & 0xf; + OperandCode::ModRM_0x0fc7 => { + if instruction.prefixes.repnz() { + let modrm = read_modrm(&mut bytes_iter, length)?; + let is_reg = (modrm & 0xc0) == 0xc0; - let operands = match high { - 0 => { - // PqQq - if low != 0x0f { - OperandCode::G_E_mm - } else { - // PALIGNR - OperandCode::G_E_mm_Ib + let r = (modrm >> 3) & 7; + match r { + 1 => { + if is_reg { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOperand); + } else { + if instruction.prefixes.rex().w() { + instruction.opcode = Opcode::CMPXCHG16B; + } else { + instruction.opcode = Opcode::CMPXCHG8B; + } + instruction.operand_count = 1; + let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + } + return Ok(()); } - }, - 1 => { - // PqQq - OperandCode::G_E_mm - }, - 0xc => { - // Vdq,Wdq - OperandCode::G_E_xmm - } - 0xf => { - match low { - 0 => OperandCode::Gv_Ev, - 1 => OperandCode::Ev_Gv, - 9 => OperandCode::M_G_xmm, - _ => { + _ => { + return Err(DecodeError::InvalidOperand); + } + } + } + if instruction.prefixes.operand_size() { + let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + let modrm = read_modrm(&mut bytes_iter, length)?; + let is_reg = (modrm & 0xc0) == 0xc0; + + let r = (modrm >> 3) & 7; + match r { + 1 => { + if is_reg { instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOperand); + } else { + if instruction.prefixes.rex().w() { + instruction.opcode = Opcode::CMPXCHG16B; + } else { + instruction.opcode = Opcode::CMPXCHG8B; + } + instruction.operand_count = 1; + let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + } + return Ok(()); + } + 6 => { + instruction.opcode = Opcode::VMCLEAR; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + if instruction.operands[0] == OperandSpec::RegMMM { + // this would be invalid as `vmclear`, so fall back to the parse as + // 66-prefixed rdrand. this is a register operand, so just demote it to the + // word-form operand: + instruction.modrm_mmm = RegSpec { bank: RegisterBank::W, num: instruction.modrm_mmm.num }; + instruction.opcode = Opcode::RDRAND; + } + instruction.operand_count = 1; + return Ok(()); + } + 7 => { + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + if instruction.operands[0] == OperandSpec::RegMMM { + // this would be invalid as `vmclear`, so fall back to the parse as + // 66-prefixed rdrand. this is a register operand, so just demote it to the + // word-form operand: + instruction.modrm_mmm = RegSpec { bank: RegisterBank::W, num: instruction.modrm_mmm.num }; + instruction.opcode = Opcode::RDSEED; + } else { return Err(DecodeError::InvalidOpcode); } + instruction.operand_count = 1; + return Ok(()); + } + _ => { + return Err(DecodeError::InvalidOpcode); } } - _ => { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } - }; - instruction.opcode = match opcode { - 0x00 => Opcode::PSHUFB, - 0x01 => Opcode::PHADDW, - 0x02 => Opcode::PHADDD, - 0x03 => Opcode::PHADDSW, - 0x04 => Opcode::PMADDUBSW, - 0x05 => Opcode::PHSUBW, - 0x06 => Opcode::PHSUBD, - 0x07 => Opcode::PHSUBSW, - 0x08 => Opcode::PSIGNB, - 0x09 => Opcode::PSIGNW, - 0x0a => Opcode::PSIGND, - 0x0b => Opcode::PMULHRSW, - - 0x0f => Opcode::PALIGNR, - - 0x1c => Opcode::PABSB, - 0x1d => Opcode::PABSW, - 0x1e => Opcode::PABSD, - - 0xc8 => Opcode::SHA1NEXTE, - 0xc9 => Opcode::SHA1MSG1, - 0xca => Opcode::SHA1MSG2, - 0xcb => Opcode::SHA256RNDS2, - 0xcc => Opcode::SHA256MSG1, - 0xcd => Opcode::SHA256MSG2, - 0xf0 | 0xf1 => Opcode::MOVBE, - 0xf9 => { - // TODO: always 32-bit mov, be careful about memory size - instruction.opcode = Opcode::MOVDIRI; - read_operands(decoder, bytes_iter, instruction, OperandCode::M_G_xmm, length)?; - instruction.modrm_rrr.bank = RegisterBank::D; - return Ok(()); - } - _ => { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } - }; + } - return read_operands(decoder, bytes_iter, instruction, operands, length); - }, - OperandCode::ModRM_0x0f3a => { - let opcode = read_modrm(&mut bytes_iter, length)?; - if opcode == 0xcc { - instruction.opcode = Opcode::SHA1RNDS4; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } else if opcode == 0x0f { - instruction.opcode = Opcode::PALIGNR; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_mm_Ib, length); - } else { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); + if instruction.prefixes.rep() { + let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + let modrm = read_modrm(&mut bytes_iter, length)?; + let is_reg = (modrm & 0xc0) == 0xc0; + + let r = (modrm >> 3) & 7; + match r { + 1 => { + if is_reg { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOperand); + } else { + if instruction.prefixes.rex().w() { + instruction.opcode = Opcode::CMPXCHG16B; + } else { + instruction.opcode = Opcode::CMPXCHG8B; + } + instruction.operand_count = 1; + let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + } + } + 6 => { + instruction.opcode = Opcode::VMXON; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + if instruction.operands[0] == OperandSpec::RegMMM { + // this would be invalid as `vmxon`, so fall back to the parse as + // f3-prefixed rdrand + instruction.opcode = Opcode::RDRAND; + } + instruction.operand_count = 1; + } + 7 => { + instruction.opcode = Opcode::RDPID; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + if instruction.operands[0] != OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + instruction.operand_count = 1; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + return Ok(()); } - }, - OperandCode::ModRM_0x0fc7 => { + let modrm = read_modrm(&mut bytes_iter, length)?; let is_reg = (modrm & 0xc0) == 0xc0; @@ -7166,6 +7510,10 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; }, OperandCode::ModRM_0x0f71 => { + if instruction.prefixes.rep() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOperand); + } + instruction.operand_count = 2; let modrm = read_modrm(&mut bytes_iter, length)?; @@ -7189,12 +7537,20 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } } - instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; + if instruction.prefixes.operand_size() { + instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 }; + } else { + instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; + } instruction.operands[0] = OperandSpec::RegMMM; instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; instruction.operands[1] = OperandSpec::ImmU8; }, OperandCode::ModRM_0x0f72 => { + if instruction.prefixes.rep() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOperand); + } + instruction.operand_count = 2; let modrm = read_modrm(&mut bytes_iter, length)?; @@ -7218,474 +7574,20 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } } - instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; - instruction.operands[0] = OperandSpec::RegMMM; - instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; - instruction.operands[1] = OperandSpec::ImmU8; - }, - OperandCode::ModRM_0x0f73 => { - instruction.operand_count = 2; - - let modrm = read_modrm(&mut bytes_iter, length)?; - if modrm & 0xc0 != 0xc0 { - return Err(DecodeError::InvalidOperand); - } - - let r = (modrm >> 3) & 7; - match r { - 2 => { - instruction.opcode = Opcode::PSRLQ; - } - 6 => { - instruction.opcode = Opcode::PSLLQ; - } - _ => { - return Err(DecodeError::InvalidOpcode); - } - } - - instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; - instruction.operands[0] = OperandSpec::RegMMM; - instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; - instruction.operands[1] = OperandSpec::ImmU8; - }, - OperandCode::ModRM_0x660f12 => { - // If this is reg-reg, interpret the instruction as 66-prefixed (no-op here) - // `movhlps`. If this is reg-mem, it's a `movlpd`. - let modrm = read_modrm(&mut bytes_iter, length)?; - if modrm & 0xc0 == 0xc0 { - instruction.opcode = Opcode::MOVHLPS; - } else { - instruction.opcode = Opcode::MOVLPD; - } - instruction.modrm_rrr = - RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); - instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; - instruction.operand_count = 2; - } - OperandCode::ModRM_0x660f16 => { - // If this is reg-reg, interpret the instruction as 66-prefixed (no-op here) - // `movlhps`. If this is reg-mem, it's a `movhpd`. - let modrm = read_modrm(&mut bytes_iter, length)?; - if modrm & 0xc0 == 0xc0 { - instruction.opcode = Opcode::MOVLHPS; + if instruction.prefixes.operand_size() { + instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 }; } else { - instruction.opcode = Opcode::MOVHPD; - } - instruction.modrm_rrr = - RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); - instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; - instruction.operand_count = 2; - } - OperandCode::ModRM_0xf20f38 => { - let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?; - match op { - 0xf0 => { - instruction.opcode = Opcode::CRC32; - return read_operands(decoder, bytes_iter, instruction, OperandCode::Gv_Eb, length); - } - 0xf1 => { - instruction.opcode = Opcode::CRC32; - return read_operands(decoder, bytes_iter, instruction, OperandCode::Gdq_Ev, length); - } - 0xf8 => { - instruction.opcode = Opcode::ENQCMD; - return read_operands(decoder, bytes_iter, instruction, OperandCode::Gdq_Ev, length); - } - _ => { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } - }; - } - OperandCode::ModRM_0xf30f38 => { - let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?; - match op { - 0xd8 => { - let modrm = read_modrm(&mut bytes_iter, length)?; - let r = (modrm >> 3) & 7; - match r { - 0b000 => { - if modrm >= 0b11_000_000 { - return Err(DecodeError::InvalidOperand); - } - instruction.opcode = Opcode::AESENCWIDE128KL; - instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?; - return Ok(()); - } - 0b001 => { - if modrm >= 0b11_000_000 { - return Err(DecodeError::InvalidOperand); - } - instruction.opcode = Opcode::AESDECWIDE128KL; - instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?; - return Ok(()); - } - 0b010 => { - if modrm >= 0b11_000_000 { - return Err(DecodeError::InvalidOperand); - } - instruction.opcode = Opcode::AESENCWIDE256KL; - instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?; - return Ok(()); - } - 0b011 => { - if modrm >= 0b11_000_000 { - return Err(DecodeError::InvalidOperand); - } - instruction.opcode = Opcode::AESDECWIDE256KL; - instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?; - return Ok(()); - } - _ => { - return Err(DecodeError::InvalidOpcode); - } - } - } - 0xdc => { - read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?; - if let OperandSpec::RegMMM = instruction.operands[1] { - instruction.opcode = Opcode::LOADIWKEY; - } else { - instruction.opcode = Opcode::AESENC128KL; - } - } - 0xdd => { - read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?; - if let OperandSpec::RegMMM = instruction.operands[1] { - return Err(DecodeError::InvalidOperand); - } else { - instruction.opcode = Opcode::AESDEC128KL; - } - } - 0xde => { - read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?; - if let OperandSpec::RegMMM = instruction.operands[1] { - return Err(DecodeError::InvalidOperand); - } else { - instruction.opcode = Opcode::AESENC256KL; - } - } - 0xde => { - read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?; - if let OperandSpec::RegMMM = instruction.operands[1] { - return Err(DecodeError::InvalidOperand); - } else { - instruction.opcode = Opcode::AESDEC256KL; - } - } - 0xf6 => { - instruction.opcode = Opcode::ADOX; - return read_operands(decoder, bytes_iter, instruction, OperandCode::Gv_Ev, length); - } - 0xf8 => { - instruction.opcode = Opcode::ENQCMDS; - return read_operands(decoder, bytes_iter, instruction, OperandCode::Gdq_Ev, length); - } - 0xfb => { - instruction.opcode = Opcode::ENCODEKEY128; - read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm, length)?; - instruction.modrm_rrr.bank = RegisterBank::D; - instruction.modrm_mmm.bank = RegisterBank::D; - return Ok(()); - } - 0xfb => { - instruction.opcode = Opcode::ENCODEKEY256; - read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm, length)?; - instruction.modrm_rrr.bank = RegisterBank::D; - instruction.modrm_mmm.bank = RegisterBank::D; - return Ok(()); - } - _ => { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } - }; - } - OperandCode::ModRM_0x660f38 => { - let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?; - match op { - 0x00 => { instruction.opcode = Opcode::PSHUFB; } - 0x01 => { instruction.opcode = Opcode::PHADDW; } - 0x02 => { instruction.opcode = Opcode::PHADDD; } - 0x03 => { instruction.opcode = Opcode::PHADDSW; } - 0x04 => { instruction.opcode = Opcode::PMADDUBSW; } - 0x05 => { instruction.opcode = Opcode::PHSUBW; } - 0x06 => { instruction.opcode = Opcode::PHSUBD; } - 0x07 => { instruction.opcode = Opcode::PHSUBSW; } - 0x08 => { instruction.opcode = Opcode::PSIGNB; } - 0x09 => { instruction.opcode = Opcode::PSIGNW; } - 0x0a => { instruction.opcode = Opcode::PSIGND; } - 0x0b => { instruction.opcode = Opcode::PMULHRSW; } - 0x0c => { instruction.opcode = Opcode::BLENDPS; } - 0x0d => { instruction.opcode = Opcode::BLENDPD; } - - 0x10 => { instruction.opcode = Opcode::PBLENDVB; } - - 0x14 => { instruction.opcode = Opcode::BLENDVPS; } - 0x15 => { instruction.opcode = Opcode::BLENDVPD; } - - 0x17 => { instruction.opcode = Opcode::PTEST; } - - 0x1c => { instruction.opcode = Opcode::PABSB; } - 0x1d => { instruction.opcode = Opcode::PABSW; } - 0x1e => { instruction.opcode = Opcode::PABSD; } - - 0x20 => { instruction.opcode = Opcode::PMOVSXBW; } - 0x21 => { instruction.opcode = Opcode::PMOVSXBD; } - 0x22 => { instruction.opcode = Opcode::PMOVSXBQ; } - 0x23 => { instruction.opcode = Opcode::PMOVSXWD; } - 0x24 => { instruction.opcode = Opcode::PMOVSXWQ; } - 0x25 => { instruction.opcode = Opcode::PMOVSXDQ; } - - 0x28 => { instruction.opcode = Opcode::PMULDQ; } - 0x29 => { instruction.opcode = Opcode::PCMPEQQ; } - 0x2a => { instruction.opcode = Opcode::MOVNTDQA; } - 0x2b => { instruction.opcode = Opcode::PACKUSDW; } - - 0x30 => { instruction.opcode = Opcode::PMOVZXBW; } - 0x31 => { instruction.opcode = Opcode::PMOVZXBD; } - 0x32 => { instruction.opcode = Opcode::PMOVZXBQ; } - 0x33 => { instruction.opcode = Opcode::PMOVZXWD; } - 0x34 => { instruction.opcode = Opcode::PMOVZXWQ; } - 0x35 => { instruction.opcode = Opcode::PMOVZXDQ; } - - 0x37 => { instruction.opcode = Opcode::PCMPGTQ; } - 0x38 => { instruction.opcode = Opcode::PMINSB; } - 0x39 => { instruction.opcode = Opcode::PMINSD; } - 0x3a => { instruction.opcode = Opcode::PMINUW; } - 0x3b => { instruction.opcode = Opcode::PMINUD; } - 0x3c => { instruction.opcode = Opcode::PMAXSB; } - 0x3d => { instruction.opcode = Opcode::PMAXSD; } - 0x3e => { instruction.opcode = Opcode::PMAXUW; } - 0x3f => { instruction.opcode = Opcode::PMAXUD; } - - 0x40 => { instruction.opcode = Opcode::PMULLD; } - 0x41 => { instruction.opcode = Opcode::PHMINPOSUW; } - - 0xdb => { instruction.opcode = Opcode::AESIMC; } - 0xdc => { instruction.opcode = Opcode::AESENC; } - 0xdd => { instruction.opcode = Opcode::AESENCLAST; } - 0xde => { instruction.opcode = Opcode::AESDEC; } - 0xdf => { instruction.opcode = Opcode::AESDECLAST; } - 0xf6 => { - instruction.opcode = Opcode::ADCX; - return read_operands(decoder, bytes_iter, instruction, OperandCode::Gv_Ev, length); - } - 0xf8 => { - instruction.opcode = Opcode::MOVDIR64B; - return read_operands(decoder, bytes_iter, instruction, OperandCode::MOVDIR64B, length); - } - _ => { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } - }; - // all these SO FAR are G_E_xmm - let modrm = read_modrm(&mut bytes_iter, length)?; - instruction.modrm_rrr = - RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); - - - instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; - instruction.operand_count = 2; - } - OperandCode::ModRM_0x660f3a => { - let op = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?; - match op { - 0x08 => { - instruction.opcode = Opcode::ROUNDPS; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x09 => { - instruction.opcode = Opcode::ROUNDPD; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x0a => { - instruction.opcode = Opcode::ROUNDSS; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x0b => { - instruction.opcode = Opcode::ROUNDSD; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x0c => { - instruction.opcode = Opcode::BLENDPS; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x0d => { - instruction.opcode = Opcode::BLENDPD; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x0e => { - instruction.opcode = Opcode::PBLENDW; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x0f => { - instruction.opcode = Opcode::PALIGNR; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x14 => { - instruction.opcode = Opcode::PEXTRB; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x15 => { - instruction.opcode = Opcode::PEXTRW; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x16 => { - instruction.opcode = Opcode::PEXTRD; - if instruction.prefixes.rex().w() { - instruction.opcode = Opcode::PEXTRQ; - } - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x17 => { - instruction.opcode = Opcode::EXTRACTPS; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x20 => { - instruction.opcode = Opcode::PINSRB; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x21 => { - instruction.opcode = Opcode::INSERTPS; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x22 => { - instruction.opcode = Opcode::PINSRD; - if instruction.prefixes.rex().w() { - instruction.opcode = Opcode::PINSRQ; - } - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x40 => { - instruction.opcode = Opcode::DPPS; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x41 => { - instruction.opcode = Opcode::DPPD; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x42 => { - instruction.opcode = Opcode::MPSADBW; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x44 => { - instruction.opcode = Opcode::PCLMULQDQ; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - - 0x60 => { - instruction.opcode = Opcode::PCMPESTRM; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x61 => { - instruction.opcode = Opcode::PCMPESTRI; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x62 => { - instruction.opcode = Opcode::PCMPISTRM; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0x63 => { - instruction.opcode = Opcode::PCMPISTRI; - return read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm_Ib, length); - } - 0xcc => { - instruction.opcode = Opcode::SHA1RNDS4; - - let modrm = read_modrm(&mut bytes_iter, length)?; - instruction.modrm_rrr = - RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); - - - instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; - instruction.imm = - read_imm_unsigned(&mut bytes_iter, 1, length)?; - instruction.operands[2] = OperandSpec::ImmU8; - instruction.operand_count = 3; - } - 0xdf => { - instruction.opcode = Opcode::AESKEYGENASSIST; - // read operands right here right now - - let modrm = read_modrm(&mut bytes_iter, length)?; - instruction.modrm_rrr = - RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); - - - instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; - instruction.imm = - read_imm_unsigned(&mut bytes_iter, 1, length)?; - instruction.operands[2] = OperandSpec::ImmU8; - instruction.operand_count = 3; - } - _ => { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } - }; - } - OperandCode::ModRM_0x660f71 => { - instruction.operand_count = 2; - - let modrm = read_modrm(&mut bytes_iter, length)?; - if modrm & 0xc0 != 0xc0 { - return Err(DecodeError::InvalidOperand); - } - - let r = (modrm >> 3) & 7; - match r { - 2 => { - instruction.opcode = Opcode::PSRLW; - } - 4 => { - instruction.opcode = Opcode::PSRAW; - } - 6 => { - instruction.opcode = Opcode::PSLLW; - } - _ => { - return Err(DecodeError::InvalidOpcode); - } + instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; } - - instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 }; instruction.operands[0] = OperandSpec::RegMMM; instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; instruction.operands[1] = OperandSpec::ImmU8; }, - OperandCode::ModRM_0x660f72 => { - instruction.operand_count = 2; - - let modrm = read_modrm(&mut bytes_iter, length)?; - if modrm & 0xc0 != 0xc0 { + OperandCode::ModRM_0x0f73 => { + if instruction.prefixes.rep() || instruction.prefixes.repnz() { return Err(DecodeError::InvalidOperand); } - let r = (modrm >> 3) & 7; - match r { - 2 => { - instruction.opcode = Opcode::PSRLD; - } - 4 => { - instruction.opcode = Opcode::PSRAD; - } - 6 => { - instruction.opcode = Opcode::PSLLD; - } - _ => { - return Err(DecodeError::InvalidOpcode); - } - } - - instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 }; - instruction.operands[0] = OperandSpec::RegMMM; - instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; - instruction.operands[1] = OperandSpec::ImmU8; - }, - OperandCode::ModRM_0x660f73 => { instruction.operand_count = 2; let modrm = read_modrm(&mut bytes_iter, length)?; @@ -7699,12 +7601,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::PSRLQ; } 3 => { + if !instruction.prefixes.operand_size() { + return Err(DecodeError::InvalidOperand); + } instruction.opcode = Opcode::PSRLDQ; } 6 => { instruction.opcode = Opcode::PSLLQ; } 7 => { + if !instruction.prefixes.operand_size() { + return Err(DecodeError::InvalidOperand); + } instruction.opcode = Opcode::PSLLDQ; } _ => { @@ -7712,158 +7620,100 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } } - instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 }; + if instruction.prefixes.operand_size() { + instruction.modrm_mmm = RegSpec { bank: RegisterBank::X, num: modrm & 7 }; + } else { + instruction.modrm_mmm = RegSpec { bank: RegisterBank::MM, num: modrm & 7 }; + } instruction.operands[0] = OperandSpec::RegMMM; instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64; instruction.operands[1] = OperandSpec::ImmU8; }, - OperandCode::ModRM_0x660fc7 => { - let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); + OperandCode::ModRM_0xf30f38d8 => { let modrm = read_modrm(&mut bytes_iter, length)?; - let r = (modrm >> 3) & 7; match r { - 6 => { - instruction.opcode = Opcode::VMCLEAR; - instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; - if instruction.operands[0] == OperandSpec::RegMMM { - // this would be invalid as `vmclear`, so fall back to the parse as - // 66-prefixed rdrand. this is a register operand, so just demote it to the - // word-form operand: - instruction.modrm_mmm = RegSpec { bank: RegisterBank::W, num: instruction.modrm_mmm.num }; - instruction.opcode = Opcode::RDRAND; - } - instruction.operand_count = 1; - } - 7 => { - instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; - if instruction.operands[0] == OperandSpec::RegMMM { - // this would be invalid as `vmclear`, so fall back to the parse as - // 66-prefixed rdrand. this is a register operand, so just demote it to the - // word-form operand: - instruction.modrm_mmm = RegSpec { bank: RegisterBank::W, num: instruction.modrm_mmm.num }; - instruction.opcode = Opcode::RDSEED; - } else { - return Err(DecodeError::InvalidOpcode); + 0b000 => { + if modrm >= 0b11_000_000 { + return Err(DecodeError::InvalidOperand); } - instruction.operand_count = 1; - } - _ => { - return Err(DecodeError::InvalidOpcode); + instruction.opcode = Opcode::AESENCWIDE128KL; + instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?; + return Ok(()); } - } - }, - OperandCode::ModRM_0x660fae => { - let modrm = read_modrm(&mut bytes_iter, length)?; - if modrm < 0xc0 { - instruction.opcode = match (modrm >> 3) & 7 { - 6 => { - Opcode::CLWB - } - 7 => { - Opcode::CLFLUSHOPT - } - _ => { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } - }; - instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 1 /* opwidth */, length)?; - instruction.operand_count = 1; - } else { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } - }, - OperandCode::ModRM_0xf30fae => { - let modrm = read_modrm(&mut bytes_iter, length)?; - - if (modrm & 0xc0) == 0xc0 { - let r = (modrm >> 3) & 7; - let m = modrm & 7; - match r { - 0 => { - instruction.opcode = Opcode::RDFSBASE; - let opwidth = if instruction.prefixes.rex().w() { - RegisterBank::Q - } else { - RegisterBank::D - }; - instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); - instruction.operands[0] = OperandSpec::RegMMM; - instruction.operand_count = 1; - } - 1 => { - instruction.opcode = Opcode::RDGSBASE; - let opwidth = if instruction.prefixes.rex().w() { - RegisterBank::Q - } else { - RegisterBank::D - }; - instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); - instruction.operands[0] = OperandSpec::RegMMM; - instruction.operand_count = 1; - - } - 2 => { - instruction.opcode = Opcode::WRFSBASE; - let opwidth = if instruction.prefixes.rex().w() { - RegisterBank::Q - } else { - RegisterBank::D - }; - instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); - instruction.operands[0] = OperandSpec::RegMMM; - instruction.operand_count = 1; - } - 3 => { - instruction.opcode = Opcode::WRGSBASE; - let opwidth = if instruction.prefixes.rex().w() { - RegisterBank::Q - } else { - RegisterBank::D - }; - instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); - instruction.operands[0] = OperandSpec::RegMMM; - instruction.operand_count = 1; - - } - _ => { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); + 0b001 => { + if modrm >= 0b11_000_000 { + return Err(DecodeError::InvalidOperand); } + instruction.opcode = Opcode::AESDECWIDE128KL; + instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?; + return Ok(()); } - } - } - OperandCode::ModRM_0xf30fc7 => { - let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); - let modrm = read_modrm(&mut bytes_iter, length)?; - - let r = (modrm >> 3) & 7; - match r { - 6 => { - instruction.opcode = Opcode::VMXON; - instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; - if instruction.operands[0] == OperandSpec::RegMMM { - // this would be invalid as `vmxon`, so fall back to the parse as - // f3-prefixed rdrand - instruction.opcode = Opcode::RDRAND; + 0b010 => { + if modrm >= 0b11_000_000 { + return Err(DecodeError::InvalidOperand); } - instruction.operand_count = 1; + instruction.opcode = Opcode::AESENCWIDE256KL; + instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?; + return Ok(()); } - 7 => { - instruction.opcode = Opcode::RDPID; - instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; - if instruction.operands[0] != OperandSpec::RegMMM { + 0b011 => { + if modrm >= 0b11_000_000 { return Err(DecodeError::InvalidOperand); } - instruction.operand_count = 1; + instruction.opcode = Opcode::AESDECWIDE256KL; + instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?; + return Ok(()); } _ => { return Err(DecodeError::InvalidOpcode); } } - }, + } + OperandCode::ModRM_0xf30f38dc => { + read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?; + if let OperandSpec::RegMMM = instruction.operands[1] { + instruction.opcode = Opcode::LOADIWKEY; + } else { + instruction.opcode = Opcode::AESENC128KL; + } + } + OperandCode::ModRM_0xf30f38dd => { + read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?; + if let OperandSpec::RegMMM = instruction.operands[1] { + return Err(DecodeError::InvalidOperand); + } else { + instruction.opcode = Opcode::AESDEC128KL; + } + } + OperandCode::ModRM_0xf30f38de => { + read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?; + if let OperandSpec::RegMMM = instruction.operands[1] { + return Err(DecodeError::InvalidOperand); + } else { + instruction.opcode = Opcode::AESENC256KL; + } + } + OperandCode::ModRM_0xf30f38df => { + read_operands(decoder, bytes_iter, instruction, OperandCode::G_E_xmm, length)?; + if let OperandSpec::RegMMM = instruction.operands[1] { + return Err(DecodeError::InvalidOperand); + } else { + instruction.opcode = Opcode::AESDEC256KL; + } + } + OperandCode::ModRM_0xf30f38fa => { + instruction.opcode = Opcode::ENCODEKEY128; + read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm, length)?; + instruction.modrm_rrr.bank = RegisterBank::D; + instruction.modrm_mmm.bank = RegisterBank::D; + } + OperandCode::ModRM_0xf30f38fb => { + instruction.opcode = Opcode::ENCODEKEY256; + read_operands(decoder, bytes_iter, instruction, OperandCode::G_U_xmm, length)?; + instruction.modrm_rrr.bank = RegisterBank::D; + instruction.modrm_mmm.bank = RegisterBank::D; + } OperandCode::G_mm_Edq => { instruction.modrm_rrr.bank = RegisterBank::MM; instruction.modrm_rrr.num &= 0b111; @@ -8056,10 +7906,17 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr.bank = RegisterBank::X; instruction.operands[1] = mem_oper; if instruction.operands[1] == OperandSpec::RegMMM { + if instruction.prefixes.operand_size() { + return Err(DecodeError::InvalidOpcode); + } instruction.modrm_mmm.bank = RegisterBank::X; instruction.opcode = Opcode::MOVHLPS; } else { - instruction.opcode = Opcode::MOVLPS; + if instruction.prefixes.operand_size() { + instruction.opcode = Opcode::MOVLPD; + } else { + instruction.opcode = Opcode::MOVLPS; + } } } OperandCode::ModRM_0x0f16 => { @@ -8067,25 +7924,33 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[1] = mem_oper; if instruction.operands[1] == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::X; + if instruction.prefixes.operand_size() { + return Err(DecodeError::InvalidOpcode); + } instruction.opcode = Opcode::MOVLHPS; } else { - instruction.opcode = Opcode::MOVHPS; + if instruction.prefixes.operand_size() { + instruction.opcode = Opcode::MOVHPD; + } else { + instruction.opcode = Opcode::MOVHPS; + } } } OperandCode::ModRM_0x0f18 => { let rrr = instruction.modrm_rrr.num & 0b111; - // only PREFETCH* are invalid on reg operand - if mem_oper == OperandSpec::RegMMM && rrr < 4{ - return Err(DecodeError::InvalidOperand); - } instruction.operands[0] = mem_oper; instruction.operand_count = 1; - instruction.opcode = match rrr { - 0 => Opcode::PREFETCHNTA, - 1 => Opcode::PREFETCH0, - 2 => Opcode::PREFETCH1, - 3 => Opcode::PREFETCH2, - _ => Opcode::NOP, + // only PREFETCH* are invalid on reg operand + instruction.opcode = if mem_oper == OperandSpec::RegMMM && rrr < 4 { + Opcode::NOP + } else { + match rrr { + 0 => Opcode::PREFETCHNTA, + 1 => Opcode::PREFETCH0, + 2 => Opcode::PREFETCH1, + 3 => Opcode::PREFETCH2, + _ => Opcode::NOP, + } }; } OperandCode::Gd_U_xmm => { @@ -8145,6 +8010,16 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr = RegSpec { bank: RegisterBank::S, num: (modrm >> 3) & 7 }; + + // quoth the manual: + // ``` + // The MOV instruction cannot be used to load the CS register. Attempting to do so + // results in an invalid opcode excep-tion (#UD). To load the CS register, use the far + // JMP, CALL, or RET instruction. + // ``` + if instruction.modrm_rrr.num == 1 { + return Err(DecodeError::InvalidOperand); + } instruction.operands[0] = OperandSpec::RegRRR; instruction.operand_count = 2; @@ -8206,10 +8081,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else if r == 5 { instruction.opcode = Opcode::VERW; } else if r == 6 { - instruction.opcode = Opcode::JMPE; + // TODO: this would be jmpe for x86-on-itanium systems. + instruction.opcode = Opcode::Invalid; instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; - return Ok(()); + return Err(DecodeError::InvalidOperand); } else if r == 7 { instruction.opcode = Opcode::Invalid; instruction.operands[0] = OperandSpec::Nothing; @@ -8454,6 +8330,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = OperandSpec::RegRRR; instruction.modrm_rrr = RegSpec::ecx(); instruction.operand_count = 1; + } else if m == 6 { + instruction.opcode = Opcode::INVLPGB; + instruction.operand_count = 3; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = OperandSpec::RegMMM; + instruction.operands[2] = OperandSpec::RegVex; + instruction.modrm_rrr = RegSpec::rax(); + instruction.modrm_mmm = RegSpec::edx(); + instruction.vex_reg = RegSpec::ecx(); + } else if m == 7 { + instruction.opcode = Opcode::TLBSYNC; + instruction.operand_count = 0; } else { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); @@ -8468,6 +8356,110 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } } OperandCode::ModRM_0x0fae => { + if instruction.prefixes.operand_size() && !(instruction.prefixes.rep() || instruction.prefixes.repnz()) { + let modrm = read_modrm(&mut bytes_iter, length)?; + if modrm < 0xc0 { + instruction.opcode = match (modrm >> 3) & 7 { + 6 => { + Opcode::CLWB + } + 7 => { + Opcode::CLFLUSHOPT + } + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + }; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 1 /* opwidth */, length)?; + instruction.operand_count = 1; + } else { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + + return Ok(()); + } + + if instruction.prefixes.rep() { + let modrm = read_modrm(&mut bytes_iter, length)?; + let r = (modrm >> 3) & 7; + + if r == 4 { + if instruction.prefixes.operand_size() { + // xed specifically rejects this. seeems out of line since rep takes + // precedence elsewhere, but ok i guess + return Err(DecodeError::InvalidOpcode); + } + instruction.opcode = Opcode::PTWRITE; + let opwidth = if instruction.prefixes.rex().w() { + 8 + } else { + 4 + }; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + instruction.operand_count = 1; + return Ok(()); + } + if (modrm & 0xc0) == 0xc0 { + let m = modrm & 7; + match r { + 0 => { + instruction.opcode = Opcode::RDFSBASE; + let opwidth = if instruction.prefixes.rex().w() { + RegisterBank::Q + } else { + RegisterBank::D + }; + instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); + instruction.operands[0] = OperandSpec::RegMMM; + instruction.operand_count = 1; + } + 1 => { + instruction.opcode = Opcode::RDGSBASE; + let opwidth = if instruction.prefixes.rex().w() { + RegisterBank::Q + } else { + RegisterBank::D + }; + instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); + instruction.operands[0] = OperandSpec::RegMMM; + instruction.operand_count = 1; + + } + 2 => { + instruction.opcode = Opcode::WRFSBASE; + let opwidth = if instruction.prefixes.rex().w() { + RegisterBank::Q + } else { + RegisterBank::D + }; + instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); + instruction.operands[0] = OperandSpec::RegMMM; + instruction.operand_count = 1; + } + 3 => { + instruction.opcode = Opcode::WRGSBASE; + let opwidth = if instruction.prefixes.rex().w() { + RegisterBank::Q + } else { + RegisterBank::D + }; + instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); + instruction.operands[0] = OperandSpec::RegMMM; + instruction.operand_count = 1; + } + _ => { + instruction.opcode = Opcode::Invalid; + return Err(DecodeError::InvalidOpcode); + } + } + return Ok(()); + } else { + return Err(DecodeError::InvalidOperand); + } + } + let modrm = read_modrm(&mut bytes_iter, length)?; let r = (modrm >> 3) & 7; let mod_bits = modrm >> 6; @@ -8518,6 +8510,10 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter _ => { unsafe { unreachable_unchecked() } /* r <=7 */ } } } else { + // these can't be prefixed, so says `xed` i guess. + if instruction.prefixes.operand_size() || instruction.prefixes.rep() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOperand); + } instruction.operand_count = 1; instruction.opcode = [ Opcode::FXSAVE, @@ -8568,11 +8564,31 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter op @ OperandCode::Rq_Dq_0 | op @ OperandCode::Cq_Rq_0 | op @ OperandCode::Dq_Rq_0 => { + let modrm = read_modrm(&mut bytes_iter, length)?; + let mut m = modrm & 7; + let mut r = (modrm >> 3) & 7; + if instruction.prefixes.rex().r() { + r += 0b1000; + } + if instruction.prefixes.rex().b() { + m += 0b1000; + } + let bank = match op { OperandCode::Rq_Cq_0 | - OperandCode::Cq_Rq_0 => RegisterBank::CR, + OperandCode::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 => RegisterBank::DR, + OperandCode::Dq_Rq_0 => { + if r > 7 { + return Err(DecodeError::InvalidOperand); + } + RegisterBank::DR + }, _ => unsafe { unreachable_unchecked() } }; let (rrr, mmm) = match op { @@ -8583,15 +8599,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter _ => unsafe { unreachable_unchecked() } }; - let modrm = read_modrm(&mut bytes_iter, length)?; - let mut m = modrm & 7; - let mut r = (modrm >> 3) & 7; - if instruction.prefixes.rex().r() { - r += 0b1000; - } - if instruction.prefixes.rex().b() { - m += 0b1000; - } instruction.modrm_rrr = RegSpec { bank: bank, num: r }; instruction.modrm_mmm = @@ -8731,12 +8738,26 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter // 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 // address-size, not operand-size. + if let OperandSpec::RegMMM = instruction.operands[1] { + return Err(DecodeError::InvalidOperand); + } if instruction.prefixes.address_size() { instruction.modrm_rrr.bank = RegisterBank::D; } else { instruction.modrm_rrr.bank = RegisterBank::Q; }; } + OperandCode::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. + if let OperandSpec::RegMMM = instruction.operands[1] { + return Err(DecodeError::InvalidOperand); + } + let temp = instruction.operands[1]; + 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 diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index bbfd508..71a5724 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -942,6 +942,16 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } 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 + }), 0x57 => (Opcode::VXORPS, if L { VEXOperandCode::G_V_E_ymm } else { @@ -1079,6 +1089,16 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & } 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 + }), 0x57 => (Opcode::VXORPD, if L { VEXOperandCode::G_V_E_ymm } else { diff --git a/test/long_mode/display.rs b/test/long_mode/display.rs index 988e360..7017270 100644 --- a/test/long_mode/display.rs +++ b/test/long_mode/display.rs @@ -152,7 +152,8 @@ fn test_instructions_c() { test_display(&[0x3a, 0xc0], "rflags = flags(al - al)"); test_display(&[0x3b, 0xc0], "rflags = flags(eax - eax)"); - test_display(&[0x41, 0x0f, 0xbc, 0xd3], "edx = lsb(r11d)"); + test_display(&[0x41, 0x0f, 0xbc, 0xd3], "edx = lsb(r11d) (x86 bsf)"); + test_display(&[0xf3, 0x41, 0x0f, 0xbc, 0xd3], "edx = lsb(r11d)"); // test_display(&[0x41, 0x0f, 0xbc, 0xd3], "edx = lsb(r11d) (x86 bsf"); // for non-bm1 test_display(&[0x41, 0x0f, 0xbd, 0xd3], "edx = msb(r11d)"); // test_display(&[0x41, 0x0f, 0xbc, 0xd3], "edx = lsb(r11d) (x86 bsr"); // for non-bm1 diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index a1e8c36..b024103 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -13,7 +13,7 @@ fn test_invalid(data: &[u8]) { fn test_invalid_under(decoder: &InstDecoder, data: &[u8]) { if let Ok(inst) = decoder.decode(data.into_iter().cloned()) { - assert_eq!(inst.opcode(), Opcode::Invalid, "decoded {:?} from {:02x?} under decoder {}", inst.opcode(), data, decoder); + panic!("decoded {:?} from {:02x?} under decoder {}", inst.opcode(), data, decoder); } else { // this is fine } @@ -161,7 +161,11 @@ fn test_mmx() { test_display(&[0x0f, 0x75, 0xc2], "pcmpeqw mm0, mm2"); test_display(&[0x0f, 0x76, 0xc2], "pcmpeqd mm0, mm2"); + test_display(&[0x66, 0x0f, 0xc5, 0xd8, 0xff], "pextrw ebx, xmm0, 0xff"); + test_invalid(&[0x66, 0x0f, 0xc5, 0x08, 0xff]); + test_display(&[0x0f, 0xc5, 0xd1, 0x00], "pextrw edx, mm1, 0x0"); + test_invalid(&[0x0f, 0xc5, 0x01, 0x00]); test_display(&[0x0f, 0xd8, 0xc2], "psubusb mm0, mm2"); test_display(&[0x0f, 0xd9, 0xc2], "psubusw mm0, mm2"); @@ -256,7 +260,6 @@ fn test_sse2() { test_instr(&[0xf2, 0x0f, 0x10, 0x0c, 0xc7], "movsd xmm1, [rdi + rax * 8]"); test_instr(&[0xf2, 0x0f, 0x11, 0x0c, 0xc7], "movsd [rdi + rax * 8], xmm1"); test_instr(&[0x66, 0x0f, 0x11, 0x0c, 0xc7], "movupd [rdi + rax * 8], xmm1"); - test_instr(&[0x66, 0x4f, 0x0f, 0x12, 0xc3], "movhlps xmm8, xmm11"); // reg-reg form is movhlps test_instr(&[0x66, 0x4f, 0x0f, 0x12, 0x03], "movlpd xmm8, [r11]"); // reg-mem is movlpd test_instr(&[0x66, 0x4f, 0x0f, 0x13, 0x03], "movlpd [r11], xmm8"); test_invalid(&[0x66, 0x4f, 0x0f, 0x13, 0xc3]); @@ -265,7 +268,6 @@ fn test_sse2() { test_instr(&[0x66, 0x4f, 0x0f, 0x15, 0x03], "unpckhpd xmm8, [r11]"); test_instr(&[0x66, 0x4f, 0x0f, 0x15, 0xc3], "unpckhpd xmm8, xmm11"); test_instr(&[0x66, 0x4f, 0x0f, 0x16, 0x03], "movhpd xmm8, [r11]"); - test_instr(&[0x66, 0x4f, 0x0f, 0x16, 0xc3], "movlhps xmm8, xmm11"); test_instr(&[0x66, 0x4f, 0x0f, 0x17, 0x03], "movhpd [r11], xmm8"); test_invalid(&[0x66, 0x4f, 0x0f, 0x17, 0xc3]); @@ -541,8 +543,11 @@ fn test_sse2() { test_instr(&[0x66, 0x0f, 0xfd, 0x01], "paddw xmm0, [rcx]"); test_instr(&[0x66, 0x0f, 0xfe, 0xc1], "paddd xmm0, xmm1"); test_instr(&[0x66, 0x0f, 0xfe, 0x01], "paddd xmm0, [rcx]"); - test_instr(&[0x66, 0x0f, 0xff, 0xc1], "paddq xmm0, xmm1"); - test_instr(&[0x66, 0x0f, 0xff, 0x01], "paddq xmm0, [rcx]"); + test_instr(&[0x66, 0x0f, 0xff, 0xc1], "ud0 eax, ecx"); + test_instr(&[0xf2, 0x0f, 0xff, 0xc1], "ud0 eax, ecx"); + test_instr(&[0xf3, 0x0f, 0xff, 0xc1], "ud0 eax, ecx"); + test_instr(&[0x66, 0x0f, 0xff, 0x01], "ud0 eax, [rcx]"); + test_instr(&[0x66, 0x4f, 0x0f, 0xff, 0xc1], "ud0 r8d, r9d"); test_instr(&[0x66, 0x0f, 0x74, 0xc1], "pcmpeqb xmm0, xmm1"); test_instr(&[0x66, 0x0f, 0x74, 0x12], "pcmpeqb xmm2, [rdx]"); @@ -571,6 +576,7 @@ fn test_sse3() { test_instr_invalid(&[0xf2, 0x0f, 0xf0, 0xcf]); test_instr(&[0xf2, 0x0f, 0xd0, 0x0f], "addsubps xmm1, [rdi]"); test_instr(&[0xf2, 0x0f, 0xd0, 0xcf], "addsubps xmm1, xmm7"); + test_invalid(&[0xf3, 0x0f, 0xd0, 0x0f]); test_instr(&[0xf2, 0x4f, 0x0f, 0xd0, 0xcf], "addsubps xmm9, xmm15"); test_instr(&[0x66, 0x0f, 0xd0, 0x0f], "addsubpd xmm1, [rdi]"); test_instr(&[0x66, 0x0f, 0xd0, 0xcf], "addsubpd xmm1, xmm7"); @@ -662,10 +668,10 @@ fn test_sse4_1() { test_invalid_under(&InstDecoder::default(), bytes); } - test_instr(&[0x66, 0x0f, 0x38, 0x0c, 0x06], "blendps xmm0, [rsi]"); - test_invalid(&[0x0f, 0x38, 0x0c, 0x06]); - test_instr(&[0x66, 0x0f, 0x38, 0x0d, 0x06], "blendpd xmm0, [rsi]"); - test_invalid(&[0x0f, 0x38, 0x0d, 0x06]); + test_instr(&[0x66, 0x0f, 0x3a, 0x0c, 0x11, 0x22], "blendps xmm2, [rcx], 0x22"); + test_instr(&[0x66, 0x0f, 0x3a, 0x0c, 0xc1, 0x22], "blendps xmm0, xmm1, 0x22"); + test_instr(&[0x66, 0x0f, 0x3a, 0x0d, 0x11, 0x22], "blendpd xmm2, [rcx], 0x22"); + test_instr(&[0x66, 0x0f, 0x3a, 0x0d, 0xc1, 0x22], "blendpd xmm0, xmm1, 0x22"); test_instr(&[0x66, 0x0f, 0x38, 0x10, 0x06], "pblendvb xmm0, [rsi]"); test_invalid(&[0x0f, 0x38, 0x10, 0x06]); @@ -696,6 +702,7 @@ fn test_sse4_1() { test_instr(&[0x66, 0x0f, 0x38, 0x29, 0x06], "pcmpeqq xmm0, [rsi]"); test_invalid(&[0x0f, 0x38, 0x29, 0x06]); test_instr(&[0x66, 0x0f, 0x38, 0x2a, 0x06], "movntdqa xmm0, [rsi]"); + test_invalid(&[0x66, 0x0f, 0x38, 0x2a, 0xc6]); test_invalid(&[0x0f, 0x38, 0x2a, 0x06]); test_instr(&[0x66, 0x0f, 0x38, 0x2b, 0x06], "packusdw xmm0, [rsi]"); test_invalid(&[0x0f, 0x38, 0x2b, 0x06]); @@ -878,6 +885,9 @@ fn test_0f01() { test_display(&[0x0f, 0x01, 0xdd], "clgi"); test_display(&[0x0f, 0x01, 0xde], "skinit eax"); test_display(&[0x0f, 0x01, 0xdf], "invlpga rax, ecx"); + test_display(&[0x0f, 0x01, 0xfe], "invlpgb rax, edx, ecx"); + test_display(&[0x0f, 0x01, 0xff], "tlbsync"); + test_display(&[0x2e, 0x67, 0x65, 0x2e, 0x46, 0x0f, 0x01, 0xff], "tlbsync"); test_display(&[0x4f, 0x0f, 0x01, 0xe0], "smsw r8w"); test_display(&[0x0f, 0x01, 0xe0], "smsw ax"); test_display(&[0x0f, 0x01, 0xe1], "smsw cx"); @@ -911,8 +921,6 @@ fn test_0f01() { test_display(&[0x0f, 0x01, 0xfb], "mwaitx"); test_display(&[0x0f, 0x01, 0xfc], "clzero"); test_display(&[0x0f, 0x01, 0xfd], "rdpru ecx"); - test_invalid(&[0x0f, 0x01, 0xfe]); - test_invalid(&[0x0f, 0x01, 0xff]); } #[test] @@ -923,6 +931,9 @@ fn test_0fae() { let minimal = InstDecoder::minimal(); // drawn heavily from "Table A-6. Opcode Extensions for One- and Two-byte Opcodes by Group // Number" + test_invalid(&[0xf3, 0x0f, 0xae, 0x87]); + test_invalid(&[0xf3, 0x0f, 0xae, 0x04, 0x4f]); + test_display(&[0x0f, 0xae, 0x04, 0x4f], "fxsave [rdi + rcx * 2]"); test_display(&[0x0f, 0xae, 0x04, 0x4f], "fxsave [rdi + rcx * 2]"); test_display(&[0x0f, 0xae, 0x0c, 0x4f], "fxrstor [rdi + rcx * 2]"); test_display(&[0x0f, 0xae, 0x14, 0x4f], "ldmxcsr [rdi + rcx * 2]"); @@ -968,16 +979,16 @@ fn test_system() { test_display(&[0x66, 0x4f, 0x0f, 0xb2, 0x00], "lss r8, [r8]"); test_display(&[0x67, 0x4f, 0x0f, 0xb2, 0x00], "lss r8, [r8d]"); test_display(&[0x4f, 0x0f, 0xb2, 0x00], "lss r8, [r8]"); - test_display(&[0x45, 0x0f, 0x22, 0xc8], "mov cr9, r8"); - test_display(&[0x45, 0x0f, 0x20, 0xc8], "mov r8, cr9"); - test_display(&[0x40, 0x0f, 0x22, 0xc8], "mov cr1, rax"); - test_display(&[0x0f, 0x22, 0xc8], "mov cr1, rax"); - test_display(&[0x44, 0x0f, 0x22, 0xcf], "mov cr9, rdi"); - test_display(&[0x0f, 0x22, 0xcf], "mov cr1, rdi"); - test_display(&[0x0f, 0x20, 0xc8], "mov rax, cr1"); - - test_display(&[0x45, 0x0f, 0x23, 0xc8], "mov dr9, r8"); - test_display(&[0x45, 0x0f, 0x21, 0xc8], "mov r8, dr9"); + test_invalid(&[0x45, 0x0f, 0x22, 0xc8]); + test_invalid(&[0x45, 0x0f, 0x20, 0xc8]); + test_display(&[0x40, 0x0f, 0x22, 0xd0], "mov cr2, rax"); + test_display(&[0x0f, 0x22, 0xd0], "mov cr2, rax"); + test_invalid(&[0x44, 0x0f, 0x22, 0xcf]); + test_display(&[0x0f, 0x22, 0xd7], "mov cr2, rdi"); + test_display(&[0x0f, 0x20, 0xd0], "mov rax, cr2"); + + test_invalid(&[0x45, 0x0f, 0x23, 0xc8]); + test_invalid(&[0x45, 0x0f, 0x21, 0xc8]); test_display(&[0x40, 0x0f, 0x23, 0xc8], "mov dr1, rax"); test_display(&[0x0f, 0x23, 0xc8], "mov dr1, rax"); test_display(&[0x0f, 0x21, 0xc8], "mov rax, dr1"); @@ -1125,10 +1136,10 @@ fn test_mov() { test_display(&[0x0f, 0x97, 0xc8], "seta al"); test_display(&[0x0f, 0x97, 0x00], "seta [rax]"); test_display(&[0x0f, 0x97, 0x08], "seta [rax]"); - test_display(&[0xd6], "salc"); +// test_display(&[0xd6], "salc"); test_display(&[0x8e, 0x00], "mov es, [rax]"); - // cs is not an allowed destination - would #ud on execution - test_display(&[0x8e, 0x08], "mov cs, [rax]"); + // cs is not an allowed destination + test_invalid(&[0x8e, 0x08]); test_display(&[0x8e, 0x10], "mov ss, [rax]"); test_display(&[0x8e, 0x18], "mov ds, [rax]"); test_display(&[0x8e, 0x20], "mov fs, [rax]"); @@ -1158,7 +1169,17 @@ fn test_prefixes() { test_invalid(&[0xf0, 0x33, 0xc0]); test_display(&[0xf0, 0x31, 0x00], "lock xor [rax], eax"); test_display(&[0xf0, 0x80, 0x30, 0x00], "lock xor [rax], 0x0"); + test_display(&[0xf0, 0x0f, 0xbb, 0x17], "lock btc [rdi], edx"); + test_display(&[0x66, 0x2e, 0xf2, 0xf0, 0x0f, 0xbb, 0x13], "lock btc [rbx], dx"); test_invalid(&[0xf0, 0xc7, 0x00, 0x00, 0x00, 0x00]); + test_display(&[0x0f, 0xc1, 0xcc], "xadd esp, ecx"); + test_display(&[0x66, 0x0f, 0xc1, 0xcc], "xadd sp, cx"); + test_display(&[0xf2, 0x0f, 0xc1, 0xcc], "xadd esp, ecx"); + test_display(&[0xf3, 0x0f, 0xc1, 0xcc], "xadd esp, ecx"); + test_display(&[0x0f, 0xc0, 0xcc], "xadd ah, cl"); + test_display(&[0x66, 0x0f, 0xc0, 0xcc], "xadd ah, cl"); + test_display(&[0xf2, 0x0f, 0xc0, 0xcc], "xadd ah, cl"); + test_display(&[0xf3, 0x0f, 0xc0, 0xcc], "xadd ah, cl"); } #[test] @@ -1215,8 +1236,10 @@ fn test_push_pop() { fn test_bmi1() { let bmi1 = InstDecoder::minimal().with_bmi1(); let no_bmi1 = InstDecoder::minimal(); - test_display_under(&bmi1, &[0x41, 0x0f, 0xbc, 0xd3], "tzcnt edx, r11d"); - test_display_under(&no_bmi1, &[0x41, 0x0f, 0xbc, 0xd3], "bsf edx, r11d"); + test_display_under(&bmi1, &[0xf3, 0x41, 0x0f, 0xbc, 0xd3], "tzcnt edx, r11d"); + test_display_under(&bmi1, &[0xf2, 0x41, 0x0f, 0xbc, 0xd3], "bsf edx, r11d"); + test_display_under(&bmi1, &[0x41, 0x0f, 0xbc, 0xd3], "bsf edx, r11d"); + test_display_under(&no_bmi1, &[0xf3, 0x41, 0x0f, 0xbc, 0xd3], "bsf edx, r11d"); // just 0f38 test_display_under(&bmi1, &[0xc4, 0xc2, 0x60, 0xf2, 0x01], "andn eax, ebx, [r9]"); @@ -1276,6 +1299,8 @@ fn test_popcnt() { #[test] fn test_bitwise() { test_display_under(&InstDecoder::minimal(), &[0x41, 0x0f, 0xbc, 0xd3], "bsf edx, r11d"); + test_display_under(&InstDecoder::minimal(), &[0x0f, 0xbb, 0x17], "btc [rdi], edx"); + test_display_under(&InstDecoder::minimal(), &[0xf0, 0x0f, 0xbb, 0x17], "lock btc [rdi], edx"); test_display(&[0x48, 0x0f, 0xa3, 0xd0], "bt rax, rdx"); test_display(&[0x48, 0x0f, 0xab, 0xd0], "bts rax, rdx"); test_display(&[0x48, 0x0f, 0xb3, 0xd0], "btr rax, rdx"); @@ -1333,6 +1358,10 @@ fn test_misc() { test_display(&[0xf3, 0x48, 0xa5], "rep movs es:[rdi], ds:[rsi]"); test_display(&[0xf3, 0x45, 0x0f, 0xbc, 0xd7], "tzcnt r10d, r15d"); + test_display(&[0xf3, 0x0f, 0xae, 0x26], "ptwrite [rsi]"); + test_display(&[0xf3, 0x0f, 0xae, 0xe6], "ptwrite esi"); + test_invalid(&[0x66, 0xf3, 0x0f, 0xae, 0xe6]); + test_display(&[0xf3, 0x49, 0x0f, 0xae, 0x26], "ptwrite [r14]"); test_display(&[0xf3, 0x0f, 0xae, 0xc4], "rdfsbase esp"); test_display(&[0xf3, 0x4f, 0x0f, 0xae, 0xc4], "rdfsbase r12"); test_display(&[0xf3, 0x0f, 0xae, 0xcc], "rdgsbase esp"); @@ -1345,6 +1374,18 @@ fn test_misc() { test_invalid(&[0x66, 0x0f, 0xae, 0xff]); test_display(&[0x66, 0x0f, 0xae, 0x37], "clwb [rdi]"); test_invalid(&[0x66, 0x0f, 0xae, 0xf7]); + test_display(&[0x66, 0x0f, 0x38, 0x80, 0x2f], "invept ebp, [rdi]"); + test_display(&[0x66, 0x49, 0x0f, 0x38, 0x80, 0x2f], "invept rbp, [r15]"); + test_invalid(&[0x0f, 0x38, 0x80, 0x2f]); + test_invalid(&[0x43, 0x0f, 0x38, 0x80, 0x2f]); + test_display(&[0x66, 0x0f, 0x38, 0x81, 0x2f], "invvpid ebp, [rdi]"); + test_display(&[0x66, 0x49, 0x0f, 0x38, 0x81, 0x2f], "invvpid rbp, [r15]"); + test_invalid(&[0x0f, 0x38, 0x81, 0x2f]); + test_invalid(&[0x43, 0x0f, 0x38, 0x81, 0x2f]); + test_display(&[0x66, 0x0f, 0x38, 0x82, 0x2f], "invpcid ebp, [rdi]"); + test_display(&[0x66, 0x49, 0x0f, 0x38, 0x82, 0x2f], "invpcid rbp, [r15]"); + test_invalid(&[0x0f, 0x38, 0x82, 0x2f]); + test_invalid(&[0x43, 0x0f, 0x38, 0x82, 0x2f]); } #[test] @@ -1494,6 +1535,12 @@ fn test_vex() { test_instr(&[0xc5, 0xf1, 0xc4, 0xd8, 0x78], "vpinsrw xmm3, xmm1, eax, 0x78"); test_instr(&[0xc5, 0xf1, 0xc4, 0x18, 0x78], "vpinsrw xmm3, xmm1, [rax], 0x78"); + + // uh oh, i think these sizes are backwards... + test_instr(&[0xc5, 0xe0, 0x54, 0x03], "vandpd xmm0, xmm3, [rbx]"); + test_instr(&[0xc5, 0xe1, 0x54, 0x03], "vandps xmm0, xmm3, [rbx]"); + test_instr(&[0xc5, 0xe0, 0x55, 0x03], "vandnpd xmm0, xmm3, [rbx]"); + test_instr(&[0xc5, 0xe1, 0x55, 0x03], "vandnps xmm0, xmm3, [rbx]"); } #[test] @@ -1531,13 +1578,14 @@ fn prefixed_0f() { test_display(&[0x0f, 0x16, 0xc0], "movlhps xmm0, xmm0"); test_invalid(&[0x0f, 0x17, 0xc0]); test_display(&[0x0f, 0x17, 0x00], "movhps [rax], xmm0"); - test_invalid(&[0x0f, 0x18, 0xc0]); + test_display(&[0x0f, 0x18, 0xc0], "nop eax"); // capstone says invalid, xed says nop test_display(&[0x0f, 0x18, 0x00], "prefetchnta [rax]"); test_display(&[0x0f, 0x18, 0x08], "prefetch0 [rax]"); test_display(&[0x0f, 0x18, 0x10], "prefetch1 [rax]"); test_display(&[0x0f, 0x18, 0x18], "prefetch2 [rax]"); test_display(&[0x0f, 0x18, 0x20], "nop [rax]"); test_display(&[0x4f, 0x0f, 0x18, 0x20], "nop [r8]"); + test_display(&[0x0f, 0x18, 0xcc], "nop esp"); test_display(&[0x0f, 0x19, 0x20], "nop [rax]"); test_display(&[0x0f, 0x1a, 0x20], "nop [rax]"); test_display(&[0x0f, 0x1b, 0x20], "nop [rax]"); @@ -1545,19 +1593,23 @@ fn prefixed_0f() { test_display(&[0x0f, 0x1d, 0x20], "nop [rax]"); test_display(&[0x0f, 0x1e, 0x20], "nop [rax]"); test_display(&[0x0f, 0x1f, 0x20], "nop [rax]"); - test_display(&[0x45, 0x0f, 0x20, 0xc8], "mov r8, cr9"); - test_display(&[0x0f, 0x20, 0xc8], "mov rax, cr1"); - test_display(&[0x45, 0x0f, 0x21, 0xc8], "mov r8, dr9"); + test_invalid(&[0x45, 0x0f, 0x20, 0xc8]); + test_display(&[0x45, 0x0f, 0x20, 0xc0], "mov r8, cr8"); + test_invalid(&[0x0f, 0x20, 0xc8]); + test_invalid(&[0x45, 0x0f, 0x21, 0xc8]); test_display(&[0x0f, 0x21, 0xc8], "mov rax, dr1"); - test_display(&[0x45, 0x0f, 0x22, 0xc8], "mov cr9, r8"); - test_display(&[0x40, 0x0f, 0x22, 0xc8], "mov cr1, rax"); - test_display(&[0x0f, 0x22, 0xc8], "mov cr1, rax"); - test_display(&[0x44, 0x0f, 0x22, 0xcf], "mov cr9, rdi"); - test_display(&[0x0f, 0x22, 0xcf], "mov cr1, rdi"); - test_display(&[0x45, 0x0f, 0x23, 0xc8], "mov dr9, r8"); + test_invalid(&[0x45, 0x0f, 0x22, 0xc8]); + test_display(&[0x45, 0x0f, 0x22, 0xc0], "mov cr8, r8"); + test_invalid(&[0x40, 0x0f, 0x22, 0xc8]); + test_invalid(&[0x0f, 0x22, 0xc8]); + test_display(&[0x0f, 0x22, 0xc0], "mov cr0, rax"); + test_invalid(&[0x44, 0x0f, 0x22, 0xcf]); + test_display(&[0x0f, 0x22, 0xc7], "mov cr0, rdi"); + test_invalid(&[0x0f, 0x22, 0xcf]); + test_invalid(&[0x45, 0x0f, 0x23, 0xc8]); test_display(&[0x40, 0x0f, 0x23, 0xc8], "mov dr1, rax"); test_display(&[0x0f, 0x23, 0xc8], "mov dr1, rax"); - test_display(&[0x44, 0x0f, 0x23, 0xcf], "mov dr9, rdi"); + test_invalid(&[0x44, 0x0f, 0x23, 0xcf]); test_display(&[0x0f, 0x23, 0xcf], "mov dr1, rdi"); test_display(&[0x0f, 0x30], "wrmsr"); test_display(&[0x0f, 0x31], "rdtsc"); @@ -1567,6 +1619,9 @@ fn prefixed_0f() { test_display(&[0x0f, 0x35], "sysexit"); test_invalid(&[0x0f, 0x36]); test_display(&[0x0f, 0x37], "getsec"); + test_invalid(&[0x66, 0x0f, 0x37]); + test_invalid(&[0xf2, 0x0f, 0x37]); + test_invalid(&[0xf3, 0x0f, 0x37]); test_display(&[0x0f, 0x60, 0x00], "punpcklbw mm0, [rax]"); test_display(&[0x0f, 0x60, 0xc2], "punpcklbw mm0, mm2"); test_display(&[0x0f, 0x61, 0x00], "punpcklwd mm0, [rax]"); @@ -1637,14 +1692,14 @@ fn prefixed_660f() { test_display(&[0x66, 0x4b, 0x0f, 0x10, 0xc0], "movupd xmm0, xmm8"); test_display(&[0x66, 0x4c, 0x0f, 0x10, 0xc0], "movupd xmm8, xmm0"); test_display(&[0x66, 0x4d, 0x0f, 0x10, 0xc0], "movupd xmm8, xmm8"); - test_display(&[0xf2, 0x66, 0x66, 0x4d, 0x0f, 0x10, 0xc0], "movupd xmm8, xmm8"); + test_display(&[0xf2, 0x66, 0x66, 0x4d, 0x0f, 0x10, 0xc0], "movsd xmm8, xmm8"); } #[test] fn prefixed_f20f() { test_invalid(&[0xf2, 0x0f, 0x16, 0xcf]); test_invalid(&[0xf2, 0x4d, 0x0f, 0x16, 0xcf]); - test_display(&[0x40, 0x66, 0xf2, 0x66, 0x4d, 0x0f, 0x16, 0xcf], "movlhps xmm9, xmm15"); + test_invalid(&[0x40, 0x66, 0xf2, 0x66, 0x4d, 0x0f, 0x16, 0xcf]); } #[test] @@ -1697,6 +1752,11 @@ fn test_svm() { fn test_movbe() { test_display(&[0x0f, 0x38, 0xf0, 0x06], "movbe eax, [rsi]"); test_display(&[0x4f, 0x0f, 0x38, 0xf0, 0x06], "movbe r8, [r14]"); + test_invalid(&[0x4f, 0x0f, 0x38, 0xf0, 0xc6]); + test_display(&[0x0f, 0x38, 0xf1, 0x06], "movbe [rsi], eax"); + test_display(&[0x4f, 0x0f, 0x38, 0xf1, 0x06], "movbe [r14], r8"); + test_display(&[0x66, 0x0f, 0x38, 0xf1, 0x06], "movbe [rsi], ax"); + test_invalid(&[0x66, 0x0f, 0x38, 0xf1, 0xc6]); } #[test] @@ -1721,6 +1781,7 @@ fn test_rand() { #[test] fn test_sha() { test_display(&[0x0f, 0x3a, 0xcc, 0x12, 0x40], "sha1rnds4 xmm2, [rdx], 0x40"); + test_display(&[0x0f, 0x3a, 0xcc, 0x12, 0xff], "sha1rnds4 xmm2, [rdx], 0xff"); test_display(&[0x0f, 0x38, 0xc8, 0x12], "sha1nexte xmm2, [rdx]"); test_display(&[0x0f, 0x38, 0xc9, 0x12], "sha1msg1 xmm2, [rdx]"); test_display(&[0x0f, 0x38, 0xca, 0x12], "sha1msg2 xmm2, [rdx]"); @@ -1754,7 +1815,13 @@ fn test_rdpid() { #[test] fn test_cmpxchg8b() { test_display(&[0x0f, 0xc7, 0x0f], "cmpxchg8b [rdi]"); + test_display(&[0xf2, 0x0f, 0xc7, 0x0f], "cmpxchg8b [rdi]"); + test_display(&[0xf3, 0x0f, 0xc7, 0x0f], "cmpxchg8b [rdi]"); + test_display(&[0x66, 0x0f, 0xc7, 0x0f], "cmpxchg8b [rdi]"); test_display(&[0x4f, 0x0f, 0xc7, 0x0f], "cmpxchg16b [r15]"); + test_display(&[0xf2, 0x4f, 0x0f, 0xc7, 0x0f], "cmpxchg16b [r15]"); + test_display(&[0xf3, 0x4f, 0x0f, 0xc7, 0x0f], "cmpxchg16b [r15]"); + test_display(&[0x66, 0x4f, 0x0f, 0xc7, 0x0f], "cmpxchg16b [r15]"); } #[test] @@ -2142,27 +2209,28 @@ fn test_mishegos_finds() { test_display(&[0x65, 0x67, 0x65, 0x65, 0x0f, 0x0e], "femms"); test_display(&[0x26, 0x66, 0x67, 0x41, 0x0f, 0x38, 0xdf, 0xe4], "aesdeclast xmm4, xmm12"); test_display(&[0x65, 0x66, 0x66, 0x64, 0x48, 0x0f, 0x38, 0xdb, 0x0f], "aesimc xmm1, fs:[rdi]"); + test_invalid(&[0xf3, 0xf2, 0x41, 0x0f, 0xae, 0x8f, 0x54, 0x3c, 0x58, 0xb7]); /* test_display(&[652e662e0f3814ff], "blendvps"); test_display(&[66666565450f3acf2b4b], "gf2 "); - test_display(&[2e64f2f3400f38fbf8], "encodekey256"); */ // might just be yax trying to do a f20f decode when it should not be f2 // impossible instruction if operands could be read: lock is illegal here. // test_display(&[f06565f2640f16], "???"); // test_display(&[0x0f, 0x38, 0xf6, 0x8c, 0x98, 0x4d, 0x33, 0xf5, 0xd3, ], "wrssd"); - test_display(&[0x26, 0x36, 0x0f, 0x0f, 0x70, 0xfb, 0x0c], "pi2fw"); + test_display(&[0x26, 0x36, 0x0f, 0x0f, 0x70, 0xfb, 0x0c], "pi2fw mm6, [rax - 0x5]"); test_display(&[0x0f, 0xc7, 0x0f], "cmpxchg8b [rdi]"); test_display(&[0x4f, 0x0f, 0xc7, 0x0f], "cmpxchg16b [r15]"); test_display(&[0x66, 0x3e, 0x26, 0x2e, 0x2e, 0x0f, 0x38, 0x2a, 0x2b, ], "movntdqa xmm5, [rbx]"); test_display(&[0x66, 0x2e, 0x67, 0x0f, 0x3a, 0x0d, 0xb8, 0xf0, 0x2f, 0x7c, 0xf0, 0x63, ], "blendpd xmm7, [eax - 0xf83d010], 0x63"); - test_display(&[0x66, 0x66, 0x64, 0x3e, 0x0f, 0x38, 0x23, 0x9d, 0x69, 0x0f, 0xa8, 0x2d, ], "pmovsxwd xmm3, [rbp + 0x2da80f69]"); + test_display(&[0x66, 0x66, 0x64, 0x3e, 0x0f, 0x38, 0x23, 0x9d, 0x69, 0x0f, 0xa8, 0x2d, ], "pmovsxwd xmm3, fs:[rbp + 0x2da80f69]"); test_display(&[0x2e, 0x66, 0x26, 0x64, 0x49, 0x0f, 0x3a, 0x21, 0x0b, 0xb1, ], "insertps xmm1, fs:[r11], -0x4f"); test_display(&[0x66, 0x26, 0x45, 0x0f, 0x3a, 0x42, 0x96, 0x74, 0x29, 0x96, 0xf9, 0x6a], "mpsadbw xmm10, [r14 - 0x669d68c], 0x6a"); test_display(&[0x67, 0x26, 0x66, 0x65, 0x0f, 0x38, 0x3f, 0x9d, 0xcc, 0x03, 0xb3, 0xfa], "pmaxud xmm3, gs:[ebp - 0x54cfc34]"); test_display(&[0x36, 0x36, 0x2e, 0x0f, 0x38, 0xf9, 0x55, 0x3e, ], "movdiri [rbp + 0x3e], edx"); test_display(&[0x36, 0x26, 0x66, 0x0f, 0x38, 0xf8, 0xad, 0x0b, 0x08, 0x29, 0x07], "movdir64b rbp, [rbp + 0x729080b]"); + test_invalid(&[0x66, 0x2e, 0x64, 0x66, 0x46, 0x0f, 0x38, 0xf8, 0xe2]); test_display(&[0x36, 0x26, 0x66, 0x67, 0x0f, 0x38, 0xf8, 0xad, 0x0b, 0x08, 0x29, 0x07], "movdir64b ebp, [ebp + 0x729080b]"); test_display(&[0x67, 0x66, 0x65, 0x3e, 0x0f, 0x6d, 0xd1], "punpckhqdq xmm2, xmm1"); test_display(&[0x2e, 0x66, 0x40, 0x0f, 0x3a, 0x0d, 0x40, 0x2d, 0x57], "blendpd xmm0, [rax + 0x2d], 0x57"); @@ -2172,10 +2240,11 @@ fn test_mishegos_finds() { test_display(&[0x2e, 0x36, 0x47, 0x0f, 0x18, 0xe7], "nop r15d"); test_display(&[0x65, 0xf0, 0x87, 0x0f], "lock xchg gs:[rdi], ecx"); test_display(&[0x66, 0x4e, 0x0f, 0x3a, 0x44, 0x88, 0xb3, 0xad, 0x26, 0x35, 0x75], "pclmulqdq xmm9, [rax + 0x3526adb3], 0x75"); - test_display(&[0x4c, 0x0f, 0xff, 0x6b, 0xac], "ud0 r13, [rbx - 0x54]"); + test_display(&[0x4c, 0x0f, 0xff, 0x6b, 0xac], "ud0 r13d, [rbx - 0x54]"); test_display(&[0xf2, 0xf2, 0x2e, 0x36, 0x47, 0x0f, 0x38, 0xf8, 0x83, 0x09, 0x1c, 0x9d, 0x3f], "enqcmd r8d, [r11 + 0x3f9d1c09]"); test_display(&[0x3e, 0x64, 0xf3, 0x64, 0x0f, 0x38, 0xf8, 0x72, 0x54], "enqcmds esi, fs:[rdx + 0x54]"); + test_invalid(&[0xf3, 0x0f, 0x38, 0xf8, 0xf3]); test_display(&[0xf3, 0x64, 0x2e, 0x65, 0x0f, 0x38, 0xdc, 0xe8], "loadiwkey xmm5, xmm0"); @@ -2198,18 +2267,44 @@ fn test_cet() { // clrssbsy f3 0f ae /6 // endbr64 f3 0f ae fa // endbr32 f3 0f ae fb + test_display(&[0x3e, 0x4f, 0x0f, 0x38, 0xf6, 0x23], "wrss [r11], r12"); + test_display(&[0x66, 0x0f, 0x38, 0xf5, 0x47, 0xe9], "wruss [rdi - 0x17], eax"); + test_invalid(&[0x0f, 0x38, 0xf5, 0x47, 0xe9]); + test_invalid(&[0x66, 0x3e, 0x65, 0x3e, 0x0f, 0x38, 0xf5, 0xf0]); } #[test] fn test_sse4a() { - // really gotta get some test cases for this + fn test_instr(bytes: &[u8], text: &'static str) { + test_display_under(&InstDecoder::minimal().with_sse4a(), bytes, text); + test_display_under(&InstDecoder::default(), bytes, text); + test_invalid_under(&InstDecoder::minimal(), bytes); + } + + test_instr(&[0xf2, 0x0f, 0x2b, 0x06], "movntsd [rsi], xmm0"); + test_invalid(&[0xf2, 0x0f, 0x2b, 0xc6]); + test_instr(&[0xf3, 0x0f, 0x2b, 0x06], "movntss [rsi], xmm0"); + test_invalid(&[0xf3, 0x0f, 0xba, 0xc6]); + test_instr(&[0x66, 0xf2, 0x0f, 0x79, 0xcf], "insertq xmm1, xmm7"); + test_invalid(&[0x66, 0xf2, 0x0f, 0x79, 0x0f]); + test_instr(&[0xf2, 0x0f, 0x79, 0xcf], "insertq xmm1, xmm7"); + test_instr(&[0xf2, 0x0f, 0x78, 0xf1, 0x4e, 0x76], "insertq xmm6, xmm1, 0x4e, 0x76"); + test_invalid(&[0xf2, 0x0f, 0x79, 0x0f]); + test_instr(&[0x66, 0x0f, 0x79, 0xcf], "extrq xmm1, xmm7"); + test_invalid(&[0x66, 0x0f, 0x79, 0x0f]); + test_instr(&[0x66, 0x0f, 0x78, 0xc1, 0x4e, 0x76], "extrq xmm1, 0x4e, 0x76"); + test_invalid(&[0x66, 0x0f, 0x78, 0xc9, 0x4e, 0x76]); } #[test] fn test_3dnow() { + test_display(&[0x0f, 0x0f, 0xe0, 0x8a], "pfnacc mm4, mm0"); + test_display(&[0x0f, 0x0f, 0x38, 0x8e], "pfpnacc mm7, [rax]"); test_display(&[0x65, 0x67, 0x65, 0x65, 0x0f, 0x0e], "femms"); test_display(&[0x3e, 0xf3, 0x2e, 0xf2, 0x0f, 0x0f, 0x64, 0x93, 0x93, 0xa4], "pfmax mm4, [rbx + rdx * 4 - 0x6d]"); - test_display(&[0x26, 0x36, 0x0f, 0x0f, 0x70, 0xfb, 0x0c], "pi2fw"); + test_display(&[0x26, 0x36, 0x0f, 0x0f, 0x70, 0xfb, 0x0c], "pi2fw mm6, [rax - 0x5]"); + test_display(&[0x66, 0x0f, 0x0f, 0xc6, 0xb7], "pmulhrw mm0, mm6"); + test_display(&[0x0f, 0x0f, 0xc6, 0xb7], "pmulhrw mm0, mm6"); } // first appeared in tremont @@ -2223,6 +2318,8 @@ fn test_direct_stores() { #[test] fn test_key_locker() { test_display(&[0xf3, 0x64, 0x2e, 0x65, 0x0f, 0x38, 0xdc, 0xe8], "loadiwkey xmm5, xmm0"); + test_display(&[0xf3, 0x0f, 0x38, 0xfa, 0xde], "encodekey128 ebx, esi"); + test_display(&[0xf3, 0x0f, 0x38, 0xfb, 0xde], "encodekey256 ebx, esi"); } // started shipping in sapphire rapids @@ -2231,3 +2328,10 @@ fn test_enqcmd() { test_display(&[0xf2, 0xf2, 0x2e, 0x36, 0x47, 0x0f, 0x38, 0xf8, 0x83, 0x09, 0x1c, 0x9d, 0x3f], "enqcmd r8d, [r11 + 0x3f9d1c09]"); test_display(&[0x3e, 0x64, 0xf3, 0x64, 0x0f, 0x38, 0xf8, 0x72, 0x54], "enqcmds esi, fs:[rdx + 0x54]"); } + +#[test] +fn test_gfni() { + test_display(&[0x3e, 0x64, 0x64, 0x66, 0x4e, 0x0f, 0x3a, 0xcf, 0xba, 0x13, 0x23, 0x04, 0xba, 0x6b], "gf2p8affineinvqb xmm15, fs:[rdx - 0x45fbdced], 0x6b"); + test_display(&[0x66, 0x36, 0x0f, 0x3a, 0xce, 0x8c, 0x56, 0x9e, 0x82, 0xd1, 0xbe, 0xad], "gf2p8affineqb xmm1, [rsi + rdx * 2 - 0x412e7d62], 0xad"); + test_display(&[0x66, 0x4e, 0x0f, 0x38, 0xcf, 0x1c, 0x54], "gf2p8mulb xmm11, [rsp + r10 * 2]"); +} |