diff options
| author | iximeow <me@iximeow.net> | 2021-06-11 17:11:20 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2021-06-11 22:02:40 -0700 | 
| commit | 27aed160a26583990e4f8c26c58327e985e8c9bc (patch) | |
| tree | 7ef74645ceccce463ac2304192f8daba21a3982f /src | |
| parent | c1d0891e2c058278f2d26691d0193e02f73a039e (diff) | |
add extensive avx and initial avx2 tests, fix several bugs and missing instructions
Diffstat (limited to 'src')
| -rw-r--r-- | src/long_mode/display.rs | 581 | ||||
| -rw-r--r-- | src/long_mode/mod.rs | 307 | ||||
| -rw-r--r-- | src/long_mode/vex.rs | 815 | 
3 files changed, 1575 insertions, 128 deletions
| diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index f84ff7a..02d8382 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -664,6 +664,7 @@ const MNEMONICS: &[&'static str] = &[      "xorpd",      "vmovddup",      "vpshuflw", +    "vpshufhw",      "vhaddps",      "vhsubps",      "vaddsubps", @@ -835,6 +836,7 @@ const MNEMONICS: &[&'static str] = &[      "vpabsd",      "vpabsw",      "vpackssdw", +    "vpackusdw",      "vpacksswb",      "vpackuswb",      "vpaddb", @@ -846,12 +848,12 @@ const MNEMONICS: &[&'static str] = &[      "vpaddusw",      "vpaddw",      "vpalignr", -    "vandps",      "vandpd", -    "vorps", +    "vandps",      "vorpd", -    "vandnps", +    "vorps",      "vandnpd", +    "vandnps",      "vpand",      "vpandn",      "vpavgb", @@ -872,6 +874,8 @@ const MNEMONICS: &[&'static str] = &[      "vpcmpgtd",      "vpcmpgtq",      "vpcmpgtw", +    "vpcmpestri", +    "vpcmpestrm",      "vpcmpistri",      "vpcmpistrm",      "vperm2f128", @@ -893,7 +897,7 @@ const MNEMONICS: &[&'static str] = &[      "vphaddd",      "vphaddsw",      "vphaddw", -    "vphaddubsw", +    "vpmaddubsw",      "vphminposuw",      "vphsubd",      "vphsubsw", @@ -911,8 +915,11 @@ const MNEMONICS: &[&'static str] = &[      "vpmaxub",      "vpmaxuw",      "vpmaxud", +    "vpminsb",      "vpminsw",      "vpminsd", +    "vpminub", +    "vpminuw",      "vpminud",      "vpmovmskb",      "vpmovsxbd", @@ -1001,6 +1008,9 @@ const MNEMONICS: &[&'static str] = &[      "vxorpd",      "vxorps",      "vzeroupper", +    "vzeroall", +    "vldmxcsr", +    "vstmxcsr",      "pclmulqdq",      "aeskeygenassist",      "aesimc", @@ -1315,6 +1325,287 @@ const MNEMONICS: &[&'static str] = &[      // TSXLDTRK      "xsusldtrk",      "xresldtrk", + +    // AVX512F +    "valignd", +    "valignq", +    "vblendmpd", +    "vblendmps", +    "vcompresspd", +    "vcompressps", +    "vcvtpd2udq", +    "vcvttpd2udq", +    "vcvtps2udq", +    "vcvttps2udq", +    "vcvtqq2pd", +    "vcvtqq2ps", +    "vcvtsd2usi", +    "vcvttsd2usi", +    "vcvtss2usi", +    "vcvttss2usi", +    "vcvtudq2pd", +    "vcvtudq2ps", +    "vcvtusi2usd", +    "vcvtusi2uss", +    "vexpandpd", +    "vexpandps", +    "vextractf32x4", +    "vextractf64x4", +    "vextracti32x4", +    "vextracti64x4", +    "vfixupimmpd", +    "vfixupimmps", +    "vfixupimmsd", +    "vfixupimmss", +    "vgetexppd", +    "vgetexpps", +    "vgetexpsd", +    "vgetexpss", +    "vgetmantpd", +    "vgetmantps", +    "vgetmantsd", +    "vgetmantss", +    "vinsertf32x4", +    "vinsertf64x4", +    "vmovdqa32", +    "vmovdqa64", +    "vmovdqu32", +    "vmovdqu64", +    "vpblendmd", +    "vpblendmq", +    "vpcmpd", +    "vpcmpud", +    "vpcmpq", +    "vpcmpuq", +    "vpcompressq", +    "vpcompressd", +    "vpermi2d", +    "vpermi2q", +    "vpermi2pd", +    "vpermi2ps", +    "vpermt2d", +    "vpermt2q", +    "vpermt2pd", +    "vpermt2ps", +    "vpmaxsq", +    "vpmaxuq", +    "vpminsq", +    "vpminuq", +    "vpmovsqb", +    "vpmovusqb", +    "vpmovsqw", +    "vpmovusqw", +    "vpmovsqd", +    "vpmovusqd", +    "vpmovsdb", +    "vpmovusdb", +    "vpmovsdw", +    "vpmovusdw", +    "vprold", +    "vprolq", +    "vprolvd", +    "vprolvq", +    "vprord", +    "vprorq", +    "vprorrd", +    "vprorrq", +    "vpscatterdd", +    "vpscatterdq", +    "vpscatterqd", +    "vpscatterqq", +    "vpsraq", +    "vpsravq", +    "vptestnmd", +    "vptestnmq", +    "vpterlogd", +    "vpterlogq", +    "vptestmd", +    "vptestmq", +    "vrcp14pd", +    "vrcp14ps", +    "vrcp14sd", +    "vrcp14ss", +    "vrndscalepd", +    "vrndscaleps", +    "vrndcsalesd", +    "vrndscaless", +    "vrsqrt14pd", +    "vrsqrt14ps", +    "vrsqrt14sd", +    "vrsqrt14ss", +    "vscaledpd", +    "vscaledps", +    "vscaledsd", +    "vscaledss", +    "vscatterdd", +    "vscatterdq", +    "vscatterqd", +    "vscatterqq", +    "vshuff32x4", +    "vshuff64x2", +    "vshufi32x4", +    "vshufi64x2", + +    // AVX512DQ +    "vcvttpd2qq", +    "vcvtpd2qq", +    "vcvttpd2uqq", +    "vcvtpd2uqq", +    "vcvttps2qq", +    "vcvtps2qq", +    "vcvttps2uqq", +    "vcvtps2uqq", +    "vcvtuqq2pd", +    "vcvtuqq2ps", +    "vextractf64x2", +    "vextracti64x2", +    "vfpclasspd", +    "vfpclassps", +    "vfpclasssd", +    "vfpclassss", +    "vinsertf64x2", +    "vinserti64x2", +    "vpmovm2d", +    "vpmovm2q", +    "vpmovb2d", +    "vpmovq2m", +    "vpmulllq", +    "vrangepd", +    "vrangeps", +    "vrangesd", +    "vrangess", +    "vreducepd", +    "vreduceps", +    "vreducesd", +    "vreducess", + +    // AVX512BW +    "vdbpsadbw", +    "vmovdqu8", +    "vmovdqu16", +    "vpblendmb", +    "vpblendmw", +    "vpcmpb", +    "vpcmpub", +    "vpcmpw", +    "vpcmpuw", +    "vpermw", +    "vpermi2b", +    "vpermi2w", +    "vpmovm2b", +    "vpmovm2w", +    "vpmovb2m", +    "vpmovw2m", +    "vpmovswb", +    "vpmovuswb", +    "vpsllvw", +    "vpsravw", +    "vpsrlvw", +    "vptestnmb", +    "vptestnmw", +    "vptestmb", +    "vptestmw", + +    // AVX512CD +    "vpbroadcastm", +    "vpconflictd", +    "vpconflictq", +    "vplzcntd", +    "vplzcntq", + +    "kunpckbw", +    "kunpckwd", +    "kunpckdq", + +    "kaddb", +    "kandb", +    "kandnb", +    "kmovb", +    "knotb", +    "korb", +    "kortestb", +    "kshiftlb", +    "kshiftrb", +    "ktestb", +    "kxnorb", +    "kxorb", +    "kaddw", +    "kandw", +    "kandnw", +    "kmovw", +    "knotw", +    "korw", +    "kortestw", +    "kshiftlw", +    "kshiftrw", +    "ktestw", +    "kxnorw", +    "kxorw", +    "kaddd", +    "kandd", +    "kandnd", +    "kmovd", +    "knotd", +    "kord", +    "kortestd", +    "kshiftld", +    "kshiftrd", +    "ktestd", +    "kxnord", +    "kxord", +    "kaddq", +    "kandq", +    "kandnq", +    "kmovq", +    "knotq", +    "korq", +    "kortestq", +    "kshiftlq", +    "kshiftrq", +    "ktestq", +    "kxnorq", +    "kxorq", + +    // AVX512ER +    "vexp2pd", +    "vexp2ps", +    "vexp2sd", +    "vexp2ss", +    "vrcp28pd", +    "vrcp28ps", +    "vrcp28sd", +    "vrcp28ss", +    "vrsqrt28pd", +    "vrsqrt28ps", +    "vrsqrt28sd", +    "vrsqrt28ss", + +    // AVX512PF +    "vgatherpf0dpd", +    "vgatherpf0dps", +    "vgatherpf0qpd", +    "vgatherpf0qps", +    "vgatherpf1dpd", +    "vgatherpf1dps", +    "vgatherpf1qpd", +    "vgatherpf1qps", +    "vscatterpf0dpd", +    "vscatterpf0dps", +    "vscatterpf0qpd", +    "vscatterpf0qps", +    "vscatterpf1dpd", +    "vscatterpf1dps", +    "vscatterpf1qpd", +    "vscatterpf1qps", + +    // MPX +    "bndmk", +    "bndcl", +    "bndcu", +    "bndcn", +    "bndmov", +    "bndldx", +    "bndstx",  ];  impl Opcode { @@ -1325,6 +1616,11 @@ impl Opcode {      }  } +    // AVX512CD + + +    // MPX +  impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {      fn colorize(&self, colors: &Y, out: &mut T) -> fmt::Result {          match self { @@ -1408,6 +1704,7 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VMULPS |              Opcode::VMULSD |              Opcode::VMULSS | +            Opcode::VPMULLLQ |              Opcode::VPABSB |              Opcode::VPABSD |              Opcode::VPABSW | @@ -1451,6 +1748,34 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VPSUBW |              Opcode::VROUNDPD |              Opcode::VROUNDPS | +            Opcode::VEXP2PD | +            Opcode::VEXP2PS | +            Opcode::VEXP2SD | +            Opcode::VEXP2SS | +            Opcode::VRCP28PD | +            Opcode::VRCP28PS | +            Opcode::VRCP28SD | +            Opcode::VRCP28SS | +            Opcode::VRCP14PD | +            Opcode::VRCP14PS | +            Opcode::VRCP14SD | +            Opcode::VRCP14SS | +            Opcode::VRNDSCALEPD | +            Opcode::VRNDSCALEPS | +            Opcode::VRNDCSALESD | +            Opcode::VRNDSCALESS | +            Opcode::VRSQRT14PD | +            Opcode::VRSQRT14PS | +            Opcode::VRSQRT14SD | +            Opcode::VRSQRT14SS | +            Opcode::VSCALEDPD | +            Opcode::VSCALEDPS | +            Opcode::VSCALEDSD | +            Opcode::VSCALEDSS | +            Opcode::VRSQRT28PD | +            Opcode::VRSQRT28PS | +            Opcode::VRSQRT28SD | +            Opcode::VRSQRT28SS |              Opcode::VRSQRTPS |              Opcode::VSQRTPD |              Opcode::VSQRTPS | @@ -1470,13 +1795,14 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VSQRTSS |              Opcode::VPSADBW |              Opcode::VMPSADBW | +            Opcode::VDBPSADBW |              Opcode::VPHADDD |              Opcode::VPHADDSW |              Opcode::VPHADDW |              Opcode::VPHSUBD |              Opcode::VPHSUBSW |              Opcode::VPHSUBW | -            Opcode::VPHADDUBSW | +            Opcode::VPMADDUBSW |              Opcode::VPMADDWD |              Opcode::VDPPD |              Opcode::VDPPS | @@ -1499,6 +1825,19 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VPSLLVD |              Opcode::VPSLLVQ |              Opcode::VPSLLW | +            Opcode::VPROLD | +            Opcode::VPROLQ | +            Opcode::VPROLVD | +            Opcode::VPROLVQ | +            Opcode::VPRORD | +            Opcode::VPRORQ | +            Opcode::VPRORRD | +            Opcode::VPRORRQ | +            Opcode::VPSLLVW | +            Opcode::VPSRAQ | +            Opcode::VPSRAVQ | +            Opcode::VPSRAVW | +            Opcode::VPSRLVW |              Opcode::VPSRAD |              Opcode::VPSRAVD |              Opcode::VPSRAW | @@ -1584,6 +1923,8 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::SUB |              Opcode::POPCNT |              Opcode::LZCNT | +            Opcode::VPLZCNTD | +            Opcode::VPLZCNTQ |              Opcode::BT |              Opcode::BTS |              Opcode::BTR | @@ -1702,6 +2043,42 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::FXTRACT |              Opcode::FYL2X |              Opcode::FYL2XP1 | +            Opcode::KADDB | +            Opcode::KANDB | +            Opcode::KANDNB | +            Opcode::KNOTB | +            Opcode::KORB | +            Opcode::KSHIFTLB | +            Opcode::KSHIFTRB | +            Opcode::KXNORB | +            Opcode::KXORB | +            Opcode::KADDW | +            Opcode::KANDW | +            Opcode::KANDNW | +            Opcode::KNOTW | +            Opcode::KORW | +            Opcode::KSHIFTLW | +            Opcode::KSHIFTRW | +            Opcode::KXNORW | +            Opcode::KXORW | +            Opcode::KADDD | +            Opcode::KANDD | +            Opcode::KANDND | +            Opcode::KNOTD | +            Opcode::KORD | +            Opcode::KSHIFTLD | +            Opcode::KSHIFTRD | +            Opcode::KXNORD | +            Opcode::KXORD | +            Opcode::KADDQ | +            Opcode::KANDQ | +            Opcode::KANDNQ | +            Opcode::KNOTQ | +            Opcode::KORQ | +            Opcode::KSHIFTLQ | +            Opcode::KSHIFTRQ | +            Opcode::KXNORQ | +            Opcode::KXORQ |              Opcode::IMUL => { write!(out, "{}", colors.arithmetic_op(self)) }              Opcode::POPF |              Opcode::PUSHF | @@ -1778,12 +2155,43 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VCVTSS2SI |              Opcode::VCVTTSD2SI |              Opcode::VCVTTSS2SI | +            Opcode::VCVTPD2UDQ | +            Opcode::VCVTTPD2UDQ | +            Opcode::VCVTPS2UDQ | +            Opcode::VCVTTPS2UDQ | +            Opcode::VCVTQQ2PD | +            Opcode::VCVTQQ2PS | +            Opcode::VCVTSD2USI | +            Opcode::VCVTTSD2USI | +            Opcode::VCVTSS2USI | +            Opcode::VCVTTSS2USI | +            Opcode::VCVTUDQ2PD | +            Opcode::VCVTUDQ2PS | +            Opcode::VCVTUSI2USD | +            Opcode::VCVTUSI2USS | +            Opcode::VCVTTPD2QQ | +            Opcode::VCVTPD2QQ | +            Opcode::VCVTTPD2UQQ | +            Opcode::VCVTPD2UQQ | +            Opcode::VCVTTPS2QQ | +            Opcode::VCVTPS2QQ | +            Opcode::VCVTTPS2UQQ | +            Opcode::VCVTPS2UQQ | +            Opcode::VCVTUQQ2PD | +            Opcode::VCVTUQQ2PS |              Opcode::VMOVDDUP |              Opcode::VPSHUFLW | +            Opcode::VPSHUFHW | +            Opcode::VBLENDMPD | +            Opcode::VBLENDMPS | +            Opcode::VPBLENDMD | +            Opcode::VPBLENDMQ |              Opcode::VBLENDPD |              Opcode::VBLENDPS |              Opcode::VBLENDVPD |              Opcode::VBLENDVPS | +            Opcode::VPBLENDMB | +            Opcode::VPBLENDMW |              Opcode::PBLENDVB |              Opcode::PBLENDW |              Opcode::BLENDPD | @@ -1795,6 +2203,7 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VBROADCASTI128 |              Opcode::VBROADCASTSD |              Opcode::VBROADCASTSS | +            Opcode::VPBROADCASTM |              Opcode::VEXTRACTF128 |              Opcode::VEXTRACTI128 |              Opcode::VEXTRACTPS | @@ -1803,10 +2212,48 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VGATHERDPS |              Opcode::VGATHERQPD |              Opcode::VGATHERQPS | +            Opcode::VGATHERPF0DPD | +            Opcode::VGATHERPF0DPS | +            Opcode::VGATHERPF0QPD | +            Opcode::VGATHERPF0QPS | +            Opcode::VGATHERPF1DPD | +            Opcode::VGATHERPF1DPS | +            Opcode::VGATHERPF1QPD | +            Opcode::VGATHERPF1QPS | +            Opcode::VSCATTERDD | +            Opcode::VSCATTERDQ | +            Opcode::VSCATTERQD | +            Opcode::VSCATTERQQ | +            Opcode::VPSCATTERDD | +            Opcode::VPSCATTERDQ | +            Opcode::VPSCATTERQD | +            Opcode::VPSCATTERQQ | +            Opcode::VSCATTERPF0DPD | +            Opcode::VSCATTERPF0DPS | +            Opcode::VSCATTERPF0QPD | +            Opcode::VSCATTERPF0QPS | +            Opcode::VSCATTERPF1DPD | +            Opcode::VSCATTERPF1DPS | +            Opcode::VSCATTERPF1QPD | +            Opcode::VSCATTERPF1QPS |              Opcode::VINSERTF128 |              Opcode::VINSERTI128 |              Opcode::VINSERTPS |              Opcode::INSERTPS | +            Opcode::VEXTRACTF32X4 | +            Opcode::VEXTRACTF64X2 | +            Opcode::VEXTRACTF64X4 | +            Opcode::VEXTRACTI32X4 | +            Opcode::VEXTRACTI64X2 | +            Opcode::VEXTRACTI64X4 | +            Opcode::VINSERTF32X4 | +            Opcode::VINSERTF64X2 | +            Opcode::VINSERTF64X4 | +            Opcode::VINSERTI64X2 | +            Opcode::VSHUFF32X4 | +            Opcode::VSHUFF64X2 | +            Opcode::VSHUFI32X4 | +            Opcode::VSHUFI64X2 |              Opcode::VMASKMOVDQU |              Opcode::VMASKMOVPD |              Opcode::VMASKMOVPS | @@ -1837,6 +2284,32 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VMOVUPS |              Opcode::VMOVSD |              Opcode::VMOVSS | +            Opcode::VMOVDQA32 | +            Opcode::VMOVDQA64 | +            Opcode::VMOVDQU32 | +            Opcode::VMOVDQU64 | +            Opcode::VPMOVM2B | +            Opcode::VPMOVM2W | +            Opcode::VPMOVB2M | +            Opcode::VPMOVW2M | +            Opcode::VPMOVSWB | +            Opcode::VPMOVUSWB | +            Opcode::VPMOVSQB | +            Opcode::VPMOVUSQB | +            Opcode::VPMOVSQW | +            Opcode::VPMOVUSQW | +            Opcode::VPMOVSQD | +            Opcode::VPMOVUSQD | +            Opcode::VPMOVSDB | +            Opcode::VPMOVUSDB | +            Opcode::VPMOVSDW | +            Opcode::VPMOVUSDW | +            Opcode::VPMOVM2D | +            Opcode::VPMOVM2Q | +            Opcode::VPMOVB2D | +            Opcode::VPMOVQ2M | +            Opcode::VMOVDQU8 | +            Opcode::VMOVDQU16 |              Opcode::VPBLENDD |              Opcode::VPBLENDVB | @@ -1875,6 +2348,9 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::PMOVZXDQ |              Opcode::PMOVZXWD |              Opcode::PMOVZXWQ | +            Opcode::KUNPCKBW | +            Opcode::KUNPCKWD | +            Opcode::KUNPCKDQ |              Opcode::VUNPCKHPD |              Opcode::VUNPCKHPS |              Opcode::VUNPCKLPD | @@ -1890,9 +2366,12 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VSHUFPD |              Opcode::VSHUFPS |              Opcode::VPACKSSDW | +            Opcode::VPACKUSDW |              Opcode::PACKUSDW |              Opcode::VPACKSSWB |              Opcode::VPACKUSWB | +            Opcode::VALIGND | +            Opcode::VALIGNQ |              Opcode::VPALIGNR |              Opcode::PALIGNR |              Opcode::VPERM2F128 | @@ -1903,6 +2382,17 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VPERMPD |              Opcode::VPERMPS |              Opcode::VPERMQ | +            Opcode::VPERMI2D | +            Opcode::VPERMI2Q | +            Opcode::VPERMI2PD | +            Opcode::VPERMI2PS | +            Opcode::VPERMT2D | +            Opcode::VPERMT2Q | +            Opcode::VPERMT2PD | +            Opcode::VPERMT2PS | +            Opcode::VPERMI2B | +            Opcode::VPERMI2W | +            Opcode::VPERMW |              Opcode::VPEXTRB |              Opcode::VPEXTRD |              Opcode::VPEXTRQ | @@ -1921,11 +2411,34 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VPINSRW |              Opcode::VPMASKMOVD |              Opcode::VPMASKMOVQ | +            Opcode::VCOMPRESSPD | +            Opcode::VCOMPRESSPS | +            Opcode::VPCOMPRESSQ | +            Opcode::VPCOMPRESSD | +            Opcode::VEXPANDPD | +            Opcode::VEXPANDPS |              Opcode::VPSHUFB |              Opcode::VPSHUFD |              Opcode::VPHMINPOSUW |              Opcode::PHMINPOSUW |              Opcode::VZEROUPPER | +            Opcode::VZEROALL | +            Opcode::VFIXUPIMMPD | +            Opcode::VFIXUPIMMPS | +            Opcode::VFIXUPIMMSD | +            Opcode::VFIXUPIMMSS | +            Opcode::VREDUCEPD | +            Opcode::VREDUCEPS | +            Opcode::VREDUCESD | +            Opcode::VREDUCESS | +            Opcode::VGETEXPPD | +            Opcode::VGETEXPPS | +            Opcode::VGETEXPSD | +            Opcode::VGETEXPSS | +            Opcode::VGETMANTPD | +            Opcode::VGETMANTPS | +            Opcode::VGETMANTSD | +            Opcode::VGETMANTSS |              Opcode::VLDDQU |              Opcode::BSWAP |              Opcode::CVTDQ2PD | @@ -1993,6 +2506,11 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::SHUFPD |              Opcode::SHUFPS |              Opcode::PMOVMSKB | +            Opcode::KMOVB | +            Opcode::KMOVW | +            Opcode::KMOVD | +            Opcode::KMOVQ | +            Opcode::BNDMOV |              Opcode::LDDQU |              Opcode::CMC |              Opcode::CLC | @@ -2109,6 +2627,32 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VCOMISS |              Opcode::VUCOMISD |              Opcode::VUCOMISS | +            Opcode::KORTESTB | +            Opcode::KTESTB | +            Opcode::KORTESTW | +            Opcode::KTESTW | +            Opcode::KORTESTD | +            Opcode::KTESTD | +            Opcode::KORTESTQ | +            Opcode::KTESTQ | +            Opcode::VPTESTNMD | +            Opcode::VPTESTNMQ | +            Opcode::VPTERLOGD | +            Opcode::VPTERLOGQ | +            Opcode::VPTESTMD | +            Opcode::VPTESTMQ | +            Opcode::VPTESTNMB | +            Opcode::VPTESTNMW | +            Opcode::VPTESTMB | +            Opcode::VPTESTMW | +            Opcode::VPCMPD | +            Opcode::VPCMPUD | +            Opcode::VPCMPQ | +            Opcode::VPCMPUQ | +            Opcode::VPCMPB | +            Opcode::VPCMPUB | +            Opcode::VPCMPW | +            Opcode::VPCMPUW |              Opcode::VCMPPD |              Opcode::VCMPPS |              Opcode::VCMPSD | @@ -2117,6 +2661,10 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VMAXPS |              Opcode::VMAXSD |              Opcode::VMAXSS | +            Opcode::VPMAXSQ | +            Opcode::VPMAXUQ | +            Opcode::VPMINSQ | +            Opcode::VPMINUQ |              Opcode::VMINPD |              Opcode::VMINPS |              Opcode::VMINSD | @@ -2129,6 +2677,8 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VPCMPGTD |              Opcode::VPCMPGTQ |              Opcode::VPCMPGTW | +            Opcode::VPCMPESTRI | +            Opcode::VPCMPESTRM |              Opcode::VPCMPISTRI |              Opcode::VPCMPISTRM |              Opcode::VPMAXSB | @@ -2137,9 +2687,22 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::VPMAXUB |              Opcode::VPMAXUW |              Opcode::VPMAXUD | +            Opcode::VPMINSB |              Opcode::VPMINSW |              Opcode::VPMINSD | +            Opcode::VPMINUB | +            Opcode::VPMINUW |              Opcode::VPMINUD | +            Opcode::VFPCLASSPD | +            Opcode::VFPCLASSPS | +            Opcode::VFPCLASSSD | +            Opcode::VFPCLASSSS | +            Opcode::VRANGEPD | +            Opcode::VRANGEPS | +            Opcode::VRANGESD | +            Opcode::VRANGESS | +            Opcode::VPCONFLICTD | +            Opcode::VPCONFLICTQ |              Opcode::VPTEST |              Opcode::VTESTPD |              Opcode::VTESTPS | @@ -2220,6 +2783,8 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::FXRSTOR |              Opcode::LDMXCSR |              Opcode::STMXCSR | +            Opcode::VLDMXCSR | +            Opcode::VSTMXCSR |              Opcode::XSAVE |              Opcode::XSAVEC |              Opcode::XSAVES | @@ -2327,6 +2892,12 @@ impl <T: fmt::Write, Y: YaxColors> Colorize<T, Y> for Opcode {              Opcode::SENDUIPI |              Opcode::XSUSLDTRK |              Opcode::XRESLDTRK | +            Opcode::BNDMK | +            Opcode::BNDCL | +            Opcode::BNDCU | +            Opcode::BNDCN | +            Opcode::BNDLDX | +            Opcode::BNDSTX |              Opcode::LAR => { write!(out, "{}", colors.platform_op(self)) }              Opcode::CRC32 | diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 57508e4..88cae67 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -1293,6 +1293,7 @@ pub enum Opcode {      VMOVDDUP,      VPSHUFLW, +    VPSHUFHW,      VHADDPS,      VHSUBPS,      VADDSUBPS, @@ -1465,6 +1466,7 @@ pub enum Opcode {      VPABSD,      VPABSW,      VPACKSSDW, +    VPACKUSDW,      VPACKSSWB,      VPACKUSWB,      VPADDB, @@ -1502,6 +1504,8 @@ pub enum Opcode {      VPCMPGTD,      VPCMPGTQ,      VPCMPGTW, +    VPCMPESTRI, +    VPCMPESTRM,      VPCMPISTRI,      VPCMPISTRM,      VPERM2F128, @@ -1523,7 +1527,7 @@ pub enum Opcode {      VPHADDD,      VPHADDSW,      VPHADDW, -    VPHADDUBSW, +    VPMADDUBSW,      VPHMINPOSUW,      VPHSUBD,      VPHSUBSW, @@ -1541,8 +1545,11 @@ pub enum Opcode {      VPMAXUB,      VPMAXUW,      VPMAXUD, +    VPMINSB,      VPMINSW,      VPMINSD, +    VPMINUB, +    VPMINUW,      VPMINUD,      VPMOVMSKB,      VPMOVSXBD, @@ -1631,6 +1638,9 @@ pub enum Opcode {      VXORPD,      VXORPS,      VZEROUPPER, +    VZEROALL, +    VLDMXCSR, +    VSTMXCSR,      PCLMULQDQ,      AESKEYGENASSIST, @@ -1960,6 +1970,287 @@ pub enum Opcode {      // TSXLDTRK      XSUSLDTRK,      XRESLDTRK, + +    // AVX512F +    VALIGND, +    VALIGNQ, +    VBLENDMPD, +    VBLENDMPS, +    VCOMPRESSPD, +    VCOMPRESSPS, +    VCVTPD2UDQ, +    VCVTTPD2UDQ, +    VCVTPS2UDQ, +    VCVTTPS2UDQ, +    VCVTQQ2PD, +    VCVTQQ2PS, +    VCVTSD2USI, +    VCVTTSD2USI, +    VCVTSS2USI, +    VCVTTSS2USI, +    VCVTUDQ2PD, +    VCVTUDQ2PS, +    VCVTUSI2USD, +    VCVTUSI2USS, +    VEXPANDPD, +    VEXPANDPS, +    VEXTRACTF32X4, +    VEXTRACTF64X4, +    VEXTRACTI32X4, +    VEXTRACTI64X4, +    VFIXUPIMMPD, +    VFIXUPIMMPS, +    VFIXUPIMMSD, +    VFIXUPIMMSS, +    VGETEXPPD, +    VGETEXPPS, +    VGETEXPSD, +    VGETEXPSS, +    VGETMANTPD, +    VGETMANTPS, +    VGETMANTSD, +    VGETMANTSS, +    VINSERTF32X4, +    VINSERTF64X4, +    VMOVDQA32, +    VMOVDQA64, +    VMOVDQU32, +    VMOVDQU64, +    VPBLENDMD, +    VPBLENDMQ, +    VPCMPD, +    VPCMPUD, +    VPCMPQ, +    VPCMPUQ, +    VPCOMPRESSQ, +    VPCOMPRESSD, +    VPERMI2D, +    VPERMI2Q, +    VPERMI2PD, +    VPERMI2PS, +    VPERMT2D, +    VPERMT2Q, +    VPERMT2PD, +    VPERMT2PS, +    VPMAXSQ, +    VPMAXUQ, +    VPMINSQ, +    VPMINUQ, +    VPMOVSQB, +    VPMOVUSQB, +    VPMOVSQW, +    VPMOVUSQW, +    VPMOVSQD, +    VPMOVUSQD, +    VPMOVSDB, +    VPMOVUSDB, +    VPMOVSDW, +    VPMOVUSDW, +    VPROLD, +    VPROLQ, +    VPROLVD, +    VPROLVQ, +    VPRORD, +    VPRORQ, +    VPRORRD, +    VPRORRQ, +    VPSCATTERDD, +    VPSCATTERDQ, +    VPSCATTERQD, +    VPSCATTERQQ, +    VPSRAQ, +    VPSRAVQ, +    VPTESTNMD, +    VPTESTNMQ, +    VPTERLOGD, +    VPTERLOGQ, +    VPTESTMD, +    VPTESTMQ, +    VRCP14PD, +    VRCP14PS, +    VRCP14SD, +    VRCP14SS, +    VRNDSCALEPD, +    VRNDSCALEPS, +    VRNDCSALESD, +    VRNDSCALESS, +    VRSQRT14PD, +    VRSQRT14PS, +    VRSQRT14SD, +    VRSQRT14SS, +    VSCALEDPD, +    VSCALEDPS, +    VSCALEDSD, +    VSCALEDSS, +    VSCATTERDD, +    VSCATTERDQ, +    VSCATTERQD, +    VSCATTERQQ, +    VSHUFF32X4, +    VSHUFF64X2, +    VSHUFI32X4, +    VSHUFI64X2, + +    // AVX512DQ +    VCVTTPD2QQ, +    VCVTPD2QQ, +    VCVTTPD2UQQ, +    VCVTPD2UQQ, +    VCVTTPS2QQ, +    VCVTPS2QQ, +    VCVTTPS2UQQ, +    VCVTPS2UQQ, +    VCVTUQQ2PD, +    VCVTUQQ2PS, +    VEXTRACTF64X2, +    VEXTRACTI64X2, +    VFPCLASSPD, +    VFPCLASSPS, +    VFPCLASSSD, +    VFPCLASSSS, +    VINSERTF64X2, +    VINSERTI64X2, +    VPMOVM2D, +    VPMOVM2Q, +    VPMOVB2D, +    VPMOVQ2M, +    VPMULLLQ, +    VRANGEPD, +    VRANGEPS, +    VRANGESD, +    VRANGESS, +    VREDUCEPD, +    VREDUCEPS, +    VREDUCESD, +    VREDUCESS, + +    // AVX512BW +    VDBPSADBW, +    VMOVDQU8, +    VMOVDQU16, +    VPBLENDMB, +    VPBLENDMW, +    VPCMPB, +    VPCMPUB, +    VPCMPW, +    VPCMPUW, +    VPERMW, +    VPERMI2B, +    VPERMI2W, +    VPMOVM2B, +    VPMOVM2W, +    VPMOVB2M, +    VPMOVW2M, +    VPMOVSWB, +    VPMOVUSWB, +    VPSLLVW, +    VPSRAVW, +    VPSRLVW, +    VPTESTNMB, +    VPTESTNMW, +    VPTESTMB, +    VPTESTMW, + +    // AVX512CD +    VPBROADCASTM, +    VPCONFLICTD, +    VPCONFLICTQ, +    VPLZCNTD, +    VPLZCNTQ, + +    KUNPCKBW, +    KUNPCKWD, +    KUNPCKDQ, + +    KADDB, +    KANDB, +    KANDNB, +    KMOVB, +    KNOTB, +    KORB, +    KORTESTB, +    KSHIFTLB, +    KSHIFTRB, +    KTESTB, +    KXNORB, +    KXORB, +    KADDW, +    KANDW, +    KANDNW, +    KMOVW, +    KNOTW, +    KORW, +    KORTESTW, +    KSHIFTLW, +    KSHIFTRW, +    KTESTW, +    KXNORW, +    KXORW, +    KADDD, +    KANDD, +    KANDND, +    KMOVD, +    KNOTD, +    KORD, +    KORTESTD, +    KSHIFTLD, +    KSHIFTRD, +    KTESTD, +    KXNORD, +    KXORD, +    KADDQ, +    KANDQ, +    KANDNQ, +    KMOVQ, +    KNOTQ, +    KORQ, +    KORTESTQ, +    KSHIFTLQ, +    KSHIFTRQ, +    KTESTQ, +    KXNORQ, +    KXORQ, + +    // AVX512ER +    VEXP2PD, +    VEXP2PS, +    VEXP2SD, +    VEXP2SS, +    VRCP28PD, +    VRCP28PS, +    VRCP28SD, +    VRCP28SS, +    VRSQRT28PD, +    VRSQRT28PS, +    VRSQRT28SD, +    VRSQRT28SS, + +    // AVX512PF +    VGATHERPF0DPD, +    VGATHERPF0DPS, +    VGATHERPF0QPD, +    VGATHERPF0QPS, +    VGATHERPF1DPD, +    VGATHERPF1DPS, +    VGATHERPF1QPD, +    VGATHERPF1QPS, +    VSCATTERPF0DPD, +    VSCATTERPF0DPS, +    VSCATTERPF0QPD, +    VSCATTERPF0QPS, +    VSCATTERPF1DPD, +    VSCATTERPF1DPS, +    VSCATTERPF1QPD, +    VSCATTERPF1QPS, + +    // MPX +    BNDMK, +    BNDCL, +    BNDCU, +    BNDCN, +    BNDMOV, +    BNDLDX, +    BNDSTX,  }  #[derive(Debug)] @@ -2936,6 +3227,7 @@ impl InstDecoder {              // AVX...              Opcode::VMOVDDUP |              Opcode::VPSHUFLW | +            Opcode::VPSHUFHW |              Opcode::VHADDPS |              Opcode::VHSUBPS |              Opcode::VADDSUBPS | @@ -3099,6 +3391,7 @@ impl InstDecoder {              Opcode::VPABSD |              Opcode::VPABSW |              Opcode::VPACKSSDW | +            Opcode::VPACKUSDW |              Opcode::VPACKSSWB |              Opcode::VPACKUSWB |              Opcode::VPADDB | @@ -3136,6 +3429,8 @@ impl InstDecoder {              Opcode::VPCMPGTD |              Opcode::VPCMPGTQ |              Opcode::VPCMPGTW | +            Opcode::VPCMPESTRI | +            Opcode::VPCMPESTRM |              Opcode::VPCMPISTRI |              Opcode::VPCMPISTRM |              Opcode::VPERM2F128 | @@ -3157,7 +3452,7 @@ impl InstDecoder {              Opcode::VPHADDD |              Opcode::VPHADDSW |              Opcode::VPHADDW | -            Opcode::VPHADDUBSW | +            Opcode::VPMADDUBSW |              Opcode::VPHMINPOSUW |              Opcode::VPHSUBD |              Opcode::VPHSUBSW | @@ -3175,8 +3470,11 @@ impl InstDecoder {              Opcode::VPMAXUB |              Opcode::VPMAXUW |              Opcode::VPMAXUD | +            Opcode::VPMINSB |              Opcode::VPMINSW |              Opcode::VPMINSD | +            Opcode::VPMINUB | +            Opcode::VPMINUW |              Opcode::VPMINUD |              Opcode::VPMOVMSKB |              Opcode::VPMOVSXBD | @@ -3264,7 +3562,10 @@ impl InstDecoder {              Opcode::VUNPCKLPS |              Opcode::VXORPD |              Opcode::VXORPS | -            Opcode::VZEROUPPER => { +            Opcode::VZEROUPPER | +            Opcode::VZEROALL | +            Opcode::VLDMXCSR | +            Opcode::VSTMXCSR => {                  // TODO: check a table for these                  if !self.avx() {                      inst.opcode = Opcode::Invalid; diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index 9d51ba4..401c61f 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -39,23 +39,33 @@ enum VEXOperandCode {      VMOVSD_10,      VMOVSD_11,      VMOVSS_11, +    VMOVLPS_12, +    VMOVHPS_16,      E_G_xmm,      U_G_xmm,      M_G_xmm,      G_M_xmm,      G_U_xmm, +    Gd_U_xmm,      E_G_xmm_imm8, -    U_G_xmm_imm8, +    Ud_G_xmm_imm8, +    Ud_G_xmm, +    Ud_G_ymm,      E_G_ymm,      U_G_ymm,      M_G_ymm,      G_E_ymm,      G_M_ymm,      G_U_ymm, +    Gd_U_ymm,      E_V_G_ymm,      E_V_G_xmm,      E_xmm_G_ymm_imm8,      Ev_G_xmm_imm8, +    Eb_G_xmm_imm8, +    Ew_G_xmm_imm8, +    Ed_G_xmm_imm8, +    Eq_G_xmm_imm8,      G_Ex_V_xmm,      G_Ey_V_ymm,      G_E_xmm, @@ -68,12 +78,17 @@ enum VEXOperandCode {      G_V_ymm_E_xmm,      M_V_G_xmm,      M_V_G_ymm, +    G_V_xmm_Ed, +    G_V_xmm_Eq,      G_V_E_xmm,      G_V_E_xmm_imm8,      G_V_E_xmm_xmm4,      G_V_E_ymm,      G_V_E_ymm_imm8,      G_V_E_ymm_ymm4, +    G_V_xmm_Eb_imm8, +    G_V_xmm_Ed_imm8, +    G_V_xmm_Eq_imm8,      G_V_M_xmm,      G_V_M_ymm,      V_xmm_G_ymm_E_ymm_imm8, @@ -86,7 +101,12 @@ enum VEXOperandCode {      G_E_V,      G_V_E,      G_E_Ib, +    VCVT_Gd_Ed_xmm, +    VCVT_Gd_Eq_xmm, +    VCVT_Gq_Ed_xmm, +    VCVT_Gq_Eq_xmm,      BMI1_F3, +    MXCSR,  }  #[inline(never)] @@ -103,7 +123,6 @@ pub(crate) fn three_byte_vex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &          _ => { unreachable!("p is two bits"); }      };      let m = vex_byte_one & 0b11111; -//    println!("m: {:05b}", m);      let m = match m {          0b00001 => VEXOpcodeMap::Map0F,          0b00010 => VEXOpcodeMap::Map0F38, @@ -151,6 +170,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst      match operand_code {          VEXOperandCode::VPS_71 => {              let modrm = read_modrm(bytes, length)?; +            if modrm & 0xc0 != 0xc0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            }              match (modrm >> 3) & 0b111 {                  0b010 => {                      instruction.opcode = Opcode::VPSRLW; @@ -177,7 +200,14 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst          }          VEXOperandCode::VPS_71_L => {              let modrm = read_modrm(bytes, length)?; +            if modrm & 0xc0 != 0xc0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            }              match (modrm >> 3) & 0b111 { +                0b001 => { +                    instruction.opcode = Opcode::VPSLLW; +                }                  0b010 => {                      instruction.opcode = Opcode::VPSRLW;                  } @@ -203,6 +233,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst          }          VEXOperandCode::VPS_72 => {              let modrm = read_modrm(bytes, length)?; +            if modrm & 0xc0 != 0xc0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            }              match (modrm >> 3) & 0b111 {                  0b010 => {                      instruction.opcode = Opcode::VPSRLD; @@ -229,6 +263,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst          }          VEXOperandCode::VPS_72_L => {              let modrm = read_modrm(bytes, length)?; +            if modrm & 0xc0 != 0xc0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            }              match (modrm >> 3) & 0b111 {                  0b010 => {                      instruction.opcode = Opcode::VPSRLD; @@ -255,6 +293,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst          }          VEXOperandCode::VPS_73 => {              let modrm = read_modrm(bytes, length)?; +            if modrm & 0xc0 != 0xc0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            }              match (modrm >> 3) & 0b111 {                  0b010 => {                      instruction.opcode = Opcode::VPSRLQ; @@ -284,6 +326,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst          }          VEXOperandCode::VPS_73_L => {              let modrm = read_modrm(bytes, length)?; +            if modrm & 0xc0 != 0xc0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            }              match (modrm >> 3) & 0b111 {                  0b000 |                  0b001 | @@ -331,6 +377,10 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst                      instruction.operand_count = 3;                  },                  other => { +                    if instruction.vex_reg.num != 0 { +                        instruction.opcode = Opcode::Invalid; +                        return Err(DecodeError::InvalidOperand); +                    }                      instruction.operands[1] = other;                      instruction.operand_count = 2;                  } @@ -343,23 +393,171 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);              let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; -            instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operands[2] = OperandSpec::RegRRR;              match mem_oper {                  OperandSpec::RegMMM => { -                    instruction.operands[0] = OperandSpec::RegVex; -                    instruction.operands[2] = OperandSpec::RegMMM; +                    instruction.operands[0] = OperandSpec::RegMMM; +                    instruction.operands[1] = OperandSpec::RegVex;                      instruction.operand_count = 3;                  },                  other => { +                    if instruction.vex_reg.num != 0 { +                        instruction.opcode = Opcode::Invalid; +                        return Err(DecodeError::InvalidOperand); +                    }                      instruction.operands[0] = other; +                    instruction.operands[1] = instruction.operands[2];                      instruction.operand_count = 2;                  }              }              Ok(())          }, +        VEXOperandCode::VMOVLPS_12 => { +            let modrm = read_modrm(bytes, length)?; +            instruction.opcode = if modrm & 0xc0 == 0xc0 { +                Opcode::VMOVHLPS +            } else { +                Opcode::VMOVLPS +            }; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = OperandSpec::RegVex; +            instruction.operands[2] = read_E_xmm(bytes, instruction, modrm, length)?; +            instruction.operand_count = 3; +            Ok(()) +        } +        VEXOperandCode::VMOVHPS_16 => { +            let modrm = read_modrm(bytes, length)?; +            instruction.opcode = if modrm & 0xc0 == 0xc0 { +                Opcode::VMOVLHPS +            } else { +                Opcode::VMOVHPS +            }; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = OperandSpec::RegVex; +            instruction.operands[2] = read_E_xmm(bytes, instruction, modrm, length)?; +            instruction.operand_count = 3; +            Ok(()) +        }          VEXOperandCode::Nothing => {              Ok(())          }, +        VEXOperandCode::Eb_G_xmm_imm8 => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            instruction.operands[0] = mem_oper; +            instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operands[2] = OperandSpec::ImmU8; +            instruction.mem_size = 1; +            instruction.operand_count = 3; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            Ok(()) +        }, +        VEXOperandCode::Ew_G_xmm_imm8 => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            instruction.operands[0] = mem_oper; +            instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operands[2] = OperandSpec::ImmU8; +            instruction.mem_size = 2; +            instruction.operand_count = 3; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            Ok(()) +        }, +        VEXOperandCode::Ed_G_xmm_imm8 => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            instruction.operands[0] = mem_oper; +            instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operands[2] = OperandSpec::ImmU8; +            instruction.mem_size = 4; +            instruction.operand_count = 3; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            Ok(()) +        }, +        VEXOperandCode::Eq_G_xmm_imm8 => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            let mem_oper = read_E(bytes, instruction, modrm, 8, length)?; +            instruction.operands[0] = mem_oper; +            instruction.operands[1] = OperandSpec::RegRRR; +            instruction.operands[2] = OperandSpec::ImmU8; +            instruction.mem_size = 8; +            instruction.operand_count = 3; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            Ok(()) +        }, +        VEXOperandCode::G_V_xmm_Eb_imm8 => { +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            instruction.vex_reg.bank = RegisterBank::X; +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = OperandSpec::RegVex; +            instruction.operands[2] = mem_oper; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            instruction.operands[3] = OperandSpec::ImmU8; +            instruction.mem_size = 1; +            instruction.operand_count = 4; +            Ok(()) +        } +        VEXOperandCode::G_V_xmm_Ed_imm8 => { +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            instruction.vex_reg.bank = RegisterBank::X; +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = OperandSpec::RegVex; +            instruction.operands[2] = mem_oper; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            instruction.operands[3] = OperandSpec::ImmU8; +            instruction.mem_size = 4; +            instruction.operand_count = 4; +            Ok(()) +        } +        VEXOperandCode::G_V_xmm_Eq_imm8 => { +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            instruction.vex_reg.bank = RegisterBank::X; +            let mem_oper = read_E(bytes, instruction, modrm, 8, length)?; +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = OperandSpec::RegVex; +            instruction.operands[2] = mem_oper; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            instruction.operands[3] = OperandSpec::ImmU8; +            instruction.mem_size = 8; +            instruction.operand_count = 4; +            Ok(()) +        }          VEXOperandCode::Ev_G_xmm_imm8 => {              if instruction.vex_reg.num != 0 {                  instruction.opcode = Opcode::Invalid; @@ -432,11 +630,85 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operand_count = 2;              Ok(())          } -        _op @ VEXOperandCode::E_G_xmm | -        _op @ VEXOperandCode::U_G_xmm | -        _op @ VEXOperandCode::M_G_xmm | -        _op @ VEXOperandCode::E_G_xmm_imm8 | -        _op @ VEXOperandCode::U_G_xmm_imm8 => { +        VEXOperandCode::VCVT_Gd_Ed_xmm => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D); +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            if let OperandSpec::RegMMM = mem_oper { +                instruction.modrm_mmm.bank = RegisterBank::X; +            } else { +                instruction.mem_size = 4; +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.operand_count = 2; +            Ok(()) +        } +        VEXOperandCode::VCVT_Gd_Eq_xmm => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D); +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            if let OperandSpec::RegMMM = mem_oper { +                instruction.modrm_mmm.bank = RegisterBank::X; +            } else { +                instruction.mem_size = 8; +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.operand_count = 2; +            Ok(()) +        } +        VEXOperandCode::VCVT_Gq_Ed_xmm => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Q); +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            if let OperandSpec::RegMMM = mem_oper { +                instruction.modrm_mmm.bank = RegisterBank::X; +            } else { +                instruction.mem_size = 4; +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.operand_count = 2; +            Ok(()) +        } +        VEXOperandCode::VCVT_Gq_Eq_xmm => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Q); +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            if let OperandSpec::RegMMM = mem_oper { +                instruction.modrm_mmm.bank = RegisterBank::X; +            } else { +                instruction.mem_size = 8; +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.operand_count = 2; +            Ok(()) +        } +        op @ VEXOperandCode::E_G_xmm | +        op @ VEXOperandCode::U_G_xmm | +        op @ VEXOperandCode::M_G_xmm => {              if instruction.vex_reg.num != 0 {                  instruction.opcode = Opcode::Invalid;                  return Err(DecodeError::InvalidOperand); @@ -445,11 +717,93 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);              let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; +            match (op, mem_oper) { +                (VEXOperandCode::E_G_xmm, OperandSpec::RegMMM) => { +                    /* this is the only accepted operand */ +                } +                (VEXOperandCode::U_G_xmm, _) | +                (VEXOperandCode::M_G_xmm, OperandSpec::RegMMM) => { +                    return Err(DecodeError::InvalidOperand); +                } +                (VEXOperandCode::M_G_xmm, _) | // otherwise it's memory-constrained and a memory operand +                (_, _) => {                    // ... or unconstrained +                    /* and this is always accepted */ +                } +            }              instruction.operands[0] = mem_oper;              instruction.operands[1] = OperandSpec::RegRRR;              instruction.operand_count = 2;              Ok(())          } +        VEXOperandCode::Ud_G_xmm => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D); +            let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; +            if mem_oper != OperandSpec::RegMMM { +                return Err(DecodeError::InvalidOperand); +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.operand_count = 2; +            Ok(()) +        } +        VEXOperandCode::Ud_G_ymm => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D); +            let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; +            if mem_oper != OperandSpec::RegMMM { +                return Err(DecodeError::InvalidOperand); +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.operand_count = 2; +            Ok(()) +        } +        VEXOperandCode::Ud_G_xmm_imm8 => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D); +            let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; +            if mem_oper != OperandSpec::RegMMM { +                return Err(DecodeError::InvalidOperand); +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            instruction.operands[2] = OperandSpec::ImmU8; +            instruction.operand_count = 3; +            Ok(()) +        } +        VEXOperandCode::E_G_xmm_imm8 => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; +            instruction.operands[0] = mem_oper; +            instruction.operands[1] = OperandSpec::RegRRR; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            instruction.operands[2] = OperandSpec::ImmU8; +            instruction.operand_count = 3; +            Ok(()) +        }          _op @ VEXOperandCode::E_xmm_G_ymm_imm8 => {              if instruction.vex_reg.num != 0 {                  instruction.opcode = Opcode::Invalid; @@ -467,16 +821,63 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              Ok(())          } -        _op @ VEXOperandCode::G_M_xmm | -        _op @ VEXOperandCode::G_U_xmm | -        _op @ VEXOperandCode::G_E_xmm | -        _op @ VEXOperandCode::G_E_xmm_imm8 => { +        VEXOperandCode::Gd_U_xmm => {              if instruction.vex_reg.num != 0 {                  instruction.opcode = Opcode::Invalid;                  return Err(DecodeError::InvalidOperand);              }              let modrm = read_modrm(bytes, length)?;              instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D); +            let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; +            if mem_oper != OperandSpec::RegMMM { +                return Err(DecodeError::InvalidOperand); +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.operand_count = 2; +            Ok(()) +        } +        VEXOperandCode::Gd_U_ymm => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::D); +            let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; +            if mem_oper != OperandSpec::RegMMM { +                return Err(DecodeError::InvalidOperand); +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.operand_count = 2; +            Ok(()) +        } + +        op @ VEXOperandCode::G_M_xmm | +        op @ VEXOperandCode::G_U_xmm | +        op @ VEXOperandCode::G_E_xmm => { +            if instruction.vex_reg.num != 0 { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            match (op, modrm & 0xc0) { +                (VEXOperandCode::G_U_xmm, 0xc0) => { +                    /* this is the only accepted operand */ +                } +                (VEXOperandCode::G_U_xmm, _) | +                (VEXOperandCode::G_M_xmm, 0xc0) => { +                    return Err(DecodeError::InvalidOperand); +                } +                (VEXOperandCode::G_M_xmm, _) | // otherwise it's memory-constrained and a memory operand +                (_, _) => {                    // ... or unconstrained +                    /* and this is always accepted */ +                } +            } +            instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);              let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?;              instruction.operands[0] = OperandSpec::RegRRR; @@ -541,14 +942,27 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              Ok(())          } -        _op @ VEXOperandCode::E_G_ymm | -        _op @ VEXOperandCode::U_G_ymm | -        _op @ VEXOperandCode::M_G_ymm => { +        op @ VEXOperandCode::E_G_ymm | +        op @ VEXOperandCode::U_G_ymm | +        op @ VEXOperandCode::M_G_ymm => {              if instruction.vex_reg.num != 0 {                  instruction.opcode = Opcode::Invalid;                  return Err(DecodeError::InvalidOperand);              }              let modrm = read_modrm(bytes, length)?; +            match (op, modrm & 0xc0) { +                (VEXOperandCode::U_G_ymm, 0xc0) => { +                    /* this is the only accepted operand */ +                } +                (VEXOperandCode::U_G_ymm, _) | +                (VEXOperandCode::M_G_ymm, 0xc0) => { +                    return Err(DecodeError::InvalidOperand); +                } +                (VEXOperandCode::M_G_ymm, _) | // otherwise it's memory-constrained and a memory operand +                (_, _) => {                    // ... or unconstrained +                    /* and this is always accepted */ +                } +            }              instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);              let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; @@ -558,14 +972,27 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              Ok(())          } -        _op @ VEXOperandCode::G_M_ymm | -        _op @ VEXOperandCode::G_U_ymm | -        _op @ VEXOperandCode::G_E_ymm => { +        op @ VEXOperandCode::G_M_ymm | +        op @ VEXOperandCode::G_U_ymm | +        op @ VEXOperandCode::G_E_ymm => {              if instruction.vex_reg.num != 0 {                  instruction.opcode = Opcode::Invalid;                  return Err(DecodeError::InvalidOperand);              }              let modrm = read_modrm(bytes, length)?; +            match (op, modrm & 0xc0) { +                (VEXOperandCode::G_U_ymm, 0xc0) => { +                    /* this is the only accepted operand */ +                } +                (VEXOperandCode::G_U_ymm, _) | +                (VEXOperandCode::G_M_ymm, 0xc0) => { +                    return Err(DecodeError::InvalidOperand); +                } +                (VEXOperandCode::G_M_ymm, _) | // otherwise it's memory-constrained and a memory operand +                (_, _) => {                    // ... or unconstrained +                    /* and this is always accepted */ +                } +            }              instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y);              let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; @@ -614,12 +1041,48 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.operand_count = 3;              Ok(())          } -        _op @ VEXOperandCode::G_V_M_xmm | -        _op @ VEXOperandCode::G_V_E_xmm => { +        VEXOperandCode::G_V_M_xmm => {              let modrm = read_modrm(bytes, length)?;              instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X);              let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; +            if mem_oper == OperandSpec::RegMMM { +                instruction.opcode = Opcode::Invalid; +                return Err(DecodeError::InvalidOpcode); +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = OperandSpec::RegVex; +            instruction.operands[2] = mem_oper; +            instruction.operand_count = 3; +            Ok(()) +        } +        VEXOperandCode::G_V_E_xmm => { +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = OperandSpec::RegVex; +            instruction.operands[2] = mem_oper; +            instruction.operand_count = 3; +            Ok(()) +        } +        VEXOperandCode::G_V_xmm_Ed => { +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = OperandSpec::RegVex; +            instruction.operands[2] = mem_oper; +            instruction.operand_count = 3; +            Ok(()) +        } +        VEXOperandCode::G_V_xmm_Eq => { +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            let mem_oper = read_E(bytes, instruction, modrm, 8, length)?;              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::RegVex;              instruction.operands[2] = mem_oper; @@ -786,7 +1249,47 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              instruction.vex_reg.bank = bank;              Ok(())          } +        VEXOperandCode::MXCSR => { +            let modrm = read_modrm(bytes, length)?; +            instruction.opcode = match (modrm >> 3) & 7 { +                2 => { +                    Opcode::VLDMXCSR +                } +                3 => { +                    Opcode::VSTMXCSR +                } +                _ => { +                    instruction.opcode = Opcode::Invalid; +                    return Err(DecodeError::InvalidOpcode); +                } +            }; +            let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; +            if let OperandSpec::RegMMM = mem_oper { +                return Err(DecodeError::InvalidOperand); +            } +            instruction.operands[0] = mem_oper; +            instruction.operand_count = 1; +            Ok(()) +        } +        VEXOperandCode::G_E_xmm_imm8 => { +            if instruction.vex_reg.num != 0 { +                return Err(DecodeError::InvalidOperand); +            } +            let modrm = read_modrm(bytes, length)?; +            instruction.modrm_rrr = +                RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); +            let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.imm = read_imm_unsigned(bytes, 1, length)?; +            instruction.operands[2] = OperandSpec::ImmU8; +            instruction.operand_count = 3; +            Ok(()) +        }          VEXOperandCode::G_E_ymm_imm8 => { +            if instruction.vex_reg.num != 0 { +                return Err(DecodeError::InvalidOperand); +            }              let modrm = read_modrm(bytes, length)?;              instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::Y); @@ -877,9 +1380,12 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                      match opc {                          0x10 => (Opcode::VMOVUPS, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }),                          0x11 => (Opcode::VMOVUPS, if L { VEXOperandCode::E_G_ymm } else { VEXOperandCode::E_G_xmm }), -                        // ugh -//                        0x12 => (Opcode::VMOVHLPS, ..), -//                        0x12 => (Opcode::VMOVLPS, ..), +                        0x12 => (Opcode::Invalid, if L { +                            instruction.opcode = Opcode::Invalid; +                            return Err(DecodeError::InvalidOpcode); +                        } else { +                            VEXOperandCode::VMOVLPS_12 +                        }),                          0x13 => (Opcode::VMOVLPS, if L {                              instruction.opcode = Opcode::Invalid;                              return Err(DecodeError::InvalidOpcode); @@ -896,9 +1402,12 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          } else {                              VEXOperandCode::G_V_E_xmm                          }), -                        // ugh -//                        0x16 => (Opcode::VMOVHPS, ..), -//                        0x16 => (Opcode::VMOVLHPS, ..), +                        0x16 => (Opcode::Invalid, if L { +                            instruction.opcode = Opcode::Invalid; +                            return Err(DecodeError::InvalidOpcode); +                        } else { +                            VEXOperandCode::VMOVHPS_16 +                        }),                          0x17 => (Opcode::VMOVHPS, if L {                              instruction.opcode = Opcode::Invalid;                              return Err(DecodeError::InvalidOpcode); @@ -923,9 +1432,9 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          0x2e => (Opcode::VUCOMISS, VEXOperandCode::G_E_xmm),                          0x2f => (Opcode::VCOMISS, VEXOperandCode::G_E_xmm),                          0x50 => (Opcode::VMOVMSKPS, if L { -                            VEXOperandCode::U_G_ymm +                            VEXOperandCode::Ud_G_ymm                          } else { -                            VEXOperandCode::U_G_xmm +                            VEXOperandCode::Ud_G_xmm                          }),                          0x51 => (Opcode::VSQRTPS, if L {                              VEXOperandCode::G_E_ymm @@ -973,7 +1482,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              VEXOperandCode::G_V_E_xmm                          }),                          0x5A => (Opcode::VCVTPS2PD, if L { -                            VEXOperandCode::G_E_ymm +                            VEXOperandCode::G_ymm_E_xmm                          } else {                              VEXOperandCode::G_E_xmm                          }), @@ -1003,6 +1512,11 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              VEXOperandCode::G_V_E_xmm                          }),                          0x77 => (Opcode::VZEROUPPER, VEXOperandCode::Nothing), +                        0xAE => (Opcode::Invalid, if L { +                            return Err(DecodeError::InvalidOpcode); +                        } else { +                            VEXOperandCode::MXCSR +                        }),                          0xC2 => (Opcode::VCMPPS, if L {                              VEXOperandCode::G_V_E_ymm_imm8                          } else { @@ -1055,12 +1569,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          } else {                              VEXOperandCode::G_V_E_xmm                          }), -                        0x16 => (Opcode::VMOVHPD, if L { -                            instruction.opcode = Opcode::Invalid; -                            return Err(DecodeError::InvalidOpcode); -                        } else { -                            VEXOperandCode::G_V_M_xmm -                        }), +                        0x16 => (Opcode::VMOVHPD, VEXOperandCode::G_V_M_xmm),                          0x17 => (Opcode::VMOVHPD, if L {                              instruction.opcode = Opcode::Invalid;                              return Err(DecodeError::InvalidOpcode); @@ -1085,9 +1594,9 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          0x2e => (Opcode::VUCOMISD, VEXOperandCode::G_E_xmm),                          0x2f => (Opcode::VCOMISD, VEXOperandCode::G_E_xmm),                          0x50 => (Opcode::VMOVMSKPD, if L { -                            VEXOperandCode::G_U_ymm +                            VEXOperandCode::Gd_U_ymm                          } else { -                            VEXOperandCode::G_U_xmm +                            VEXOperandCode::Gd_U_xmm                          }),                          0x51 => (Opcode::VSQRTPD, if L {                              VEXOperandCode::G_E_ymm @@ -1310,9 +1819,9 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              VEXOperandCode::E_G_xmm                          }),                          0xC2 => (Opcode::VCMPPD, if L { -                            VEXOperandCode::G_V_E_ymm +                            VEXOperandCode::G_V_E_ymm_imm8                          } else { -                            VEXOperandCode::G_V_E_xmm +                            VEXOperandCode::G_V_E_xmm_imm8                          }),                          0xC4 => (Opcode::VPINSRW, if L {                              instruction.opcode = Opcode::Invalid; @@ -1324,12 +1833,12 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              instruction.opcode = Opcode::Invalid;                              return Err(DecodeError::InvalidOpcode);                          } else { -                            VEXOperandCode::U_G_xmm_imm8 +                            VEXOperandCode::Ud_G_xmm_imm8                          }),                          0xC6 => (Opcode::VSHUFPD, if L { -                            VEXOperandCode::G_V_E_ymm +                            VEXOperandCode::G_V_E_ymm_imm8                          } else { -                            VEXOperandCode::G_V_E_xmm +                            VEXOperandCode::G_V_E_xmm_imm8                          }),                          0xD0 => (Opcode::VADDSUBPD, if L {                              VEXOperandCode::G_V_E_ymm @@ -1337,17 +1846,17 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              VEXOperandCode::G_V_E_xmm                          }),                          0xD1 => (Opcode::VPSRLW, if L { -                            VEXOperandCode::G_V_E_ymm +                            VEXOperandCode::G_V_ymm_E_xmm                          } else {                              VEXOperandCode::G_V_E_xmm                          }),                          0xD2 => (Opcode::VPSRLD, if L { -                            VEXOperandCode::G_V_E_ymm +                            VEXOperandCode::G_V_ymm_E_xmm                          } else {                              VEXOperandCode::G_V_E_xmm                          }),                          0xD3 => (Opcode::VPSRLQ, if L { -                            VEXOperandCode::G_V_E_ymm +                            VEXOperandCode::G_V_ymm_E_xmm                          } else {                              VEXOperandCode::G_V_E_xmm                          }), @@ -1368,9 +1877,9 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              VEXOperandCode::G_E_xmm                          }),                          0xD7 => (Opcode::VPMOVMSKB, if L { -                            VEXOperandCode::U_G_ymm +                            VEXOperandCode::Ud_G_ymm                          } else { -                            VEXOperandCode::U_G_xmm +                            VEXOperandCode::Ud_G_xmm                          }),                          0xD8 => (Opcode::VPSUBUSB, if L {                              VEXOperandCode::G_V_E_ymm @@ -1382,6 +1891,11 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          } else {                              VEXOperandCode::G_V_E_xmm                          }), +                        0xDA => (Opcode::VPMINSW, if L { +                            VEXOperandCode::G_V_E_ymm +                        } else { +                            VEXOperandCode::G_V_E_xmm +                        }),                          0xDB => (Opcode::VPAND, if L {                              VEXOperandCode::G_V_E_ymm                          } else { @@ -1521,7 +2035,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              instruction.opcode = Opcode::Invalid;                              return Err(DecodeError::InvalidOpcode);                          } else { -                            VEXOperandCode::G_E_xmm +                            VEXOperandCode::G_U_xmm                          }),                          0xF8 => (Opcode::VPSUBB, if L {                              VEXOperandCode::G_V_E_ymm @@ -1574,24 +2088,24 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              VEXOperandCode::G_E_xmm                          }),                          0x2a => (Opcode::VCVTSI2SD, if instruction.prefixes.vex().w() { -                            VEXOperandCode::G_V_E_xmm // 64-bit last operand +                            VEXOperandCode::G_V_xmm_Eq // 64-bit last operand                          } else { -                            VEXOperandCode::G_V_E_xmm // 32-bit last operand +                            VEXOperandCode::G_V_xmm_Ed // 32-bit last operand                          }),                          0x2c => (Opcode::VCVTTSD2SI, if instruction.prefixes.vex().w() { -                            VEXOperandCode::G_E_xmm // 64-bit +                            VEXOperandCode::VCVT_Gq_Eq_xmm // 64-bit                          } else { -                            VEXOperandCode::G_E_xmm // 32-bit +                            VEXOperandCode::VCVT_Gd_Ed_xmm // 32-bit                          }),                          0x2d => (Opcode::VCVTSD2SI, if instruction.prefixes.vex().w() { -                            VEXOperandCode::G_E_xmm // 64-bit +                            VEXOperandCode::VCVT_Gq_Eq_xmm // 64-bit                          } else { -                            VEXOperandCode::G_E_xmm // 32-bit +                            VEXOperandCode::VCVT_Gd_Ed_xmm // 32-bit                          }),                          0x51 => (Opcode::VSQRTSD, VEXOperandCode::G_V_E_xmm),                          0x58 => (Opcode::VADDSD, VEXOperandCode::G_V_E_xmm),                          0x59 => (Opcode::VMULSD, VEXOperandCode::G_V_E_xmm), -                        0x5a => (Opcode::CVTSD2SS, VEXOperandCode::G_V_E_xmm), +                        0x5a => (Opcode::VCVTSD2SS, VEXOperandCode::G_V_E_xmm),                          0x5c => (Opcode::VSUBSD, VEXOperandCode::G_V_E_xmm),                          0x5d => (Opcode::VMINSD, VEXOperandCode::G_V_E_xmm),                          0x5e => (Opcode::VDIVSD, VEXOperandCode::G_V_E_xmm), @@ -1625,7 +2139,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          0xf0 => (Opcode::VLDDQU, if L {                              VEXOperandCode::G_M_ymm                          } else { -                            VEXOperandCode::G_M_ymm +                            VEXOperandCode::G_M_xmm                          }),                          _ => {                              instruction.opcode = Opcode::Invalid; @@ -1640,19 +2154,19 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          0x12 => (Opcode::VMOVSLDUP, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }),                          0x16 => (Opcode::VMOVSHDUP, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }),                          0x2a => (Opcode::VCVTSI2SS, if instruction.prefixes.vex().w() { -                            VEXOperandCode::G_V_E_xmm // 64-bit last operand +                            VEXOperandCode::G_V_xmm_Eq                          } else { -                            VEXOperandCode::G_V_E_xmm // 32-bit last operand +                            VEXOperandCode::G_V_xmm_Ed                          }),                          0x2c => (Opcode::VCVTTSS2SI, if instruction.prefixes.vex().w() { -                            VEXOperandCode::G_E_xmm // 64-bit +                            VEXOperandCode::VCVT_Gq_Eq_xmm                          } else { -                            VEXOperandCode::G_E_xmm // 32-bit +                            VEXOperandCode::VCVT_Gd_Ed_xmm                          }), -                        0x2d => (Opcode::VCVTSD2SI, if instruction.prefixes.vex().w() { -                            VEXOperandCode::G_E_xmm // 64-bit +                        0x2d => (Opcode::VCVTSS2SI, if instruction.prefixes.vex().w() { +                            VEXOperandCode::VCVT_Gq_Eq_xmm                          } else { -                            VEXOperandCode::G_E_xmm // 32-bit +                            VEXOperandCode::VCVT_Gd_Ed_xmm                          }),                          0x51 => (Opcode::VSQRTSS, VEXOperandCode::G_V_E_xmm),                          0x52 => (Opcode::VRSQRTSS, VEXOperandCode::G_V_E_xmm), @@ -1666,7 +2180,11 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          0x5e => (Opcode::VDIVSS, VEXOperandCode::G_V_E_xmm),                          0x5f => (Opcode::VMAXSS, VEXOperandCode::G_V_E_xmm),                          0x6f => (Opcode::VMOVDQU, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }), -//                        0x70 => (Opcode::VMOVSHDUP, if L { VEXOperandCode::G_E_ymm_imm8 } else { VEXOperandCode::G_E_xmm_imm8 }), +                        0x70 => (Opcode::VPSHUFHW, if L { +                            VEXOperandCode::G_E_ymm_imm8 +                        } else { +                            VEXOperandCode::G_E_xmm_imm8 +                        }),                          0x7e => (Opcode::VMOVQ, if L { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }),                          0x7f => (Opcode::VMOVDQU, if L { VEXOperandCode::E_G_ymm } else { VEXOperandCode::E_G_xmm }),                          0xc2 => (Opcode::VCMPSS, VEXOperandCode::G_V_E_xmm_imm8), @@ -1704,7 +2222,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                      } else {                          VEXOperandCode::G_V_E_xmm                      }), -                    0x04 => (Opcode::VPHADDUBSW, if L { +                    0x04 => (Opcode::VPMADDUBSW, if L {                          VEXOperandCode::G_V_E_ymm                      } else {                          VEXOperandCode::G_V_E_xmm @@ -1780,16 +2298,26 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                      } else {                          VEXOperandCode::G_E_xmm                      }), -                    0x18 => (Opcode::VBROADCASTSS, if L { -                        VEXOperandCode::G_E_ymm +                    0x18 => if instruction.prefixes.vex().w() { +                        instruction.opcode = Opcode::Invalid; +                        return Err(DecodeError::InvalidOpcode);                      } else { -                        VEXOperandCode::G_E_xmm -                    }), -                    0x19 => (Opcode::VBROADCASTSD, if L { -                        VEXOperandCode::G_E_ymm +                        (Opcode::VBROADCASTSS, if L { +                            VEXOperandCode::G_E_ymm +                        } else { +                            VEXOperandCode::G_E_xmm +                        }) +                    }, +                    0x19 => if instruction.prefixes.vex().w() { +                        instruction.opcode = Opcode::Invalid; +                        return Err(DecodeError::InvalidOpcode);                      } else { -                        VEXOperandCode::G_E_xmm -                    }), +                        (Opcode::VBROADCASTSD, if L { +                            VEXOperandCode::G_E_ymm +                        } else { +                            VEXOperandCode::G_E_xmm +                        }) +                    }                      0x1A => (Opcode::VBROADCASTF128, if L {                          VEXOperandCode::G_M_ymm                      } else { @@ -1812,32 +2340,32 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          VEXOperandCode::G_E_xmm                      }),                      0x20 => (Opcode::VPMOVSXBW, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x21 => (Opcode::VPMOVSXBD, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x22 => (Opcode::VPMOVSXBQ, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x23 => (Opcode::VPMOVSXWD, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x24 => (Opcode::VPMOVSXWQ, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x25 => (Opcode::VPMOVSXDQ, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }), @@ -1856,6 +2384,11 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                      } else {                          VEXOperandCode::G_M_xmm                      }), +                    0x2B => (Opcode::VPACKUSDW, if L { +                        VEXOperandCode::G_V_E_ymm +                    } else { +                        VEXOperandCode::G_V_E_xmm +                    }),                      0x2C => (Opcode::VMASKMOVPS, if L {                          VEXOperandCode::G_V_M_ymm                      } else { @@ -1877,35 +2410,34 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          VEXOperandCode::M_V_G_xmm                      }),                      0x30 => (Opcode::VPMOVZXBW, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x31 => (Opcode::VPMOVZXBD, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x32 => (Opcode::VPMOVZXBQ, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x33 => (Opcode::VPMOVZXWD, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x34 => (Opcode::VPMOVZXWQ, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else {                          VEXOperandCode::G_E_xmm                      }),                      0x35 => (Opcode::VPMOVZXDQ, if L { -                        VEXOperandCode::G_E_ymm +                        VEXOperandCode::G_ymm_E_xmm                      } else { -                        instruction.opcode = Opcode::Invalid; -                        return Err(DecodeError::InvalidOpcode); +                        VEXOperandCode::G_E_xmm                      }),                      0x36 => (Opcode::VPERMD, if L {                          VEXOperandCode::G_V_E_ymm @@ -1918,11 +2450,21 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                      } else {                          VEXOperandCode::G_V_E_xmm                      }), +                    0x38 => (Opcode::VPMINSB, if L { +                        VEXOperandCode::G_V_E_ymm +                    } else { +                        VEXOperandCode::G_V_E_xmm +                    }),                      0x39 => (Opcode::VPMINSD, if L {                          VEXOperandCode::G_V_E_ymm                      } else {                          VEXOperandCode::G_V_E_xmm                      }), +                    0x3A => (Opcode::VPMINUW, if L { +                        VEXOperandCode::G_V_E_ymm +                    } else { +                        VEXOperandCode::G_V_E_xmm +                    }),                      0x3B => (Opcode::VPMINUD, if L {                          VEXOperandCode::G_V_E_ymm                      } else { @@ -2443,26 +2985,22 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          VEXOperandCode::G_E_xmm                      }),                      0xDC => (Opcode::VAESENC, if L { -                        instruction.opcode = Opcode::Invalid; -                        return Err(DecodeError::InvalidOpcode); +                        VEXOperandCode::G_V_E_ymm                      } else {                          VEXOperandCode::G_V_E_xmm                      }),                      0xDD => (Opcode::VAESENCLAST, if L { -                        instruction.opcode = Opcode::Invalid; -                        return Err(DecodeError::InvalidOpcode); +                        VEXOperandCode::G_V_E_ymm                      } else {                          VEXOperandCode::G_V_E_xmm                      }),                      0xDE => (Opcode::VAESDEC, if L { -                        instruction.opcode = Opcode::Invalid; -                        return Err(DecodeError::InvalidOpcode); +                        VEXOperandCode::G_V_E_ymm                      } else {                          VEXOperandCode::G_V_E_xmm                      }),                      0xDF => (Opcode::VAESDECLAST, if L { -                        instruction.opcode = Opcode::Invalid; -                        return Err(DecodeError::InvalidOpcode); +                        VEXOperandCode::G_V_E_ymm                      } else {                          VEXOperandCode::G_V_E_xmm                      }), @@ -2576,17 +3114,17 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          VEXOperandCode::G_V_E_xmm                      }),                      0x04 => (Opcode::VPERMILPS, if L { -                        VEXOperandCode::G_V_E_ymm +                        VEXOperandCode::G_E_ymm_imm8                      } else { -                        VEXOperandCode::G_V_E_xmm +                        VEXOperandCode::G_E_xmm_imm8                      }),                      0x05 => (Opcode::VPERMILPD, if L { -                        VEXOperandCode::G_V_E_ymm +                        VEXOperandCode::G_E_ymm_imm8                      } else { -                        VEXOperandCode::G_V_E_xmm +                        VEXOperandCode::G_E_xmm_imm8                      }),                      0x06 => (Opcode::VPERM2F128, if L { -                        VEXOperandCode::G_V_E_ymm +                        VEXOperandCode::G_V_E_ymm_imm8                      } else {                          instruction.opcode = Opcode::Invalid;                          return Err(DecodeError::InvalidOpcode); @@ -2601,6 +3139,16 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                      } else {                          VEXOperandCode::G_E_xmm_imm8                      }), +                    0x0A => (Opcode::VROUNDSS, if L { +                        VEXOperandCode::G_V_E_ymm_imm8 +                    } else { +                        VEXOperandCode::G_V_E_xmm_imm8 +                    }), +                    0x0B => (Opcode::VROUNDSD, if L { +                        VEXOperandCode::G_V_E_ymm_imm8 +                    } else { +                        VEXOperandCode::G_V_E_xmm_imm8 +                    }),                      0x0C => (Opcode::VBLENDPS, if L {                          VEXOperandCode::G_V_E_ymm_imm8                      } else { @@ -2625,20 +3173,20 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          instruction.opcode = Opcode::Invalid;                          return Err(DecodeError::InvalidOpcode);                      } else { -                        VEXOperandCode::Ev_G_xmm_imm8 +                        VEXOperandCode::Eb_G_xmm_imm8                      }),                      0x15 => (Opcode::VPEXTRW, if L || instruction.prefixes.vex().w() {                          instruction.opcode = Opcode::Invalid;                          return Err(DecodeError::InvalidOpcode);                      } else { -                        VEXOperandCode::Ev_G_xmm_imm8 +                        VEXOperandCode::Ew_G_xmm_imm8                      }),                      0x16 => if instruction.prefixes.vex().w() {                          (Opcode::VPEXTRQ, if L {                              instruction.opcode = Opcode::Invalid;                              return Err(DecodeError::InvalidOpcode);                          } else { -                            VEXOperandCode::G_E_ymm_imm8 +                            VEXOperandCode::Eq_G_xmm_imm8                          })                      } else {                          (Opcode::VPEXTRD, if L { @@ -2646,27 +3194,37 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              return Err(DecodeError::InvalidOpcode);                          } else {                              // varies on W -                            VEXOperandCode::Ev_G_xmm_imm8 +                            VEXOperandCode::Ed_G_xmm_imm8                          })                      },                      0x17 => (Opcode::VEXTRACTPS, if L {                          instruction.opcode = Opcode::Invalid;                          return Err(DecodeError::InvalidOpcode);                      } else { -                        VEXOperandCode::G_E_ymm_imm8 +                        VEXOperandCode::Ed_G_xmm_imm8                      }), -                    0x18 => (Opcode::VINSERTF128, if L { -                        VEXOperandCode::G_V_E_ymm_imm8 -                    } else { +                    0x18 => if instruction.prefixes.vex().w() {                          instruction.opcode = Opcode::Invalid;                          return Err(DecodeError::InvalidOpcode); -                    }), -                    0x19 => (Opcode::VEXTRACTF128, if L { -                        VEXOperandCode::E_xmm_G_ymm_imm8                      } else { +                        (Opcode::VINSERTF128, if L { +                            VEXOperandCode::G_V_E_ymm_imm8 +                        } else { +                            instruction.opcode = Opcode::Invalid; +                            return Err(DecodeError::InvalidOpcode); +                        }) +                    }, +                    0x19 => if instruction.prefixes.vex().w() {                          instruction.opcode = Opcode::Invalid;                          return Err(DecodeError::InvalidOpcode); -                    }), +                    } else { +                        (Opcode::VEXTRACTF128, if L { +                            VEXOperandCode::E_xmm_G_ymm_imm8 +                        } else { +                            instruction.opcode = Opcode::Invalid; +                            return Err(DecodeError::InvalidOpcode); +                        }) +                    },                      0x1D => (Opcode::VCVTPS2PH, if L {                          VEXOperandCode::E_xmm_G_ymm_imm8                      } else { @@ -2676,7 +3234,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                          instruction.opcode = Opcode::Invalid;                          return Err(DecodeError::InvalidOpcode);                      } else { -                        VEXOperandCode::G_V_E_xmm_imm8 +                        VEXOperandCode::G_V_xmm_Eb_imm8                      }),                      0x21 => (Opcode::VINSERTPS, if L {                          instruction.opcode = Opcode::Invalid; @@ -2689,14 +3247,14 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                              instruction.opcode = Opcode::Invalid;                              return Err(DecodeError::InvalidOpcode);                          } else { -                            VEXOperandCode::G_V_E_xmm_imm8 +                            VEXOperandCode::G_V_xmm_Eq_imm8                          })                      } else {                          (Opcode::VPINSRD, if L {                              instruction.opcode = Opcode::Invalid;                              return Err(DecodeError::InvalidOpcode);                          } else { -                            VEXOperandCode::G_V_E_xmm_imm8 +                            VEXOperandCode::G_V_xmm_Ed_imm8                          })                      },                      0x38 => (Opcode::VINSERTI128, if L { @@ -2749,10 +3307,27 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: &                      } else {                          VEXOperandCode::G_V_E_xmm_xmm4                      }), -                    0x4C => (Opcode::VPBLENDVB, if L { -                        VEXOperandCode::G_V_E_ymm_ymm4 +                    0x4C => if instruction.prefixes.vex().w() { +                        instruction.opcode = Opcode::Invalid; +                        return Err(DecodeError::InvalidOpcode);                      } else { -                        VEXOperandCode::G_V_E_xmm_xmm4 +                        (Opcode::VPBLENDVB, if L { +                            VEXOperandCode::G_V_E_ymm_ymm4 +                        } else { +                            VEXOperandCode::G_V_E_xmm_xmm4 +                        }) +                    }, +                    0x60 => (Opcode::VPCMPESTRM, if L { +                        instruction.opcode = Opcode::Invalid; +                        return Err(DecodeError::InvalidOpcode); +                    } else { +                        VEXOperandCode::G_E_xmm_imm8 +                    }), +                    0x61 => (Opcode::VPCMPESTRI, if L { +                        instruction.opcode = Opcode::Invalid; +                        return Err(DecodeError::InvalidOpcode); +                    } else { +                        VEXOperandCode::G_E_xmm_imm8                      }),                      0x62 => (Opcode::VPCMPISTRM, if L {                          instruction.opcode = Opcode::Invalid; | 
