diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/long_mode/vex.rs | 86 | ||||
| -rw-r--r-- | src/protected_mode/vex.rs | 63 | ||||
| -rw-r--r-- | src/real_mode/vex.rs | 65 | 
3 files changed, 184 insertions, 30 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), diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs index bac5ee1..337e9bc 100644 --- a/src/protected_mode/vex.rs +++ b/src/protected_mode/vex.rs @@ -79,6 +79,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, @@ -92,6 +94,7 @@ enum VEXOperandCode {      G_V_E,      G_E_Ib,      VCVT_Gd_Ed_xmm, +    VCVT_Gd_Eq_xmm,      BMI1_F3,      MXCSR,  } @@ -591,11 +594,25 @@ fn read_vex_operands<              if let OperandSpec::RegMMM = mem_oper {                  instruction.regs[1].bank = RegisterBank::X;              } else { -                if instruction.opcode == Opcode::VCVTTSD2SI || instruction.opcode == Opcode::VCVTSD2SI { -                    instruction.mem_size = 8; -                } else { -                    instruction.mem_size = 4; -                } +                instruction.mem_size = 4; +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            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, 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; @@ -1148,6 +1165,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, 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, 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] = @@ -1810,15 +1855,15 @@ fn read_vex_instruction<                              VEXOperandCode::G_V_xmm_Ed // 32-bit last operand                          }),                          0x2c => (Opcode::VCVTTSD2SI, { -                            VEXOperandCode::VCVT_Gd_Ed_xmm // 32-bit +                            VEXOperandCode::VCVT_Gd_Eq_xmm                          }),                          0x2d => (Opcode::VCVTSD2SI, { -                            VEXOperandCode::VCVT_Gd_Ed_xmm // 32-bit +                            VEXOperandCode::VCVT_Gd_Eq_xmm                          }),                          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), @@ -1863,7 +1908,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), diff --git a/src/real_mode/vex.rs b/src/real_mode/vex.rs index 79c6961..afa9565 100644 --- a/src/real_mode/vex.rs +++ b/src/real_mode/vex.rs @@ -79,6 +79,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, @@ -92,6 +94,7 @@ enum VEXOperandCode {      G_V_E,      G_E_Ib,      VCVT_Gd_Ed_xmm, +    VCVT_Gd_Eq_xmm,      BMI1_F3,      MXCSR,  } @@ -591,11 +594,25 @@ fn read_vex_operands<              if let OperandSpec::RegMMM = mem_oper {                  instruction.regs[1].bank = RegisterBank::X;              } else { -                if instruction.opcode == Opcode::VCVTTSD2SI || instruction.opcode == Opcode::VCVTSD2SI { -                    instruction.mem_size = 8; -                } else { -                    instruction.mem_size = 4; -                } +                instruction.mem_size = 4; +            } +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            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, 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; @@ -1148,6 +1165,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, 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, 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] = @@ -1810,15 +1855,15 @@ fn read_vex_instruction<                              VEXOperandCode::G_V_xmm_Ed // 32-bit last operand                          }),                          0x2c => (Opcode::VCVTTSD2SI, { -                            VEXOperandCode::VCVT_Gd_Ed_xmm // 32-bit +                            VEXOperandCode::VCVT_Gd_Eq_xmm                          }),                          0x2d => (Opcode::VCVTSD2SI, { -                            VEXOperandCode::VCVT_Gd_Ed_xmm // 32-bit +                            VEXOperandCode::VCVT_Gd_Eq_xmm                          }),                          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), @@ -1862,8 +1907,8 @@ fn read_vex_instruction<                          0x52 => (Opcode::VRSQRTSS, VEXOperandCode::G_V_E_xmm),                          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), +                        0x59 => (Opcode::VMULSS, VEXOperandCode::G_V_Ed_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),  | 
