mirror of https://github.com/cemu-project/Cemu.git
PPCRec: Clean up code and optimize
This commit is contained in:
parent
97ef9524b0
commit
aa904b6d1c
|
@ -543,23 +543,31 @@ boost::container::small_vector<raLivenessRange*, 8> IMLRA_GetRangeWithFixedRegRe
|
|||
|
||||
void IMLRA_HandleFixedRegisters(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||
{
|
||||
// first pass - iterate over all ranges with fixed register requirements and split them if they cross the segment border (we can later optimize this)
|
||||
for(raLivenessRange* currentRange = imlSegment->raInfo.linkedList_allSubranges; currentRange; currentRange = currentRange->link_allSegmentRanges.next)
|
||||
// first pass - iterate over all ranges with fixed register requirements and split them if they cross the segment border
|
||||
// todo - this can be optimized. Ranges only need to be split if there are conflicts with other segments. Note that below passes rely on the fact that this pass currently splits all ranges with fixed register requirements
|
||||
for(raLivenessRange* currentRange = imlSegment->raInfo.linkedList_allSubranges; currentRange;)
|
||||
{
|
||||
IMLPhysRegisterSet allowedRegs;
|
||||
if(!currentRange->GetAllowedRegistersEx(allowedRegs))
|
||||
{
|
||||
currentRange = currentRange->link_allSegmentRanges.next;
|
||||
continue;
|
||||
}
|
||||
if(currentRange->interval2.ExtendsPreviousSegment() || currentRange->interval2.ExtendsIntoNextSegment())
|
||||
{
|
||||
raLivenessRange* nextRange = currentRange->link_allSegmentRanges.next;
|
||||
PPCRecRA_explodeRange(ppcImlGenContext, currentRange);
|
||||
// currentRange may be invalidated, therefore iterate from the beginning again (todo - can be optimized)
|
||||
currentRange = imlSegment->raInfo.linkedList_allSubranges;
|
||||
currentRange = nextRange;
|
||||
continue;
|
||||
}
|
||||
currentRange = currentRange->link_allSegmentRanges.next;
|
||||
}
|
||||
// second pass - look for ranges with conflicting fixed register requirements and split these too (locally)
|
||||
for(raLivenessRange* currentRange = imlSegment->raInfo.linkedList_allSubranges; currentRange; currentRange = currentRange->link_allSegmentRanges.next)
|
||||
{
|
||||
IMLPhysRegisterSet allowedRegs;
|
||||
if(currentRange->list_fixedRegRequirements.empty())
|
||||
continue; // we dont need to check whole clusters because the pass above guarantees that there are no ranges with fixed register requirements that extend outside of this segment
|
||||
if(!currentRange->GetAllowedRegistersEx(allowedRegs))
|
||||
continue;
|
||||
if(allowedRegs.HasAnyAvailable())
|
||||
|
@ -607,6 +615,8 @@ void IMLRA_HandleFixedRegisters(ppcImlGenContext_t* ppcImlGenContext, IMLSegment
|
|||
for(raLivenessRange* currentRange = imlSegment->raInfo.linkedList_allSubranges; currentRange; currentRange = currentRange->link_allSegmentRanges.next)
|
||||
{
|
||||
IMLPhysRegisterSet allowedRegs;
|
||||
if(currentRange->list_fixedRegRequirements.empty())
|
||||
continue; // we dont need to check whole clusters because the pass above guarantees that there are no ranges with fixed register requirements that extend outside of this segment
|
||||
if(!currentRange->GetAllowedRegistersEx(allowedRegs))
|
||||
{
|
||||
cemu_assert_debug(currentRange->list_fixedRegRequirements.empty());
|
||||
|
@ -1074,23 +1084,8 @@ void IMLRA_FilterReservedFixedRegisterRequirementsForCluster(IMLRegisterAllocato
|
|||
IMLRA_FilterReservedFixedRegisterRequirementsForSegment(ctx, currentRange, candidatePhysRegSet);
|
||||
}
|
||||
|
||||
void __DebugTestA(IMLSegment* imlSegment)
|
||||
{
|
||||
// iterate all ranges
|
||||
raLivenessRange* subrangeItr = imlSegment->raInfo.linkedList_allSubranges;
|
||||
while(subrangeItr)
|
||||
{
|
||||
if(!subrangeItr->list_fixedRegRequirements.empty())
|
||||
{
|
||||
cemu_assert_debug(subrangeItr->HasPhysicalRegister());
|
||||
}
|
||||
subrangeItr = subrangeItr->link_allSegmentRanges.next;
|
||||
}
|
||||
}
|
||||
|
||||
bool IMLRA_AssignSegmentRegisters(IMLRegisterAllocatorContext& ctx, ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment)
|
||||
{
|
||||
DbgVerifyAllRanges(ctx);
|
||||
// sort subranges ascending by start index
|
||||
_sortSegmentAllSubrangesLinkedList(imlSegment);
|
||||
|
||||
|
@ -1108,7 +1103,6 @@ bool IMLRA_AssignSegmentRegisters(IMLRegisterAllocatorContext& ctx, ppcImlGenCon
|
|||
RASpillStrategy_ExplodeRangeInter explodeRangeInter;
|
||||
}strategy;
|
||||
|
||||
sint32 dbgIndex = 0;
|
||||
while(subrangeItr)
|
||||
{
|
||||
raInstructionEdge currentRangeStart = subrangeItr->interval2.start; // used to be currentIndex before refactor
|
||||
|
@ -1147,7 +1141,6 @@ bool IMLRA_AssignSegmentRegisters(IMLRegisterAllocatorContext& ctx, ppcImlGenCon
|
|||
cemu_assert_debug(allowedRegs.HasAnyAvailable()); // if zero regs are available, then this range needs to be split to avoid mismatching register requirements (do this in the initial pass to keep the code here simpler)
|
||||
candidatePhysRegSet &= allowedRegs;
|
||||
|
||||
__DebugTestA(imlSegment);
|
||||
for (auto& liverangeItr : livenessTimeline.activeRanges)
|
||||
{
|
||||
cemu_assert_debug(liverangeItr->GetPhysicalRegister() >= 0);
|
||||
|
@ -1175,7 +1168,6 @@ bool IMLRA_AssignSegmentRegisters(IMLRegisterAllocatorContext& ctx, ppcImlGenCon
|
|||
subrangeItr = subrangeItr->link_allSegmentRanges.next; // next
|
||||
continue;
|
||||
}
|
||||
__DebugTestA(imlSegment);
|
||||
// there is no free register for the entire range
|
||||
// evaluate different strategies of splitting ranges to free up another register or shorten the current range
|
||||
strategy.localRangeHoleCutting.Reset();
|
||||
|
@ -1205,20 +1197,17 @@ bool IMLRA_AssignSegmentRegisters(IMLRegisterAllocatorContext& ctx, ppcImlGenCon
|
|||
// evaluate strategy: Explode inter-segment ranges
|
||||
strategy.explodeRange.Evaluate(imlSegment, subrangeItr, livenessTimeline, allowedRegs);
|
||||
SelectStrategyIfBetter(strategy.explodeRange);
|
||||
__DebugTestA(imlSegment);
|
||||
}
|
||||
else // if subrangeItr->interval2.ExtendsIntoNextSegment()
|
||||
{
|
||||
strategy.explodeRangeInter.Reset();
|
||||
strategy.explodeRangeInter.Evaluate(imlSegment, subrangeItr, livenessTimeline, allowedRegs);
|
||||
SelectStrategyIfBetter(strategy.explodeRangeInter);
|
||||
__DebugTestA(imlSegment);
|
||||
}
|
||||
// choose strategy
|
||||
if(selectedStrategy)
|
||||
{
|
||||
selectedStrategy->Apply(ppcImlGenContext, imlSegment, subrangeItr);
|
||||
__DebugTestA(imlSegment);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1226,12 +1215,7 @@ bool IMLRA_AssignSegmentRegisters(IMLRegisterAllocatorContext& ctx, ppcImlGenCon
|
|||
cemu_assert_debug(subrangeItr->interval2.ExtendsPreviousSegment());
|
||||
// alternative strategy if we have no other choice: explode current range
|
||||
PPCRecRA_explodeRange(ppcImlGenContext, subrangeItr);
|
||||
__DebugTestA(imlSegment);
|
||||
}
|
||||
// DEBUG BEGIN
|
||||
DbgVerifyAllRanges(ctx);
|
||||
dbgIndex++;
|
||||
// DEBUG END
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -2131,37 +2115,15 @@ void IMLRegisterAllocator_AllocateRegisters(ppcImlGenContext_t* ppcImlGenContext
|
|||
ctx.raParam = &raParam;
|
||||
ctx.deprGenContext = ppcImlGenContext;
|
||||
|
||||
DbgVerifyAllRanges(ctx); // DEBUG
|
||||
|
||||
IMLRA_ReshapeForRegisterAllocation(ppcImlGenContext);
|
||||
|
||||
DbgVerifyAllRanges(ctx); // DEBUG
|
||||
|
||||
ppcImlGenContext->UpdateSegmentIndices(); // update momentaryIndex of each segment
|
||||
|
||||
DbgVerifyAllRanges(ctx); // DEBUG
|
||||
ctx.perSegmentAbstractRanges.resize(ppcImlGenContext->segmentList2.size());
|
||||
|
||||
IMLRA_CalculateLivenessRanges(ctx);
|
||||
DbgVerifyAllRanges(ctx); // DEBUG
|
||||
IMLRA_ProcessFlowAndCalculateLivenessRanges(ctx);
|
||||
DbgVerifyAllRanges(ctx); // DEBUG
|
||||
IMLRA_AssignRegisters(ctx, ppcImlGenContext);
|
||||
DbgVerifyAllRanges(ctx); // DEBUG
|
||||
|
||||
// debug print
|
||||
//IMLDebug_Dump(ppcImlGenContext, true);
|
||||
|
||||
// debug print
|
||||
// if (ppcImlGenContext->debug_entryPPCAddress == 0x2BDA9F4)
|
||||
// {
|
||||
// IMLDebug_Dump(ppcImlGenContext, true);
|
||||
// __debugbreak();
|
||||
// }
|
||||
|
||||
IMLRA_AnalyzeRangeDataFlow(ppcImlGenContext);
|
||||
IMLRA_GenerateMoveInstructions(ctx);
|
||||
|
||||
|
||||
PPCRecRA_deleteAllRanges(ppcImlGenContext);
|
||||
IMLRA_DeleteAllRanges(ppcImlGenContext);
|
||||
}
|
||||
|
|
|
@ -32,10 +32,10 @@ void raLivenessRange::SetPhysicalRegisterForCluster(sint32 physicalRegister)
|
|||
range->physicalRegister = physicalRegister;
|
||||
}
|
||||
|
||||
boost::container::small_vector<raLivenessRange*, 32> raLivenessRange::GetAllSubrangesInCluster()
|
||||
boost::container::small_vector<raLivenessRange*, 128> raLivenessRange::GetAllSubrangesInCluster()
|
||||
{
|
||||
uint32 iterationIndex = PPCRecRA_getNextIterationIndex();
|
||||
boost::container::small_vector<raLivenessRange*, 32> subranges;
|
||||
boost::container::small_vector<raLivenessRange*, 128> subranges;
|
||||
subranges.push_back(this);
|
||||
this->lastIterationIndex = iterationIndex;
|
||||
size_t i = 0;
|
||||
|
@ -302,7 +302,7 @@ void PPCRecRA_deleteSubrangeCluster(ppcImlGenContext_t* ppcImlGenContext, raLive
|
|||
}
|
||||
}
|
||||
|
||||
void PPCRecRA_deleteAllRanges(ppcImlGenContext_t* ppcImlGenContext)
|
||||
void IMLRA_DeleteAllRanges(ppcImlGenContext_t* ppcImlGenContext)
|
||||
{
|
||||
for(auto& seg : ppcImlGenContext->segmentList2)
|
||||
{
|
||||
|
|
|
@ -324,7 +324,7 @@ struct raLivenessRange
|
|||
// register allocator result
|
||||
sint32 physicalRegister;
|
||||
|
||||
boost::container::small_vector<raLivenessRange*, 32> GetAllSubrangesInCluster();
|
||||
boost::container::small_vector<raLivenessRange*, 128> GetAllSubrangesInCluster();
|
||||
bool GetAllowedRegistersEx(IMLPhysRegisterSet& allowedRegisters); // if the cluster has fixed register requirements in any instruction this returns the combined register mask. Otherwise returns false in which case allowedRegisters is left undefined
|
||||
IMLPhysRegisterSet GetAllowedRegisters(IMLPhysRegisterSet regPool); // return regPool with fixed register requirements filtered out
|
||||
|
||||
|
@ -339,7 +339,7 @@ struct raLivenessRange
|
|||
|
||||
raLivenessRange* PPCRecRA_createSubrange2(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, IMLRegID virtualRegister, IMLName name, raInstructionEdge startPosition, raInstructionEdge endPosition);
|
||||
void PPCRecRA_deleteSubrange(ppcImlGenContext_t* ppcImlGenContext, raLivenessRange* subrange);
|
||||
void PPCRecRA_deleteAllRanges(ppcImlGenContext_t* ppcImlGenContext);
|
||||
void IMLRA_DeleteAllRanges(ppcImlGenContext_t* ppcImlGenContext);
|
||||
|
||||
void PPCRecRA_explodeRange(ppcImlGenContext_t* ppcImlGenContext, raLivenessRange* originRange);
|
||||
|
||||
|
|
|
@ -212,85 +212,6 @@ PPCRecFunction_t* PPCRecompiler_recompileFunction(PPCFunctionBoundaryTracker::PP
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
// DEBUG BEGIN
|
||||
// if(ppcRecFunc->ppcAddress != 0x2BDA9F4) // TP
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
// if(ppcRecFunc->ppcAddress < 0x2BDA9F4) // TP
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
// this prevents the crashing
|
||||
// if((ppcRecFunc->ppcAddress >= 0x02ade400 && ppcRecFunc->ppcAddress < 0x02ade600)) -> no crash
|
||||
//if((ppcRecFunc->ppcAddress >= 0x02ade500 && ppcRecFunc->ppcAddress < 0x02ade600)) -> no crash
|
||||
// if((ppcRecFunc->ppcAddress >= 0x02ade580 && ppcRecFunc->ppcAddress < 0x02ade600)) // -> crashed around 0x0x2b874b0 (but rare? Out of 5 runs it only crashed once)
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
// the problem with Shovel Knight is that the crash seems to be pretty instable, at least when trying to narrow it down. Lets look for another game for now
|
||||
|
||||
// check TP bug...
|
||||
// if(ppcRecFunc->ppcAddress >= 0x03000000) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02800000) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02C00000) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02A00000) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B00000) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B80000) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B40000) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B60000) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B70000) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B68000) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B64000) -> no bug (I went into wrong direction)
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B6C000) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B6A000) -> has bug (double checked, it has bug)
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B6B000) -> has bug (I went into the wrong direction again? Or does A000 have no bug??
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B69000) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B68800) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B68400) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B68600) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B68500) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B68580) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B685C0) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B685A0) -> has bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B68590) -> no bug
|
||||
// if(ppcRecFunc->ppcAddress >= 0x02B68598) -> has bug
|
||||
|
||||
// if(ppcRecFunc->ppcAddress != 0x02B68594) -> seems fine. No bug (against the expectation)
|
||||
// if(ppcRecFunc->ppcAddress == 0x02B68594) -> Still has the bug
|
||||
|
||||
// if(ppcRecFunc->ppcAddress == 0x02B68594)
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
// if(ppcRecFunc->ppcAddress >= 0x2B7A8D4 && ppcRecFunc->ppcAddress < 0x02B7AC9C && ppcRecFunc->ppcAddress != 0x2B7A8D4)
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
// doing both of these means no bug!
|
||||
// excluding just ppcAddress == 0x2B7A8D4 is enough to trigger the bug again. So it definitely that function
|
||||
// next: Debug it!
|
||||
|
||||
// In Pikmin 3 030a9998 is broken?
|
||||
// if(!(ppcRecFunc->ppcAddress >= 0x030a9998 && ppcRecFunc->ppcAddress < 0x030AA208))
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
// DEBUG END
|
||||
|
||||
|
||||
// apply passes
|
||||
if (!PPCRecompiler_ApplyIMLPasses(ppcImlGenContext))
|
||||
|
@ -299,90 +220,11 @@ PPCRecFunction_t* PPCRecompiler_recompileFunction(PPCFunctionBoundaryTracker::PP
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// TP
|
||||
// if (ppcRecFunc->ppcAddress == 0x2B7A8D4)
|
||||
// {
|
||||
// debug_printf("----------------------------------------\n");
|
||||
// IMLDebug_Dump(&ppcImlGenContext);
|
||||
// //__debugbreak();
|
||||
// }
|
||||
// // Bad Function in SM3DW
|
||||
// if (ppcRecFunc->ppcAddress == 0x023D5768)
|
||||
// {
|
||||
// debug_printf("----------------------------------------\n");
|
||||
// IMLDebug_Dump(&ppcImlGenContext);
|
||||
// }
|
||||
// if (ppcRecFunc->ppcAddress >= 0x023D5768 && ppcRecFunc->ppcAddress < 0x023D58DC)
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
//
|
||||
|
||||
//
|
||||
// // 0x02846c74
|
||||
// if (ppcRecFunc->ppcAddress == 0x02846c74)
|
||||
// {
|
||||
// debug_printf("----------------------------------------\n");
|
||||
// IMLDebug_Dump(&ppcImlGenContext);
|
||||
// __debugbreak();
|
||||
// }
|
||||
|
||||
// Shovel Knight
|
||||
// if (ppcRecFunc->ppcAddress >= 0x02A1E630 && ppcRecFunc->ppcAddress < 0x02A1E9D8)
|
||||
// {
|
||||
// // debug_printf("----------------------------------------\n");
|
||||
// // IMLDebug_Dump(&ppcImlGenContext);
|
||||
// // __debugbreak();
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
//
|
||||
// //
|
||||
// if (ppcRecFunc->ppcAddress == 0x02ade5c4 || ppcRecFunc->ppcAddress == 0x02ade5c8)
|
||||
// {
|
||||
// // debug_printf("----------------------------------------\n");
|
||||
// IMLDebug_Dump(&ppcImlGenContext);
|
||||
// __debugbreak();
|
||||
// }
|
||||
|
||||
// else
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
//if (ppcRecFunc->ppcAddress == 0x11223344)
|
||||
//{
|
||||
// //debug_printf("----------------------------------------\n");
|
||||
// //IMLDebug_Dump(&ppcImlGenContext);
|
||||
// //__debugbreak();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
//}
|
||||
|
||||
// if (ppcRecFunc->ppcAddress >= 0x2BDA9F4 && ppcRecFunc->ppcAddress < 0x02BDAB38)
|
||||
// {
|
||||
// return nullptr;
|
||||
// //IMLDebug_Dump(&ppcImlGenContext);
|
||||
// //__debugbreak();
|
||||
// }
|
||||
|
||||
// if (ppcRecFunc->ppcAddress == 0x2BDA9F4)
|
||||
// {
|
||||
// IMLDebug_Dump(&ppcImlGenContext);
|
||||
// __debugbreak();
|
||||
// }
|
||||
// 31A8778
|
||||
|
||||
// if(ppcRecFunc->ppcAddress >= 0x2759E20 && ppcRecFunc->ppcAddress < 0x0275A0CC)
|
||||
// {
|
||||
// delete ppcRecFunc;
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
// Functions for testing (botw):
|
||||
// 3B4049C (large with switch case)
|
||||
|
|
|
@ -2876,75 +2876,6 @@ bool PPCIMLGen_FillBasicBlock(ppcImlGenContext_t& ppcImlGenContext, PPCBasicBloc
|
|||
uint32 addressOfCurrentInstruction = (uint32)((uint8*)ppcImlGenContext.currentInstruction - memory_base);
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction = addressOfCurrentInstruction;
|
||||
|
||||
// DEBUG BEGIN
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7A8D4+0x10) -> stops bug
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7A9C0) -> has bug (optional code path)
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AA50) -> stops bug
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AC34) -> stops bug
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AC78) -> has bug
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AC70) -> has bug
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AC88) -> has bug
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7AC3C) -> has bug
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7AC38) -> no bug
|
||||
// weirdly, excluding 0x02B7AC38 fixes the issue. Excluding both 0x02B7AC3C and 0x2B7AC88 (the follow up instructions) does not fix the bug
|
||||
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7ABE4) -> has bug
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7AAD0) -> fixes bug
|
||||
|
||||
// maybe try to place as many leave instructions as possible while keeping the bug alive
|
||||
// eventually we should end up with a relatively small IR footprint that is easier to analyze
|
||||
|
||||
// 0x023d5818
|
||||
// SM3DW debug
|
||||
// if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x23D58A8)
|
||||
// {
|
||||
// ppcImlGenContext.emitInst().make_macro(PPCREC_IML_MACRO_DEBUGBREAK, ppcImlGenContext.ppcAddressOfCurrentInstruction, 0, 0, IMLREG_INVALID);
|
||||
// }
|
||||
|
||||
#if 0 // TP
|
||||
if(ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AC78 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AC70 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7A9C0 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7AC3C || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7AADC || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7ABE4 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7ABC0 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7ABA8 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AB90 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AB04 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02b7abc4 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7A9B0 || // verified
|
||||
//ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02b7aa10 -> fixes bug (this is after a bl)
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7AA3C || // verified
|
||||
//ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7AA44 -> fixes bug (this is on the main path, the one before, 0x02B7AA3C, does not break)
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7AADC || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7ABC4 || // verified
|
||||
ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02b7ac88 || // verified
|
||||
// ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02b7aad0 || -> fixes it
|
||||
// ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02b7aa30 || -> fixes it (mostly. There was a small glitch on eponas tail?)
|
||||
//ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02b7aa24 || -> this fixes it
|
||||
//ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7A918 || -> this fixes it
|
||||
//ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7A9A0 || -> this fixes it
|
||||
//ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x02B7AC38 || -> this fixes it
|
||||
//ppcImlGenContext.ppcAddressOfCurrentInstruction == 0x2B7A8D4 || -> this fixes it
|
||||
(ppcImlGenContext.ppcAddressOfCurrentInstruction >= 0x2B7AC44 && ppcImlGenContext.ppcAddressOfCurrentInstruction <= 0x2B7AC84) || // verified
|
||||
(ppcImlGenContext.ppcAddressOfCurrentInstruction >= 0x02B7AADC && ppcImlGenContext.ppcAddressOfCurrentInstruction <= 0x2B7ABC0) || // verified
|
||||
(ppcImlGenContext.ppcAddressOfCurrentInstruction >= 0x2B7A9B0 && ppcImlGenContext.ppcAddressOfCurrentInstruction <= 0x02B7AA0C) ||
|
||||
(ppcImlGenContext.ppcAddressOfCurrentInstruction >= 0x02B7AAE4 && ppcImlGenContext.ppcAddressOfCurrentInstruction <= 0x02b7ac20) // verified
|
||||
|
||||
// disabling IMLOptimizerX86_SubstituteCJumpForEflagsJump fixes it...
|
||||
|
||||
//(ppcImlGenContext.ppcAddressOfCurrentInstruction >= 0x2B7AA1C && ppcImlGenContext.ppcAddressOfCurrentInstruction <= 0x02B7AA40) -> fixes it
|
||||
)
|
||||
{
|
||||
ppcImlGenContext.emitInst().make_macro(PPCREC_IML_MACRO_LEAVE, ppcImlGenContext.ppcAddressOfCurrentInstruction, 0, 0, IMLREG_INVALID);
|
||||
// this doesnt work any longer because the basic blocks are determined before the recompiler is called
|
||||
basicBlockInfo.GetSegmentForInstructionAppend()->SetLinkBranchTaken(nullptr);
|
||||
basicBlockInfo.GetSegmentForInstructionAppend()->SetLinkBranchNotTaken(nullptr);
|
||||
break; // but we should be able to just exit the block early?
|
||||
}
|
||||
#endif
|
||||
|
||||
if (PPCRecompiler_decodePPCInstruction(&ppcImlGenContext))
|
||||
{
|
||||
debug_printf("Recompiler encountered unsupported instruction at 0x%08x\n", addressOfCurrentInstruction);
|
||||
|
|
Loading…
Reference in New Issue