diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index 3510c60321..37ea9459f1 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -221,7 +221,9 @@ public: void ps_sum0(UGeckoInstruction _inst); void ps_sum1(UGeckoInstruction _inst); void ps_madd(UGeckoInstruction _inst); + void ps_nmadd(UGeckoInstruction _inst); void ps_msub(UGeckoInstruction _inst); + void ps_nmsub(UGeckoInstruction _inst); void ps_madds0(UGeckoInstruction _inst); void ps_madds1(UGeckoInstruction _inst); void ps_sub(UGeckoInstruction _inst); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Paired.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Paired.cpp index 6e3c898c7f..175fc9e31e 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Paired.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Paired.cpp @@ -47,6 +47,39 @@ void JitArm::ps_add(UGeckoInstruction inst) VADD(vD1, vA1, vB1); } +void JitArm::ps_nmadd(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITPairedOff) + + u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD; + + if (inst.Rc) { + Default(inst); return; + } + ARMReg vA0 = fpr.R0(a); + ARMReg vA1 = fpr.R1(a); + ARMReg vB0 = fpr.R0(b); + ARMReg vB1 = fpr.R1(b); + ARMReg vC0 = fpr.R0(c); + ARMReg vC1 = fpr.R1(c); + ARMReg vD0 = fpr.R0(d, false); + ARMReg vD1 = fpr.R1(d, false); + + ARMReg V0 = fpr.GetReg(); + ARMReg V1 = fpr.GetReg(); + + VMUL(V0, vA0, vC0); + VMUL(V1, vA1, vC1); + VADD(vD0, V0, vB0); + VADD(vD1, V1, vB1); + VNEG(vD0, vD0); + VNEG(vD1, vD1); + + fpr.Unlock(V0); + fpr.Unlock(V1); +} + void JitArm::ps_madd(UGeckoInstruction inst) { INSTRUCTION_START @@ -78,6 +111,39 @@ void JitArm::ps_madd(UGeckoInstruction inst) fpr.Unlock(V1); } +void JitArm::ps_nmsub(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITPairedOff) + + u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD; + + if (inst.Rc) { + Default(inst); return; + } + ARMReg vA0 = fpr.R0(a); + ARMReg vA1 = fpr.R1(a); + ARMReg vB0 = fpr.R0(b); + ARMReg vB1 = fpr.R1(b); + ARMReg vC0 = fpr.R0(c); + ARMReg vC1 = fpr.R1(c); + ARMReg vD0 = fpr.R0(d, false); + ARMReg vD1 = fpr.R1(d, false); + + ARMReg V0 = fpr.GetReg(); + ARMReg V1 = fpr.GetReg(); + + VMUL(V0, vA0, vC0); + VMUL(V1, vA1, vC1); + VSUB(vD0, V0, vB0); + VSUB(vD1, V1, vB1); + VNEG(vD0, vD0); + VNEG(vD1, vD1); + + fpr.Unlock(V0); + fpr.Unlock(V1); +} + void JitArm::ps_msub(UGeckoInstruction inst) { INSTRUCTION_START diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp index 8427956340..cd67098ae3 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -158,8 +158,8 @@ static GekkoOPTemplate table4_2[] = {26, &JitArm::Default}, //"ps_rsqrte", OPTYPE_PS, 0, 1}}, {28, &JitArm::ps_msub}, //"ps_msub", OPTYPE_PS, 0}}, {29, &JitArm::ps_madd}, //"ps_madd", OPTYPE_PS, 0}}, - {30, &JitArm::Default}, //"ps_nmsub", OPTYPE_PS, 0}}, - {31, &JitArm::Default}, //"ps_nmadd", OPTYPE_PS, 0}}, + {30, &JitArm::ps_nmsub}, //"ps_nmsub", OPTYPE_PS, 0}}, + {31, &JitArm::ps_nmadd}, //"ps_nmadd", OPTYPE_PS, 0}}, };