mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-04-29 14:59:26 -04:00
PPCRec: Reintroduce optimization for BDNZ loops
This commit is contained in:
parent
60d3233151
commit
711b56c9f6
1 changed files with 25 additions and 2 deletions
|
@ -2930,6 +2930,30 @@ void PPCIMLGen_AssertIfNotLastSegmentInstruction(ppcImlGenContext_t& ppcImlGenCo
|
||||||
cemu_assert_debug(ppcImlGenContext.currentBasicBlock->lastAddress == ppcImlGenContext.ppcAddressOfCurrentInstruction);
|
cemu_assert_debug(ppcImlGenContext.currentBasicBlock->lastAddress == ppcImlGenContext.ppcAddressOfCurrentInstruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PPCRecompiler_IsBasicBlockATightFiniteLoop(IMLSegment* imlSegment, PPCBasicBlockInfo& basicBlockInfo)
|
||||||
|
{
|
||||||
|
// if we detect a finite loop we can skip generating the cycle check
|
||||||
|
// currently we only check for BDNZ loops since thats reasonably safe to rely on
|
||||||
|
// however there are other forms of loops that can be classified as finite,
|
||||||
|
// but detecting those involves analyzing PPC code and we dont have the infrastructure for that (e.g. IML has CheckRegisterUsage but we dont have an equivalent for PPC code)
|
||||||
|
|
||||||
|
// base criteria, must jump to beginning of same segment
|
||||||
|
if (imlSegment->nextSegmentBranchTaken != imlSegment)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 opcode = *(uint32be*)(memory_base + basicBlockInfo.lastAddress);
|
||||||
|
if (Espresso::GetPrimaryOpcode(opcode) != Espresso::PrimaryOpcode::BC)
|
||||||
|
return false;
|
||||||
|
uint32 BO, BI, BD;
|
||||||
|
PPC_OPC_TEMPL_B(opcode, BO, BI, BD);
|
||||||
|
Espresso::BOField boField(BO);
|
||||||
|
if(!boField.conditionIgnore() || boField.branchAlways())
|
||||||
|
return false;
|
||||||
|
if(boField.decrementerIgnore())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void PPCRecompiler_HandleCycleCheckCount(ppcImlGenContext_t& ppcImlGenContext, PPCBasicBlockInfo& basicBlockInfo)
|
void PPCRecompiler_HandleCycleCheckCount(ppcImlGenContext_t& ppcImlGenContext, PPCBasicBlockInfo& basicBlockInfo)
|
||||||
{
|
{
|
||||||
IMLSegment* imlSegment = basicBlockInfo.GetFirstSegmentInChain();
|
IMLSegment* imlSegment = basicBlockInfo.GetFirstSegmentInChain();
|
||||||
|
@ -2938,8 +2962,7 @@ void PPCRecompiler_HandleCycleCheckCount(ppcImlGenContext_t& ppcImlGenContext, P
|
||||||
if (basicBlockInfo.branchTarget > basicBlockInfo.startAddress)
|
if (basicBlockInfo.branchTarget > basicBlockInfo.startAddress)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// exclude non-infinite tight loops
|
if (PPCRecompiler_IsBasicBlockATightFiniteLoop(imlSegment, basicBlockInfo))
|
||||||
if (IMLAnalyzer_IsTightFiniteLoop(imlSegment))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// make the segment enterable so execution can return after passing a check
|
// make the segment enterable so execution can return after passing a check
|
||||||
|
|
Loading…
Add table
Reference in a new issue