From 8a351085be1cab446bd61c26c66e6b0206827454 Mon Sep 17 00:00:00 2001 From: iximeow Date: Mon, 16 Dec 2019 01:34:22 -0800 Subject: avx feature flag and avx/aesni instructions flagged properly --- src/lib.rs | 355 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- test/test.rs | 195 ++++++++++++++++---------------- 2 files changed, 453 insertions(+), 97 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ddba4bb..81bc4aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2016,6 +2016,348 @@ impl InstDecoder { return Err(()); } } + Opcode::VMOVDDUP | + Opcode::VPSHUFLW | + Opcode::VHADDPS | + Opcode::VHSUBPS | + Opcode::VADDSUBPS | + Opcode::VCVTPD2DQ | + Opcode::VLDDQU | + Opcode::VCOMISD | + Opcode::VCOMISS | + Opcode::VUCOMISD | + Opcode::VUCOMISS | + Opcode::VADDPD | + Opcode::VADDPS | + Opcode::VADDSD | + Opcode::VADDSS | + Opcode::VADDSUBPD | + Opcode::VBLENDPD | + Opcode::VBLENDPS | + Opcode::VBLENDVPD | + Opcode::VBLENDVPS | + Opcode::VBROADCASTF128 | + Opcode::VBROADCASTI128 | + Opcode::VBROADCASTSD | + Opcode::VBROADCASTSS | + Opcode::VCMPSD | + Opcode::VCMPSS | + Opcode::VCMPPD | + Opcode::VCMPPS | + Opcode::VCVTDQ2PD | + Opcode::VCVTDQ2PS | + Opcode::VCVTPD2PS | + Opcode::VCVTPH2PS | + Opcode::VCVTPS2DQ | + Opcode::VCVTPS2PD | + Opcode::VCVTSS2SD | + Opcode::VCVTSI2SS | + Opcode::VCVTSI2SD | + Opcode::VCVTSD2SI | + Opcode::VCVTSD2SS | + Opcode::VCVTPS2PH | + Opcode::VCVTSS2SI | + Opcode::VCVTTPD2DQ | + Opcode::VCVTTPS2DQ | + Opcode::VCVTTSS2SI | + Opcode::VCVTTSD2SI | + Opcode::VDIVPD | + Opcode::VDIVPS | + Opcode::VDIVSD | + Opcode::VDIVSS | + Opcode::VDPPD | + Opcode::VDPPS | + Opcode::VEXTRACTF128 | + Opcode::VEXTRACTI128 | + Opcode::VEXTRACTPS | + Opcode::VFMADD132PD | + Opcode::VFMADD132PS | + Opcode::VFMADD132SD | + Opcode::VFMADD132SS | + Opcode::VFMADD213PD | + Opcode::VFMADD213PS | + Opcode::VFMADD213SD | + Opcode::VFMADD213SS | + Opcode::VFMADD231PD | + Opcode::VFMADD231PS | + Opcode::VFMADD231SD | + Opcode::VFMADD231SS | + Opcode::VFMADDSUB132PD | + Opcode::VFMADDSUB132PS | + Opcode::VFMADDSUB213PD | + Opcode::VFMADDSUB213PS | + Opcode::VFMADDSUB231PD | + Opcode::VFMADDSUB231PS | + Opcode::VFMSUB132PD | + Opcode::VFMSUB132PS | + Opcode::VFMSUB132SD | + Opcode::VFMSUB132SS | + Opcode::VFMSUB213PD | + Opcode::VFMSUB213PS | + Opcode::VFMSUB213SD | + Opcode::VFMSUB213SS | + Opcode::VFMSUB231PD | + Opcode::VFMSUB231PS | + Opcode::VFMSUB231SD | + Opcode::VFMSUB231SS | + Opcode::VFMSUBADD132PD | + Opcode::VFMSUBADD132PS | + Opcode::VFMSUBADD213PD | + Opcode::VFMSUBADD213PS | + Opcode::VFMSUBADD231PD | + Opcode::VFMSUBADD231PS | + Opcode::VFNMADD132PD | + Opcode::VFNMADD132PS | + Opcode::VFNMADD132SD | + Opcode::VFNMADD132SS | + Opcode::VFNMADD213PD | + Opcode::VFNMADD213PS | + Opcode::VFNMADD213SD | + Opcode::VFNMADD213SS | + Opcode::VFNMADD231PD | + Opcode::VFNMADD231PS | + Opcode::VFNMADD231SD | + Opcode::VFNMADD231SS | + Opcode::VFNMSUB132PD | + Opcode::VFNMSUB132PS | + Opcode::VFNMSUB132SD | + Opcode::VFNMSUB132SS | + Opcode::VFNMSUB213PD | + Opcode::VFNMSUB213PS | + Opcode::VFNMSUB213SD | + Opcode::VFNMSUB213SS | + Opcode::VFNMSUB231PD | + Opcode::VFNMSUB231PS | + Opcode::VFNMSUB231SD | + Opcode::VFNMSUB231SS | + Opcode::VGATHERDPD | + Opcode::VGATHERDPS | + Opcode::VGATHERQPD | + Opcode::VGATHERQPS | + Opcode::VHADDPD | + Opcode::VHSUBPD | + Opcode::VINSERTF128 | + Opcode::VINSERTI128 | + Opcode::VINSERTPS | + Opcode::VMASKMOVDQU | + Opcode::VMASKMOVPD | + Opcode::VMASKMOVPS | + Opcode::VMAXPD | + Opcode::VMAXPS | + Opcode::VMAXSD | + Opcode::VMAXSS | + Opcode::VMINPD | + Opcode::VMINPS | + Opcode::VMINSD | + Opcode::VMINSS | + Opcode::VMOVAPD | + Opcode::VMOVAPS | + Opcode::VMOVD | + Opcode::VMOVDQA | + Opcode::VMOVDQU | + Opcode::VMOVHLPS | + Opcode::VMOVHPD | + Opcode::VMOVHPS | + Opcode::VMOVLHPS | + Opcode::VMOVLPD | + Opcode::VMOVLPS | + Opcode::VMOVMSKPD | + Opcode::VMOVMSKPS | + Opcode::VMOVNTDQ | + Opcode::VMOVNTDQA | + Opcode::VMOVNTPD | + Opcode::VMOVNTPS | + Opcode::VMOVQ | + Opcode::VMOVSS | + Opcode::VMOVSD | + Opcode::VMOVSHDUP | + Opcode::VMOVSLDUP | + Opcode::VMOVUPD | + Opcode::VMOVUPS | + Opcode::VMPSADBW | + Opcode::VMULPD | + Opcode::VMULPS | + Opcode::VMULSD | + Opcode::VMULSS | + Opcode::VPABSB | + Opcode::VPABSD | + Opcode::VPABSW | + Opcode::VPACKSSDW | + Opcode::VPACKSSWB | + Opcode::VPACKUSWB | + Opcode::VPADDB | + Opcode::VPADDD | + Opcode::VPADDQ | + Opcode::VPADDSB | + Opcode::VPADDSW | + Opcode::VPADDUSB | + Opcode::VPADDUSW | + Opcode::VPADDW | + Opcode::VPALIGNR | + Opcode::VPAND | + Opcode::VPANDN | + Opcode::VPAVGB | + Opcode::VPAVGW | + Opcode::VPBLENDD | + Opcode::VPBLENDVB | + Opcode::VPBLENDW | + Opcode::VPBROADCASTB | + Opcode::VPBROADCASTD | + Opcode::VPBROADCASTQ | + Opcode::VPBROADCASTW | + Opcode::VPCLMULQDQ | + Opcode::VPCMPEQB | + Opcode::VPCMPEQD | + Opcode::VPCMPEQQ | + Opcode::VPCMPEQW | + Opcode::VPCMPGTB | + Opcode::VPCMPGTD | + Opcode::VPCMPGTQ | + Opcode::VPCMPGTW | + Opcode::VPCMPISTRI | + Opcode::VPCMPISTRM | + Opcode::VPERM2F128 | + Opcode::VPERM2I128 | + Opcode::VPERMD | + Opcode::VPERMILPD | + Opcode::VPERMILPS | + Opcode::VPERMPD | + Opcode::VPERMPS | + Opcode::VPERMQ | + Opcode::VPEXTRB | + Opcode::VPEXTRD | + Opcode::VPEXTRQ | + Opcode::VPEXTRW | + Opcode::VPGATHERDD | + Opcode::VPGATHERDQ | + Opcode::VPGATHERQD | + Opcode::VPGATHERQQ | + Opcode::VPHADDD | + Opcode::VPHADDSW | + Opcode::VPHADDW | + Opcode::VPHADDUBSW | + Opcode::VPHMINPOSUW | + Opcode::VPHSUBD | + Opcode::VPHSUBSW | + Opcode::VPHSUBW | + Opcode::VPINSRB | + Opcode::VPINSRD | + Opcode::VPINSRQ | + Opcode::VPINSRW | + Opcode::VPMADDWD | + Opcode::VPMASKMOVD | + Opcode::VPMASKMOVQ | + Opcode::VPMAXSB | + Opcode::VPMAXSD | + Opcode::VPMAXSW | + Opcode::VPMAXUD | + Opcode::VPMINSD | + Opcode::VPMINUD | + Opcode::VPMOVMSKB | + Opcode::VPMOVSXBD | + Opcode::VPMOVSXBQ | + Opcode::VPMOVSXBW | + Opcode::VPMOVSXDQ | + Opcode::VPMOVSXWD | + Opcode::VPMOVSXWQ | + Opcode::VPMOVZXBD | + Opcode::VPMOVZXBQ | + Opcode::VPMOVZXBW | + Opcode::VPMOVZXDQ | + Opcode::VPMOVZXWD | + Opcode::VPMOVZXWQ | + Opcode::VPMULDQ | + Opcode::VPMULHRSW | + Opcode::VPMULHUW | + Opcode::VPMULHW | + Opcode::VPMULLD | + Opcode::VPMULLW | + Opcode::VPMULUDQ | + Opcode::VPOR | + Opcode::VPSADBW | + Opcode::VPSHUFB | + Opcode::VPSHUFD | + Opcode::VPSIGNB | + Opcode::VPSIGND | + Opcode::VPSIGNW | + Opcode::VPSLLD | + Opcode::VPSLLDQ | + Opcode::VPSLLQ | + Opcode::VPSLLVD | + Opcode::VPSLLVQ | + Opcode::VPSLLW | + Opcode::VPSRAD | + Opcode::VPSRAVD | + Opcode::VPSRAW | + Opcode::VPSRLD | + Opcode::VPSRLDQ | + Opcode::VPSRLQ | + Opcode::VPSRLVD | + Opcode::VPSRLVQ | + Opcode::VPSRLW | + Opcode::VPSUBB | + Opcode::VPSUBD | + Opcode::VPSUBQ | + Opcode::VPSUBSB | + Opcode::VPSUBSW | + Opcode::VPSUBUSB | + Opcode::VPSUBUSW | + Opcode::VPSUBW | + Opcode::VPTEST | + Opcode::VPUNPCKHBW | + Opcode::VPUNPCKHDQ | + Opcode::VPUNPCKHQDQ | + Opcode::VPUNPCKHWD | + Opcode::VPUNPCKLBW | + Opcode::VPUNPCKLDQ | + Opcode::VPUNPCKLQDQ | + Opcode::VPUNPCKLWD | + Opcode::VPXOR | + Opcode::VRCPPS | + Opcode::VROUNDPD | + Opcode::VROUNDPS | + Opcode::VROUNDSD | + Opcode::VROUNDSS | + Opcode::VRSQRTPS | + Opcode::VRSQRTSS | + Opcode::VRCPSS | + Opcode::VSHUFPD | + Opcode::VSHUFPS | + Opcode::VSQRTPD | + Opcode::VSQRTPS | + Opcode::VSQRTSS | + Opcode::VSQRTSD | + Opcode::VSUBPD | + Opcode::VSUBPS | + Opcode::VSUBSD | + Opcode::VSUBSS | + Opcode::VTESTPD | + Opcode::VTESTPS | + Opcode::VUNPCKHPD | + Opcode::VUNPCKHPS | + Opcode::VUNPCKLPD | + Opcode::VUNPCKLPS | + Opcode::VXORPD | + Opcode::VXORPS | + Opcode::VZEROUPPER => { + // TODO: check a table for these + if !self.avx() { + inst.opcode = Opcode::Invalid; + return Err(()); + } + } + Opcode::VAESDEC | + Opcode::VAESDECLAST | + Opcode::VAESENC | + Opcode::VAESENCLAST | + Opcode::VAESIMC | + Opcode::VAESKEYGENASSIST => { + // TODO: check a table for these + if !self.avx() || !self.aesni() { + inst.opcode = Opcode::Invalid; + return Err(()); + } + } _ => {} } Ok(()) @@ -4264,7 +4606,12 @@ pub fn read_instr>(decoder: &InstDecoder, mut bytes_iter: T return Err(()); } else { instruction.prefixes = prefixes; - return vex::two_byte_vex(&mut bytes_iter, instruction, length); + vex::two_byte_vex(&mut bytes_iter, instruction, length)?; + + if decoder != &InstDecoder::default() { + decoder.revise_instruction(instruction)?; + } + return Ok(()); } } else if b == 0xc4 { if prefixes.rex().present() || prefixes.lock() || prefixes.operand_size() || prefixes.rep() || prefixes.repnz() { @@ -4273,7 +4620,11 @@ pub fn read_instr>(decoder: &InstDecoder, mut bytes_iter: T return Err(()); } else { instruction.prefixes = prefixes; - return vex::three_byte_vex(&mut bytes_iter, instruction, length); + vex::three_byte_vex(&mut bytes_iter, instruction, length)?; + if decoder != &InstDecoder::default() { + decoder.revise_instruction(instruction)?; + } + return Ok(()); } } diff --git a/test/test.rs b/test/test.rs index cd2f6c0..662d358 100644 --- a/test/test.rs +++ b/test/test.rs @@ -413,13 +413,6 @@ fn test_test_cmp() { } #[test] -#[ignore] -// VEX prefixes are not supported at the moment, in any form -fn test_avx() { - test_display(&[0xc5, 0xf8, 0x10, 0x00], "vmovups xmm0, [rax]"); -} - -#[test] fn test_push_pop() { test_display(&[0x5b], "pop rbx"); test_display(&[0x41, 0x5e], "pop r14"); @@ -470,95 +463,107 @@ fn evex() { #[test] fn test_vex() { - test_display(&[0xc5, 0xf8, 0x10, 0x00], "vmovups xmm0, [rax]"); - test_display(&[0xc5, 0x78, 0x10, 0x0f], "vmovups xmm9, [rdi]"); - test_display(&[0xc5, 0xf8, 0x10, 0xcf], "vmovups xmm1, xmm7"); - test_display(&[0xc5, 0xf9, 0x10, 0x0f], "vmovupd xmm1, [rdi]"); - test_display(&[0xc5, 0xfa, 0x7e, 0x10], "vmovq xmm2, [rax]"); - test_display(&[0xc5, 0xfc, 0x10, 0x0f], "vmovups ymm1, [rdi]"); - test_display(&[0xc5, 0xfd, 0x10, 0x0f], "vmovupd ymm1, [rdi]"); - test_display(&[0xc5, 0xfe, 0x10, 0x0f], "vmovss xmm1, [rdi]"); - test_display(&[0xc5, 0xff, 0x10, 0xcf], "vmovsd xmm1, xmm0, xmm7"); - test_display(&[0xc5, 0xff, 0x10, 0x00], "vmovsd xmm0, [rax]"); - test_invalid(&[0x4f, 0xc5, 0xf8, 0x10, 0x00]); - test_invalid(&[0xf0, 0xc5, 0xf8, 0x10, 0x00]); - test_display(&[0xc4, 0x02, 0x71, 0x00, 0x0f], "vpshufb xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x00, 0x0f], "vpshufb ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x00, 0xcd], "vpshufb xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x00, 0xcd], "vpshufb ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x01, 0x0f], "vphaddw xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x01, 0x0f], "vphaddw ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x01, 0xcd], "vphaddw xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x01, 0xcd], "vphaddw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x02, 0x0f], "vphaddd xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x02, 0x0f], "vphaddd ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x02, 0xcd], "vphaddd xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x02, 0xcd], "vphaddd ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x03, 0x0f], "vphaddsw xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x03, 0x0f], "vphaddsw ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x03, 0xcd], "vphaddsw xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x03, 0xcd], "vphaddsw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x04, 0x0f], "vphaddubsw xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x04, 0x0f], "vphaddubsw ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x04, 0xcd], "vphaddubsw xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x04, 0xcd], "vphaddubsw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x05, 0x0f], "vphsubw xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x05, 0x0f], "vphsubw ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x05, 0xcd], "vphsubw xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x05, 0xcd], "vphsubw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x06, 0x0f], "vphsubd xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x06, 0x0f], "vphsubd ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x06, 0xcd], "vphsubd xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x06, 0xcd], "vphsubd ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x07, 0x0f], "vphsubsw xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x07, 0x0f], "vphsubsw ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x07, 0xcd], "vphsubsw xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x07, 0xcd], "vphsubsw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x08, 0x0f], "vpsignb xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x08, 0x0f], "vpsignb ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x08, 0xcd], "vpsignb xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x08, 0xcd], "vpsignb ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x09, 0x0f], "vpsignw xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x09, 0x0f], "vpsignw ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x09, 0xcd], "vpsignw xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x09, 0xcd], "vpsignw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x0a, 0x0f], "vpsignd xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x0a, 0x0f], "vpsignd ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x0a, 0xcd], "vpsignd xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x0a, 0xcd], "vpsignd ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x0b, 0x0f], "vpmulhrsw xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x0b, 0x0f], "vpmulhrsw ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x0b, 0xcd], "vpmulhrsw xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x0b, 0xcd], "vpmulhrsw ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x0c, 0x0f], "vpermilps xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x0c, 0x0f], "vpermilps ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x0c, 0xcd], "vpermilps xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x0c, 0xcd], "vpermilps ymm9, ymm1, ymm13"); - test_display(&[0xc4, 0x02, 0x71, 0x0d, 0x0f], "vpermilpd xmm9, xmm1, [r15]"); - test_display(&[0xc4, 0x02, 0x75, 0x0d, 0x0f], "vpermilpd ymm9, ymm1, [r15]"); - test_display(&[0xc4, 0x02, 0x71, 0x0d, 0xcd], "vpermilpd xmm9, xmm1, xmm13"); - test_display(&[0xc4, 0x02, 0x75, 0x0d, 0xcd], "vpermilpd ymm9, ymm1, ymm13"); - test_invalid(&[0xc4, 0x02, 0x71, 0x0e, 0x00]); - test_display(&[0xc4, 0x02, 0x79, 0x0e, 0x0f], "vtestps xmm9, [r15]"); - test_display(&[0xc4, 0x02, 0x7d, 0x0e, 0x0f], "vtestps ymm9, [r15]"); - test_display(&[0xc4, 0x02, 0x79, 0x0e, 0xcd], "vtestps xmm9, xmm13"); - test_display(&[0xc4, 0x02, 0x7d, 0x0e, 0xcd], "vtestps ymm9, ymm13"); - test_invalid(&[0xc4, 0x02, 0x71, 0x0f, 0x00]); - test_display(&[0xc4, 0x02, 0x79, 0x0f, 0x0f], "vtestpd xmm9, [r15]"); - test_display(&[0xc4, 0x02, 0x7d, 0x0f, 0x0f], "vtestpd ymm9, [r15]"); - test_display(&[0xc4, 0x02, 0x79, 0x0f, 0xcd], "vtestpd xmm9, xmm13"); - test_display(&[0xc4, 0x02, 0x7d, 0x0f, 0xcd], "vtestpd ymm9, ymm13"); - test_display(&[0xc4, 0xe2, 0x65, 0x90, 0x04, 0x51], "vpgatherdd ymm0, [rcx + ymm2 * 2], ymm3"); - test_display(&[0xc4, 0xe2, 0xe5, 0x90, 0x04, 0x51], "vpgatherdq ymm0, [rcx + ymm2 * 2], ymm3"); - test_display(&[0xc4, 0xe2, 0x65, 0x91, 0x04, 0x51], "vpgatherqd ymm0, [rcx + ymm2 * 2], ymm3"); - test_display(&[0xc4, 0xe2, 0xe5, 0x91, 0x04, 0x51], "vpgatherqq ymm0, [rcx + ymm2 * 2], ymm3"); - test_display(&[0xc4, 0x02, 0x09, 0x9d, 0xcd], "vfnmadd132ss xmm9, xmm14, xmm13"); - test_display(&[0xc4, 0x02, 0x89, 0x9d, 0xcd], "vfnmadd132sd xmm9, xmm14, xmm13"); + fn test_instr(bytes: &[u8], text: &'static str) { + test_display_under(&InstDecoder::minimal().with_avx(), bytes, text); + test_display_under(&InstDecoder::default(), bytes, text); + test_invalid_under(&InstDecoder::minimal(), bytes); + } + + fn test_instr_invalid(bytes: &[u8]) { + test_invalid_under(&InstDecoder::minimal().with_avx(), bytes); + test_invalid_under(&InstDecoder::default(), bytes); + } + + test_instr(&[0xc5, 0xf8, 0x10, 0x00], "vmovups xmm0, [rax]"); + test_instr(&[0xc5, 0xf8, 0x10, 0x00], "vmovups xmm0, [rax]"); + test_instr(&[0xc5, 0x78, 0x10, 0x0f], "vmovups xmm9, [rdi]"); + test_instr(&[0xc5, 0xf8, 0x10, 0xcf], "vmovups xmm1, xmm7"); + test_instr(&[0xc5, 0xf9, 0x10, 0x0f], "vmovupd xmm1, [rdi]"); + test_instr(&[0xc5, 0xfa, 0x7e, 0x10], "vmovq xmm2, [rax]"); + test_instr(&[0xc5, 0xfc, 0x10, 0x0f], "vmovups ymm1, [rdi]"); + test_instr(&[0xc5, 0xfd, 0x10, 0x0f], "vmovupd ymm1, [rdi]"); + test_instr(&[0xc5, 0xfe, 0x10, 0x0f], "vmovss xmm1, [rdi]"); + test_instr(&[0xc5, 0xff, 0x10, 0xcf], "vmovsd xmm1, xmm0, xmm7"); + test_instr(&[0xc5, 0xff, 0x10, 0x00], "vmovsd xmm0, [rax]"); + test_instr_invalid(&[0x4f, 0xc5, 0xf8, 0x10, 0x00]); + test_instr_invalid(&[0xf0, 0xc5, 0xf8, 0x10, 0x00]); + test_instr(&[0xc4, 0x02, 0x71, 0x00, 0x0f], "vpshufb xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x00, 0x0f], "vpshufb ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x00, 0xcd], "vpshufb xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x00, 0xcd], "vpshufb ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x01, 0x0f], "vphaddw xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x01, 0x0f], "vphaddw ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x01, 0xcd], "vphaddw xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x01, 0xcd], "vphaddw ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x02, 0x0f], "vphaddd xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x02, 0x0f], "vphaddd ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x02, 0xcd], "vphaddd xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x02, 0xcd], "vphaddd ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x03, 0x0f], "vphaddsw xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x03, 0x0f], "vphaddsw ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x03, 0xcd], "vphaddsw xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x03, 0xcd], "vphaddsw ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x04, 0x0f], "vphaddubsw xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x04, 0x0f], "vphaddubsw ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x04, 0xcd], "vphaddubsw xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x04, 0xcd], "vphaddubsw ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x05, 0x0f], "vphsubw xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x05, 0x0f], "vphsubw ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x05, 0xcd], "vphsubw xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x05, 0xcd], "vphsubw ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x06, 0x0f], "vphsubd xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x06, 0x0f], "vphsubd ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x06, 0xcd], "vphsubd xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x06, 0xcd], "vphsubd ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x07, 0x0f], "vphsubsw xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x07, 0x0f], "vphsubsw ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x07, 0xcd], "vphsubsw xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x07, 0xcd], "vphsubsw ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x08, 0x0f], "vpsignb xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x08, 0x0f], "vpsignb ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x08, 0xcd], "vpsignb xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x08, 0xcd], "vpsignb ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x09, 0x0f], "vpsignw xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x09, 0x0f], "vpsignw ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x09, 0xcd], "vpsignw xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x09, 0xcd], "vpsignw ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x0a, 0x0f], "vpsignd xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x0a, 0x0f], "vpsignd ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x0a, 0xcd], "vpsignd xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x0a, 0xcd], "vpsignd ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x0b, 0x0f], "vpmulhrsw xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x0b, 0x0f], "vpmulhrsw ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x0b, 0xcd], "vpmulhrsw xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x0b, 0xcd], "vpmulhrsw ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x0c, 0x0f], "vpermilps xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x0c, 0x0f], "vpermilps ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x0c, 0xcd], "vpermilps xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x0c, 0xcd], "vpermilps ymm9, ymm1, ymm13"); + test_instr(&[0xc4, 0x02, 0x71, 0x0d, 0x0f], "vpermilpd xmm9, xmm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x75, 0x0d, 0x0f], "vpermilpd ymm9, ymm1, [r15]"); + test_instr(&[0xc4, 0x02, 0x71, 0x0d, 0xcd], "vpermilpd xmm9, xmm1, xmm13"); + test_instr(&[0xc4, 0x02, 0x75, 0x0d, 0xcd], "vpermilpd ymm9, ymm1, ymm13"); + test_instr_invalid(&[0xc4, 0x02, 0x71, 0x0e, 0x00]); + test_instr(&[0xc4, 0x02, 0x79, 0x0e, 0x0f], "vtestps xmm9, [r15]"); + test_instr(&[0xc4, 0x02, 0x7d, 0x0e, 0x0f], "vtestps ymm9, [r15]"); + test_instr(&[0xc4, 0x02, 0x79, 0x0e, 0xcd], "vtestps xmm9, xmm13"); + test_instr(&[0xc4, 0x02, 0x7d, 0x0e, 0xcd], "vtestps ymm9, ymm13"); + test_instr_invalid(&[0xc4, 0x02, 0x71, 0x0f, 0x00]); + test_instr(&[0xc4, 0x02, 0x79, 0x0f, 0x0f], "vtestpd xmm9, [r15]"); + test_instr(&[0xc4, 0x02, 0x7d, 0x0f, 0x0f], "vtestpd ymm9, [r15]"); + test_instr(&[0xc4, 0x02, 0x79, 0x0f, 0xcd], "vtestpd xmm9, xmm13"); + test_instr(&[0xc4, 0x02, 0x7d, 0x0f, 0xcd], "vtestpd ymm9, ymm13"); + test_instr(&[0xc4, 0xe2, 0x65, 0x90, 0x04, 0x51], "vpgatherdd ymm0, [rcx + ymm2 * 2], ymm3"); + test_instr(&[0xc4, 0xe2, 0xe5, 0x90, 0x04, 0x51], "vpgatherdq ymm0, [rcx + ymm2 * 2], ymm3"); + test_instr(&[0xc4, 0xe2, 0x65, 0x91, 0x04, 0x51], "vpgatherqd ymm0, [rcx + ymm2 * 2], ymm3"); + test_instr(&[0xc4, 0xe2, 0xe5, 0x91, 0x04, 0x51], "vpgatherqq ymm0, [rcx + ymm2 * 2], ymm3"); + test_instr(&[0xc4, 0x02, 0x09, 0x9d, 0xcd], "vfnmadd132ss xmm9, xmm14, xmm13"); + test_instr(&[0xc4, 0x02, 0x89, 0x9d, 0xcd], "vfnmadd132sd xmm9, xmm14, xmm13"); // ... - test_display(&[0xc4, 0xe3, 0x79, 0x14, 0xd0, 0x0a], "vpextrb rax, xmm2, 0xa"); - test_display(&[0xc4, 0xe3, 0x79, 0x14, 0x10, 0x0a], "vpextrb [rax], xmm2, 0xa"); - test_invalid(&[0xc4, 0xe3, 0xf9, 0x14, 0x00, 0xd0]); - test_invalid(&[0xc4, 0xe3, 0xf9, 0x14, 0x00, 0x0a]); + test_instr(&[0xc4, 0xe3, 0x79, 0x14, 0xd0, 0x0a], "vpextrb rax, xmm2, 0xa"); + test_instr(&[0xc4, 0xe3, 0x79, 0x14, 0x10, 0x0a], "vpextrb [rax], xmm2, 0xa"); + test_instr_invalid(&[0xc4, 0xe3, 0xf9, 0x14, 0x00, 0xd0]); + test_instr_invalid(&[0xc4, 0xe3, 0xf9, 0x14, 0x00, 0x0a]); } #[test] -- cgit v1.1