diff options
| author | iximeow <me@iximeow.net> | 2026-05-02 22:04:07 +0000 |
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2026-05-25 01:30:19 +0000 |
| commit | 706ec278edebe06eff9f91f5cb30f5faba46132d (patch) | |
| tree | 8b6dea2263c387fe0dfd9ea318b306cf26846b5f /src/protected_mode/vex.rs | |
| parent | 1652c236ee3441c89f294fda93faefadb10874e7 (diff) | |
vmaskmovdqu, vmovq were also incorrect in some ways...
Diffstat (limited to 'src/protected_mode/vex.rs')
| -rw-r--r-- | src/protected_mode/vex.rs | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs index 1ba9c66..1b5c9d9 100644 --- a/src/protected_mode/vex.rs +++ b/src/protected_mode/vex.rs @@ -46,7 +46,7 @@ enum VEXOperandCode { VMOVHPS_16, M_G_xmm, G_M_xmm, - G_U_xmm, + G_U_xmm_vmaskmovdqu, Gd_U_xmm, E_G_xmm_imm8, Ud_G_xmm_imm8, @@ -784,17 +784,12 @@ fn read_vex_operands< } op @ VEXOperandCode::G_M_xmm | - op @ VEXOperandCode::G_U_xmm | op @ VEXOperandCode::G_E_xmm => { if instruction.regs[3].num != 0 { return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; match (op, modrm & 0xc0) { - (VEXOperandCode::G_U_xmm, 0xc0) => { - /* this is the only accepted operand */ - } - (VEXOperandCode::G_U_xmm, _) | (VEXOperandCode::G_M_xmm, 0xc0) => { return Err(DecodeError::InvalidOperand); } @@ -820,6 +815,23 @@ fn read_vex_operands< instruction.operand_count = 2; Ok(()) } + VEXOperandCode::G_U_xmm_vmaskmovdqu => { + if instruction.regs[3].num != 0 { + return Err(DecodeError::InvalidOperand); + } + let modrm = read_modrm(words)?; + if modrm & 0xc0 != 0xc0 { + return Err(DecodeError::InvalidOperand); + } + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); + let mem_oper = read_E_xmm(words, instruction, modrm, sink)?; + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = mem_oper; + instruction.mem_size = 16; + instruction.operand_count = 2; + Ok(()) + } VEXOperandCode::G_xmm_E_xmm => { if instruction.regs[3].num != 0 { return Err(DecodeError::InvalidOperand); @@ -1040,7 +1052,7 @@ fn read_vex_operands< RegSpec::from_parts((modrm >> 3) & 7, bank); let mem_oper = read_E(words, instruction, modrm, bank, sink)?; if mem_oper != OperandSpec::RegMMM { - if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS { + if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS || instruction.opcode == Opcode::VMOVQ { instruction.mem_size = 8; } else { if L { @@ -1769,10 +1781,10 @@ fn read_vex_instruction< }), 0xD4 => (Opcode::VPADDQ, VEXOperandCode::G_V_E_xyLmm), 0xD5 => (Opcode::VPMULLW, VEXOperandCode::G_V_E_xyLmm), - 0xD6 => (Opcode::VMOVD, if L { + 0xD6 => (Opcode::VMOVQ, if L { return Err(DecodeError::InvalidOpcode); } else { - VEXOperandCode::G_E_xmm + VEXOperandCode::E_G_xyLmm }), 0xD7 => (Opcode::VPMOVMSKB, VEXOperandCode::Ud_G_xyLmm), 0xD8 => (Opcode::VPSUBUSB, VEXOperandCode::G_V_E_xyLmm), @@ -1832,7 +1844,7 @@ fn read_vex_instruction< 0xF7 => (Opcode::VMASKMOVDQU, if L { return Err(DecodeError::InvalidOpcode); } else { - VEXOperandCode::G_U_xmm + VEXOperandCode::G_U_xmm_vmaskmovdqu }), 0xF8 => (Opcode::VPSUBB, VEXOperandCode::G_V_E_xyLmm), 0xF9 => (Opcode::VPSUBW, VEXOperandCode::G_V_E_xyLmm), @@ -1916,7 +1928,7 @@ fn read_vex_instruction< 0x5f => (Opcode::VMAXSS, VEXOperandCode::G_V_E_xmm), 0x6f => (Opcode::VMOVDQU, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }), 0x70 => (Opcode::VPSHUFHW, VEXOperandCode::G_E_xyLmm_imm8), - 0x7e => (Opcode::VMOVD, if L { return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), + 0x7e => (Opcode::VMOVQ, if L { return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }), 0x7f => (Opcode::VMOVDQU, VEXOperandCode::E_G_xyLmm), 0xc2 => (Opcode::VCMPSS, VEXOperandCode::G_V_E_xmm_imm8), 0xe6 => (Opcode::VCVTDQ2PD, if L { VEXOperandCode::G_ymm_E_xmm } else { VEXOperandCode::G_xmm_E_xmm }), |
