From d89d73077887f2c263b5c5f2f1d40afd8b398bf2 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Mon, 17 Jan 2011 04:29:23 +0000 Subject: [PATCH] add tw/twi to Jit64 git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6869 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Interpreter/Interpreter_Tables.cpp | 4 +- Source/Core/Core/Src/PowerPC/Jit64/Jit.h | 2 + .../Core/Src/PowerPC/Jit64/Jit64_Tables.cpp | 4 +- .../Core/Src/PowerPC/Jit64/Jit_Integer.cpp | 60 +++++++++++++++++++ 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp index 498ac69af8..2171214b52 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp @@ -40,7 +40,7 @@ static GekkoOPTemplate primarytable[] = {1, Interpreter::HLEFunction, {"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {2, Interpreter::CompiledBlock, {"DynaBlock", OPTYPE_SYSTEM, 0}}, - {3, Interpreter::twi, {"twi", OPTYPE_SYSTEM, 0}}, + {3, Interpreter::twi, {"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {17, Interpreter::sc, {"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, {7, Interpreter::mulli, {"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}}, @@ -278,7 +278,7 @@ static GekkoOPTemplate table31[] = {595, Interpreter::mfsr, {"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}}, {659, Interpreter::mfsrin, {"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}}, - {4, Interpreter::tw, {"tw", OPTYPE_SYSTEM, 0, 1}}, + {4, Interpreter::tw, {"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, {598, Interpreter::sync, {"sync", OPTYPE_SYSTEM, 0, 2}}, {982, Interpreter::icbi, {"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}}, diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index e8f5130860..38de5c8fa2 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -252,6 +252,8 @@ public: void subfmex(UGeckoInstruction inst); void subfzex(UGeckoInstruction inst); + void twx(UGeckoInstruction inst); + void lXXx(UGeckoInstruction inst); void stXx(UGeckoInstruction inst); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp index f3bf4c8648..a1001bcf1b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp @@ -54,7 +54,7 @@ static GekkoOPTemplate primarytable[] = {1, &Jit64::HLEFunction}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {2, &Jit64::Default}, //"DynaBlock", OPTYPE_SYSTEM, 0}}, - {3, &Jit64::Default}, //"twi", OPTYPE_SYSTEM, 0}}, + {3, &Jit64::twx}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {17, &Jit64::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, {7, &Jit64::mulli}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}}, @@ -291,7 +291,7 @@ static GekkoOPTemplate table31[] = {595, &Jit64::Default}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}}, {659, &Jit64::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}}, - {4, &Jit64::Default}, //"tw", OPTYPE_SYSTEM, 0, 1}}, + {4, &Jit64::twx}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, {598, &Jit64::DoNothing}, //"sync", OPTYPE_SYSTEM, 0, 2}}, {982, &Jit64::icbi}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}}, diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp index 50ef4711e8..7863d55639 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp @@ -1490,3 +1490,63 @@ void Jit64::cntlzwx(UGeckoInstruction inst) // TODO: Check PPC manual too } } + +void Jit64::twx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + s32 a = inst.RA; + s32 TO = inst.TO; + + gpr.Flush(FLUSH_ALL); + fpr.Flush(FLUSH_ALL); + + if (inst.OPCD == 3) // twi + CMP(32, gpr.R(a), gpr.R(inst.RB)); + else // tw + CMP(32, gpr.R(a), Imm32((s32)(s16)inst.SIMM_16)); + + FixupBranch al = J_CC(CC_L); + FixupBranch ag = J_CC(CC_G); + FixupBranch ae = J_CC(CC_Z); + // FIXME: will never be reached. But also no known code uses it... + FixupBranch ll = J_CC(CC_NO); + FixupBranch lg = J_CC(CC_O); + + SetJumpTarget(al); + TEST(8, R(BL), Imm8(16)); + FixupBranch exit1 = J_CC(CC_NZ); + FixupBranch take1 = J(); + SetJumpTarget(ag); + TEST(8, R(BL), Imm8(8)); + FixupBranch exit2 = J_CC(CC_NZ); + FixupBranch take2 = J(); + SetJumpTarget(ae); + TEST(8, R(BL), Imm8(4)); + FixupBranch exit3 = J_CC(CC_NZ); + FixupBranch take3 = J(); + SetJumpTarget(ll); + TEST(8, R(BL), Imm8(2)); + FixupBranch exit4 = J_CC(CC_NZ); + FixupBranch take4 = J(); + SetJumpTarget(lg); + TEST(8, R(BL), Imm8(1)); + FixupBranch exit5 = J_CC(CC_NZ); + FixupBranch take5 = J(); + + SetJumpTarget(take1); + SetJumpTarget(take2); + SetJumpTarget(take3); + SetJumpTarget(take4); + SetJumpTarget(take5); + LOCK(); + OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_PROGRAM)); + WriteExceptionExit(); + + SetJumpTarget(exit1); + SetJumpTarget(exit2); + SetJumpTarget(exit3); + SetJumpTarget(exit4); + SetJumpTarget(exit5); +}