From df32c99be6e6837c44937fe2e3528b62871fff47 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 16 Aug 2013 01:07:11 -0700 Subject: [PATCH] Attempt to follow branches to a max # of ops. Seems to make it slower also. Maybe taking the branch would be better... hmmph. --- Core/MIPS/x86/CompBranch.cpp | 80 +++++++++++++++++++++++++++--------- Core/MIPS/x86/Jit.cpp | 9 +++- Core/MIPS/x86/Jit.h | 21 +++++++++- 3 files changed, 87 insertions(+), 23 deletions(-) diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index dbb8ca77bb..7f9052dbff 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -188,17 +188,18 @@ void Jit::BranchRSRTComp(u32 op, Gen::CCFlags cc, bool likely) } Gen::FixupBranch ptr; + RegCacheState state; if (!likely) { if (!delaySlotIsNice) - CompileDelaySlot(DELAYSLOT_SAFE_FLUSH); + CompileDelaySlot(DELAYSLOT_SAFE_FLUSH, state); else - FlushAll(); + GetStateAndFlushAll(state); ptr = J_CC(cc, true); } else { - FlushAll(); + GetStateAndFlushAll(state); ptr = J_CC(cc, true); CompileDelaySlot(DELAYSLOT_FLUSH); } @@ -209,9 +210,18 @@ void Jit::BranchRSRTComp(u32 op, Gen::CCFlags cc, bool likely) SetJumpTarget(ptr); // Not taken CONDITIONAL_LOG_EXIT(js.compilerPC + 8); - WriteExit(js.compilerPC + 8, js.nextExit++); - js.compiling = false; + if (CanContinueBranch()) + { + // Account for the delay slot. + js.compilerPC += 4; + RestoreState(state); + } + else + { + WriteExit(js.compilerPC + 8, js.nextExit++); + js.compiling = false; + } } void Jit::BranchRSZeroComp(u32 op, Gen::CCFlags cc, bool andLink, bool likely) @@ -271,17 +281,18 @@ void Jit::BranchRSZeroComp(u32 op, Gen::CCFlags cc, bool andLink, bool likely) CMP(32, gpr.R(rs), Imm32(0)); Gen::FixupBranch ptr; + RegCacheState state; if (!likely) { if (!delaySlotIsNice) - CompileDelaySlot(DELAYSLOT_SAFE_FLUSH); + CompileDelaySlot(DELAYSLOT_SAFE_FLUSH, state); else - FlushAll(); + GetStateAndFlushAll(state); ptr = J_CC(cc, true); } else { - FlushAll(); + GetStateAndFlushAll(state); ptr = J_CC(cc, true); CompileDelaySlot(DELAYSLOT_FLUSH); } @@ -295,9 +306,18 @@ void Jit::BranchRSZeroComp(u32 op, Gen::CCFlags cc, bool andLink, bool likely) SetJumpTarget(ptr); // Not taken CONDITIONAL_LOG_EXIT(js.compilerPC + 8); - WriteExit(js.compilerPC + 8, js.nextExit++); - js.compiling = false; + if (CanContinueBranch()) + { + // Account for the delay slot. + js.compilerPC += 4; + RestoreState(state); + } + else + { + WriteExit(js.compilerPC + 8, js.nextExit++); + js.compiling = false; + } } @@ -361,17 +381,18 @@ void Jit::BranchFPFlag(u32 op, Gen::CCFlags cc, bool likely) TEST(32, M((void *)&(mips_->fpcond)), Imm32(1)); Gen::FixupBranch ptr; + RegCacheState state; if (!likely) { if (!delaySlotIsNice) - CompileDelaySlot(DELAYSLOT_SAFE_FLUSH); + CompileDelaySlot(DELAYSLOT_SAFE_FLUSH, state); else - FlushAll(); + GetStateAndFlushAll(state); ptr = J_CC(cc, true); } else { - FlushAll(); + GetStateAndFlushAll(state); ptr = J_CC(cc, true); CompileDelaySlot(DELAYSLOT_FLUSH); } @@ -383,9 +404,18 @@ void Jit::BranchFPFlag(u32 op, Gen::CCFlags cc, bool likely) SetJumpTarget(ptr); // Not taken CONDITIONAL_LOG_EXIT(js.compilerPC + 8); - WriteExit(js.compilerPC + 8, js.nextExit++); - js.compiling = false; + if (CanContinueBranch()) + { + // Account for the delay slot. + js.compilerPC += 4; + RestoreState(state); + } + else + { + WriteExit(js.compilerPC + 8, js.nextExit++); + js.compiling = false; + } } @@ -433,17 +463,18 @@ void Jit::BranchVFPUFlag(u32 op, Gen::CCFlags cc, bool likely) //int val = (mips_->vfpuCtrl[VFPU_CTRL_CC] >> imm3) & 1; TEST(32, M((void *)&(mips_->vfpuCtrl[VFPU_CTRL_CC])), Imm32(1 << imm3)); Gen::FixupBranch ptr; + RegCacheState state; if (!likely) { if (!delaySlotIsNice && !delaySlotIsBranch) - CompileDelaySlot(DELAYSLOT_SAFE_FLUSH); + CompileDelaySlot(DELAYSLOT_SAFE_FLUSH, state); else - FlushAll(); + GetStateAndFlushAll(state); ptr = J_CC(cc, true); } else { - FlushAll(); + GetStateAndFlushAll(state); ptr = J_CC(cc, true); if (!delaySlotIsBranch) CompileDelaySlot(DELAYSLOT_FLUSH); @@ -457,9 +488,18 @@ void Jit::BranchVFPUFlag(u32 op, Gen::CCFlags cc, bool likely) // Not taken u32 notTakenTarget = js.compilerPC + (delaySlotIsBranch ? 4 : 8); CONDITIONAL_LOG_EXIT(notTakenTarget); - WriteExit(notTakenTarget, js.nextExit++); - js.compiling = false; + if (CanContinueBranch() && !delaySlotIsBranch) + { + // Account for the delay slot. + js.compilerPC += 4; + RestoreState(state); + } + else + { + WriteExit(notTakenTarget, js.nextExit++); + js.compiling = false; + } } diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index a760c0a99b..c73e6a5691 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -194,7 +194,7 @@ void Jit::ClearCacheAt(u32 em_address) ClearCache(); } -void Jit::CompileDelaySlot(int flags) +void Jit::CompileDelaySlot(int flags, RegCacheState *state) { const u32 addr = js.compilerPC + 4; @@ -210,7 +210,12 @@ void Jit::CompileDelaySlot(int flags) js.inDelaySlot = false; if (flags & DELAYSLOT_FLUSH) - FlushAll(); + { + if (state != NULL) + GetStateAndFlushAll(*state); + else + FlushAll(); + } if (flags & DELAYSLOT_SAFE) LOAD_FLAGS; // restore flag! } diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 0d24c0f60c..64546ecc68 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -43,10 +43,15 @@ struct JitOptions enableBlocklink = true; // Seems to hurt performance? immBranches = false; + // Seems to hurt performance also? + continueBranches = false; + continueMaxInstructions = 100; } bool enableBlocklink; bool immBranches; + bool continueBranches; + int continueMaxInstructions; }; struct JitState @@ -272,7 +277,10 @@ private: void WriteDowncount(int offset = 0); // See CompileDelaySlotFlags for flags. - void CompileDelaySlot(int flags); + void CompileDelaySlot(int flags, RegCacheState *state = NULL); + void CompileDelaySlot(int flags, RegCacheState &state) { + CompileDelaySlot(flags, &state); + } void EatInstruction(u32 op); void WriteExit(u32 destination, int exit_num); @@ -307,6 +315,17 @@ private: void CallProtectedFunction(void *func, const u32 arg1, const u32 arg2, const u32 arg3); void CallProtectedFunction(void *func, const OpArg &arg1, const u32 arg2, const u32 arg3); + bool CanContinueBranch() { + if (!jo.continueBranches || js.numInstructions >= jo.continueMaxInstructions) { + return false; + } + // Need at least 2 exits left over. + if (js.nextExit >= MAX_JIT_BLOCK_EXITS - 1) { + return false; + } + return true; + } + JitBlockCache blocks; JitOptions jo; JitState js;