Interpreter: Idle skipping support
This commit is contained in:
parent
12fe42b2a3
commit
717d4bfbcc
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -529,11 +529,6 @@ void CheckBreakPoints()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnIdle()
|
|
||||||
{
|
|
||||||
CoreTiming::Idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue