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(())  | 
