summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Houdek <Sonicadvance1@gmail.com>2015-07-01 11:40:07 -0500
committerRyan Houdek <Sonicadvance1@gmail.com>2015-07-01 11:40:07 -0500
commite9921044b5de732411c8aef798283063fc64d2e7 (patch)
tree79bc4bdef384c30adcba7038305fc0bb10c4464c
parent8d69c2b4b722e2c4f9f0496b9ff1912c1a10d9e1 (diff)
parent245a639e2c729af3f9ef22a7d1d36e2b85d79aa9 (diff)
Merge pull request #2671 from degasus/jitarmbranch
JitArm64: branching fallbacks
-rw-r--r--Source/Core/Core/ConfigManager.cpp1
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.cpp35
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.h1
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp53
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp9
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp4
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp2
7 files changed, 66 insertions, 39 deletions
diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp
index 75f047129d..bace9b7971 100644
--- a/Source/Core/Core/ConfigManager.cpp
+++ b/Source/Core/Core/ConfigManager.cpp
@@ -621,6 +621,7 @@ void SConfig::LoadDefaults()
bJITIntegerOff = false;
bJITPairedOff = false;
bJITSystemRegistersOff = false;
+ bJITBranchOff = false;
m_strName = "NONE";
m_strUniqueID = "00000000";
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
index b968aeacf9..a658252043 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
@@ -51,10 +51,45 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
{
gpr.Flush(FlushMode::FLUSH_INTERPRETER, js.op);
fpr.Flush(FlushMode::FLUSH_INTERPRETER, js.op);
+
+ if (js.op->opinfo->flags & FL_ENDBLOCK)
+ {
+ // also flush the program counter
+ ARM64Reg WA = gpr.GetReg();
+ MOVI2R(WA, js.compilerPC);
+ STR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(pc));
+ ADD(WA, WA, 4);
+ STR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(npc));
+ gpr.Unlock(WA);
+ }
+
Interpreter::_interpreterInstruction instr = GetInterpreterOp(inst);
MOVI2R(W0, inst.hex);
MOVI2R(X30, (u64)instr);
BLR(X30);
+
+ if (js.op->opinfo->flags & FL_ENDBLOCK)
+ {
+ if (js.isLastInstruction)
+ {
+ ARM64Reg WA = gpr.GetReg();
+ LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(npc));
+ WriteExceptionExit(WA);
+ }
+ else
+ {
+ // only exit if ppcstate.npc was changed
+ ARM64Reg WA = gpr.GetReg();
+ LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(npc));
+ ARM64Reg WB = gpr.GetReg();
+ MOVI2R(WB, js.compilerPC + 4);
+ CMP(WB, WA);
+ gpr.Unlock(WB);
+ FixupBranch c = B(CC_EQ);
+ WriteExceptionExit(WA);
+ SetJumpTarget(c);
+ }
+ }
}
void JitArm64::HLEFunction(UGeckoInstruction inst)
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h
index aa9f43add3..6b2d0c3fe8 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.h
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h
@@ -114,7 +114,6 @@ public:
void mtspr(UGeckoInstruction inst);
// LoadStore
- void icbi(UGeckoInstruction inst);
void lXX(UGeckoInstruction inst);
void stX(UGeckoInstruction inst);
void lmw(UGeckoInstruction inst);
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp
index 8efd81e0f1..4dfd88b92e 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp
@@ -18,6 +18,7 @@ using namespace Arm64Gen;
void JitArm64::sc(UGeckoInstruction inst)
{
INSTRUCTION_START
+ JITDISABLE(bJITBranchOff);
gpr.Flush(FlushMode::FLUSH_ALL);
fpr.Flush(FlushMode::FLUSH_ALL);
@@ -38,6 +39,7 @@ void JitArm64::sc(UGeckoInstruction inst)
void JitArm64::rfi(UGeckoInstruction inst)
{
INSTRUCTION_START
+ JITDISABLE(bJITBranchOff);
gpr.Flush(FlushMode::FLUSH_ALL);
fpr.Flush(FlushMode::FLUSH_ALL);
@@ -78,6 +80,7 @@ void JitArm64::rfi(UGeckoInstruction inst)
void JitArm64::bx(UGeckoInstruction inst)
{
INSTRUCTION_START
+ JITDISABLE(bJITBranchOff);
gpr.Flush(FlushMode::FLUSH_ALL);
fpr.Flush(FlushMode::FLUSH_ALL);
@@ -115,6 +118,7 @@ void JitArm64::bx(UGeckoInstruction inst)
void JitArm64::bcx(UGeckoInstruction inst)
{
INSTRUCTION_START
+ JITDISABLE(bJITBranchOff);
ARM64Reg WA = gpr.GetReg();
FixupBranch pCTRDontBranch;
@@ -173,45 +177,42 @@ void JitArm64::bcx(UGeckoInstruction inst)
void JitArm64::bcctrx(UGeckoInstruction inst)
{
INSTRUCTION_START
+ JITDISABLE(bJITBranchOff);
+
+ // Rare condition seen in (just some versions of?) Nintendo's NES Emulator
+ // BO_2 == 001zy -> b if false
+ // BO_2 == 011zy -> b if true
+ FALLBACK_IF(!(inst.BO_2 & BO_DONT_CHECK_CONDITION));
// bcctrx doesn't decrement and/or test CTR
_assert_msg_(DYNA_REC, inst.BO_2 & BO_DONT_DECREMENT_FLAG, "bcctrx with decrement and test CTR option is invalid!");
- if (inst.BO_2 & BO_DONT_CHECK_CONDITION)
- {
- // BO_2 == 1z1zz -> b always
-
- //NPC = CTR & 0xfffffffc;
- gpr.Flush(FlushMode::FLUSH_ALL);
- fpr.Flush(FlushMode::FLUSH_ALL);
-
- if (inst.LK_3)
- {
- ARM64Reg WB = gpr.GetReg();
- u32 Jumpto = js.compilerPC + 4;
- MOVI2R(WB, Jumpto);
- STR(INDEX_UNSIGNED, WB, X29, PPCSTATE_OFF(spr[SPR_LR]));
- gpr.Unlock(WB);
- }
+ // BO_2 == 1z1zz -> b always
- ARM64Reg WA = gpr.GetReg();
+ //NPC = CTR & 0xfffffffc;
+ gpr.Flush(FlushMode::FLUSH_ALL);
+ fpr.Flush(FlushMode::FLUSH_ALL);
- LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(spr[SPR_CTR]));
- AND(WA, WA, 30, 29); // Wipe the bottom 2 bits.
- WriteExitDestInR(WA);
- }
- else
+ if (inst.LK_3)
{
- // Rare condition seen in (just some versions of?) Nintendo's NES Emulator
- // BO_2 == 001zy -> b if false
- // BO_2 == 011zy -> b if true
- _assert_msg_(DYNA_REC, false, "Haven't implemented rare form of bcctrx yet");
+ ARM64Reg WB = gpr.GetReg();
+ u32 Jumpto = js.compilerPC + 4;
+ MOVI2R(WB, Jumpto);
+ STR(INDEX_UNSIGNED, WB, X29, PPCSTATE_OFF(spr[SPR_LR]));
+ gpr.Unlock(WB);
}
+
+ ARM64Reg WA = gpr.GetReg();
+
+ LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(spr[SPR_CTR]));
+ AND(WA, WA, 30, 29); // Wipe the bottom 2 bits.
+ WriteExitDestInR(WA);
}
void JitArm64::bclrx(UGeckoInstruction inst)
{
INSTRUCTION_START
+ JITDISABLE(bJITBranchOff);
ARM64Reg WA = gpr.GetReg();
FixupBranch pCTRDontBranch;
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp
index 9739fb35c1..19433dcda0 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp
@@ -18,15 +18,6 @@
using namespace Arm64Gen;
-void JitArm64::icbi(UGeckoInstruction inst)
-{
- gpr.Flush(FlushMode::FLUSH_ALL);
- fpr.Flush(FlushMode::FLUSH_ALL);
-
- FallBackToInterpreter(inst);
- WriteExit(js.compilerPC + 4);
-}
-
void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 offset, bool update)
{
// We want to make sure to not get LR as a temp register
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp
index 72e42c1769..212c12fa8c 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_SystemRegisters.cpp
@@ -48,8 +48,7 @@ FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
void JitArm64::mtmsr(UGeckoInstruction inst)
{
INSTRUCTION_START
- // Don't interpret this, if we do we get thrown out
- //JITDISABLE(bJITSystemRegistersOff)
+ JITDISABLE(bJITSystemRegistersOff);
gpr.BindToRegister(inst.RS, true);
STR(INDEX_UNSIGNED, gpr.R(inst.RS), X29, PPCSTATE_OFF(msr));
@@ -143,6 +142,7 @@ void JitArm64::mtsrin(UGeckoInstruction inst)
void JitArm64::twx(UGeckoInstruction inst)
{
INSTRUCTION_START
+ JITDISABLE(bJITSystemRegistersOff);
s32 a = inst.RA;
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
index fe3bb519a4..7bf211bdc5 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
@@ -302,7 +302,7 @@ static GekkoOPTemplate table31[] =
{4, &JitArm64::twx}, // tw
{598, &JitArm64::DoNothing}, // sync
- {982, &JitArm64::icbi}, // icbi
+ {982, &JitArm64::FallBackToInterpreter}, // icbi
// Unused instructions on GC
{310, &JitArm64::FallBackToInterpreter}, // eciwx