From b4baa4fdb9f4edc273aac1b057798c684e0ee787 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 19 Aug 2013 06:25:45 +0000 Subject: [PATCH] [ARM] Add mullwx, mulhwux and half implemented srawix instructions. Change fsubsx/fmulsx slightly, still broken. --- Source/Core/Core/Src/PowerPC/JitArm32/Jit.h | 3 + .../PowerPC/JitArm32/JitArm_FloatingPoint.cpp | 12 +-- .../Src/PowerPC/JitArm32/JitArm_Integer.cpp | 75 +++++++++++++++++++ .../Src/PowerPC/JitArm32/JitArm_Tables.cpp | 6 +- 4 files changed, 87 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index f3fded30e8..43fdbfa1df 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -156,6 +156,8 @@ public: void cmpli(UGeckoInstruction _inst); void negx(UGeckoInstruction _inst); void mulli(UGeckoInstruction _inst); + void mullwx(UGeckoInstruction _inst); + void mulhwux(UGeckoInstruction _inst); void ori(UGeckoInstruction _inst); void oris(UGeckoInstruction _inst); void orx(UGeckoInstruction _inst); @@ -166,6 +168,7 @@ public: void rlwimix(UGeckoInstruction _inst); void rlwinmx(UGeckoInstruction _inst); void subfx(UGeckoInstruction _inst); + void srawix(UGeckoInstruction _inst); void extshx(UGeckoInstruction inst); void extsbx(UGeckoInstruction inst); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp index 6dd1f80cd6..250058d099 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp @@ -87,13 +87,13 @@ void JitArm::fsubsx(UGeckoInstruction inst) Default(inst); return; - ARMReg vD0 = fpr.R0(inst.FD); - ARMReg vD1 = fpr.R1(inst.FD); ARMReg vA = fpr.R0(inst.FA); ARMReg vB = fpr.R0(inst.FB); + ARMReg vD0 = fpr.R0(inst.FD); + ARMReg vD1 = fpr.R1(inst.FD); VSUB(vD0, vA, vB); - VSUB(vD1, vA, vB); + VMOV(vD1, vD0); if (inst.Rc) Helper_UpdateCR1(vD0); } @@ -117,13 +117,13 @@ void JitArm::fmulsx(UGeckoInstruction inst) Default(inst); return; - ARMReg vD0 = fpr.R0(inst.FD); - ARMReg vD1 = fpr.R1(inst.FD); ARMReg vA = fpr.R0(inst.FA); ARMReg vC = fpr.R0(inst.FC); + ARMReg vD0 = fpr.R0(inst.FD); + ARMReg vD1 = fpr.R1(inst.FD); VMUL(vD0, vA, vC); - VMUL(vD1, vA, vC); + VMOV(vD1, vD0); if (inst.Rc) Helper_UpdateCR1(vD0); } void JitArm::fmulx(UGeckoInstruction inst) diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp index d0c4f35fe3..e840d4dd49 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp @@ -239,6 +239,36 @@ void JitArm::mulli(UGeckoInstruction inst) gpr.Unlock(rA); } +void JitArm::mullwx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + u32 a = inst.RA, b = inst.RB, d = inst.RD; + + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); + ARMReg RD = gpr.R(d); + MULS(RD, RA, RB); + if (inst.OE) PanicAlert("OE: mullwx"); + if (inst.Rc) ComputeRC(); +} + +void JitArm::mulhwux(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + u32 a = inst.RA, b = inst.RB, d = inst.RD; + + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); + ARMReg RD = gpr.R(d); + ARMReg rA = gpr.GetReg(false); + UMULLS(rA, RD, RA, RB); + if (inst.Rc) ComputeRC(); +} + void JitArm::ori(UGeckoInstruction inst) { INSTRUCTION_START @@ -583,4 +613,49 @@ void JitArm::rlwinmx(UGeckoInstruction inst) //m_GPR[inst.RA] = _rotl(m_GPR[inst.RS],inst.SH) & mask; } +void JitArm::srawix(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + int a = inst.RA; + int s = inst.RS; + int amount = inst.SH; + if (amount != 0) + { + Default(inst); return; + ARMReg RA = gpr.R(a); + ARMReg RS = gpr.R(s); + ARMReg tmp = gpr.GetReg(); + Operand2 mask = Operand2(2, 2); // XER_CA_MASK + + MOV(tmp, RS); + ASRS(RA, RS, amount); + if (inst.Rc) + GenerateRC(); + LSL(tmp, tmp, 32 - amount); + TST(tmp, RA); + + LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + BIC(tmp, tmp, mask); + SetCC(CC_EQ); + ORR(tmp, tmp, mask); + SetCC(); + STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + gpr.Unlock(tmp); + } + else + { + ARMReg RA = gpr.R(a); + ARMReg RS = gpr.R(s); + MOV(RA, RS); + + ARMReg tmp = gpr.GetReg(); + Operand2 mask = Operand2(2, 2); // XER_CA_MASK + LDR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + BIC(tmp, tmp, mask); + STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); + gpr.Unlock(tmp); + + } +} diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp index 7d9ae6f47a..fcfde2aae5 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -209,7 +209,7 @@ static GekkoOPTemplate table31[] = {954, &JitArm::extsbx}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, {536, &JitArm::Default}, //"srwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, {792, &JitArm::Default}, //"srawx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, - {824, &JitArm::Default}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + {824, &JitArm::srawix}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, {24, &JitArm::Default}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, {54, &JitArm::dcbst}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, @@ -318,8 +318,8 @@ static GekkoOPTemplate table31_2[] = {459, &JitArm::Default}, //"divwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, {971, &JitArm::Default}, //"divwuox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, {75, &JitArm::Default}, //"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, - {11, &JitArm::Default}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, - {235, &JitArm::Default}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {11, &JitArm::mulhwux}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {235, &JitArm::mullwx}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, {747, &JitArm::Default}, //"mullwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, {104, &JitArm::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, {40, &JitArm::subfx}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},