From c8cdc81ce34faf3b389df14c63d59f4a9f158ed3 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 28 Dec 2013 04:43:07 -0600 Subject: [PATCH] [ARM] Implement tw/twi --- Source/Core/Core/Src/PowerPC/JitArm32/Jit.h | 1 + .../Src/PowerPC/JitArm32/JitArm_Integer.cpp | 73 ++++++++++++++++++- .../Src/PowerPC/JitArm32/JitArm_Tables.cpp | 4 +- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index fc1911c5bf..b245a38952 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -187,6 +187,7 @@ public: void mtsr(UGeckoInstruction _inst); void mfsr(UGeckoInstruction _inst); void mcrxr(UGeckoInstruction _inst); + void twx(UGeckoInstruction _inst); // LoadStore void stX(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 4d79dc037e..f39ffd01a2 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp @@ -90,7 +90,6 @@ void JitArm::ComputeCarry(bool Carry) BIC(tmp, tmp, mask); STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER])); gpr.Unlock(tmp); - } void JitArm::GetCarryAndClear(ARMReg reg) @@ -802,7 +801,6 @@ void JitArm::cmpli(UGeckoInstruction inst) STRB(rA, R9, PPCSTATE_OFF(cr_fast) + crf); gpr.Unlock(rA); - } void JitArm::negx(UGeckoInstruction inst) @@ -950,3 +948,74 @@ void JitArm::srawix(UGeckoInstruction inst) } } +void JitArm::twx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITIntegerOff) + + s32 a = inst.RA; + + gpr.Flush(); + fpr.Flush(); + + ARMReg RA = gpr.GetReg(); + ARMReg RB = gpr.GetReg(); + MOV(RA, inst.TO); + + if (inst.OPCD == 3) // twi + CMP(gpr.R(a), gpr.R(inst.RB)); + else // tw + { + MOVI2R(RB, (s32)(s16)inst.SIMM_16); + CMP(gpr.R(a), RB); + } + + FixupBranch al = B_CC(CC_LT); + FixupBranch ag = B_CC(CC_GT); + FixupBranch ae = B_CC(CC_EQ); + // FIXME: will never be reached. But also no known code uses it... + FixupBranch ll = B_CC(CC_VC); + FixupBranch lg = B_CC(CC_VS); + + SetJumpTarget(al); + TST(RA, 16); + FixupBranch exit1 = B_CC(CC_NEQ); + FixupBranch take1 = B(); + SetJumpTarget(ag); + TST(RA, 8); + FixupBranch exit2 = B_CC(CC_NEQ); + FixupBranch take2 = B(); + SetJumpTarget(ae); + TST(RA, 4); + FixupBranch exit3 = B_CC(CC_NEQ); + FixupBranch take3 = B(); + SetJumpTarget(ll); + TST(RA, 2); + FixupBranch exit4 = B_CC(CC_NEQ); + FixupBranch take4 = B(); + SetJumpTarget(lg); + TST(RA, 1); + FixupBranch exit5 = B_CC(CC_NEQ); + FixupBranch take5 = B(); + + SetJumpTarget(take1); + SetJumpTarget(take2); + SetJumpTarget(take3); + SetJumpTarget(take4); + SetJumpTarget(take5); + + LDR(RA, R9, PPCSTATE_OFF(Exceptions)); + MOVI2R(RB, EXCEPTION_PROGRAM); // XXX: Can be optimized + ORR(RA, RA, RB); + STR(RA, R9, PPCSTATE_OFF(Exceptions)); + WriteExceptionExit(); + + SetJumpTarget(exit1); + SetJumpTarget(exit2); + SetJumpTarget(exit3); + SetJumpTarget(exit4); + SetJumpTarget(exit5); + WriteExit(js.compilerPC + 4, 1); + + gpr.Unlock(RA, RB); +} diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp index 20c2dffc9c..7729cf498b 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -55,7 +55,7 @@ static GekkoOPTemplate primarytable[] = {1, &JitArm::HLEFunction}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {2, &JitArm::Default}, //"DynaBlock", OPTYPE_SYSTEM, 0}}, - {3, &JitArm::Break}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + {3, &JitArm::twx}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {17, &JitArm::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, {7, &JitArm::arith}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}}, @@ -292,7 +292,7 @@ static GekkoOPTemplate table31[] = {595, &JitArm::mfsr}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}}, {659, &JitArm::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}}, - {4, &JitArm::Break}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, + {4, &JitArm::twx}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, {598, &JitArm::DoNothing}, //"sync", OPTYPE_SYSTEM, 0, 2}}, {982, &JitArm::icbi}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}},