diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index 7ad9464e05..1016ddec9f 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -137,16 +137,13 @@ public: void stfXX(UGeckoInstruction inst); // Floating point + void fp_arith(UGeckoInstruction inst); void fabsx(UGeckoInstruction inst); - void faddsx(UGeckoInstruction inst); - void faddx(UGeckoInstruction inst); void fmaddsx(UGeckoInstruction inst); void fmaddx(UGeckoInstruction inst); void fmrx(UGeckoInstruction inst); void fmsubsx(UGeckoInstruction inst); void fmsubx(UGeckoInstruction inst); - void fmulsx(UGeckoInstruction inst); - void fmulx(UGeckoInstruction inst); void fnabsx(UGeckoInstruction inst); void fnegx(UGeckoInstruction inst); void fnmaddsx(UGeckoInstruction inst); @@ -154,13 +151,9 @@ public: void fnmsubsx(UGeckoInstruction inst); void fnmsubx(UGeckoInstruction inst); void fselx(UGeckoInstruction inst); - void fsubsx(UGeckoInstruction inst); - void fsubx(UGeckoInstruction inst); void fcmpX(UGeckoInstruction inst); void frspx(UGeckoInstruction inst); void fctiwzx(UGeckoInstruction inst); - void fdivx(UGeckoInstruction inst); - void fdivsx(UGeckoInstruction inst); // Paired void ps_abs(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp index 5ad2bf8321..e30a3ca3aa 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp @@ -30,37 +30,42 @@ void JitArm64::fabsx(UGeckoInstruction inst) m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB)); } -void JitArm64::faddsx(UGeckoInstruction inst) +void JitArm64::fp_arith(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(bJITFloatingPointOff); FALLBACK_IF(inst.Rc); FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - u32 a = inst.FA, b = inst.FB, d = inst.FD; + u32 a = inst.FA, d = inst.FD; + u32 b = inst.SUBOP5 == 25 ? inst.FC : inst.FB; - ARM64Reg VA = fpr.R(a, REG_IS_LOADED); - ARM64Reg VB = fpr.R(b, REG_IS_LOADED); - ARM64Reg VD = fpr.RW(d, REG_DUP); + bool single = inst.OPCD == 4 || inst.OPCD == 59; - m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB)); - fpr.FixSinglePrecision(d); -} + ARM64Reg VA = EncodeRegToDouble(fpr.R(a, REG_IS_LOADED)); + ARM64Reg VB = EncodeRegToDouble(fpr.R(b, REG_IS_LOADED)); + ARM64Reg VD = EncodeRegToDouble(fpr.RW(d, single ? REG_DUP : REG_LOWER_PAIR)); -void JitArm64::faddx(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(bJITFloatingPointOff); - FALLBACK_IF(inst.Rc); - FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); + switch (inst.SUBOP5) + { + case 18: + m_float_emit.FDIV(VD, VA, VB); + break; + case 20: + m_float_emit.FSUB(VD, VA, VB); + break; + case 21: + m_float_emit.FADD(VD, VA, VB); + break; + case 25: + m_float_emit.FMUL(VD, VA, VB); + break; + default: + _assert_msg_(DYNA_REC, 0, "fp_arith WTF!!!"); + } - u32 a = inst.FA, b = inst.FB, d = inst.FD; - - ARM64Reg VA = fpr.R(a, REG_IS_LOADED); - ARM64Reg VB = fpr.R(b, REG_IS_LOADED); - ARM64Reg VD = fpr.RW(d); - - m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB)); + if (single) + fpr.FixSinglePrecision(d); } void JitArm64::fmaddsx(UGeckoInstruction inst) @@ -155,39 +160,6 @@ void JitArm64::fmsubx(UGeckoInstruction inst) m_float_emit.FNMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB)); } -void JitArm64::fmulsx(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(bJITFloatingPointOff); - FALLBACK_IF(inst.Rc); - FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - - u32 a = inst.FA, c = inst.FC, d = inst.FD; - - ARM64Reg VA = fpr.R(a, REG_IS_LOADED); - ARM64Reg VC = fpr.R(c, REG_IS_LOADED); - ARM64Reg VD = fpr.RW(d, REG_DUP); - - m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC)); - fpr.FixSinglePrecision(d); -} - -void JitArm64::fmulx(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(bJITFloatingPointOff); - FALLBACK_IF(inst.Rc); - FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - - u32 a = inst.FA, c = inst.FC, d = inst.FD; - - ARM64Reg VA = fpr.R(a, REG_IS_LOADED); - ARM64Reg VC = fpr.R(c, REG_IS_LOADED); - ARM64Reg VD = fpr.RW(d); - - m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC)); -} - void JitArm64::fnabsx(UGeckoInstruction inst) { INSTRUCTION_START @@ -314,39 +286,6 @@ void JitArm64::fselx(UGeckoInstruction inst) m_float_emit.FCSEL(EncodeRegToDouble(VD), EncodeRegToDouble(VC), EncodeRegToDouble(VB), CC_GE); } -void JitArm64::fsubsx(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(bJITFloatingPointOff); - FALLBACK_IF(inst.Rc); - FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - - u32 a = inst.FA, b = inst.FB, d = inst.FD; - - ARM64Reg VA = fpr.R(a, REG_IS_LOADED); - ARM64Reg VB = fpr.R(b, REG_IS_LOADED); - ARM64Reg VD = fpr.RW(d, REG_DUP); - - m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB)); - fpr.FixSinglePrecision(d); -} - -void JitArm64::fsubx(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(bJITFloatingPointOff); - FALLBACK_IF(inst.Rc); - FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - - u32 a = inst.FA, b = inst.FB, d = inst.FD; - - ARM64Reg VA = fpr.R(a, REG_IS_LOADED); - ARM64Reg VB = fpr.R(b, REG_IS_LOADED); - ARM64Reg VD = fpr.RW(d); - - m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB)); -} - void JitArm64::frspx(UGeckoInstruction inst) { INSTRUCTION_START @@ -448,36 +387,3 @@ void JitArm64::fctiwzx(UGeckoInstruction inst) m_float_emit.ORR(EncodeRegToDouble(VD), EncodeRegToDouble(VD), EncodeRegToDouble(V0)); fpr.Unlock(V0); } - -void JitArm64::fdivx(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(bJITFloatingPointOff); - FALLBACK_IF(inst.Rc); - FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - - u32 a = inst.FA, b = inst.FB, d = inst.FD; - - ARM64Reg VA = fpr.R(a, REG_IS_LOADED); - ARM64Reg VB = fpr.R(b, REG_IS_LOADED); - ARM64Reg VD = fpr.RW(d); - - m_float_emit.FDIV(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB)); -} - -void JitArm64::fdivsx(UGeckoInstruction inst) -{ - INSTRUCTION_START - JITDISABLE(bJITFloatingPointOff); - FALLBACK_IF(inst.Rc); - FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); - - u32 a = inst.FA, b = inst.FB, d = inst.FD; - - ARM64Reg VA = fpr.R(a, REG_IS_LOADED); - ARM64Reg VB = fpr.R(b, REG_IS_LOADED); - ARM64Reg VD = fpr.RW(d, REG_DUP); - - m_float_emit.FDIV(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB)); - fpr.FixSinglePrecision(d); -} diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index af5bc38481..0bade60745 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -313,11 +313,11 @@ static GekkoOPTemplate table31[] = static GekkoOPTemplate table59[] = { - {18, &JitArm64::fdivsx}, // fdivsx - {20, &JitArm64::fsubsx}, // fsubsx - {21, &JitArm64::faddsx}, // faddsx + {18, &JitArm64::fp_arith}, // fdivsx + {20, &JitArm64::fp_arith}, // fsubsx + {21, &JitArm64::fp_arith}, // faddsx {24, &JitArm64::FallBackToInterpreter}, // fresx - {25, &JitArm64::fmulsx}, // fmulsx + {25, &JitArm64::fp_arith}, // fmulsx {28, &JitArm64::fmsubsx}, // fmsubsx {29, &JitArm64::fmaddsx}, // fmaddsx {30, &JitArm64::fnmsubsx}, // fnmsubsx @@ -346,11 +346,11 @@ static GekkoOPTemplate table63[] = static GekkoOPTemplate table63_2[] = { - {18, &JitArm64::fdivx}, // fdivx - {20, &JitArm64::fsubx}, // fsubx - {21, &JitArm64::faddx}, // faddx + {18, &JitArm64::fp_arith}, // fdivx + {20, &JitArm64::fp_arith}, // fsubx + {21, &JitArm64::fp_arith}, // faddx {23, &JitArm64::fselx}, // fselx - {25, &JitArm64::fmulx}, // fmulx + {25, &JitArm64::fp_arith}, // fmulx {26, &JitArm64::FallBackToInterpreter}, // frsqrtex {28, &JitArm64::fmsubx}, // fmsubx {29, &JitArm64::fmaddx}, // fmaddx