From 717d4bfbccba7b3f9b6a3787809a17130dd49afc Mon Sep 17 00:00:00 2001 From: degasus Date: Sun, 28 Jun 2015 11:05:14 +0200 Subject: [PATCH] Interpreter: Idle skipping support --- .../Interpreter/Interpreter_Branch.cpp | 22 +++++++++++++++++++ .../Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp | 2 +- Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp | 2 +- .../PowerPC/JitArm64/JitArm64_LoadStore.cpp | 2 +- Source/Core/Core/PowerPC/PowerPC.cpp | 5 ----- Source/Core/Core/PowerPC/PowerPC.h | 2 -- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp index 67f2707e9a..d642ad897c 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -23,6 +23,11 @@ void Interpreter::bx(UGeckoInstruction _inst) #endif*/ m_EndBlock = true; + + if (NPC == PC && SConfig::GetInstance().bSkipIdle) + { + CoreTiming::Idle(); + } } // bcx - ugly, straight from PPC manual equations :) @@ -50,6 +55,23 @@ void Interpreter::bcx(UGeckoInstruction _inst) } m_EndBlock = true; + + // this code trys to detect the most common idle loop: + // lwz r0, XXXX(r13) + // cmpXwi r0,0 + // beq -8 + if (NPC == PC - 8 && _inst.hex == 0x4182fff8 /* beq */ && SConfig::GetInstance().bSkipIdle) + { + if (PowerPC::HostRead_U32(PC - 8) >> 16 == 0x800D /* lwz */ ) + { + u32 last_inst = PowerPC::HostRead_U32(PC - 4); + + if (last_inst == 0x28000000 /* cmplwi */ || (last_inst == 0x2C000000 /* cmpwi */ && SConfig::GetInstance().bWii)) + { + CoreTiming::Idle(); + } + } + } } void Interpreter::bcctrx(UGeckoInstruction _inst) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp index 74bbe9d407..03c426e24c 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp @@ -137,7 +137,7 @@ void Jit64::lXXx(UGeckoInstruction inst) BitSet32 registersInUse = CallerSavedRegistersInUse(); ABI_PushRegistersAndAdjustStack(registersInUse, 0); - ABI_CallFunction((void *)&PowerPC::OnIdle); + ABI_CallFunction((void *)&CoreTiming::Idle); ABI_PopRegistersAndAdjustStack(registersInUse, 0); diff --git a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp index 17007be31f..399f1cbd6c 100644 --- a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp @@ -2111,7 +2111,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) FixupBranch noidle = Jit->J_CC(CC_NZ); RI.Jit->Cleanup(); // is it needed? - Jit->ABI_CallFunction((void *)&PowerPC::OnIdle); + Jit->ABI_CallFunction((void *)&CoreTiming::Idle); Jit->MOV(32, PPCSTATE(pc), Imm32(ibuild->GetImmValue( getOp2(I) ))); Jit->WriteExceptionExit(); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp index 9739fb35c1..6d86fa004f 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp @@ -426,7 +426,7 @@ void JitArm64::lXX(UGeckoInstruction inst) ARM64Reg WA = gpr.GetReg(); ARM64Reg XA = EncodeRegTo64(WA); - MOVI2R(XA, (u64)&PowerPC::OnIdle); + MOVI2R(XA, (u64)&CoreTiming::Idle); BLR(XA); gpr.Unlock(WA); diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp index 27274d51e7..057d41730f 100644 --- a/Source/Core/Core/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/PowerPC/PowerPC.cpp @@ -529,11 +529,6 @@ void CheckBreakPoints() } } -void OnIdle() -{ - CoreTiming::Idle(); -} - } // namespace diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 67a0f9d85f..1ad1bc8f62 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -163,8 +163,6 @@ volatile CPUState *GetStatePtr(); // this oddity is here instead of an extern d u32 CompactCR(); void ExpandCR(u32 cr); -void OnIdle(); - void UpdatePerformanceMonitor(u32 cycles, u32 num_load_stores, u32 num_fp_inst); // Easy register access macros.