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/JitArm64_Branch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Branch.cpp index 8efd81e0f1..2abe7d1016 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,6 +177,7 @@ void JitArm64::bcx(UGeckoInstruction inst) void JitArm64::bcctrx(UGeckoInstruction inst) { INSTRUCTION_START + JITDISABLE(bJITBranchOff); // 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!"); @@ -212,6 +217,7 @@ void JitArm64::bcctrx(UGeckoInstruction inst) void JitArm64::bclrx(UGeckoInstruction inst) { INSTRUCTION_START + JITDISABLE(bJITBranchOff); ARM64Reg WA = gpr.GetReg(); FixupBranch pCTRDontBranch; 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;