diff options
author | iximeow <me@iximeow.net> | 2021-06-27 00:19:09 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2021-06-27 00:19:09 -0700 |
commit | dc4de3f7678218b29075aa9f24bfb06b5cb4df75 (patch) | |
tree | 6bc7087639f5beba049d2854f19f5a9a02fd65d6 /src | |
parent | 0299223a04f0aed9cec74440237460ce6a139959 (diff) |
report memory sizes for all long-mode instructions
Diffstat (limited to 'src')
-rw-r--r-- | src/long_mode/display.rs | 56 | ||||
-rw-r--r-- | src/long_mode/mod.rs | 684 | ||||
-rw-r--r-- | src/long_mode/vex.rs | 212 |
3 files changed, 747 insertions, 205 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 4702861..f235c6a 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -3307,13 +3307,13 @@ impl Instruction { const MEM_SIZE_STRINGS: [&'static str; 64] = [ "byte", "word", "BUG", "dword", "BUG", "BUG", "BUG", "qword", - "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "xmmword", + "far", "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", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", - "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "zmmword", + "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "ptr", "zmmword", ]; fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: &Y, _address: u64, _context: Option<&NoContext>, out: &mut T) -> fmt::Result { @@ -3343,57 +3343,19 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: if instr.operand_count > 0 { out.write_str(" ")?; - if let Some(prefix) = instr.segment_override_for_op(0) { - write!(out, "{}:", prefix)?; - } - let x = Operand::from_spec(instr, instr.operands[0]); if x.is_memory() { out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?; out.write_str(" ")?; } + + if let Some(prefix) = instr.segment_override_for_op(0) { + write!(out, "{}:", prefix)?; + } x.colorize(colors, out)?; for i in 1..instr.operand_count { match instr.opcode { - Opcode::MOVSX_b | - Opcode::MOVZX_b => { - match &instr.operands[i as usize] { - &OperandSpec::Nothing => { - return Ok(()); - }, - &OperandSpec::RegMMM => { - out.write_str(", ")?; - } - _ => { - out.write_str(", byte ")?; - if let Some(prefix) = instr.segment_override_for_op(i) { - write!(out, "{}:", prefix)?; - } - } - } - let x = Operand::from_spec(instr, instr.operands[i as usize]); - x.colorize(colors, out)? - }, - Opcode::MOVSX_w | - Opcode::MOVZX_w => { - match &instr.operands[i as usize] { - &OperandSpec::Nothing => { - return Ok(()); - }, - &OperandSpec::RegMMM => { - out.write_str(", ")?; - } - _ => { - out.write_str(", word ")?; - if let Some(prefix) = instr.segment_override_for_op(i) { - write!(out, "{}:", prefix)?; - } - } - } - let x = Operand::from_spec(instr, instr.operands[i as usize]); - x.colorize(colors, out)?; - }, _ => { match &instr.operands[i as usize] { &OperandSpec::Nothing => { @@ -3401,14 +3363,14 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: }, _ => { out.write_str(", ")?; - if let Some(prefix) = instr.segment_override_for_op(i) { - write!(out, "{}:", prefix)?; - } let x = Operand::from_spec(instr, instr.operands[i as usize]); if x.is_memory() { out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?; out.write_str(" ")?; } + if let Some(prefix) = instr.segment_override_for_op(i) { + write!(out, "{}:", prefix)?; + } x.colorize(colors, out)?; if let Some(evex) = instr.prefixes.evex() { if evex.broadcast() && x.is_memory() { diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index e14fb4a..60a18c5 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -4180,7 +4180,7 @@ impl Instruction { Instruction { prefixes: Prefixes::new(0), opcode: Opcode::Invalid, - mem_size: 1, + mem_size: 0, modrm_rrr: RegSpec::rax(), modrm_mmm: RegSpec::rax(), // doubles as sib_base sib_index: RegSpec::rax(), @@ -4954,7 +4954,6 @@ enum OperandCode { // Edq_Gdq = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().read_E().operand_case(49).bits(), Gdq_Ev = OperandCodeBuilder::new().op0_is_rrr_and_embedded_instructions().operand_case(40).bits(), Mdq_Gdq = 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(), @@ -4971,7 +4970,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(), // gap, 0x9a @@ -4984,11 +4983,13 @@ 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_Edq, 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(), @@ -5000,7 +5001,7 @@ enum OperandCode { 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_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(), @@ -5029,6 +5030,11 @@ enum OperandCode { Yb_AL = OperandCodeBuilder::new().special_case(99).bits(), Yb_Xb = OperandCodeBuilder::new().special_case(100).bits(), Yv_AX = OperandCodeBuilder::new().special_case(101).bits(), + INV_Gv_M = OperandCodeBuilder::new().special_case(102).bits(), + PMOVX_G_E_xmm = OperandCodeBuilder::new().operand_case(103).bits(), + PMOVX_E_G_xmm = OperandCodeBuilder::new().operand_case(104).bits(), + G_Ev_xmm_Ib = OperandCodeBuilder::new().operand_case(105).bits(), + G_E_mm_Ib = OperandCodeBuilder::new().operand_case(106).bits(), } const LOCKABLE_INSTRUCTIONS: &[Opcode] = &[ @@ -5205,7 +5211,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), @@ -5640,9 +5646,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), @@ -5669,8 +5675,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_Edq), 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), @@ -5709,21 +5715,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), @@ -5815,10 +5821,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), @@ -5917,8 +5923,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), @@ -5986,21 +5992,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), @@ -6092,10 +6098,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), @@ -6196,12 +6202,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), @@ -6225,8 +6231,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), @@ -6366,10 +6372,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), @@ -6385,7 +6391,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), @@ -6404,7 +6410,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), @@ -6475,7 +6481,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), @@ -6499,8 +6505,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), @@ -6548,7 +6554,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), @@ -6648,10 +6654,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 @@ -6707,7 +6713,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), @@ -6748,7 +6754,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), @@ -6762,7 +6768,7 @@ fn read_0f38_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { 0xf1 => OpcodeRecord(Interpretation::Instruction(Opcode::CRC32), OperandCode::Gdq_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), }; @@ -6794,22 +6800,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), @@ -6821,9 +6827,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), @@ -6876,9 +6882,9 @@ fn read_0f3a_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord { if prefixes.operand_size() { if opcode == 0x16 && prefixes.rex().w() { - return OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRQ), OperandCode::G_E_xmm_Ib); + return OpcodeRecord(Interpretation::Instruction(Opcode::PEXTRQ), OperandCode::G_Ev_xmm_Ib); } else if opcode == 0x22 && prefixes.rex().w() { - return OpcodeRecord(Interpretation::Instruction(Opcode::PINSRQ), OperandCode::G_E_xmm_Ib); + return OpcodeRecord(Interpretation::Instruction(Opcode::PINSRQ), OperandCode::G_Ev_xmm_Ib); } return match opcode { @@ -6890,13 +6896,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), @@ -7423,6 +7429,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 = 8; + } else if opcode == Opcode::CALLF || opcode == Opcode::JMPF { + instruction.mem_size = 9; + } } instruction.opcode = opcode; instruction.operand_count = 1; @@ -7432,8 +7444,14 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, let modrm = read_modrm(&mut bytes_iter, length)?; instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 1, length)?; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 1; + } instruction.modrm_rrr = RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()); + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 1; + } instruction.operand_count = 2; }, 16 => { @@ -7443,6 +7461,9 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; instruction.modrm_rrr = RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()); + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 2; + } instruction.operand_count = 2; }, 17 => { @@ -7450,6 +7471,7 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, let modrm = read_modrm(&mut bytes_iter, length)?; instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 4 /* opwidth */, length)?; + instruction.mem_size = 4; instruction.modrm_rrr = RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()); instruction.operand_count = 2; @@ -7466,6 +7488,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 | @@ -7480,6 +7504,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 => { @@ -7491,6 +7521,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 u64; *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; }, @@ -7544,12 +7583,16 @@ 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 + 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; @@ -7560,8 +7603,26 @@ fn read_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, instruction.opcode = [ Opcode::POP, ][r as usize]; + if mem_oper != OperandSpec::RegMMM { + // the right size is set by default except for the default case; by default + // operands are dword, but 0x8f `pop` defaults to qword (with no way to encode a + // `pop dword [mem]`) + if !instruction.prefixes.operand_size() { + instruction.mem_size = 8; + } + } 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)?; @@ -7573,6 +7634,108 @@ 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::from_parts((modrm >> 3) & 7, false, RegisterBank::MM); + instruction.imm = + read_num(&mut bytes_iter, 1)? as u8 as u64; + *length += 1; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 8; + } + 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::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); + instruction.imm = + read_num(&mut bytes_iter, 1)? as u8 as u64; + *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::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); + 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::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::X); + 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].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::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::Q); + 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.rex().w() { + instruction.mem_size = 10; + } else { + instruction.mem_size = 4; + } + } else if [Opcode::ENQCMD, Opcode::ENQCMDS].contains(&instruction.opcode) { + instruction.mem_size = 64; + } else { + instruction.mem_size = 16; + } + } OperandCode::G_U_xmm_Ub => { let modrm = read_modrm(&mut bytes_iter, length)?; @@ -7647,6 +7810,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.imm = read_num(&mut bytes_iter, 1)? as u8 as u64; *length += 1; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operands[2] = OperandSpec::ImmU8; instruction.operand_count = 3; } @@ -7654,6 +7820,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr.bank = RegisterBank::D; if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::D; + } else { + instruction.mem_size = 4; } instruction.operands[1] = mem_oper; instruction.operand_count = 2; @@ -7692,7 +7860,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; } @@ -7732,6 +7900,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter RegSpec::from_parts((modrm >> 3) & 7, false, 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 u64; @@ -7745,6 +7915,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; }, @@ -7778,6 +7954,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter // `opwidth` can be 2, 4, or 8 here. if opwidth is 2, the first operand is a dword. // if opwidth is 4, both registers are dwords. and if opwidth is 8, both registers are // qword. + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 4; + } let regwidth = if opwidth == 2 { 4 } else { @@ -7798,6 +7977,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter unsafe { unreachable_unchecked() } } }; + instruction.mem_size = opwidth; let addr_width = if instruction.prefixes.address_size() { 4 } else { 8 }; let imm = read_num(&mut bytes_iter, addr_width)?; *length += addr_width; @@ -7822,6 +8002,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter unsafe { unreachable_unchecked() } } }; + instruction.mem_size = opwidth; let addr_width = if instruction.prefixes.address_size() { 4 } else { 8 }; let imm = read_num(&mut bytes_iter, addr_width)?; *length += addr_width; @@ -7872,6 +8053,8 @@ 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 { return Err(DecodeError::InvalidOperand); + } else { + instruction.mem_size = opwidth; } instruction.modrm_rrr = RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()); @@ -7900,6 +8083,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_rrr = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::Q); instruction.operand_count = 2; + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = 8; + } } OperandCode::G_E_q => { if instruction.prefixes.operand_size() { @@ -7913,13 +8099,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), RegisterBank::Q); instruction.operands[1] = read_E(&mut bytes_iter, instruction, modrm, 8, length)?; instruction.operand_count = 2; + if instruction.operands[1] != OperandSpec::RegMMM { + instruction.mem_size = 8; + } } - 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; @@ -7962,6 +8153,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 => { @@ -7972,6 +8166,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 { @@ -8066,8 +8263,10 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { if instruction.prefixes.rex().w() { instruction.opcode = Opcode::CMPXCHG16B; + instruction.mem_size = 16; } else { instruction.opcode = Opcode::CMPXCHG8B; + instruction.mem_size = 8; } instruction.operand_count = 1; let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); @@ -8094,8 +8293,10 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { if instruction.prefixes.rex().w() { instruction.opcode = Opcode::CMPXCHG16B; + instruction.mem_size = 16; } else { instruction.opcode = Opcode::CMPXCHG8B; + instruction.mem_size = 8; } instruction.operand_count = 1; let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); @@ -8112,6 +8313,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(()); @@ -8150,8 +8353,10 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { if instruction.prefixes.rex().w() { instruction.opcode = Opcode::CMPXCHG16B; + instruction.mem_size = 16; } else { instruction.opcode = Opcode::CMPXCHG8B; + instruction.mem_size = 8; } instruction.operand_count = 1; let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); @@ -8166,6 +8371,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::SENDUIPI; // and the operand is always a qword register instruction.modrm_mmm.bank = RegisterBank::Q; + } else { + instruction.mem_size = 8; } instruction.operand_count = 1; } @@ -8196,8 +8403,10 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter return Err(DecodeError::InvalidOperand); } else { if instruction.prefixes.rex().w() { + instruction.mem_size = 16; Opcode::CMPXCHG16B } else { + instruction.mem_size = 8; Opcode::CMPXCHG8B } } @@ -8207,6 +8416,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; if instruction.prefixes.rex().w() { Opcode::XRSTORS64 } else { @@ -8219,6 +8429,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; if instruction.prefixes.rex().w() { Opcode::XSAVEC64 } else { @@ -8231,6 +8442,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; if instruction.prefixes.rex().w() { Opcode::XSAVES64 } else { @@ -8242,6 +8454,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 } } @@ -8249,6 +8462,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 } } @@ -8485,6 +8699,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::Edq_G_mm => { @@ -8498,6 +8714,12 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { instruction.modrm_mmm.bank = RegisterBank::D; } + } else { + if instruction.prefixes.rex().w() { + instruction.mem_size = 8; + } else { + instruction.mem_size = 4; + } } } OperandCode::Edq_G_xmm => { @@ -8512,6 +8734,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } else { instruction.modrm_mmm.bank = RegisterBank::D; } + } else { + if instruction.prefixes.rex().w() { + instruction.opcode = Opcode::MOVQ; + instruction.mem_size = 8; + } else { + instruction.mem_size = 4; + } } } OperandCode::E_G_mm => { @@ -8522,6 +8751,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; } } /* @@ -8543,7 +8774,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter } } }, - OperandCode::G_xmm_Ed_Ib => { + OperandCode::G_xmm_Ew_Ib => { instruction.operands[2] = OperandSpec::ImmU8; instruction.operand_count = 3; instruction.imm = @@ -8552,12 +8783,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_Eq => { instruction.modrm_rrr.bank = RegisterBank::X; if mem_oper == OperandSpec::RegMMM { instruction.modrm_mmm.bank = RegisterBank::Q; + } else { + instruction.mem_size = 8; } }, OperandCode::G_mm_E_xmm => { @@ -8565,6 +8800,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 | @@ -8576,6 +8813,12 @@ 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 { + if instruction.prefixes.rex().w() { + instruction.mem_size = 8; + } else { + instruction.mem_size = 4; + } } } }, @@ -8666,6 +8909,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter instruction.modrm_mmm.bank = RegisterBank::X; instruction.opcode = Opcode::MOVHLPS; } else { + instruction.mem_size = 8; if instruction.prefixes.operand_size() { instruction.opcode = Opcode::MOVLPD; } else { @@ -8683,6 +8927,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 { @@ -8706,6 +8951,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 { @@ -8718,6 +8966,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 => { @@ -8726,6 +8976,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; } @@ -8751,6 +9009,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 => { @@ -8784,6 +9043,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 => { @@ -8884,6 +9144,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 { @@ -8940,6 +9201,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 { @@ -8975,6 +9237,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 { @@ -9039,6 +9302,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 { @@ -9046,6 +9310,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; @@ -9055,6 +9320,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, 8, length)?; + instruction.mem_size = 8; instruction.operand_count = 1; return Ok(()); } @@ -9156,6 +9422,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; @@ -9205,6 +9472,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 { @@ -9232,6 +9500,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 { @@ -9286,6 +9555,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter 4 }; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; + if instruction.operands[0] != OperandSpec::RegMMM { + instruction.mem_size = opwidth; + } instruction.operand_count = 1; return Ok(()); } @@ -9365,6 +9637,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, 8, length)?; instruction.operand_count = 1; + instruction.mem_size = 8; return Ok(()); } _ => { @@ -9426,17 +9699,20 @@ 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)?; + instruction.mem_size = mem_size; } } OperandCode::ModRM_0x0fba => { @@ -9652,6 +9928,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter if let OperandSpec::RegMMM = instruction.operands[1] { return Err(DecodeError::InvalidOperand); } + instruction.mem_size = 64; if instruction.prefixes.address_size() { instruction.modrm_rrr.bank = RegisterBank::D; } else { @@ -9690,13 +9967,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, } @@ -9708,20 +9994,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) @@ -9744,7 +10030,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 => { @@ -9878,8 +10164,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); } @@ -9891,26 +10177,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"); } } } @@ -9930,13 +10216,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"); } } @@ -10000,14 +10286,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"); } } } @@ -10020,7 +10306,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)?; @@ -10032,10 +10318,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 => { @@ -10045,18 +10372,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)?; @@ -10064,10 +10398,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 => { @@ -10075,6 +10450,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; @@ -10082,6 +10468,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/long_mode/vex.rs b/src/long_mode/vex.rs index 7a58fe6..6db99a1 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -61,6 +61,7 @@ enum VEXOperandCode { Ed_G_xmm_imm8, Eq_G_xmm_imm8, G_Ex_V_xmm, + G_Ey_V_xmm, G_Ey_V_ymm, G_E_xmm, G_E_xmm_imm8, @@ -373,6 +374,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst 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; } @@ -397,6 +403,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst 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.operands[1] = instruction.operands[2]; instruction.operand_count = 2; @@ -416,6 +427,7 @@ 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] = read_E_xmm(bytes, instruction, modrm, length)?; + instruction.mem_size = 4; instruction.operand_count = 3; Ok(()) } @@ -431,6 +443,7 @@ 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] = read_E_xmm(bytes, instruction, modrm, length)?; + instruction.mem_size = 8; instruction.operand_count = 3; Ok(()) } @@ -449,7 +462,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; - instruction.mem_size = 1; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 1; + } instruction.operand_count = 3; instruction.imm = read_imm_unsigned(bytes, 1, length)?; Ok(()) @@ -466,7 +481,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; - instruction.mem_size = 2; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 2; + } instruction.operand_count = 3; instruction.imm = read_imm_unsigned(bytes, 1, length)?; Ok(()) @@ -483,7 +500,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; - instruction.mem_size = 4; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 4; + } instruction.operand_count = 3; instruction.imm = read_imm_unsigned(bytes, 1, length)?; Ok(()) @@ -500,7 +519,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; - instruction.mem_size = 8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 8; + } instruction.operand_count = 3; instruction.imm = read_imm_unsigned(bytes, 1, length)?; Ok(()) @@ -517,6 +538,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.imm = read_imm_unsigned(bytes, 1, length)?; instruction.operands[3] = OperandSpec::ImmU8; instruction.mem_size = 1; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 1; + } instruction.operand_count = 4; Ok(()) } @@ -532,6 +556,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.imm = read_imm_unsigned(bytes, 1, length)?; instruction.operands[3] = OperandSpec::ImmU8; instruction.mem_size = 4; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 4; + } instruction.operand_count = 4; Ok(()) } @@ -546,7 +573,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::ImmU8; - instruction.mem_size = 8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 8; + } instruction.operand_count = 4; Ok(()) } @@ -561,6 +590,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E(bytes, instruction, modrm, 8, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 8; + } instruction.operand_count = 2; Ok(()) } @@ -575,6 +607,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 4; + } instruction.operand_count = 2; Ok(()) } @@ -589,6 +624,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E(bytes, instruction, modrm, 8, length)?; instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 8; + } instruction.operand_count = 2; Ok(()) } @@ -603,6 +641,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E(bytes, instruction, modrm, 4, length)?; instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 4; + } instruction.operand_count = 2; Ok(()) } @@ -637,7 +678,11 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst if let OperandSpec::RegMMM = mem_oper { instruction.modrm_mmm.bank = RegisterBank::X; } else { - instruction.mem_size = 8; + if instruction.opcode == Opcode::VCVTSS2SI { + instruction.mem_size = 4; + } else { + instruction.mem_size = 8; + } } instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; @@ -666,6 +711,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst /* and this is always accepted */ } } + if mem_oper != OperandSpec::RegMMM { + if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } + } instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; instruction.operand_count = 2; @@ -737,10 +789,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[1] = OperandSpec::RegRRR; instruction.imm = read_imm_unsigned(bytes, 1, length)?; instruction.operands[2] = OperandSpec::ImmU8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operand_count = 3; Ok(()) } - _op @ VEXOperandCode::E_xmm_G_ymm_imm8 => { + VEXOperandCode::E_xmm_G_ymm_imm8 => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); @@ -753,6 +808,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst instruction.operands[1] = OperandSpec::RegRRR; instruction.imm = read_imm_unsigned(bytes, 1, length)?; instruction.operands[2] = OperandSpec::ImmU8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operand_count = 3; Ok(()) } @@ -818,10 +876,19 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + if [Opcode::VBROADCASTSS, Opcode::VUCOMISS, Opcode::VCOMISS].contains(&instruction.opcode) { + instruction.mem_size = 4; + } else if [Opcode::VMOVDDUP, Opcode::VUCOMISD, Opcode::VCOMISD, Opcode::VCVTPS2PD, Opcode::VMOVQ].contains(&instruction.opcode) { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + }; + } instruction.operand_count = 2; Ok(()) } - _op @ VEXOperandCode::G_xmm_E_xmm => { + VEXOperandCode::G_xmm_E_xmm => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); @@ -832,10 +899,13 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operand_count = 2; Ok(()) } - _op @ VEXOperandCode::G_xmm_E_ymm => { + VEXOperandCode::G_xmm_E_ymm => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); @@ -846,6 +916,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 32; + } instruction.operand_count = 2; Ok(()) } @@ -866,10 +939,19 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E_xmm(bytes, instruction, modrm, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + if [Opcode::VBROADCASTSS].contains(&instruction.opcode) { + instruction.mem_size = 4; + } else if [Opcode::VBROADCASTSD].contains(&instruction.opcode) { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } + } instruction.operand_count = 2; Ok(()) } - _op @ VEXOperandCode::G_ymm_E_ymm => { + VEXOperandCode::G_ymm_E_ymm => { if instruction.vex_reg.num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); @@ -880,6 +962,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 32; + } instruction.operand_count = 2; Ok(()) } @@ -905,6 +990,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegRRR; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 32; + } instruction.operand_count = 2; Ok(()) } @@ -930,6 +1018,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 32; + } instruction.operand_count = 2; Ok(()) } @@ -947,6 +1038,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 32; + } instruction.operands[2] = mem_oper; instruction.operand_count = 3; Ok(()) @@ -962,6 +1056,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::ImmU8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 32; + } instruction.operand_count = 4; Ok(()) } @@ -977,6 +1074,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 = 32; + } instruction.operand_count = 3; Ok(()) } @@ -995,6 +1095,13 @@ 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 instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD { + instruction.mem_size = 8; + } else { + instruction.mem_size = 16; + } + } instruction.operand_count = 3; Ok(()) } @@ -1006,6 +1113,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(()) } @@ -1017,6 +1133,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 = 4; + } instruction.operand_count = 3; Ok(()) } @@ -1028,6 +1147,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 = 8; + } instruction.operand_count = 3; Ok(()) } @@ -1041,6 +1163,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::ImmU8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operand_count = 4; Ok(()) } @@ -1055,6 +1180,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::ImmU8; + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 16; + } instruction.operand_count = 4; Ok(()) } @@ -1070,6 +1198,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(()) } @@ -1083,6 +1214,25 @@ 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(()) + } + VEXOperandCode::G_Ey_V_xmm => { + let modrm = read_modrm(bytes, length)?; + instruction.modrm_rrr = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex().r(), RegisterBank::X); + let mem_oper = read_E_ymm(bytes, instruction, modrm, length)?; + instruction.vex_reg.bank = RegisterBank::X; + instruction.sib_index.bank = RegisterBank::Y; + 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(()) } @@ -1096,6 +1246,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(()) } @@ -1113,6 +1270,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(()) } @@ -1130,6 +1290,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(()) } @@ -1147,6 +1310,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(()) } @@ -1178,6 +1344,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(()) } @@ -1199,6 +1368,9 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst if let OperandSpec::RegMMM = mem_oper { return Err(DecodeError::InvalidOperand); } + if mem_oper != OperandSpec::RegMMM { + instruction.mem_size = 4; + } instruction.operands[0] = mem_oper; instruction.operand_count = 1; Ok(()) @@ -1215,6 +1387,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 = 16; + } instruction.operand_count = 3; Ok(()) } @@ -1230,6 +1405,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(()) } @@ -1244,6 +1422,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(()) } @@ -1258,6 +1439,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(()) } @@ -1270,6 +1454,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(()) } @@ -1285,6 +1472,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(()) @@ -2556,7 +2746,7 @@ fn read_vex_instruction<T: Iterator<Item=u8>>(opcode_map: VEXOpcodeMap, bytes: & }) } else { (Opcode::VPGATHERQD, if L { - VEXOperandCode::G_Ey_V_ymm + VEXOperandCode::G_Ey_V_xmm } else { VEXOperandCode::G_Ex_V_xmm }) |