Interpreter: Idle skipping support

This commit is contained in:
degasus 2015-06-28 11:05:14 +02:00
parent 12fe42b2a3
commit 717d4bfbcc
6 changed files with 25 additions and 10 deletions

View File

@ -23,6 +23,11 @@ void Interpreter::bx(UGeckoInstruction _inst)
#endif*/ #endif*/
m_EndBlock = true; m_EndBlock = true;
if (NPC == PC && SConfig::GetInstance().bSkipIdle)
{
CoreTiming::Idle();
}
} }
// bcx - ugly, straight from PPC manual equations :) // bcx - ugly, straight from PPC manual equations :)
@ -50,6 +55,23 @@ void Interpreter::bcx(UGeckoInstruction _inst)
} }
m_EndBlock = true; 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) void Interpreter::bcctrx(UGeckoInstruction _inst)

View File

@ -137,7 +137,7 @@ void Jit64::lXXx(UGeckoInstruction inst)
BitSet32 registersInUse = CallerSavedRegistersInUse(); BitSet32 registersInUse = CallerSavedRegistersInUse();
ABI_PushRegistersAndAdjustStack(registersInUse, 0); ABI_PushRegistersAndAdjustStack(registersInUse, 0);
ABI_CallFunction((void *)&PowerPC::OnIdle); ABI_CallFunction((void *)&CoreTiming::Idle);
ABI_PopRegistersAndAdjustStack(registersInUse, 0); ABI_PopRegistersAndAdjustStack(registersInUse, 0);

View File

@ -2111,7 +2111,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
FixupBranch noidle = Jit->J_CC(CC_NZ); FixupBranch noidle = Jit->J_CC(CC_NZ);
RI.Jit->Cleanup(); // is it needed? 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->MOV(32, PPCSTATE(pc), Imm32(ibuild->GetImmValue( getOp2(I) )));
Jit->WriteExceptionExit(); Jit->WriteExceptionExit();

View File

@ -426,7 +426,7 @@ void JitArm64::lXX(UGeckoInstruction inst)
ARM64Reg WA = gpr.GetReg(); ARM64Reg WA = gpr.GetReg();
ARM64Reg XA = EncodeRegTo64(WA); ARM64Reg XA = EncodeRegTo64(WA);
MOVI2R(XA, (u64)&PowerPC::OnIdle); MOVI2R(XA, (u64)&CoreTiming::Idle);
BLR(XA); BLR(XA);
gpr.Unlock(WA); gpr.Unlock(WA);

View File

@ -529,11 +529,6 @@ void CheckBreakPoints()
} }
} }
void OnIdle()
{
CoreTiming::Idle();
}
} // namespace } // namespace

View File

@ -163,8 +163,6 @@ volatile CPUState *GetStatePtr(); // this oddity is here instead of an extern d
u32 CompactCR(); u32 CompactCR();
void ExpandCR(u32 cr); void ExpandCR(u32 cr);
void OnIdle();
void UpdatePerformanceMonitor(u32 cycles, u32 num_load_stores, u32 num_fp_inst); void UpdatePerformanceMonitor(u32 cycles, u32 num_load_stores, u32 num_fp_inst);
// Easy register access macros. // Easy register access macros.