summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorShawn Hoffman <godisgovernment@gmail.com>2011-01-17 04:29:23 +0000
committerShawn Hoffman <godisgovernment@gmail.com>2011-01-17 04:29:23 +0000
commitd89d73077887f2c263b5c5f2f1d40afd8b398bf2 (patch)
tree68f8c5b6dd723117048b758afa536bf646d1d4dd /Source/Core
parentdf3aecafef68d0c5857e05f7d17d90ab5281c6d2 (diff)
add tw/twi to Jit64
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6869 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp4
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.h2
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp4
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp60
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);
+}