From 429dc24587e342ca74cd1387dadb5db246c1f3a3 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Fri, 2 Feb 2018 21:55:23 +0000 Subject: [PATCH] IR: Merge U32 and U64 variants of FP instructions --- .../A32/translate/translate_arm/vfp2.cpp | 118 ++++-------------- src/frontend/ir/ir_emitter.cpp | 114 ++++++++--------- src/frontend/ir/ir_emitter.h | 24 ++-- 3 files changed, 92 insertions(+), 164 deletions(-) diff --git a/src/frontend/A32/translate/translate_arm/vfp2.cpp b/src/frontend/A32/translate/translate_arm/vfp2.cpp index a3cf9198..1e6fd2f1 100644 --- a/src/frontend/A32/translate/translate_arm/vfp2.cpp +++ b/src/frontend/A32/translate/translate_arm/vfp2.cpp @@ -98,13 +98,8 @@ bool ArmTranslatorVisitor::vfp2_VADD(Cond cond, bool D, size_t Vn, size_t Vd, bo return EmitVfpVectorOperation(sz, d, n, m, [sz, this](ExtReg d, ExtReg n, ExtReg m) { auto reg_n = ir.GetExtendedRegister(n); auto reg_m = ir.GetExtendedRegister(m); - if (sz) { - auto result = ir.FPAdd64(reg_n, reg_m, true); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPAdd32(reg_n, reg_m, true); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPAdd(reg_n, reg_m, true); + ir.SetExtendedRegister(d, result); }); } return true; @@ -119,13 +114,8 @@ bool ArmTranslatorVisitor::vfp2_VSUB(Cond cond, bool D, size_t Vn, size_t Vd, bo return EmitVfpVectorOperation(sz, d, n, m, [sz, this](ExtReg d, ExtReg n, ExtReg m) { auto reg_n = ir.GetExtendedRegister(n); auto reg_m = ir.GetExtendedRegister(m); - if (sz) { - auto result = ir.FPSub64(reg_n, reg_m, true); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPSub32(reg_n, reg_m, true); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPSub(reg_n, reg_m, true); + ir.SetExtendedRegister(d, result); }); } return true; @@ -140,13 +130,8 @@ bool ArmTranslatorVisitor::vfp2_VMUL(Cond cond, bool D, size_t Vn, size_t Vd, bo return EmitVfpVectorOperation(sz, d, n, m, [sz, this](ExtReg d, ExtReg n, ExtReg m) { auto reg_n = ir.GetExtendedRegister(n); auto reg_m = ir.GetExtendedRegister(m); - if (sz) { - auto result = ir.FPMul64(reg_n, reg_m, true); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPMul32(reg_n, reg_m, true); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPMul(reg_n, reg_m, true); + ir.SetExtendedRegister(d, result); }); } return true; @@ -162,13 +147,8 @@ bool ArmTranslatorVisitor::vfp2_VMLA(Cond cond, bool D, size_t Vn, size_t Vd, bo auto reg_n = ir.GetExtendedRegister(n); auto reg_m = ir.GetExtendedRegister(m); auto reg_d = ir.GetExtendedRegister(d); - if (sz) { - auto result = ir.FPAdd64(reg_d, ir.FPMul64(reg_n, reg_m, true), true); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPAdd32(reg_d, ir.FPMul32(reg_n, reg_m, true), true); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPAdd(reg_d, ir.FPMul(reg_n, reg_m, true), true); + ir.SetExtendedRegister(d, result); }); } return true; @@ -184,13 +164,8 @@ bool ArmTranslatorVisitor::vfp2_VMLS(Cond cond, bool D, size_t Vn, size_t Vd, bo auto reg_n = ir.GetExtendedRegister(n); auto reg_m = ir.GetExtendedRegister(m); auto reg_d = ir.GetExtendedRegister(d); - if (sz) { - auto result = ir.FPAdd64(reg_d, ir.FPNeg64(ir.FPMul64(reg_n, reg_m, true)), true); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPAdd32(reg_d, ir.FPNeg32(ir.FPMul32(reg_n, reg_m, true)), true); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPAdd(reg_d, ir.FPNeg(ir.FPMul(reg_n, reg_m, true)), true); + ir.SetExtendedRegister(d, result); }); } return true; @@ -205,13 +180,8 @@ bool ArmTranslatorVisitor::vfp2_VNMUL(Cond cond, bool D, size_t Vn, size_t Vd, b return EmitVfpVectorOperation(sz, d, n, m, [sz, this](ExtReg d, ExtReg n, ExtReg m) { auto reg_n = ir.GetExtendedRegister(n); auto reg_m = ir.GetExtendedRegister(m); - if (sz) { - auto result = ir.FPNeg64(ir.FPMul64(reg_n, reg_m, true)); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPNeg32(ir.FPMul32(reg_n, reg_m, true)); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPNeg(ir.FPMul(reg_n, reg_m, true)); + ir.SetExtendedRegister(d, result); }); } return true; @@ -227,13 +197,8 @@ bool ArmTranslatorVisitor::vfp2_VNMLA(Cond cond, bool D, size_t Vn, size_t Vd, b auto reg_n = ir.GetExtendedRegister(n); auto reg_m = ir.GetExtendedRegister(m); auto reg_d = ir.GetExtendedRegister(d); - if (sz) { - auto result = ir.FPAdd64(ir.FPNeg64(reg_d), ir.FPNeg64(ir.FPMul64(reg_n, reg_m, true)), true); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPAdd32(ir.FPNeg32(reg_d), ir.FPNeg32(ir.FPMul32(reg_n, reg_m, true)), true); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPAdd(ir.FPNeg(reg_d), ir.FPNeg(ir.FPMul(reg_n, reg_m, true)), true); + ir.SetExtendedRegister(d, result); }); } return true; @@ -249,13 +214,8 @@ bool ArmTranslatorVisitor::vfp2_VNMLS(Cond cond, bool D, size_t Vn, size_t Vd, b auto reg_n = ir.GetExtendedRegister(n); auto reg_m = ir.GetExtendedRegister(m); auto reg_d = ir.GetExtendedRegister(d); - if (sz) { - auto result = ir.FPAdd64(ir.FPNeg64(reg_d), ir.FPMul64(reg_n, reg_m, true), true); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPAdd32(ir.FPNeg32(reg_d), ir.FPMul32(reg_n, reg_m, true), true); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPAdd(ir.FPNeg(reg_d), ir.FPMul(reg_n, reg_m, true), true); + ir.SetExtendedRegister(d, result); }); } return true; @@ -270,13 +230,8 @@ bool ArmTranslatorVisitor::vfp2_VDIV(Cond cond, bool D, size_t Vn, size_t Vd, bo return EmitVfpVectorOperation(sz, d, n, m, [sz, this](ExtReg d, ExtReg n, ExtReg m) { auto reg_n = ir.GetExtendedRegister(n); auto reg_m = ir.GetExtendedRegister(m); - if (sz) { - auto result = ir.FPDiv64(reg_n, reg_m, true); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPDiv32(reg_n, reg_m, true); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPDiv(reg_n, reg_m, true); + ir.SetExtendedRegister(d, result); }); } return true; @@ -403,13 +358,8 @@ bool ArmTranslatorVisitor::vfp2_VABS(Cond cond, bool D, size_t Vd, bool sz, bool if (ConditionPassed(cond)) { return EmitVfpVectorOperation(sz, d, m, [sz, this](ExtReg d, ExtReg m) { auto reg_m = ir.GetExtendedRegister(m); - if (sz) { - auto result = ir.FPAbs64(reg_m); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPAbs32(reg_m); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPAbs(reg_m); + ir.SetExtendedRegister(d, result); }); } return true; @@ -422,13 +372,8 @@ bool ArmTranslatorVisitor::vfp2_VNEG(Cond cond, bool D, size_t Vd, bool sz, bool if (ConditionPassed(cond)) { return EmitVfpVectorOperation(sz, d, m, [sz, this](ExtReg d, ExtReg m) { auto reg_m = ir.GetExtendedRegister(m); - if (sz) { - auto result = ir.FPNeg64(reg_m); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPNeg32(reg_m); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPNeg(reg_m); + ir.SetExtendedRegister(d, result); }); } return true; @@ -441,13 +386,8 @@ bool ArmTranslatorVisitor::vfp2_VSQRT(Cond cond, bool D, size_t Vd, bool sz, boo if (ConditionPassed(cond)) { return EmitVfpVectorOperation(sz, d, m, [sz, this](ExtReg d, ExtReg m) { auto reg_m = ir.GetExtendedRegister(m); - if (sz) { - auto result = ir.FPSqrt64(reg_m); - ir.SetExtendedRegister(d, result); - } else { - auto result = ir.FPSqrt32(reg_m); - ir.SetExtendedRegister(d, result); - } + auto result = ir.FPSqrt(reg_m); + ir.SetExtendedRegister(d, result); }); } return true; @@ -533,11 +473,7 @@ bool ArmTranslatorVisitor::vfp2_VCMP(Cond cond, bool D, size_t Vd, bool sz, bool if (ConditionPassed(cond)) { auto reg_d = ir.GetExtendedRegister(d); auto reg_m = ir.GetExtendedRegister(m); - if (sz) { - ir.FPCompare64(reg_d, reg_m, exc_on_qnan, true); - } else { - ir.FPCompare32(reg_d, reg_m, exc_on_qnan, true); - } + ir.FPCompare(reg_d, reg_m, exc_on_qnan, true); } return true; } @@ -550,9 +486,9 @@ bool ArmTranslatorVisitor::vfp2_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz, if (ConditionPassed(cond)) { auto reg_d = ir.GetExtendedRegister(d); if (sz) { - ir.FPCompare64(reg_d, ir.Imm64(0), exc_on_qnan, true); + ir.FPCompare(reg_d, ir.Imm64(0), exc_on_qnan, true); } else { - ir.FPCompare32(reg_d, ir.Imm32(0), exc_on_qnan, true); + ir.FPCompare(reg_d, ir.Imm32(0), exc_on_qnan, true); } } return true; diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index be072f12..e72bfd23 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -869,78 +869,78 @@ U128 IREmitter::VectorZeroUpper(const U128& a) { return Inst(Opcode::VectorZeroUpper, a); } -U32 IREmitter::FPAbs32(const U32& a) { - return Inst(Opcode::FPAbs32, a); +U32U64 IREmitter::FPAbs(const U32U64& a) { + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPAbs32, a); + } else { + return Inst(Opcode::FPAbs64, a); + } } -U64 IREmitter::FPAbs64(const U64& a) { - return Inst(Opcode::FPAbs64, a); -} - -U32 IREmitter::FPAdd32(const U32& a, const U32& b, bool fpscr_controlled) { +U32U64 IREmitter::FPAdd(const U32U64& a, const U32U64& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPAdd32, a, b); + ASSERT(a.GetType() == b.GetType()); + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPAdd32, a, b); + } else { + return Inst(Opcode::FPAdd64, a, b); + } } -U64 IREmitter::FPAdd64(const U64& a, const U64& b, bool fpscr_controlled) { +void IREmitter::FPCompare(const U32U64& a, const U32U64& b, bool exc_on_qnan, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPAdd64, a, b); + ASSERT(a.GetType() == b.GetType()); + if (a.GetType() == Type::U32) { + Inst(Opcode::FPCompare32, a, b, Imm1(exc_on_qnan)); + } else { + Inst(Opcode::FPCompare64, a, b, Imm1(exc_on_qnan)); + } } -void IREmitter::FPCompare32(const U32& a, const U32& b, bool exc_on_qnan, bool fpscr_controlled) { +U32U64 IREmitter::FPDiv(const U32U64& a, const U32U64& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - Inst(Opcode::FPCompare32, a, b, Imm1(exc_on_qnan)); + ASSERT(a.GetType() == b.GetType()); + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPDiv32, a, b); + } else { + return Inst(Opcode::FPDiv64, a, b); + } } -void IREmitter::FPCompare64(const U64& a, const U64& b, bool exc_on_qnan, bool fpscr_controlled) { +U32U64 IREmitter::FPMul(const U32U64& a, const U32U64& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - Inst(Opcode::FPCompare64, a, b, Imm1(exc_on_qnan)); + ASSERT(a.GetType() == b.GetType()); + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPMul32, a, b); + } else { + return Inst(Opcode::FPMul64, a, b); + } } -U32 IREmitter::FPDiv32(const U32& a, const U32& b, bool fpscr_controlled) { +U32U64 IREmitter::FPNeg(const U32U64& a) { + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPNeg32, a); + } else { + return Inst(Opcode::FPNeg64, a); + } +} + +U32U64 IREmitter::FPSqrt(const U32U64& a) { + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPSqrt32, a); + } else { + return Inst(Opcode::FPSqrt64, a); + } +} + +U32U64 IREmitter::FPSub(const U32U64& a, const U32U64& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPDiv32, a, b); -} - -U64 IREmitter::FPDiv64(const U64& a, const U64& b, bool fpscr_controlled) { - ASSERT(fpscr_controlled); - return Inst(Opcode::FPDiv64, a, b); -} - -U32 IREmitter::FPMul32(const U32& a, const U32& b, bool fpscr_controlled) { - ASSERT(fpscr_controlled); - return Inst(Opcode::FPMul32, a, b); -} - -U64 IREmitter::FPMul64(const U64& a, const U64& b, bool fpscr_controlled) { - ASSERT(fpscr_controlled); - return Inst(Opcode::FPMul64, a, b); -} - -U32 IREmitter::FPNeg32(const U32& a) { - return Inst(Opcode::FPNeg32, a); -} - -U64 IREmitter::FPNeg64(const U64& a) { - return Inst(Opcode::FPNeg64, a); -} - -U32 IREmitter::FPSqrt32(const U32& a) { - return Inst(Opcode::FPSqrt32, a); -} - -U64 IREmitter::FPSqrt64(const U64& a) { - return Inst(Opcode::FPSqrt64, a); -} - -U32 IREmitter::FPSub32(const U32& a, const U32& b, bool fpscr_controlled) { - ASSERT(fpscr_controlled); - return Inst(Opcode::FPSub32, a, b); -} - -U64 IREmitter::FPSub64(const U64& a, const U64& b, bool fpscr_controlled) { - ASSERT(fpscr_controlled); - return Inst(Opcode::FPSub64, a, b); + ASSERT(a.GetType() == b.GetType()); + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPSub32, a, b); + } else { + return Inst(Opcode::FPSub64, a, b); + } } U32 IREmitter::FPDoubleToSingle(const U64& a, bool fpscr_controlled) { diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index 4fd58483..7c59d186 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -229,22 +229,14 @@ public: U128 VectorPairedAdd64(const U128& a, const U128& b); U128 VectorZeroUpper(const U128& a); - U32 FPAbs32(const U32& a); - U64 FPAbs64(const U64& a); - U32 FPAdd32(const U32& a, const U32& b, bool fpscr_controlled); - U64 FPAdd64(const U64& a, const U64& b, bool fpscr_controlled); - void FPCompare32(const U32& a, const U32& b, bool exc_on_qnan, bool fpscr_controlled); - void FPCompare64(const U64& a, const U64& b, bool exc_on_qnan, bool fpscr_controlled); - U32 FPDiv32(const U32& a, const U32& b, bool fpscr_controlled); - U64 FPDiv64(const U64& a, const U64& b, bool fpscr_controlled); - U32 FPMul32(const U32& a, const U32& b, bool fpscr_controlled); - U64 FPMul64(const U64& a, const U64& b, bool fpscr_controlled); - U32 FPNeg32(const U32& a); - U64 FPNeg64(const U64& a); - U32 FPSqrt32(const U32& a); - U64 FPSqrt64(const U64& a); - U32 FPSub32(const U32& a, const U32& b, bool fpscr_controlled); - U64 FPSub64(const U64& a, const U64& b, bool fpscr_controlled); + U32U64 FPAbs(const U32U64& a); + U32U64 FPAdd(const U32U64& a, const U32U64& b, bool fpscr_controlled); + void FPCompare(const U32U64& a, const U32U64& b, bool exc_on_qnan, bool fpscr_controlled); + U32U64 FPDiv(const U32U64& a, const U32U64& b, bool fpscr_controlled); + U32U64 FPMul(const U32U64& a, const U32U64& b, bool fpscr_controlled); + U32U64 FPNeg(const U32U64& a); + U32U64 FPSqrt(const U32U64& a); + U32U64 FPSub(const U32U64& a, const U32U64& b, bool fpscr_controlled); U32 FPDoubleToSingle(const U64& a, bool fpscr_controlled); U64 FPSingleToDouble(const U32& a, bool fpscr_controlled); U32 FPSingleToS32(const U32& a, bool round_towards_zero, bool fpscr_controlled);