aboutsummaryrefslogtreecommitdiff
path: root/src/long_mode
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2023-07-23 13:13:44 -0700
committeriximeow <me@iximeow.net>2023-07-23 13:13:44 -0700
commit855fa08f1d2f4bc405a1cfc205b5e9321dd4ebf5 (patch)
tree83dc40b8d30b9a9a3a76b94ea6760cfe2163e4e5 /src/long_mode
parent4e5dfd758a22818c5f8496025e8c0b3dd00f0f50 (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.rs86
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),