From 48559b18574b44e2de879a5c641ab602ec22f0d8 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 4 Jul 2021 12:20:13 -0700 Subject: fix several incorrect tests and docs in 64- and 32-bit modes --- src/lib.rs | 34 ++++++++++++++++++++++++-- src/long_mode/mod.rs | 2 +- src/long_mode/vex.rs | 10 ++++---- src/protected_mode/display.rs | 12 +++++----- src/protected_mode/mod.rs | 55 ++++++++++++++++++++++++++++++------------- src/protected_mode/vex.rs | 28 ++++++---------------- test/long_mode/mod.rs | 14 +++++------ test/protected_mode/mod.rs | 41 ++++++++++++++++---------------- 8 files changed, 118 insertions(+), 78 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cb879fd..057c125 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,8 +84,8 @@ mod real_mode; pub use real_mode::Arch as x86_16; const MEM_SIZE_STRINGS: [&'static str; 64] = [ - "byte", "word", "BUG", "dword", "far", "ptr", "BUG", "qword", - "far", "mword", "BUG", "BUG", "BUG", "BUG", "BUG", "xmmword", + "byte", "word", "BUG", "dword", "ptr", "far", "BUG", "qword", + "BUG", "mword", "BUG", "BUG", "BUG", "BUG", "BUG", "xmmword", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "ymmword", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", @@ -98,6 +98,11 @@ pub struct MemoryAccessSize { size: u8, } impl MemoryAccessSize { + /// return the number of bytes referenced by this memory access. + /// + /// if the number of bytes cannot be confidently known by the instruction in isolation (as is + /// the case for `xsave`/`xrstor`-style "operate on all processor state" instructions), this + /// function will return `None`. pub fn bytes_size(&self) -> Option { if self.size == 63 { None @@ -106,6 +111,31 @@ impl MemoryAccessSize { } } + /// a human-friendly label for the number of bytes this memory access references. + /// + /// there are some differences from size names that may be expected elsewhere; `yaxpeax-x86` + /// prefers to use consistent names for a width even if the way those bytes are used varies. + /// + /// the sizes `yaxpeax-x86` knows are as follows: + /// | size (bytes) | name | + /// |--------------|------------| + /// | 1 | `byte` | + /// | 2 | `word` | + /// | 4 | `dword` | + /// | 6 | `far` | + /// | 8 | `qword` | + /// | 10 | `mword` | + /// | 16 | `xmmword` | + /// | 32 | `ymmword` | + /// | 64 | `zmmword` | + /// | variable | `ptr` | + /// + /// "mword" refers to an mmx-sized access - 80 bits, or 10 bytes. `mword` is also used for + /// 64-bit far calls, because they reference a contiguous ten bytes; two bytes of segment + /// selector and eight bytes of address. + /// + /// "variable" accesses access a number of bytes dependent on the physical processor and its + /// operating mode. this is particularly relevant for `xsave`/`xrstor`-style instructions. pub fn size_name(&self) -> &'static str { MEM_SIZE_STRINGS[self.size as usize - 1] } diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 600a81a..79f3fee 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -7673,7 +7673,7 @@ fn read_operands::Address, ::Address, ::Address, (Opcode::VPMINSW, if L { + 0xDA => (Opcode::VPMINUB, if L { VEXOperandCode::G_V_E_ymm } else { VEXOperandCode::G_V_E_xmm @@ -3201,12 +3201,12 @@ fn read_vex_instruction::Address, (Opcode::VROUNDSS, if L { - VEXOperandCode::G_V_E_ymm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 } else { VEXOperandCode::G_V_E_xmm_imm8 }), 0x0B => (Opcode::VROUNDSD, if L { - VEXOperandCode::G_V_E_ymm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 } else { VEXOperandCode::G_V_E_xmm_imm8 }), @@ -3269,7 +3269,7 @@ fn read_vex_instruction::Address, Colorize for Opcode { Opcode::AAS | Opcode::DAS | Opcode::DAA | - Opcode::ADX | - Opcode::AMX | + Opcode::AAD | + Opcode::AAM | Opcode::KADDB | Opcode::KANDB | Opcode::KANDNB | @@ -2403,7 +2403,7 @@ impl Colorize for Opcode { Opcode::LOOPNZ | Opcode::LOOPZ | Opcode::LOOP | - Opcode::JRCXZ | + Opcode::JECXZ | Opcode::CALL | Opcode::CALLF | Opcode::JMP | diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index 3678bf8..a6ad2ee 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -888,7 +888,7 @@ const REGISTER_CLASS_NAMES: &[&'static str] = &[ "eflags", ]; -/// high-level register classes in an x86 machine, such as "8-byte general purpose", "xmm", "x87", +/// high-level register classes in an x86 machine, such as "4-byte general purpose", "xmm", "x87", /// and so on. constants in this module are useful for inspecting the register class of a decoded /// instruction. as an example: /// ``` @@ -2078,7 +2078,7 @@ pub enum Opcode { LOOPNZ, LOOPZ, LOOP, - JRCXZ, + JECXZ, PUSHA, POPA, @@ -2088,8 +2088,8 @@ pub enum Opcode { AAA, DAS, DAA, - AMX, - ADX, + AAM, + AAD, // started shipping in Tremont, 2020 sept 23 MOVDIR64B, @@ -5471,8 +5471,8 @@ const OPCODES: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xd1_Ev_1), OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xd2_Eb_CL), OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xd3_Ev_CL), - OpcodeRecord(Interpretation::Instruction(Opcode::AMX), OperandCode::Ib), - OpcodeRecord(Interpretation::Instruction(Opcode::ADX), OperandCode::Ib), + OpcodeRecord(Interpretation::Instruction(Opcode::AAM), OperandCode::Ib), + OpcodeRecord(Interpretation::Instruction(Opcode::AAD), OperandCode::Ib), OpcodeRecord(Interpretation::Instruction(Opcode::SALC), OperandCode::Nothing), // XLAT OpcodeRecord(Interpretation::Instruction(Opcode::XLAT), OperandCode::Nothing), @@ -5496,7 +5496,7 @@ const OPCODES: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::LOOPNZ), OperandCode::Ibs), OpcodeRecord(Interpretation::Instruction(Opcode::LOOPZ), OperandCode::Ibs), OpcodeRecord(Interpretation::Instruction(Opcode::LOOP), OperandCode::Ibs), - OpcodeRecord(Interpretation::Instruction(Opcode::JRCXZ), OperandCode::Ibs), + OpcodeRecord(Interpretation::Instruction(Opcode::JECXZ), OperandCode::Ibs), OpcodeRecord(Interpretation::Instruction(Opcode::IN), OperandCode::AL_Ib), OpcodeRecord(Interpretation::Instruction(Opcode::IN), OperandCode::AX_Ib), OpcodeRecord(Interpretation::Instruction(Opcode::OUT), OperandCode::Ib_AL), @@ -5721,19 +5721,35 @@ fn read_M_16bit::Address, { - instr.disp = read_num(words, 1)?; + instr.disp = read_num(words, 1)? as i8 as i32 as u32; if mmm > 3 { - Ok(OperandSpec::RegDisp) + if instr.disp != 0 { + Ok(OperandSpec::RegDisp) + } else { + Ok(OperandSpec::Deref) + } } else { - Ok(OperandSpec::RegIndexBaseDisp) + if instr.disp != 0 { + Ok(OperandSpec::RegIndexBaseDisp) + } else { + Ok(OperandSpec::RegIndexBase) + } } }, 0b10 => { - instr.disp = read_num(words, 2)?; + instr.disp = read_num(words, 2)? as i16 as i32 as u32; if mmm > 3 { - Ok(OperandSpec::RegDisp) + if instr.disp != 0 { + Ok(OperandSpec::RegDisp) + } else { + Ok(OperandSpec::Deref) + } } else { - Ok(OperandSpec::RegIndexBaseDisp) + if instr.disp != 0 { + Ok(OperandSpec::RegIndexBaseDisp) + } else { + Ok(OperandSpec::RegIndexBase) + } } }, _ => { @@ -7528,7 +7544,7 @@ fn read_operands::Address, ::Address, > 3) & 7 }; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = read_E_xmm(words, instruction, modrm)?; + if instruction.opcode == Opcode::CVTTSD2SI || instruction.opcode == Opcode::CVTSD2SI { + instruction.regs[0].bank = RegisterBank::D; + } if instruction.operands[1] != OperandSpec::RegMMM { if [Opcode::PMOVSXBQ, Opcode::PMOVZXBQ].contains(&instruction.opcode) { instruction.mem_size = 2; @@ -8462,7 +8481,7 @@ fn unlikely_operands::Address, { instruction.opcode = Opcode::RDPID; - instruction.operands[0] = read_E(words, instruction, modrm, opwidth)?; + instruction.operands[0] = read_E(words, instruction, modrm, 4)?; if instruction.operands[0] != OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); } @@ -9668,7 +9687,11 @@ fn unlikely_operands::Address, { instruction.opcode = Opcode::UMONITOR; - instruction.regs[1] = RegSpec::from_parts(m, RegisterBank::D); + if instruction.prefixes.address_size() { + instruction.regs[1] = RegSpec::from_parts(m, RegisterBank::W); + } else { + instruction.regs[1] = RegSpec::from_parts(m, RegisterBank::D); + }; instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs index 053d1aa..3550f77 100644 --- a/src/protected_mode/vex.rs +++ b/src/protected_mode/vex.rs @@ -412,7 +412,7 @@ fn read_vex_operands::Address, ::Address, (Opcode::VPMINSW, if L { + 0xDA => (Opcode::VPMINUB, if L { VEXOperandCode::G_V_E_ymm } else { VEXOperandCode::G_V_E_xmm @@ -3130,12 +3130,12 @@ fn read_vex_instruction::Address, (Opcode::VROUNDSS, if L { - VEXOperandCode::G_V_E_ymm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 } else { VEXOperandCode::G_V_E_xmm_imm8 }), 0x0B => (Opcode::VROUNDSD, if L { - VEXOperandCode::G_V_E_ymm_imm8 + VEXOperandCode::G_V_E_xmm_imm8 } else { VEXOperandCode::G_V_E_xmm_imm8 }), @@ -3171,14 +3171,7 @@ fn read_vex_instruction::Address, if instruction.prefixes.vex_unchecked().w() { - (Opcode::VPEXTRQ, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } else { - VEXOperandCode::Ev_G_xmm_imm8 - }) - } else { + 0x16 => { (Opcode::VPEXTRD, if L { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); @@ -3198,7 +3191,7 @@ fn read_vex_instruction::Address, ::Address, if instruction.prefixes.vex_unchecked().w() { - (Opcode::VPINSRQ, if L { - instruction.opcode = Opcode::Invalid; - return Err(DecodeError::InvalidOpcode); - } else { - VEXOperandCode::G_V_xmm_Ev_imm8 - }) - } else { + 0x22 => { (Opcode::VPINSRD, if L { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOpcode); diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index d33a4ec..6c2cdc9 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -1218,7 +1218,7 @@ fn test_control_flow() { test_display(&[0x66, 0xff, 0xe0], "jmp rax"); test_display(&[0x67, 0xff, 0xe0], "jmp rax"); test_invalid(&[0xff, 0xd8]); - test_display(&[0xff, 0x18], "callf far [rax]"); + test_display(&[0xff, 0x18], "callf mword [rax]"); test_display(&[0xe0, 0x12], "loopnz 0x12"); test_display(&[0xe1, 0x12], "loopz 0x12"); test_display(&[0xe2, 0x12], "loop 0x12"); @@ -1489,9 +1489,9 @@ fn test_vex() { test_invalid(&[0xc4, 0b000_00011, 0b0_0111_001, 0x09, 0b11_001_010, 0x77]); test_invalid(&[0xc4, 0b000_00011, 0b0_0111_101, 0x09, 0b11_001_010, 0x77]); test_instr(&[0xc4, 0b000_00011, 0b0_0111_001, 0x0a, 0b11_001_010, 0x77], "vroundss xmm9, xmm8, xmm10, 0x77"); - test_instr(&[0xc4, 0b000_00011, 0b0_0111_101, 0x0a, 0b11_001_010, 0x77], "vroundss ymm9, ymm8, ymm10, 0x77"); + test_instr(&[0xc4, 0b000_00011, 0b0_0111_101, 0x0a, 0b11_001_010, 0x77], "vroundss xmm9, xmm8, xmm10, 0x77"); test_instr(&[0xc4, 0b000_00011, 0b0_0111_001, 0x0b, 0b11_001_010, 0x77], "vroundsd xmm9, xmm8, xmm10, 0x77"); - test_instr(&[0xc4, 0b000_00011, 0b0_0111_101, 0x0b, 0b11_001_010, 0x77], "vroundsd ymm9, ymm8, ymm10, 0x77"); + test_instr(&[0xc4, 0b000_00011, 0b0_0111_101, 0x0b, 0b11_001_010, 0x77], "vroundsd xmm9, xmm8, xmm10, 0x77"); test_instr(&[0xc4, 0b000_00011, 0b1_0111_001, 0x0f, 0b11_001_010, 0x77], "vpalignr xmm9, xmm8, xmm10, 0x77"); test_instr(&[0xc4, 0b000_00011, 0b1_0111_101, 0x0f, 0b11_001_010, 0x77], "vpalignr ymm9, ymm8, ymm10, 0x77"); @@ -1517,7 +1517,7 @@ fn test_vex() { test_invalid(&[0xc4, 0b000_00011, 0b0_0111_101, 0x17, 0b00_001_010, 0x77]); test_invalid(&[0xc4, 0b000_00011, 0b1_0111_001, 0x18, 0b11_001_010, 0x77]); - test_instr(&[0xc4, 0b000_00011, 0b0_0111_101, 0x18, 0b11_001_010, 0x77], "vinsertf128 ymm9, ymm8, ymm10, 0x77"); + test_instr(&[0xc4, 0b000_00011, 0b0_0111_101, 0x18, 0b11_001_010, 0x77], "vinsertf128 ymm9, ymm8, xmm10, 0x77"); test_invalid(&[0xc4, 0b000_00011, 0b1_0111_101, 0x18, 0b11_001_010, 0x77]); test_instr(&[0xc4, 0b000_00011, 0b0_1111_101, 0x19, 0b11_001_010, 0x77], "vextractf128 xmm10, ymm9, 0x77"); test_invalid(&[0xc4, 0b000_00011, 0b0_1111_001, 0x19, 0b11_001_010, 0x77]); @@ -1853,7 +1853,7 @@ fn test_vex() { test_invalid(&[0xc4, 0b000_00001, 0b0_0111_011, 0x12, 0b00_001_010]); test_invalid(&[0xc4, 0b000_00001, 0b0_0111_111, 0x12, 0b00_001_010]); test_instr(&[0xc4, 0b000_00001, 0b1_0111_000, 0x12, 0b11_001_010], "vmovhlps xmm9, xmm8, xmm10"); - test_instr(&[0xc4, 0b000_00001, 0b1_0111_000, 0x12, 0b00_001_010], "vmovlps xmm9, xmm8, dword [r10]"); + test_instr(&[0xc4, 0b000_00001, 0b1_0111_000, 0x12, 0b00_001_010], "vmovlps xmm9, xmm8, qword [r10]"); test_invalid(&[0xc4, 0b000_00001, 0b1_0111_100, 0x12, 0b11_001_010]); test_invalid(&[0xc4, 0b000_00001, 0b1_0111_111, 0x12, 0b11_001_010]); test_instr(&[0xc4, 0b000_00001, 0b1_1111_010, 0x12, 0b00_001_010], "vmovsldup xmm9, xmmword [r10]"); @@ -2269,8 +2269,8 @@ fn test_vex() { test_instr(&[0xc4, 0b000_00001, 0b1_0111_001, 0xd9, 0b11_001_010], "vpsubusw xmm9, xmm8, xmm10"); test_avx2(&[0xc4, 0b000_00001, 0b1_0111_101, 0xd9, 0b11_001_010], "vpsubusw ymm9, ymm8, ymm10"); - test_instr(&[0xc4, 0b000_00001, 0b0_0111_001, 0xda, 0b11_001_010], "vpminsw xmm9, xmm8, xmm10"); - test_avx2(&[0xc4, 0b000_00001, 0b0_0111_101, 0xda, 0b11_001_010], "vpminsw ymm9, ymm8, ymm10"); + test_instr(&[0xc4, 0b000_00001, 0b0_0111_001, 0xda, 0b11_001_010], "vpminub xmm9, xmm8, xmm10"); + test_avx2(&[0xc4, 0b000_00001, 0b0_0111_101, 0xda, 0b11_001_010], "vpminub ymm9, ymm8, ymm10"); test_instr(&[0xc4, 0b000_00001, 0b1_0111_001, 0xdb, 0b11_001_010], "vpand xmm9, xmm8, xmm10"); test_avx2(&[0xc4, 0b000_00001, 0b1_0111_101, 0xdb, 0b11_001_010], "vpand ymm9, ymm8, ymm10"); test_instr(&[0xc4, 0b000_00001, 0b1_0111_001, 0xdc, 0b11_001_010], "vpaddusb xmm9, xmm8, xmm10"); diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index 76876e3..dd52cfe 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -247,12 +247,12 @@ fn test_sse2() { test_instr(&[0x66, 0x0f, 0x2b, 0x0f], "movntpd xmmword [edi], xmm1"); test_instr(&[0x66, 0x0f, 0x2c, 0xcf], "cvttpd2pi mm1, xmm7"); test_instr(&[0x66, 0x0f, 0x2c, 0x0f], "cvttpd2pi mm1, xmmword [edi]"); - test_instr(&[0xf2, 0x0f, 0x2c, 0xcf], "cvttsd2si xmm1, xmm7"); - test_instr(&[0xf2, 0x0f, 0x2c, 0x0f], "cvttsd2si xmm1, qword [edi]"); + test_instr(&[0xf2, 0x0f, 0x2c, 0xcf], "cvttsd2si ecx, xmm7"); + test_instr(&[0xf2, 0x0f, 0x2c, 0x0f], "cvttsd2si ecx, qword [edi]"); test_instr(&[0x66, 0x0f, 0x2d, 0xcf], "cvtpd2pi mm1, xmm7"); test_instr(&[0x66, 0x0f, 0x2d, 0x0f], "cvtpd2pi mm1, xmmword [edi]"); - test_instr(&[0xf2, 0x0f, 0x2d, 0xcf], "cvtsd2si xmm1, xmm7"); - test_instr(&[0xf2, 0x0f, 0x2d, 0x0f], "cvtsd2si xmm1, qword [edi]"); + test_instr(&[0xf2, 0x0f, 0x2d, 0xcf], "cvtsd2si ecx, xmm7"); + test_instr(&[0xf2, 0x0f, 0x2d, 0x0f], "cvtsd2si ecx, qword [edi]"); test_instr(&[0x66, 0x0f, 0x2e, 0xcf], "ucomisd xmm1, xmm7"); test_instr(&[0x66, 0x0f, 0x2e, 0x0f], "ucomisd xmm1, qword [edi]"); test_instr(&[0x66, 0x0f, 0x2f, 0xcf], "comisd xmm1, xmm7"); @@ -1108,7 +1108,7 @@ fn test_control_flow() { test_display(&[0xe0, 0x12], "loopnz 0x12"); test_display(&[0xe1, 0x12], "loopz 0x12"); test_display(&[0xe2, 0x12], "loop 0x12"); - test_display(&[0xe3, 0x12], "jrcxz 0x12"); + test_display(&[0xe3, 0x12], "jecxz 0x12"); test_display(&[0xc3], "ret"); } @@ -1291,6 +1291,7 @@ fn test_misc() { test_display(&[0x66, 0x0f, 0xae, 0x37], "clwb zmmword [edi]"); test_display(&[0x66, 0x0f, 0xae, 0xf7], "tpause edi"); test_display(&[0xf3, 0x0f, 0xae, 0xf1], "umonitor ecx"); + test_display(&[0x67, 0xf3, 0x0f, 0xae, 0xf1], "umonitor cx"); test_display(&[0xf2, 0x0f, 0xae, 0xf1], "umwait ecx"); test_display(&[0x66, 0x0f, 0x38, 0x80, 0x2f], "invept ebp, xmmword [edi]"); test_invalid(&[0x0f, 0x38, 0x80, 0x2f]); @@ -1371,9 +1372,9 @@ fn test_vex() { test_invalid(&[0xc4, 0b110_00011, 0b0_0111_001, 0x09, 0b11_001_010, 0x77]); test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x09, 0b11_001_010, 0x77]); test_instr(&[0xc4, 0b110_00011, 0b0_0111_001, 0x0a, 0b11_001_010, 0x77], "vroundss xmm1, xmm0, xmm2, 0x77"); - test_instr(&[0xc4, 0b110_00011, 0b0_0111_101, 0x0a, 0b11_001_010, 0x77], "vroundss ymm1, ymm0, ymm2, 0x77"); + test_instr(&[0xc4, 0b110_00011, 0b0_0111_101, 0x0a, 0b11_001_010, 0x77], "vroundss xmm1, xmm0, xmm2, 0x77"); test_instr(&[0xc4, 0b110_00011, 0b0_0111_001, 0x0b, 0b11_001_010, 0x77], "vroundsd xmm1, xmm0, xmm2, 0x77"); - test_instr(&[0xc4, 0b110_00011, 0b0_0111_101, 0x0b, 0b11_001_010, 0x77], "vroundsd ymm1, ymm0, ymm2, 0x77"); + test_instr(&[0xc4, 0b110_00011, 0b0_0111_101, 0x0b, 0b11_001_010, 0x77], "vroundsd xmm1, xmm0, xmm2, 0x77"); test_instr(&[0xc4, 0b110_00011, 0b1_0111_001, 0x0f, 0b11_001_010, 0x77], "vpalignr xmm1, xmm0, xmm2, 0x77"); test_instr(&[0xc4, 0b110_00011, 0b1_0111_101, 0x0f, 0b11_001_010, 0x77], "vpalignr ymm1, ymm0, ymm2, 0x77"); @@ -1390,16 +1391,16 @@ fn test_vex() { test_instr(&[0xc4, 0b110_00011, 0b0_1111_001, 0x16, 0b00_001_010, 0x77], "vpextrd dword [edx], xmm1, 0x77"); test_invalid(&[0xc4, 0b110_00011, 0b0_0111_001, 0x16, 0b00_001_010, 0x77]); test_invalid(&[0xc4, 0b110_00011, 0b0_1111_101, 0x16, 0b00_001_010, 0x77]); - test_instr(&[0xc4, 0b110_00011, 0b1_1111_001, 0x16, 0b11_001_010, 0x77], "vpextrq edx, xmm1, 0x77"); + test_instr(&[0xc4, 0b110_00011, 0b1_1111_001, 0x16, 0b11_001_010, 0x77], "vpextrd edx, xmm1, 0x77"); test_invalid(&[0xc4, 0b110_00011, 0b1_0111_001, 0x16, 0b00_001_010, 0x77]); - test_instr(&[0xc4, 0b110_00011, 0b1_1111_001, 0x16, 0b00_001_010, 0x77], "vpextrq qword [edx], xmm1, 0x77"); + test_instr(&[0xc4, 0b110_00011, 0b1_1111_001, 0x16, 0b00_001_010, 0x77], "vpextrd dword [edx], xmm1, 0x77"); test_instr(&[0xc4, 0b110_00011, 0b0_1111_001, 0x17, 0b11_001_010, 0x77], "vextractps edx, xmm1, 0x77"); test_instr(&[0xc4, 0b110_00011, 0b0_1111_001, 0x17, 0b00_001_010, 0x77], "vextractps dword [edx], xmm1, 0x77"); test_invalid(&[0xc4, 0b110_00011, 0b0_1111_101, 0x17, 0b00_001_010, 0x77]); test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x17, 0b00_001_010, 0x77]); test_invalid(&[0xc4, 0b110_00011, 0b1_0111_001, 0x18, 0b11_001_010, 0x77]); - test_instr(&[0xc4, 0b110_00011, 0b0_0111_101, 0x18, 0b11_001_010, 0x77], "vinsertf128 ymm1, ymm0, ymm2, 0x77"); + test_instr(&[0xc4, 0b110_00011, 0b0_0111_101, 0x18, 0b11_001_010, 0x77], "vinsertf128 ymm1, ymm0, xmm2, 0x77"); test_invalid(&[0xc4, 0b110_00011, 0b1_0111_101, 0x18, 0b11_001_010, 0x77]); test_instr(&[0xc4, 0b110_00011, 0b0_1111_101, 0x19, 0b11_001_010, 0x77], "vextractf128 xmm2, ymm1, 0x77"); test_invalid(&[0xc4, 0b110_00011, 0b0_1111_001, 0x19, 0b11_001_010, 0x77]); @@ -1420,8 +1421,8 @@ fn test_vex() { test_instr(&[0xc4, 0b110_00011, 0b0_0111_001, 0x22, 0b11_001_010, 0x77], "vpinsrd xmm1, xmm0, edx, 0x77"); test_instr(&[0xc4, 0b110_00011, 0b0_0111_001, 0x22, 0b00_001_010, 0x77], "vpinsrd xmm1, xmm0, dword [edx], 0x77"); test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x22, 0b00_001_010, 0x77]); - test_instr(&[0xc4, 0b110_00011, 0b1_0111_001, 0x22, 0b11_001_010, 0x77], "vpinsrq xmm1, xmm0, edx, 0x77"); - test_instr(&[0xc4, 0b110_00011, 0b1_0111_001, 0x22, 0b00_001_010, 0x77], "vpinsrq xmm1, xmm0, qword [edx], 0x77"); + test_instr(&[0xc4, 0b110_00011, 0b1_0111_001, 0x22, 0b11_001_010, 0x77], "vpinsrd xmm1, xmm0, edx, 0x77"); + test_instr(&[0xc4, 0b110_00011, 0b1_0111_001, 0x22, 0b00_001_010, 0x77], "vpinsrd xmm1, xmm0, dword [edx], 0x77"); test_invalid(&[0xc4, 0b110_00011, 0b1_0111_101, 0x22, 0b00_001_010, 0x77]); test_instr(&[0xc4, 0b110_00011, 0b0_0111_001, 0x40, 0b11_001_010, 0x77], "vdpps xmm1, xmm0, xmm2, 0x77"); @@ -1737,7 +1738,7 @@ fn test_vex() { test_invalid(&[0xc4, 0b110_00001, 0b0_0111_011, 0x12, 0b00_001_010]); test_invalid(&[0xc4, 0b110_00001, 0b0_0111_111, 0x12, 0b00_001_010]); test_instr(&[0xc4, 0b110_00001, 0b1_0111_000, 0x12, 0b11_001_010], "vmovhlps xmm1, xmm0, xmm2"); - test_instr(&[0xc4, 0b110_00001, 0b1_0111_000, 0x12, 0b00_001_010], "vmovlps xmm1, xmm0, dword [edx]"); + test_instr(&[0xc4, 0b110_00001, 0b1_0111_000, 0x12, 0b00_001_010], "vmovlps xmm1, xmm0, qword [edx]"); test_invalid(&[0xc4, 0b110_00001, 0b1_0111_100, 0x12, 0b11_001_010]); test_invalid(&[0xc4, 0b110_00001, 0b1_0111_111, 0x12, 0b11_001_010]); test_instr(&[0xc4, 0b110_00001, 0b1_1111_010, 0x12, 0b00_001_010], "vmovsldup xmm1, xmmword [edx]"); @@ -2131,8 +2132,8 @@ fn test_vex() { test_avx2(&[0xc4, 0b110_00001, 0b1_0111_101, 0xd8, 0b11_001_010], "vpsubusb ymm1, ymm0, ymm2"); test_instr(&[0xc4, 0b110_00001, 0b1_0111_001, 0xd9, 0b11_001_010], "vpsubusw xmm1, xmm0, xmm2"); test_avx2(&[0xc4, 0b110_00001, 0b1_0111_101, 0xd9, 0b11_001_010], "vpsubusw ymm1, ymm0, ymm2"); - test_instr(&[0xc4, 0b110_00001, 0b0_0111_001, 0xda, 0b11_001_010], "vpminsw xmm1, xmm0, xmm2"); - test_avx2(&[0xc4, 0b110_00001, 0b0_0111_101, 0xda, 0b11_001_010], "vpminsw ymm1, ymm0, ymm2"); + test_instr(&[0xc4, 0b110_00001, 0b0_0111_001, 0xda, 0b11_001_010], "vpminub xmm1, xmm0, xmm2"); + test_avx2(&[0xc4, 0b110_00001, 0b0_0111_101, 0xda, 0b11_001_010], "vpminub ymm1, ymm0, ymm2"); test_instr(&[0xc4, 0b110_00001, 0b1_0111_001, 0xdb, 0b11_001_010], "vpand xmm1, xmm0, xmm2"); test_avx2(&[0xc4, 0b110_00001, 0b1_0111_101, 0xdb, 0b11_001_010], "vpand ymm1, ymm0, ymm2"); test_instr(&[0xc4, 0b110_00001, 0b1_0111_001, 0xdc, 0b11_001_010], "vpaddusb xmm1, xmm0, xmm2"); @@ -2387,12 +2388,12 @@ fn only_32bit() { test_display(&[0x2f], "das"); test_display(&[0x37], "aaa"); test_display(&[0x3f], "aas"); - test_display(&[0xd4, 0x01], "amx 0x1"); - test_display(&[0xd4, 0x0a], "amx 0xa"); // aka "aam" - test_display(&[0xd5, 0x01], "adx 0x1"); - test_display(&[0xd5, 0x0a], "adx 0xa"); // aka "aad" + test_display(&[0xd4, 0x01], "aam 0x1"); + test_display(&[0xd4, 0x0a], "aam 0xa"); + test_display(&[0xd5, 0x01], "aad 0x1"); + test_display(&[0xd5, 0x0a], "aad 0xa"); - test_display(&[0xc5, 0x78, 0x10], "lds edi, ptr [eax + 0x10]"); + test_display(&[0xc5, 0x78, 0x10], "lds edi, far [eax + 0x10]"); test_display(&[0x66, 0xc5, 0x78, 0x10], "lds di, dword [eax + 0x10]"); } -- cgit v1.1