diff options
author | iximeow <me@iximeow.net> | 2021-06-28 00:09:40 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2021-06-28 00:09:40 -0700 |
commit | 5a1fd6f773320c845f2549722b9f27094d68bdf2 (patch) | |
tree | e65285474a54641c70761db9f38ab5a2c1460748 /src/protected_mode | |
parent | c42f84b37c9be599442a44caab289f5fdf971649 (diff) |
protected mode memory sizes
also some long-mode cleanup in corresponding areas
Diffstat (limited to 'src/protected_mode')
-rw-r--r-- | src/protected_mode/display.rs | 4 | ||||
-rw-r--r-- | src/protected_mode/mod.rs | 688 | ||||
-rw-r--r-- | src/protected_mode/vex.rs | 94 |
3 files changed, 627 insertions, 159 deletions
diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs index f258bad..1964758 100644 --- a/src/protected_mode/display.rs +++ b/src/protected_mode/display.rs @@ -3314,8 +3314,8 @@ impl Instruction { } const MEM_SIZE_STRINGS: [&'static str; 64] = [ - "byte", "word", "BUG", "dword", "BUG", "BUG", "BUG", "qword", - "far", "mword", "BUG", "BUG", "BUG", "BUG", "BUG", "xmmword", + "byte", "word", "BUG", "dword", "far", "BUG", "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", diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index dec7c86..971d7a6 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -3662,8 +3662,8 @@ impl InstDecoder { Opcode::VPAND | Opcode::VANDPD | Opcode::VANDPS | - Opcode::VANDNPS | Opcode::VANDNPD | + Opcode::VANDNPS | Opcode::VORPD | Opcode::VORPS | Opcode::VPANDN | @@ -3724,8 +3724,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 | @@ -3814,7 +3817,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; @@ -4100,7 +4106,7 @@ impl Instruction { Instruction { prefixes: Prefixes::new(0), opcode: Opcode::Invalid, - mem_size: 1, + mem_size: 0, modrm_rrr: RegSpec::eax(), modrm_mmm: RegSpec::eax(), // doubles as sib_base sib_index: RegSpec::eax(), @@ -4865,7 +4871,6 @@ enum OperandCode { // Gdq_Ed = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(17).bits(), Gd_Ev = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(40).bits(), // Md_Gd = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(51).bits(), - G_E_mm_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().with_imm(false, 0).reg_mem().operand_case(29).bits(), G_E_xmm_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(22).bits(), G_E_xmm_Ub = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(60).bits(), G_U_xmm_Ub = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(61).bits(), @@ -4882,7 +4887,7 @@ enum OperandCode { Gv_M = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().only_modrm_operands().reg_mem().operand_case(25).bits(), MOVDIR64B = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(108).bits(), M_Gv = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(109).bits(), - Gb_Eb_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().with_imm(false, 0).byte_operands().reg_mem().operand_case(40).bits(), + Gv_Ev_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().with_imm(false, 0).reg_mem().operand_case(40).bits(), Gv_Ev_Iv = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(41).bits(), Rv_Gmm_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_modrm().read_E().reg_mem().operand_case(55).bits(), @@ -4895,26 +4900,28 @@ enum OperandCode { Gd_U_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(59).bits(), Gv_E_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(60).bits(), //= 0x816f, // mirror G_xmm_Ed, but also read an immediate - G_xmm_Ed_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(61).bits(), + G_xmm_Ew_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(61).bits(), G_U_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(62).bits(), G_M_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(20).bits(), G_E_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(21).bits(), E_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(19).bits(), + G_Ed_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(31).bits(), + Ed_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(29).bits(), M_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(63).bits(), G_E_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(64).bits(), G_U_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(65).bits(), E_G_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(66).bits(), Ed_G_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(67).bits(), - Ed_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(68).bits(), + // Ed_G_xmm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(68).bits(), G_mm_Ed = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(69).bits(), G_mm_E = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().mem_reg().operand_case(70).bits(), Ev_Gv_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(71).bits(), Ev_Gv_CL = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(72).bits(), G_mm_U_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(73).bits(), - G_Md_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(74).bits(), + G_Mq_mm = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().reg_mem().operand_case(74).bits(), G_mm_Ew_Ib = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(75).bits(), - G_E_d = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(76).bits(), - E_G_d = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(77).bits(), + G_E_q = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(76).bits(), + E_G_q = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(77).bits(), CVT_AA = OperandCodeBuilder::new().special_case(77).bits(), CVT_DA = OperandCodeBuilder::new().special_case(78).bits(), Rq_Cq_0 = OperandCodeBuilder::new().special_case(79).bits(), @@ -4946,6 +4953,11 @@ enum OperandCode { SS = OperandCodeBuilder::new().special_case(105).bits(), DS = OperandCodeBuilder::new().special_case(106).bits(), ModRM_0x62 = OperandCodeBuilder::new().special_case(107).bits(), + INV_Gv_M = OperandCodeBuilder::new().special_case(108).bits(), + PMOVX_G_E_xmm = OperandCodeBuilder::new().operand_case(109).bits(), + PMOVX_E_G_xmm = OperandCodeBuilder::new().operand_case(110).bits(), + G_Ev_xmm_Ib = OperandCodeBuilder::new().operand_case(111).bits(), + G_E_mm_Ib = OperandCodeBuilder::new().operand_case(112).bits(), } const LOCKABLE_INSTRUCTIONS: &[Opcode] = &[ @@ -5121,7 +5133,7 @@ const OPCODES: [OpcodeRecord; 256] = [ OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::Ivs), OpcodeRecord(Interpretation::Instruction(Opcode::IMUL), OperandCode::Gv_Ev_Iv), OpcodeRecord(Interpretation::Instruction(Opcode::PUSH), OperandCode::Ibs), - OpcodeRecord(Interpretation::Instruction(Opcode::IMUL), OperandCode::Gb_Eb_Ib), + OpcodeRecord(Interpretation::Instruction(Opcode::IMUL), OperandCode::Gv_Ev_Ib), OpcodeRecord(Interpretation::Instruction(Opcode::INS), OperandCode::Yb_DX), OpcodeRecord(Interpretation::Instruction(Opcode::INS), OperandCode::Yv_DX), OpcodeRecord(Interpretation::Instruction(Opcode::OUTS), OperandCode::DX_Xb), @@ -5574,9 +5586,9 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x0e => OpcodeRecord(Interpretation::Instruction(Opcode::FEMMS), OperandCode::Nothing), 0x0f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0f), - 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSD), OperandCode::G_E_xmm), - 0x11 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSD), OperandCode::E_G_xmm), - 0x12 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDDUP), OperandCode::G_E_xmm), + 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSD), OperandCode::PMOVX_G_E_xmm), + 0x11 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSD), OperandCode::PMOVX_E_G_xmm), + 0x12 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVDDUP), OperandCode::PMOVX_G_E_xmm), 0x13 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5603,8 +5615,8 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x29 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x2a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSI2SD), OperandCode::G_xmm_Ed), 0x2b => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTSD), OperandCode::M_G_xmm), - 0x2c => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTSD2SI), OperandCode::G_E_xmm), - 0x2d => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSD2SI), OperandCode::G_E_xmm), + 0x2c => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTSD2SI), OperandCode::PMOVX_G_E_xmm), + 0x2d => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSD2SI), OperandCode::PMOVX_G_E_xmm), 0x2e => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x2f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5643,21 +5655,21 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x4f => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVG), OperandCode::Gv_Ev), 0x50 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - 0x51 => OpcodeRecord(Interpretation::Instruction(Opcode::SQRTSD), OperandCode::G_E_xmm), + 0x51 => OpcodeRecord(Interpretation::Instruction(Opcode::SQRTSD), OperandCode::PMOVX_G_E_xmm), 0x52 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x53 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x54 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x55 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x56 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x57 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - 0x58 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDSD), OperandCode::G_E_xmm), - 0x59 => OpcodeRecord(Interpretation::Instruction(Opcode::MULSD), OperandCode::G_E_xmm), - 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSD2SS), OperandCode::G_E_xmm), + 0x58 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDSD), OperandCode::PMOVX_G_E_xmm), + 0x59 => OpcodeRecord(Interpretation::Instruction(Opcode::MULSD), OperandCode::PMOVX_G_E_xmm), + 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSD2SS), OperandCode::PMOVX_G_E_xmm), 0x5b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - 0x5c => OpcodeRecord(Interpretation::Instruction(Opcode::SUBSD), OperandCode::G_E_xmm), - 0x5d => OpcodeRecord(Interpretation::Instruction(Opcode::MINSD), OperandCode::G_E_xmm), - 0x5e => OpcodeRecord(Interpretation::Instruction(Opcode::DIVSD), OperandCode::G_E_xmm), - 0x5f => OpcodeRecord(Interpretation::Instruction(Opcode::MAXSD), OperandCode::G_E_xmm), + 0x5c => OpcodeRecord(Interpretation::Instruction(Opcode::SUBSD), OperandCode::PMOVX_G_E_xmm), + 0x5d => OpcodeRecord(Interpretation::Instruction(Opcode::MINSD), OperandCode::PMOVX_G_E_xmm), + 0x5e => OpcodeRecord(Interpretation::Instruction(Opcode::DIVSD), OperandCode::PMOVX_G_E_xmm), + 0x5f => OpcodeRecord(Interpretation::Instruction(Opcode::MAXSD), OperandCode::PMOVX_G_E_xmm), 0x60 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x61 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5749,10 +5761,10 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { // 0xb0 0xb0 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb), 0xb1 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv), - 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M), + 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::INV_Gv_M), 0xb3 => OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::Ev_Gv), - 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M), - 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M), + 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::INV_Gv_M), + 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::INV_Gv_M), 0xb6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb), 0xb7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew), 0xb8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5851,8 +5863,8 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x0e => OpcodeRecord(Interpretation::Instruction(Opcode::FEMMS), OperandCode::Nothing), 0x0f => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f0f), - 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSS), OperandCode::G_E_xmm), - 0x11 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSS), OperandCode::E_G_xmm), + 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSS), OperandCode::G_Ed_xmm), + 0x11 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSS), OperandCode::Ed_G_xmm), 0x12 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVSLDUP), OperandCode::G_E_xmm), 0x13 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5920,21 +5932,21 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x4f => OpcodeRecord(Interpretation::Instruction(Opcode::CMOVG), OperandCode::Gv_Ev), // 0x50 0x50 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - 0x51 => OpcodeRecord(Interpretation::Instruction(Opcode::SQRTSS), OperandCode::G_E_xmm), - 0x52 => OpcodeRecord(Interpretation::Instruction(Opcode::RSQRTSS), OperandCode::G_E_xmm), - 0x53 => OpcodeRecord(Interpretation::Instruction(Opcode::RCPSS), OperandCode::G_E_xmm), + 0x51 => OpcodeRecord(Interpretation::Instruction(Opcode::SQRTSS), OperandCode::G_Ed_xmm), + 0x52 => OpcodeRecord(Interpretation::Instruction(Opcode::RSQRTSS), OperandCode::G_Ed_xmm), + 0x53 => OpcodeRecord(Interpretation::Instruction(Opcode::RCPSS), OperandCode::G_Ed_xmm), 0x54 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x55 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x56 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x57 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - 0x58 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDSS), OperandCode::G_E_xmm), - 0x59 => OpcodeRecord(Interpretation::Instruction(Opcode::MULSS), OperandCode::G_E_xmm), - 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSS2SD), OperandCode::G_E_xmm), + 0x58 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDSS), OperandCode::G_Ed_xmm), + 0x59 => OpcodeRecord(Interpretation::Instruction(Opcode::MULSS), OperandCode::G_Ed_xmm), + 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTSS2SD), OperandCode::PMOVX_G_E_xmm), 0x5b => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPS2DQ), OperandCode::G_E_xmm), - 0x5c => OpcodeRecord(Interpretation::Instruction(Opcode::SUBSS), OperandCode::G_E_xmm), - 0x5d => OpcodeRecord(Interpretation::Instruction(Opcode::MINSS), OperandCode::G_E_xmm), - 0x5e => OpcodeRecord(Interpretation::Instruction(Opcode::DIVSS), OperandCode::G_E_xmm), - 0x5f => OpcodeRecord(Interpretation::Instruction(Opcode::MAXSS), OperandCode::G_E_xmm), + 0x5c => OpcodeRecord(Interpretation::Instruction(Opcode::SUBSS), OperandCode::G_Ed_xmm), + 0x5d => OpcodeRecord(Interpretation::Instruction(Opcode::MINSS), OperandCode::G_Ed_xmm), + 0x5e => OpcodeRecord(Interpretation::Instruction(Opcode::DIVSS), OperandCode::G_Ed_xmm), + 0x5f => OpcodeRecord(Interpretation::Instruction(Opcode::MAXSS), OperandCode::G_Ed_xmm), // 0x60 0x60 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x61 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -6026,10 +6038,10 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { // 0xb0 0xb0 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb), 0xb1 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv), - 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M), + 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::INV_Gv_M), 0xb3 => OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::Ev_Gv), - 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M), - 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M), + 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::INV_Gv_M), + 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::INV_Gv_M), 0xb6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb), 0xb7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew), 0xb8 => OpcodeRecord(Interpretation::Instruction(Opcode::POPCNT), OperandCode::Gv_Ev), @@ -6130,12 +6142,12 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x10 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPD), OperandCode::G_E_xmm), 0x11 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVUPD), OperandCode::E_G_xmm), - 0x12 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPD), OperandCode::G_M_xmm), - 0x13 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPD), OperandCode::M_G_xmm), + 0x12 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPD), OperandCode::PMOVX_G_E_xmm), + 0x13 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVLPD), OperandCode::PMOVX_E_G_xmm), 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKLPD), OperandCode::G_E_xmm), 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKHPD), OperandCode::G_E_xmm), - 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::G_M_xmm), - 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::M_G_xmm), + 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::PMOVX_G_E_xmm), + 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPD), OperandCode::PMOVX_E_G_xmm), 0x18 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f18), 0x19 => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), 0x1a => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), @@ -6159,8 +6171,8 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x2b => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTPD), OperandCode::M_G_xmm), 0x2c => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPD2PI), OperandCode::G_mm_E_xmm), 0x2d => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPD2PI), OperandCode::G_mm_E_xmm), - 0x2e => OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISD), OperandCode::G_E_xmm), - 0x2f => OpcodeRecord(Interpretation::Instruction(Opcode::COMISD), OperandCode::G_E_xmm), + 0x2e => OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISD), OperandCode::PMOVX_G_E_xmm), + 0x2f => OpcodeRecord(Interpretation::Instruction(Opcode::COMISD), OperandCode::PMOVX_G_E_xmm), 0x30 => OpcodeRecord(Interpretation::Instruction(Opcode::WRMSR), OperandCode::Nothing), 0x31 => OpcodeRecord(Interpretation::Instruction(Opcode::RDTSC), OperandCode::Nothing), @@ -6319,7 +6331,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0xc1 => OpcodeRecord(Interpretation::Instruction(Opcode::XADD), OperandCode::Ev_Gv), 0xc2 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPPD), OperandCode::G_E_xmm_Ib), 0xc3 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - 0xc4 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRW), OperandCode::G_xmm_Ed_Ib), + 0xc4 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRW), OperandCode::G_xmm_Ew_Ib), 0xc5 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::G_U_xmm_Ub), 0xc6 => OpcodeRecord(Interpretation::Instruction(Opcode::SHUFPD), OperandCode::G_E_xmm_Ib), 0xc7 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0fc7), @@ -6338,7 +6350,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0xd3 => OpcodeRecord(Interpretation::Instruction(Opcode::PSRLQ), OperandCode::G_E_xmm), 0xd4 => OpcodeRecord(Interpretation::Instruction(Opcode::PADDQ), OperandCode::G_E_xmm), 0xd5 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULLW), OperandCode::G_E_xmm), - 0xd6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::E_G_xmm), + 0xd6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVQ), OperandCode::PMOVX_E_G_xmm), 0xd7 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVMSKB), OperandCode::Gd_U_xmm), 0xd8 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSB), OperandCode::G_E_xmm), 0xd9 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBUSW), OperandCode::G_E_xmm), @@ -6409,7 +6421,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKLPS), OperandCode::G_E_xmm), 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::UNPCKHPS), OperandCode::G_E_xmm), 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f16), - 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPS), OperandCode::M_G_xmm), + 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVHPS), OperandCode::PMOVX_E_G_xmm), 0x18 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f18), 0x19 => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), 0x1a => OpcodeRecord(Interpretation::Instruction(Opcode::NOP), OperandCode::Ev), @@ -6433,8 +6445,8 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x2b => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTPS), OperandCode::M_G_xmm), 0x2c => OpcodeRecord(Interpretation::Instruction(Opcode::CVTTPS2PI), OperandCode::G_mm_E_xmm), 0x2d => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2PI), OperandCode::G_mm_E_xmm), - 0x2e => OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISS), OperandCode::G_E_xmm), - 0x2f => OpcodeRecord(Interpretation::Instruction(Opcode::COMISS), OperandCode::G_E_xmm), + 0x2e => OpcodeRecord(Interpretation::Instruction(Opcode::UCOMISS), OperandCode::PMOVX_G_E_xmm), + 0x2f => OpcodeRecord(Interpretation::Instruction(Opcode::COMISS), OperandCode::PMOVX_G_E_xmm), // 0x30 0x30 => OpcodeRecord(Interpretation::Instruction(Opcode::WRMSR), OperandCode::Nothing), 0x31 => OpcodeRecord(Interpretation::Instruction(Opcode::RDTSC), OperandCode::Nothing), @@ -6482,7 +6494,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x57 => OpcodeRecord(Interpretation::Instruction(Opcode::XORPS), OperandCode::G_E_xmm), 0x58 => OpcodeRecord(Interpretation::Instruction(Opcode::ADDPS), OperandCode::G_E_xmm), 0x59 => OpcodeRecord(Interpretation::Instruction(Opcode::MULPS), OperandCode::G_E_xmm), - 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2PD), OperandCode::G_E_xmm), + 0x5a => OpcodeRecord(Interpretation::Instruction(Opcode::CVTPS2PD), OperandCode::PMOVX_G_E_xmm), 0x5b => OpcodeRecord(Interpretation::Instruction(Opcode::CVTDQ2PS), OperandCode::G_E_xmm), 0x5c => OpcodeRecord(Interpretation::Instruction(Opcode::SUBPS), OperandCode::G_E_xmm), 0x5d => OpcodeRecord(Interpretation::Instruction(Opcode::MINPS), OperandCode::G_E_xmm), @@ -6516,8 +6528,8 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x75 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQW), OperandCode::G_E_mm), 0x76 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQD), OperandCode::G_E_mm), 0x77 => OpcodeRecord(Interpretation::Instruction(Opcode::EMMS), OperandCode::Nothing), - 0x78 => OpcodeRecord(Interpretation::Instruction(Opcode::VMREAD), OperandCode::E_G_d), - 0x79 => OpcodeRecord(Interpretation::Instruction(Opcode::VMWRITE), OperandCode::G_E_d), + 0x78 => OpcodeRecord(Interpretation::Instruction(Opcode::VMREAD), OperandCode::E_G_q), + 0x79 => OpcodeRecord(Interpretation::Instruction(Opcode::VMWRITE), OperandCode::G_E_q), 0x7a => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x7b => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), 0x7c => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -6582,10 +6594,10 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { // 0xb0 0xb0 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb), 0xb1 => OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv), - 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M), + 0xb2 => OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::INV_Gv_M), 0xb3 => OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::Ev_Gv), - 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M), - 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M), + 0xb4 => OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::INV_Gv_M), + 0xb5 => OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::INV_Gv_M), 0xb6 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb), 0xb7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew), 0xb8 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // JMPE, ITANIUM @@ -6641,7 +6653,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0xe4 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULHUW), OperandCode::G_E_mm), 0xe5 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULHW), OperandCode::G_E_mm), 0xe6 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), - 0xe7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTQ), OperandCode::G_Md_mm), + 0xe7 => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTQ), OperandCode::G_Mq_mm), 0xe8 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSB), OperandCode::G_E_mm), 0xe9 => OpcodeRecord(Interpretation::Instruction(Opcode::PSUBSW), OperandCode::G_E_mm), 0xea => OpcodeRecord(Interpretation::Instruction(Opcode::PMINSW), OperandCode::G_E_mm), @@ -6682,7 +6694,7 @@ fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0xf6 => OpcodeRecord(Interpretation::Instruction(Opcode::ADOX), OperandCode::Gv_Ev), 0xf8 => { prefixes.unset_operand_size(); - OpcodeRecord(Interpretation::Instruction(Opcode::ENQCMDS), OperandCode::Gv_M) + OpcodeRecord(Interpretation::Instruction(Opcode::ENQCMDS), OperandCode::INV_Gv_M) }, 0xfa => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38fa), 0xfb => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0xf30f38fb), @@ -6696,7 +6708,7 @@ fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::CRC32), OperandCode::Gd_Ev), 0xf8 => { prefixes.unset_operand_size(); - OpcodeRecord(Interpretation::Instruction(Opcode::ENQCMD), OperandCode::Gv_M) + OpcodeRecord(Interpretation::Instruction(Opcode::ENQCMD), OperandCode::INV_Gv_M) }, _ => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), }; @@ -6728,22 +6740,22 @@ fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x1c => OpcodeRecord(Interpretation::Instruction(Opcode::PABSB), OperandCode::G_E_xmm), 0x1d => OpcodeRecord(Interpretation::Instruction(Opcode::PABSW), OperandCode::G_E_xmm), 0x1e => OpcodeRecord(Interpretation::Instruction(Opcode::PABSD), OperandCode::G_E_xmm), - 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXBW), OperandCode::G_E_xmm), - 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXBD), OperandCode::G_E_xmm), - 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXBQ), OperandCode::G_E_xmm), - 0x23 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXWD), OperandCode::G_E_xmm), - 0x24 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXWQ), OperandCode::G_E_xmm), - 0x25 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXDQ), OperandCode::G_E_xmm), + 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXBW), OperandCode::PMOVX_G_E_xmm), + 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXBD), OperandCode::PMOVX_G_E_xmm), + 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXBQ), OperandCode::PMOVX_G_E_xmm), + 0x23 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXWD), OperandCode::PMOVX_G_E_xmm), + 0x24 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXWQ), OperandCode::PMOVX_G_E_xmm), + 0x25 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVSXDQ), OperandCode::PMOVX_G_E_xmm), 0x28 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULDQ), OperandCode::G_E_xmm), 0x29 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPEQQ), OperandCode::G_E_xmm), 0x2a => OpcodeRecord(Interpretation::Instruction(Opcode::MOVNTDQA), OperandCode::G_M_xmm), 0x2b => OpcodeRecord(Interpretation::Instruction(Opcode::PACKUSDW), OperandCode::G_E_xmm), - 0x30 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXBW), OperandCode::G_E_xmm), - 0x31 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXBD), OperandCode::G_E_xmm), - 0x32 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXBQ), OperandCode::G_E_xmm), - 0x33 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXWD), OperandCode::G_E_xmm), - 0x34 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXWQ), OperandCode::G_E_xmm), - 0x35 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXDQ), OperandCode::G_E_xmm), + 0x30 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXBW), OperandCode::PMOVX_G_E_xmm), + 0x31 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXBD), OperandCode::PMOVX_G_E_xmm), + 0x32 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXBQ), OperandCode::PMOVX_G_E_xmm), + 0x33 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXWD), OperandCode::PMOVX_G_E_xmm), + 0x34 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXWQ), OperandCode::PMOVX_G_E_xmm), + 0x35 => OpcodeRecord(Interpretation::Instruction(Opcode::PMOVZXDQ), OperandCode::PMOVX_G_E_xmm), 0x37 => OpcodeRecord(Interpretation::Instruction(Opcode::PCMPGTQ), OperandCode::G_E_xmm), 0x38 => OpcodeRecord(Interpretation::Instruction(Opcode::PMINSB), OperandCode::G_E_xmm), 0x39 => OpcodeRecord(Interpretation::Instruction(Opcode::PMINSD), OperandCode::G_E_xmm), @@ -6755,9 +6767,9 @@ fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x3f => OpcodeRecord(Interpretation::Instruction(Opcode::PMAXUD), OperandCode::G_E_xmm), 0x40 => OpcodeRecord(Interpretation::Instruction(Opcode::PMULLD), OperandCode::G_E_xmm), 0x41 => OpcodeRecord(Interpretation::Instruction(Opcode::PHMINPOSUW), OperandCode::G_E_xmm), - 0x80 => OpcodeRecord(Interpretation::Instruction(Opcode::INVEPT), OperandCode::Gv_M), - 0x81 => OpcodeRecord(Interpretation::Instruction(Opcode::INVVPID), OperandCode::Gv_M), - 0x82 => OpcodeRecord(Interpretation::Instruction(Opcode::INVPCID), OperandCode::Gv_M), + 0x80 => OpcodeRecord(Interpretation::Instruction(Opcode::INVEPT), OperandCode::INV_Gv_M), + 0x81 => OpcodeRecord(Interpretation::Instruction(Opcode::INVVPID), OperandCode::INV_Gv_M), + 0x82 => OpcodeRecord(Interpretation::Instruction(Opcode::INVPCID), OperandCode::INV_Gv_M), 0xcf => OpcodeRecord(Interpretation::Instruction(Opcode::GF2P8MULB), OperandCode::G_E_xmm), 0xdb => OpcodeRecord(Interpretation::Instruction(Opcode::AESIMC), OperandCode::G_E_xmm), 0xdc => OpcodeRecord(Interpretation::Instruction(Opcode::AESENC), OperandCode::G_E_xmm), @@ -6818,13 +6830,13 @@ fn read_0f3a_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0x0d => OpcodeRecord(Interpretation::Instruction(Opcode::BLENDPD), OperandCode::G_E_xmm_Ib), 0x0e => OpcodeRecord(Interpretation::Instruction(Opcode::PBLENDW), OperandCode::G_E_xmm_Ib), 0x0f => OpcodeRecord(Interpretation::Instruction(Opcode::PALIGNR), OperandCode::G_E_xmm_Ib), - 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRB), OperandCode::G_E_xmm_Ib), - 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::G_E_xmm_Ib), - 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRD), OperandCode::G_E_xmm_Ib), - 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::EXTRACTPS), OperandCode::G_E_xmm_Ib), - 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRB), OperandCode::G_E_xmm_Ib), - 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::INSERTPS), OperandCode::G_E_xmm_Ib), - 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRD), OperandCode::G_E_xmm_Ib), + 0x14 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRB), OperandCode::G_Ev_xmm_Ib), + 0x15 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRW), OperandCode::G_Ev_xmm_Ib), + 0x16 => OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRD), OperandCode::G_Ev_xmm_Ib), + 0x17 => OpcodeRecord(Interpretation::Instruction(Opcode::EXTRACTPS), OperandCode::G_Ev_xmm_Ib), + 0x20 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRB), OperandCode::G_Ev_xmm_Ib), + 0x21 => OpcodeRecord(Interpretation::Instruction(Opcode::INSERTPS), OperandCode::G_Ev_xmm_Ib), + 0x22 => OpcodeRecord(Interpretation::Instruction(Opcode::PINSRD), OperandCode::G_Ev_xmm_Ib), 0x40 => OpcodeRecord(Interpretation::Instruction(Opcode::DPPS), OperandCode::G_E_xmm_Ib), 0x41 => OpcodeRecord(Interpretation::Instruction(Opcode::DPPD), OperandCode::G_E_xmm_Ib), 0x42 => OpcodeRecord(Interpretation::Instruction(Opcode::MPSADBW), OperandCode::G_E_xmm_Ib), @@ -7286,6 +7298,12 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, } else if opcode == Opcode::CALLF || opcode == Opcode::JMPF { return Err(DecodeError::InvalidOperand); } + } else { + if opcode == Opcode::CALL || opcode == Opcode::JMP || opcode == Opcode::PUSH || opcode == Opcode::POP { + instruction.mem_size = 4; + } else if opcode == Opcode::CALLF || opcode == Opcode::JMPF { + instruction.mem_size = 5; + } } instruction.opcode = opcode; instruction.operand_count = 1; @@ -7299,6 +7317,9 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, } else { RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D) }; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 1; + } instruction.operand_count = 2; }, 16 => { @@ -7310,6 +7331,9 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, } else { RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D) }; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 2; + } instruction.operand_count = 2; }, 18 => { @@ -7324,6 +7348,8 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, if instruction.operands[0] == OperandSpec::RegMMM { // fix the register to XMM instruction.modrm_mmm.bank = RegisterBank::X; + } else { + instruction.mem_size = 16; } }, op @ 20 | @@ -7338,6 +7364,12 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, // fix the register to XMM instruction.modrm_mmm.bank = RegisterBank::X; } + } else { + if instruction.opcode == Opcode::MOVDDUP { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } } }, 22 => { @@ -7349,6 +7381,15 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction.imm = read_num(&mut bytes_iter, 1)? as u8 as u32; *length += 1; + if instruction.operands[1] != OperandSpec::RegMMM { + if instruction.opcode == Opcode::CMPSS { + instruction.mem_size = 4; + } else if instruction.opcode == Opcode::CMPSD { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } + } instruction.operands[2] = OperandSpec::ImmI8; instruction.operand_count = 3; }, @@ -7409,12 +7450,20 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, return Ok(()); }, 29 => { - instruction.modrm_rrr = RegSpec { bank: RegisterBank::MM, num: (modrm >> 3) & 7 }; - if instruction.operands[1] == OperandSpec::RegMMM { - instruction.modrm_mmm.bank = RegisterBank::MM; + instruction.modrm_rrr.bank = RegisterBank::X; + instruction.operands[0] = mem_oper; + instruction.operands[1] = OperandSpec::RegRRR; + instruction.operand_count = 2; + if instruction.operands[0] == OperandSpec::RegMMM { + // fix the register to XMM + if instruction.opcode == Opcode::MOVD { + instruction.modrm_mmm.bank = RegisterBank::D; + } else { + instruction.modrm_mmm.bank = RegisterBank::X; + } + } else { + instruction.mem_size = 4; } - instruction.operands[2] = OperandSpec::ImmI8; - instruction.operand_count = 3; }, 30 => { instruction.operands[0] = mem_oper; @@ -7427,6 +7476,16 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, ][r as usize]; instruction.operand_count = 1; } + 31 => { + instruction.modrm_rrr.bank = RegisterBank::X; + instruction.operand_count = 2; + if instruction.operands[1] == OperandSpec::RegMMM { + // fix the register to XMM + instruction.modrm_mmm.bank = RegisterBank::X; + } else { + instruction.mem_size = 4; + } + }, _ => { let operand_code: OperandCode = unsafe { core::mem::transmute(operand_code.bits()) }; unlikely_operands(decoder, bytes_iter, instruction, operand_code, mem_oper, length)?; @@ -7438,6 +7497,103 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, } fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, mem_oper: OperandSpec, length: &mut u8) -> Result<(), DecodeError> { match operand_code { + OperandCode::G_E_mm_Ib => { + let modrm = read_modrm(&mut bytes_iter, length)?; + + instruction.operands[1] = read_E_mm(&mut bytes_iter, instruction, modrm, length)?; + instruction.modrm_rrr = RegSpec { bank: RegisterBank::MM, num: (modrm >> 3) & 7 }; + if instruction.operands[1] == OperandSpec::RegMMM { + instruction.modrm_mmm.bank = RegisterBank::MM; + } else { + instruction.mem_size = 8; + } + instruction.imm = read_num(&mut bytes_iter, 1)? as u8 as u32; + *length += 1; + instruction.operands[2] = OperandSpec::ImmI8; + instruction.operand_count = 3; + } + OperandCode::G_Ev_xmm_Ib => { + let modrm = read_modrm(&mut bytes_iter, length)?; + + instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; + instruction.modrm_rrr = RegSpec { bank: RegisterBank::X, num: (modrm >> 3) & 7 }; + instruction.imm = read_num(&mut bytes_iter, 1)? as u8 as u32; + *length += 1; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = match instruction.opcode { + Opcode::PEXTRB => 1, + Opcode::PEXTRW => 2, + Opcode::PEXTRD => 4, + Opcode::EXTRACTPS => 4, + Opcode::INSERTPS => 4, + Opcode::PINSRB => 1, + Opcode::PINSRW => 2, + Opcode::PINSRD => 4, + _ => 8, + }; + } + instruction.operands[2] = OperandSpec::ImmI8; + instruction.operand_count = 3; + } + OperandCode::PMOVX_E_G_xmm => { + let modrm = read_modrm(&mut bytes_iter, length)?; + + instruction.modrm_rrr = RegSpec { bank: RegisterBank::X, num: (modrm >> 3) & 7 }; + instruction.operands[1] = OperandSpec::RegRRR; + instruction.operands[0] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; + if instruction.operands[0] != OperandSpec::RegMMM { + if [].contains(&instruction.opcode) { + instruction.mem_size = 2; + } else { + instruction.mem_size = 8; + } + } else { + if instruction.opcode == Opcode::MOVLPD || instruction.opcode == Opcode::MOVHPD || instruction.opcode == Opcode::MOVHPS { + return Err(DecodeError::InvalidOperand); + } + } + } + OperandCode::PMOVX_G_E_xmm => { + let modrm = read_modrm(&mut bytes_iter, length)?; + + instruction.modrm_rrr = RegSpec { bank: RegisterBank::X, num: (modrm >> 3) & 7 }; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; + if instruction.operands[1] != OperandSpec::RegMMM { + if [Opcode::PMOVSXBQ, Opcode::PMOVZXBQ].contains(&instruction.opcode) { + instruction.mem_size = 2; + } else if [Opcode::PMOVZXBD, Opcode::UCOMISS, Opcode::COMISS, Opcode::CVTSS2SD].contains(&instruction.opcode) { + instruction.mem_size = 4; + } else { + instruction.mem_size = 8; + } + } else { + if instruction.opcode == Opcode::MOVLPD || instruction.opcode == Opcode::MOVHPD { + return Err(DecodeError::InvalidOperand); + } + } + } + OperandCode::INV_Gv_M => { + let modrm = read_modrm(&mut bytes_iter, length)?; + + instruction.modrm_rrr = RegSpec { bank: RegisterBank::D, num: (modrm >> 3) & 7 }; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?; + if instruction.operands[1] == OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + if [Opcode::LFS, Opcode::LGS, Opcode::LSS].contains(&instruction.opcode) { + if instruction.prefixes.vex().w() { + instruction.mem_size = 6; + } else { + instruction.mem_size = 4; + } + } else if [Opcode::ENQCMD, Opcode::ENQCMDS].contains(&instruction.opcode) { + instruction.mem_size = 64; + } else { + instruction.mem_size = 16; + } + } OperandCode::ModRM_0xc4 => { let modrm = bytes_iter.next().ok_or(DecodeError::ExhaustedInput).map(|b| { *length += 1; b })?; if modrm & 0b11000000 == 0b11000000 { @@ -7560,6 +7716,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.imm = read_num(&mut bytes_iter, 1)? as u8 as u32; *length += 1; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operands[2] = OperandSpec::ImmU8; instruction.operand_count = 3; } @@ -7588,7 +7747,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_mmm.bank = RegisterBank::X; instruction.operand_count = 2; }, - OperandCode::Gb_Eb_Ib => { + OperandCode::Gv_Ev_Ib => { instruction.operands[2] = OperandSpec::ImmI8; instruction.operand_count = 3; } @@ -7630,6 +7789,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::MM); if instruction.operands[1] == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::D; + } else { + instruction.mem_size = 2; } instruction.imm = read_num(&mut bytes_iter, 1)? as u8 as u32; @@ -7643,6 +7804,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::MM; instruction.modrm_mmm.num &= 0b111; + } else { + if [Opcode::PACKSSWB, Opcode::PCMPGTB, Opcode::PCMPGTW, Opcode::PCMPGTD, Opcode::PACKUSWB, Opcode::PUNPCKHBW, Opcode::PUNPCKHWD, Opcode::PUNPCKHDQ, Opcode::PACKSSDW, Opcode::PSRLW, Opcode::PMULHW, Opcode::PSHUFB, Opcode::PHADDW, Opcode::PHADDD, Opcode::PHADDSW, Opcode::PMADDUBSW, Opcode::PHSUBW, Opcode::PHSUBD, Opcode::PHSUBSW, Opcode::PSIGNB, Opcode::PSIGNW, Opcode::PSIGND, Opcode::PMULHRSW, Opcode::PABSB, Opcode::PABSW, Opcode::PABSD].contains(&instruction.opcode) { + instruction.mem_size = 8; + } else { + instruction.mem_size = 4; + } } instruction.operand_count = 2; }, @@ -7684,15 +7851,23 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); instruction.operand_count = 2; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = opwidth; + } }, op @ OperandCode::AL_Ob | op @ OperandCode::AX_Ov => { instruction.modrm_rrr = match op { - OperandCode::AL_Ob => RegSpec::al(), + OperandCode::AL_Ob => { + instruction.mem_size = 1; + RegSpec::al() + }, OperandCode::AX_Ov => { if instruction.prefixes.operand_size() { + instruction.mem_size = 2; RegSpec::ax() } else { + instruction.mem_size = 4; RegSpec::eax() } } @@ -7714,11 +7889,16 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter op @ OperandCode::Ob_AL | op @ OperandCode::Ov_AX => { instruction.modrm_rrr = match op { - OperandCode::Ob_AL => RegSpec::al(), + OperandCode::Ob_AL => { + instruction.mem_size = 1; + RegSpec::al() + }, OperandCode::Ov_AX => { if instruction.prefixes.operand_size() { + instruction.mem_size = 2; RegSpec::ax() } else { + instruction.mem_size = 4; RegSpec::eax() } } @@ -7774,7 +7954,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr.num &= 0b111; instruction.operand_count = 2; }, - OperandCode::E_G_d => { + OperandCode::E_G_q => { if instruction.prefixes.operand_size() { return Err(DecodeError::InvalidOpcode); } @@ -7786,8 +7966,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); instruction.operand_count = 2; + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = 8; + } } - OperandCode::G_E_d => { + OperandCode::G_E_q => { if instruction.prefixes.operand_size() { return Err(DecodeError::InvalidOpcode); } @@ -7798,14 +7981,19 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = 8; + } instruction.operand_count = 2; } - OperandCode::G_Md_mm => { + OperandCode::G_Mq_mm => { instruction.operands[1] = instruction.operands[0]; instruction.operands[0] = mem_oper; instruction.modrm_rrr.bank = RegisterBank::MM; if mem_oper == OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); + } else { + instruction.mem_size = 8; } instruction.modrm_rrr.num &= 0b111; instruction.operand_count = 2; @@ -7836,6 +8024,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } } instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = 64; + } instruction.operand_count = 1; } OperandCode::ModRM_0x0f0f => { @@ -7846,6 +8037,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[1] = read_E_mm(&mut bytes_iter, instruction, modrm, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.modrm_rrr = RegSpec { bank: RegisterBank::MM, num: (modrm >> 3) & 7 }; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 8; + } let opcode = read_modrm(&mut bytes_iter, length)?; match opcode { @@ -7939,6 +8133,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter return Err(DecodeError::InvalidOperand); } else { instruction.opcode = Opcode::CMPXCHG8B; + instruction.mem_size = 8; instruction.operand_count = 1; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; } @@ -7966,6 +8161,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter return Err(DecodeError::InvalidOperand); } else { instruction.opcode = Opcode::CMPXCHG8B; + instruction.mem_size = 8; instruction.operand_count = 1; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; } @@ -7980,6 +8176,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter // word-form operand: instruction.modrm_mmm = RegSpec { bank: RegisterBank::W, num: instruction.modrm_mmm.num }; instruction.opcode = Opcode::RDRAND; + } else { + instruction.mem_size = 8; } instruction.operand_count = 1; return Ok(()); @@ -8021,6 +8219,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter return Err(DecodeError::InvalidOperand); } else { instruction.opcode = Opcode::CMPXCHG8B; + instruction.mem_size = 8; instruction.operand_count = 1; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; } @@ -8033,6 +8232,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::SENDUIPI; // and the operand is always a dword register instruction.modrm_mmm.bank = RegisterBank::D; + } else { + instruction.mem_size = 8; } instruction.operand_count = 1; } @@ -8062,6 +8263,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { + instruction.mem_size = 8; Opcode::CMPXCHG8B } } @@ -8070,6 +8272,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { + instruction.mem_size = 63; Opcode::XRSTORS } } @@ -8078,6 +8281,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { + instruction.mem_size = 63; Opcode::XSAVEC } } @@ -8086,6 +8290,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } else { + instruction.mem_size = 63; Opcode::XSAVES } } @@ -8093,6 +8298,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter if is_reg { Opcode::RDRAND } else { + instruction.mem_size = 8; Opcode::VMPTRLD } } @@ -8100,6 +8306,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter if is_reg { Opcode::RDSEED } else { + instruction.mem_size = 8; Opcode::VMPTRST } } @@ -8324,6 +8531,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr.num &= 0b111; if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::D; + } else { + instruction.mem_size = 4; } } OperandCode::G_mm_E => { @@ -8332,6 +8541,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::MM; instruction.modrm_mmm.num &= 0b111; + } else { + instruction.mem_size = 8; } } OperandCode::Ed_G_mm => { @@ -8341,14 +8552,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr.num &= 0b111; if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::D; + } else { + instruction.mem_size = 4; } } OperandCode::Ed_G_xmm => { instruction.operands[1] = instruction.operands[0]; instruction.operands[0] = mem_oper; - instruction.modrm_rrr.bank = RegisterBank::X; + instruction.modrm_rrr.bank = RegisterBank::Y; if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::D; + } else { + instruction.mem_size = 4; } } OperandCode::E_G_mm => { @@ -8359,9 +8574,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::MM; instruction.modrm_mmm.num &= 0b111; + } else { + instruction.mem_size = 8; } } - OperandCode::G_xmm_Ed_Ib => { + OperandCode::G_xmm_Ew_Ib => { instruction.operands[2] = OperandSpec::ImmU8; instruction.operand_count = 3; instruction.imm = @@ -8370,12 +8587,16 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr.bank = RegisterBank::X; if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::D; + } else { + instruction.mem_size = 2; } }, OperandCode::G_xmm_Ed => { instruction.modrm_rrr.bank = RegisterBank::X; if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::D; + } else { + instruction.mem_size = 4; } }, OperandCode::G_mm_E_xmm => { @@ -8383,6 +8604,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr.num &= 0b111; if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::X; + } else { + instruction.mem_size = 16; } }, op @ OperandCode::G_xmm_U_mm | @@ -8394,6 +8617,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { if op == OperandCode::G_xmm_U_mm { return Err(DecodeError::InvalidOperand); + } else { + instruction.mem_size = 8; } } }, @@ -8479,10 +8704,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr.bank = RegisterBank::X; instruction.operands[1] = mem_oper; if instruction.operands[1] == OperandSpec::RegMMM { + if instruction.prefixes.operand_size() { + return Err(DecodeError::InvalidOpcode); + } instruction.modrm_mmm.bank = RegisterBank::X; instruction.opcode = Opcode::MOVHLPS; } else { - instruction.opcode = Opcode::MOVLPS; + instruction.mem_size = 8; + if instruction.prefixes.operand_size() { + instruction.opcode = Opcode::MOVLPD; + } else { + instruction.opcode = Opcode::MOVLPS; + } } } OperandCode::ModRM_0x0f16 => { @@ -8495,6 +8728,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } instruction.opcode = Opcode::MOVLHPS; } else { + instruction.mem_size = 8; if instruction.prefixes.operand_size() { instruction.opcode = Opcode::MOVHPD; } else { @@ -8517,6 +8751,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter _ => Opcode::NOP, } }; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 64; + } } OperandCode::Gd_U_xmm => { if instruction.operands[1] != OperandSpec::RegMMM { @@ -8529,6 +8766,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter OperandCode::Gv_E_xmm => { if instruction.operands[1] == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::X; + } else { + instruction.mem_size = 4; } } OperandCode::M_G_xmm => { @@ -8537,6 +8776,14 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter if instruction.operands[0] == OperandSpec::RegMMM { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); + } else { + if instruction.opcode == Opcode::MOVNTSS { + instruction.mem_size = 4; + } else if instruction.opcode == Opcode::MOVNTPD || instruction.opcode == Opcode::MOVNTDQ || instruction.opcode == Opcode::MOVNTPS { + instruction.mem_size = 16; + } else { + instruction.mem_size = 8; + } } instruction.modrm_rrr.bank = RegisterBank::X; } @@ -8547,6 +8794,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter RegSpec { bank: RegisterBank::W, num: (modrm >> 3) & 7 }; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; instruction.operands[1] = OperandSpec::RegRRR; + instruction.mem_size = 2; instruction.operand_count = 2; }, OperandCode::Ew_Sw => { @@ -8571,6 +8819,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = OperandSpec::RegMMM; } else { instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + instruction.mem_size = 2; } }, OperandCode::Sw_Ew => { @@ -8604,6 +8853,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.operands[1] = OperandSpec::RegMMM; } else { instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?; + instruction.mem_size = 2; } }, OperandCode::CVT_AA => { @@ -8704,6 +8954,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { instruction.opcode = Opcode::SGDT; instruction.operand_count = 1; + instruction.mem_size = 63; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; } } else if r == 1 { @@ -8760,6 +9011,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { instruction.opcode = Opcode::SIDT; instruction.operand_count = 1; + instruction.mem_size = 63; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; } } else if r == 2 { @@ -8795,6 +9047,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { instruction.opcode = Opcode::LGDT; instruction.operand_count = 1; + instruction.mem_size = 63; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; } } else if r == 3 { @@ -8859,6 +9112,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { instruction.opcode = Opcode::LIDT; instruction.operand_count = 1; + instruction.mem_size = 63; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; } } else if r == 4 { @@ -8866,6 +9120,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter // spec suggets this might do something different for f.ex rdi? instruction.opcode = Opcode::SMSW; instruction.operand_count = 1; + instruction.mem_size = 2; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; } else if r == 5 { let mod_bits = modrm >> 6; @@ -8875,6 +9130,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } instruction.opcode = Opcode::RSTORSSP; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; + instruction.mem_size = 8; instruction.operand_count = 1; return Ok(()); } @@ -8976,6 +9232,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else if r == 6 { instruction.opcode = Opcode::LMSW; instruction.operand_count = 1; + instruction.mem_size = 2; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; } else if r == 7 { let mod_bits = modrm >> 6; @@ -9025,6 +9282,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { instruction.opcode = Opcode::INVLPG; instruction.operand_count = 1; + instruction.mem_size = 1; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; } } else { @@ -9052,6 +9310,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } }; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 1 /* opwidth */, length)?; + instruction.mem_size = 64; instruction.operand_count = 1; } else { instruction.opcode = match (modrm >> 3) & 7 { @@ -9100,6 +9359,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } instruction.opcode = Opcode::PTWRITE; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = 4; + } instruction.operand_count = 1; return Ok(()); } @@ -9154,6 +9416,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::CLRSSBSY; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; instruction.operand_count = 1; + instruction.mem_size = 8; return Ok(()); } _ => { @@ -9215,16 +9478,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter return Err(DecodeError::InvalidOperand); } instruction.operand_count = 1; - instruction.opcode = [ - Opcode::FXSAVE, - Opcode::FXRSTOR, - Opcode::LDMXCSR, - Opcode::STMXCSR, - Opcode::XSAVE, - Opcode::XRSTOR, - Opcode::XSAVEOPT, - Opcode::CLFLUSH, + let (opcode, mem_size) = [ + (Opcode::FXSAVE, 63), + (Opcode::FXRSTOR, 63), + (Opcode::LDMXCSR, 4), + (Opcode::STMXCSR, 4), + (Opcode::XSAVE, 63), + (Opcode::XRSTOR, 63), + (Opcode::XSAVEOPT, 63), + (Opcode::CLFLUSH, 64), ][r as usize]; + instruction.opcode = opcode; + instruction.mem_size = mem_size; instruction.operands[0] = read_M(&mut bytes_iter, instruction, modrm, length)?; } }, @@ -9508,13 +9773,22 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i enum OperandCodeX87 { Est, St_Est, + St_Edst, + St_Eqst, St_Ew, + St_Mw, St_Md, - Md, + St_Mq, + St_Mm, Ew, Est_St, + Edst_St, + Eqst_St, Ed_St, + Mw_St, Md_St, + Mq_St, + Mm_St, Ex87S, Nothing, } @@ -9526,20 +9800,20 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i let (opcode, x87_operands) = match operand_code { OperandCode::x87_d8 => { match r { - 0 => (Opcode::FADD, OperandCodeX87::St_Est), - 1 => (Opcode::FMUL, OperandCodeX87::St_Est), - 2 => (Opcode::FCOM, OperandCodeX87::St_Est), - 3 => (Opcode::FCOMP, OperandCodeX87::St_Est), - 4 => (Opcode::FSUB, OperandCodeX87::St_Est), - 5 => (Opcode::FSUBR, OperandCodeX87::St_Est), - 6 => (Opcode::FDIV, OperandCodeX87::St_Est), - 7 => (Opcode::FDIVR, OperandCodeX87::St_Est), + 0 => (Opcode::FADD, OperandCodeX87::St_Edst), + 1 => (Opcode::FMUL, OperandCodeX87::St_Edst), + 2 => (Opcode::FCOM, OperandCodeX87::St_Edst), + 3 => (Opcode::FCOMP, OperandCodeX87::St_Edst), + 4 => (Opcode::FSUB, OperandCodeX87::St_Edst), + 5 => (Opcode::FSUBR, OperandCodeX87::St_Edst), + 6 => (Opcode::FDIV, OperandCodeX87::St_Edst), + 7 => (Opcode::FDIVR, OperandCodeX87::St_Edst), _ => { unreachable!("impossible r"); } } } OperandCode::x87_d9 => { match r { - 0 => (Opcode::FLD, OperandCodeX87::St_Est), + 0 => (Opcode::FLD, OperandCodeX87::St_Edst), 1 => { if modrm >= 0xc0 { (Opcode::FXCH, OperandCodeX87::St_Est) @@ -9562,7 +9836,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i if modrm >= 0xc0 { (Opcode::FSTPNCE, OperandCodeX87::Est_St) } else { - (Opcode::FSTP, OperandCodeX87::Est_St) + (Opcode::FSTP, OperandCodeX87::Edst_St) } }, 4 => { @@ -9696,8 +9970,8 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i 1 => (Opcode::FISTTP, OperandCodeX87::Md_St), 2 => (Opcode::FIST, OperandCodeX87::Md_St), 3 => (Opcode::FISTP, OperandCodeX87::Md_St), - 5 => (Opcode::FLD, OperandCodeX87::St_Md), // 80bit - 7 => (Opcode::FSTP, OperandCodeX87::Md_St), // 80bit + 5 => (Opcode::FLD, OperandCodeX87::St_Mm), // 80bit + 7 => (Opcode::FSTP, OperandCodeX87::Mm_St), // 80bit _ => { return Err(DecodeError::InvalidOpcode); } @@ -9709,26 +9983,26 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i // mod=11 swaps operand order for some instructions if modrm >= 0xc0 { match r { - 0 => (Opcode::FADD, OperandCodeX87::Est_St), - 1 => (Opcode::FMUL, OperandCodeX87::Est_St), - 2 => (Opcode::FCOM, OperandCodeX87::St_Est), - 3 => (Opcode::FCOMP, OperandCodeX87::St_Est), - 4 => (Opcode::FSUBR, OperandCodeX87::Est_St), - 5 => (Opcode::FSUB, OperandCodeX87::Est_St), - 6 => (Opcode::FDIVR, OperandCodeX87::Est_St), - 7 => (Opcode::FDIV, OperandCodeX87::Est_St), + 0 => (Opcode::FADD, OperandCodeX87::Eqst_St), + 1 => (Opcode::FMUL, OperandCodeX87::Eqst_St), + 2 => (Opcode::FCOM, OperandCodeX87::St_Eqst), + 3 => (Opcode::FCOMP, OperandCodeX87::St_Eqst), + 4 => (Opcode::FSUBR, OperandCodeX87::Eqst_St), + 5 => (Opcode::FSUB, OperandCodeX87::Eqst_St), + 6 => (Opcode::FDIVR, OperandCodeX87::Eqst_St), + 7 => (Opcode::FDIV, OperandCodeX87::Eqst_St), _ => { unreachable!("impossible r"); } } } else { match r { - 0 => (Opcode::FADD, OperandCodeX87::St_Est), - 1 => (Opcode::FMUL, OperandCodeX87::St_Est), - 2 => (Opcode::FCOM, OperandCodeX87::St_Est), - 3 => (Opcode::FCOMP, OperandCodeX87::St_Est), - 4 => (Opcode::FSUB, OperandCodeX87::St_Est), - 5 => (Opcode::FSUBR, OperandCodeX87::St_Est), - 6 => (Opcode::FDIV, OperandCodeX87::St_Est), - 7 => (Opcode::FDIVR, OperandCodeX87::St_Est), + 0 => (Opcode::FADD, OperandCodeX87::St_Eqst), + 1 => (Opcode::FMUL, OperandCodeX87::St_Eqst), + 2 => (Opcode::FCOM, OperandCodeX87::St_Eqst), + 3 => (Opcode::FCOMP, OperandCodeX87::St_Eqst), + 4 => (Opcode::FSUB, OperandCodeX87::St_Eqst), + 5 => (Opcode::FSUBR, OperandCodeX87::St_Eqst), + 6 => (Opcode::FDIV, OperandCodeX87::St_Eqst), + 7 => (Opcode::FDIVR, OperandCodeX87::St_Eqst), _ => { unreachable!("impossible r"); } } } @@ -9748,13 +10022,13 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i } } else { match r { - 0 => (Opcode::FLD, OperandCodeX87::St_Est), - 1 => (Opcode::FISTTP, OperandCodeX87::Est_St), - 2 => (Opcode::FST, OperandCodeX87::Est_St), - 3 => (Opcode::FSTP, OperandCodeX87::Est_St), - 4 => (Opcode::FRSTOR, OperandCodeX87::Md), // TODO: m94/108byte + 0 => (Opcode::FLD, OperandCodeX87::St_Eqst), + 1 => (Opcode::FISTTP, OperandCodeX87::Eqst_St), + 2 => (Opcode::FST, OperandCodeX87::Eqst_St), + 3 => (Opcode::FSTP, OperandCodeX87::Eqst_St), + 4 => (Opcode::FRSTOR, OperandCodeX87::Ex87S), 5 => (Opcode::Invalid, OperandCodeX87::Nothing), - 6 => (Opcode::FNSAVE, OperandCodeX87::Est), + 6 => (Opcode::FNSAVE, OperandCodeX87::Ex87S), 7 => (Opcode::FNSTSW, OperandCodeX87::Ew), _ => { unreachable!("impossible r"); } } @@ -9818,14 +10092,14 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i } } else { match r { - 0 => (Opcode::FILD, OperandCodeX87::St_Est), - 1 => (Opcode::FISTTP, OperandCodeX87::Est_St), - 2 => (Opcode::FIST, OperandCodeX87::Est_St), - 3 => (Opcode::FISTP, OperandCodeX87::Est_St), - 4 => (Opcode::FBLD, OperandCodeX87::St_Est), - 5 => (Opcode::FILD, OperandCodeX87::St_Est), - 6 => (Opcode::FBSTP, OperandCodeX87::Est_St), - 7 => (Opcode::FISTP, OperandCodeX87::Est_St), + 0 => (Opcode::FILD, OperandCodeX87::St_Mw), + 1 => (Opcode::FISTTP, OperandCodeX87::Mw_St), + 2 => (Opcode::FIST, OperandCodeX87::Mw_St), + 3 => (Opcode::FISTP, OperandCodeX87::Mw_St), + 4 => (Opcode::FBLD, OperandCodeX87::St_Mm), + 5 => (Opcode::FILD, OperandCodeX87::St_Mq), + 6 => (Opcode::FBSTP, OperandCodeX87::Mm_St), + 7 => (Opcode::FISTP, OperandCodeX87::Mq_St), _ => { unreachable!("impossible r"); } } } @@ -9838,7 +10112,7 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i if instruction.opcode == Opcode::Invalid { return Err(DecodeError::InvalidOpcode); } - // TODO: support 80-bit operands + match x87_operands { OperandCodeX87::Est => { instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?; @@ -9850,10 +10124,51 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i instruction.operands[1] = read_E_st(&mut bytes_iter, instruction, modrm, length)?; instruction.operand_count = 2; } + OperandCodeX87::St_Edst => { + instruction.operands[0] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); + instruction.operands[1] = read_E_st(&mut bytes_iter, instruction, modrm, length)?; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 4; + } + instruction.operand_count = 2; + } + OperandCodeX87::St_Eqst => { + instruction.operands[0] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); + instruction.operands[1] = read_E_st(&mut bytes_iter, instruction, modrm, length)?; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 8; + } + instruction.operand_count = 2; + } OperandCodeX87::St_Ew => { instruction.operands[0] = OperandSpec::RegRRR; instruction.modrm_rrr = RegSpec::st(0); instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 2; + } + instruction.operand_count = 2; + } + OperandCodeX87::St_Mm => { + instruction.operands[0] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); + instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; + if instruction.operands[1] == OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + instruction.mem_size = 10; + instruction.operand_count = 2; + } + OperandCodeX87::St_Mq => { + instruction.operands[0] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); + instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; + if instruction.operands[1] == OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + instruction.mem_size = 8; instruction.operand_count = 2; } OperandCodeX87::St_Md => { @@ -9863,18 +10178,25 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i if instruction.operands[1] == OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); } + instruction.mem_size = 4; instruction.operand_count = 2; } - OperandCodeX87::Md => { - instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; - if instruction.operands[0] == OperandSpec::RegMMM { + OperandCodeX87::St_Mw => { + instruction.operands[0] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); + instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; + if instruction.operands[1] == OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); } - instruction.operand_count = 1; + instruction.mem_size = 2; + instruction.operand_count = 2; } OperandCodeX87::Ew => { instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; instruction.operand_count = 1; + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = 2; + } } OperandCodeX87::Est_St => { instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?; @@ -9882,10 +10204,51 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i instruction.modrm_rrr = RegSpec::st(0); instruction.operand_count = 2; } + OperandCodeX87::Edst_St => { + instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?; + instruction.operands[1] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); + instruction.operand_count = 2; + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = 4; + } + } + OperandCodeX87::Eqst_St => { + instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?; + instruction.operands[1] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); + instruction.operand_count = 2; + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = 8; + } + } OperandCodeX87::Ed_St => { instruction.operands[0] = read_E_st(&mut bytes_iter, instruction, modrm, length)?; instruction.operands[1] = OperandSpec::RegRRR; instruction.modrm_rrr = RegSpec::st(0); + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = 4; + } + instruction.operand_count = 2; + } + OperandCodeX87::Mm_St => { + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; + if instruction.operands[0] == OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + instruction.mem_size = 10; + instruction.operands[1] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); + instruction.operand_count = 2; + } + OperandCodeX87::Mq_St => { + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; + if instruction.operands[0] == OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + instruction.mem_size = 8; + instruction.operands[1] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); instruction.operand_count = 2; } OperandCodeX87::Md_St => { @@ -9893,6 +10256,17 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i if instruction.operands[0] == OperandSpec::RegMMM { return Err(DecodeError::InvalidOperand); } + instruction.mem_size = 4; + instruction.operands[1] = OperandSpec::RegRRR; + instruction.modrm_rrr = RegSpec::st(0); + instruction.operand_count = 2; + } + OperandCodeX87::Mw_St => { + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; + if instruction.operands[0] == OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + instruction.mem_size = 2; instruction.operands[1] = OperandSpec::RegRRR; instruction.modrm_rrr = RegSpec::st(0); instruction.operand_count = 2; @@ -9900,6 +10274,10 @@ fn decode_x87<T: Iterator<Item=u8>>(_decoder: &InstDecoder, mut bytes_iter: T, i OperandCodeX87::Ex87S => { instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 4, length)?; instruction.operand_count = 1; + if instruction.operands[0] == OperandSpec::RegMMM { + return Err(DecodeError::InvalidOperand); + } + instruction.mem_size = 63; } OperandCodeX87::Nothing => { instruction.operand_count = 0; diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs index 5c66654..d4104cd 100644 --- a/src/protected_mode/vex.rs +++ b/src/protected_mode/vex.rs @@ -328,6 +328,15 @@ 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); + } + if instruction.opcode == Opcode::VMOVSS { + instruction.mem_size = 4; + } else { + instruction.mem_size = 8; + } instruction.operands[1] = other; instruction.operand_count = 2; } @@ -348,6 +357,15 @@ 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); + } + if instruction.opcode == Opcode::VMOVSS { + instruction.mem_size = 4; + } else { + instruction.mem_size = 8; + } instruction.operands[0] = other; instruction.operand_count = 2; } @@ -369,6 +387,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; instruction.operands[2] = OperandSpec::ImmU8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 1; + } instruction.operand_count = 3; instruction.imm = read_imm_unsigned(bytes, 1, length)?; Ok(()) @@ -611,8 +632,28 @@ 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)?; + if modrm & 0xc0 == 0xc0 { + return Err(DecodeError::InvalidOperand); + } + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, 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; + if mem_oper != OperandSpec::RegMMM { + if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } + } + 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, RegisterBank::X); @@ -620,6 +661,15 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; instruction.operands[2] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + if [Opcode::VSQRTSS, Opcode::VADDSS, Opcode::VMULSS, Opcode::VSUBSS, Opcode::VMINSS, Opcode::VDIVSS, Opcode::VMAXSS].contains(&instruction.opcode) { + instruction.mem_size = 4; + } else if [Opcode::VSQRTSD, Opcode::VADDSD, Opcode::VMULSD, Opcode::VSUBSD, Opcode::VMINSD, Opcode::VDIVSD, Opcode::VMAXSD].contains(&instruction.opcode) { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } + } instruction.operand_count = 3; Ok(()) } @@ -672,6 +722,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegVex; instruction.operands[2] = OperandSpec::RegRRR; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operand_count = 3; Ok(()) } @@ -685,6 +738,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; instruction.operands[2] = OperandSpec::RegVex; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 4; + } instruction.operand_count = 3; Ok(()) } @@ -698,6 +754,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; instruction.operands[2] = OperandSpec::RegVex; + if mem_oper != OperandSpec::RegMMM { + if instruction.opcode == Opcode::VPGATHERDD { + instruction.mem_size = 4; + } else { + instruction.mem_size = 8; + } + } instruction.operand_count = 3; Ok(()) } @@ -711,6 +774,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; instruction.operands[2] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = opwidth; + } instruction.operand_count = 3; Ok(()) } @@ -724,6 +790,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; instruction.operands[2] = OperandSpec::RegVex; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = opwidth; + } instruction.operand_count = 3; Ok(()) } @@ -737,6 +806,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[1] = mem_oper; instruction.imm = read_imm_unsigned(bytes, 1, length)?; instruction.operands[2] = OperandSpec::ImmI8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = opwidth; + } instruction.operand_count = 3; Ok(()) } @@ -764,6 +836,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[0] = OperandSpec::RegVex; instruction.operands[1] = mem_oper; instruction.operand_count = 2; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = opwidth; + } instruction.vex_reg.bank = bank; Ok(()) } @@ -776,6 +851,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[1] = mem_oper; instruction.imm = read_imm_unsigned(bytes, 1, length)?; instruction.operands[2] = OperandSpec::ImmU8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 32; + } instruction.operand_count = 3; Ok(()) } @@ -790,6 +868,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[2] = mem_oper; instruction.imm = read_imm_unsigned(bytes, 1, length)? >> 4; instruction.operands[3] = OperandSpec::Reg4; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 32; + } instruction.operand_count = 4; Ok(()) } @@ -804,6 +885,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[2] = mem_oper; instruction.imm = read_imm_unsigned(bytes, 1, length)? >> 4; instruction.operands[3] = OperandSpec::Reg4; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operand_count = 4; Ok(()) } @@ -816,6 +900,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; instruction.operands[2] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operand_count = 3; Ok(()) } @@ -831,6 +918,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[2] = mem_oper; instruction.imm = read_imm_unsigned(bytes, 1, length)?; instruction.operands[3] = OperandSpec::ImmI8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 2; + } instruction.operand_count = 4; Ok(()) |