diff options
author | iximeow <me@iximeow.net> | 2023-07-23 13:13:44 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2023-07-23 13:13:44 -0700 |
commit | 855fa08f1d2f4bc405a1cfc205b5e9321dd4ebf5 (patch) | |
tree | 83dc40b8d30b9a9a3a76b94ea6760cfe2163e4e5 /src/long_mode | |
parent | 4e5dfd758a22818c5f8496025e8c0b3dd00f0f50 (diff) |
fix inconsistently-poreted memory access size of vcvt{,t}{sd,si}
Diffstat (limited to 'src/long_mode')
-rw-r--r-- | src/long_mode/vex.rs | 86 |
1 files changed, 75 insertions, 11 deletions
diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index e83c735..2ee9749 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -80,6 +80,8 @@ enum VEXOperandCode { G_V_E_xmm, G_V_E_xmm_imm8, G_V_E_xmm_xmm4, + G_V_Ed_xmm, + G_V_Eq_xmm, G_V_E_ymm, G_V_E_ymm_imm8, G_V_E_ymm_ymm4, @@ -95,7 +97,9 @@ enum VEXOperandCode { G_V_E, G_E_Ib, VCVT_Gd_Ed_xmm, + VCVT_Gd_Eq_xmm, VCVT_Gq_Eq_xmm, + VCVT_Gq_Ed_xmm, BMI1_F3, MXCSR, } @@ -634,6 +638,42 @@ fn read_vex_operands< instruction.operand_count = 2; Ok(()) } + VEXOperandCode::VCVT_Gd_Eq_xmm => { + if instruction.regs[3].num != 0 { + return Err(DecodeError::InvalidOperand); + } + let modrm = read_modrm(words)?; + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::D); + let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?; + if let OperandSpec::RegMMM = mem_oper { + instruction.regs[1].bank = RegisterBank::X; + } else { + instruction.mem_size = 8; + } + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = mem_oper; + instruction.operand_count = 2; + Ok(()) + } + VEXOperandCode::VCVT_Gq_Ed_xmm => { + if instruction.regs[3].num != 0 { + return Err(DecodeError::InvalidOperand); + } + let modrm = read_modrm(words)?; + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::Q); + let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?; + if let OperandSpec::RegMMM = mem_oper { + instruction.regs[1].bank = RegisterBank::X; + } else { + instruction.mem_size = 4; + } + instruction.operands[0] = OperandSpec::RegRRR; + instruction.operands[1] = mem_oper; + instruction.operand_count = 2; + Ok(()) + } VEXOperandCode::VCVT_Gq_Eq_xmm => { if instruction.regs[3].num != 0 { return Err(DecodeError::InvalidOperand); @@ -645,11 +685,7 @@ fn read_vex_operands< if let OperandSpec::RegMMM = mem_oper { instruction.regs[1].bank = RegisterBank::X; } else { - if instruction.opcode == Opcode::VCVTSS2SI { - instruction.mem_size = 4; - } else { - instruction.mem_size = 8; - } + instruction.mem_size = 8; } instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; @@ -1202,6 +1238,34 @@ fn read_vex_operands< instruction.operand_count = 3; Ok(()) } + VEXOperandCode::G_V_Ed_xmm => { + let modrm = read_modrm(words)?; + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X); + let mem_oper = read_E_xmm(words, instruction, modrm, sink)?; + 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(()) + } + VEXOperandCode::G_V_Eq_xmm => { + let modrm = read_modrm(words)?; + instruction.regs[0] = + RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X); + let mem_oper = read_E_xmm(words, instruction, modrm, sink)?; + 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(()) + } VEXOperandCode::G_V_xmm_Ed => { let modrm = read_modrm(words)?; instruction.regs[0] = @@ -1912,17 +1976,17 @@ fn read_vex_instruction< 0x2c => (Opcode::VCVTTSD2SI, if instruction.prefixes.vex_unchecked().w() { VEXOperandCode::VCVT_Gq_Eq_xmm // 64-bit } else { - VEXOperandCode::VCVT_Gd_Ed_xmm // 32-bit + VEXOperandCode::VCVT_Gd_Eq_xmm // 32-bit }), 0x2d => (Opcode::VCVTSD2SI, if instruction.prefixes.vex_unchecked().w() { VEXOperandCode::VCVT_Gq_Eq_xmm // 64-bit } else { - VEXOperandCode::VCVT_Gd_Ed_xmm // 32-bit + VEXOperandCode::VCVT_Gd_Eq_xmm // 32-bit }), 0x51 => (Opcode::VSQRTSD, VEXOperandCode::G_V_E_xmm), 0x58 => (Opcode::VADDSD, VEXOperandCode::G_V_E_xmm), 0x59 => (Opcode::VMULSD, VEXOperandCode::G_V_E_xmm), - 0x5a => (Opcode::VCVTSD2SS, VEXOperandCode::G_V_E_xmm), + 0x5a => (Opcode::VCVTSD2SS, VEXOperandCode::G_V_Eq_xmm), 0x5c => (Opcode::VSUBSD, VEXOperandCode::G_V_E_xmm), 0x5d => (Opcode::VMINSD, VEXOperandCode::G_V_E_xmm), 0x5e => (Opcode::VDIVSD, VEXOperandCode::G_V_E_xmm), @@ -1959,12 +2023,12 @@ fn read_vex_instruction< VEXOperandCode::G_V_xmm_Ed }), 0x2c => (Opcode::VCVTTSS2SI, if instruction.prefixes.vex_unchecked().w() { - VEXOperandCode::VCVT_Gq_Eq_xmm + VEXOperandCode::VCVT_Gq_Ed_xmm } else { VEXOperandCode::VCVT_Gd_Ed_xmm }), 0x2d => (Opcode::VCVTSS2SI, if instruction.prefixes.vex_unchecked().w() { - VEXOperandCode::VCVT_Gq_Eq_xmm + VEXOperandCode::VCVT_Gq_Ed_xmm } else { VEXOperandCode::VCVT_Gd_Ed_xmm }), @@ -1973,7 +2037,7 @@ fn read_vex_instruction< 0x53 => (Opcode::VRCPSS, VEXOperandCode::G_V_E_xmm), 0x58 => (Opcode::VADDSS, VEXOperandCode::G_V_E_xmm), 0x59 => (Opcode::VMULSS, VEXOperandCode::G_V_E_xmm), - 0x5a => (Opcode::VCVTSS2SD, VEXOperandCode::G_V_E_xmm), + 0x5a => (Opcode::VCVTSS2SD, VEXOperandCode::G_V_Ed_xmm), 0x5b => (Opcode::VCVTTPS2DQ, if L { VEXOperandCode::G_ymm_E_ymm } else { VEXOperandCode::G_xmm_E_xmm }), 0x5c => (Opcode::VSUBSS, VEXOperandCode::G_V_E_xmm), 0x5d => (Opcode::VMINSS, VEXOperandCode::G_V_E_xmm), |