mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-01-30 13:07:18 -03:00
PPCRec: Move IML register allocator
This commit is contained in:
parent
e53c6ad2e9
commit
d1fe1a905f
13 changed files with 145 additions and 136 deletions
4
bin/keys.txt
Normal file
4
bin/keys.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# this file contains keys needed for decryption of disc file system data (WUD/WUX)
|
||||||
|
# 1 key per line, any text after a '#' character is considered a comment
|
||||||
|
# the emulator will automatically pick the right key
|
||||||
|
541b9889519b27d363cd21604b97c67a # example key (can be deleted)
|
|
@ -75,12 +75,12 @@ add_library(CemuCafe
|
||||||
HW/Espresso/Recompiler/IML/IMLDebug.cpp
|
HW/Espresso/Recompiler/IML/IMLDebug.cpp
|
||||||
HW/Espresso/Recompiler/IML/IMLAnalyzer.cpp
|
HW/Espresso/Recompiler/IML/IMLAnalyzer.cpp
|
||||||
HW/Espresso/Recompiler/IML/IMLOptimizer.cpp
|
HW/Espresso/Recompiler/IML/IMLOptimizer.cpp
|
||||||
|
HW/Espresso/Recompiler/IML/IMLRegisterAllocator.cpp
|
||||||
|
HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.cpp
|
||||||
|
HW/Espresso/Recompiler/IML/IMLRegisterAllocatorRanges.h
|
||||||
HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp
|
HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp
|
||||||
HW/Espresso/Recompiler/PPCRecompilerImlGenFPU.cpp
|
HW/Espresso/Recompiler/PPCRecompilerImlGenFPU.cpp
|
||||||
HW/Espresso/Recompiler/PPCRecompilerIml.h
|
HW/Espresso/Recompiler/PPCRecompilerIml.h
|
||||||
HW/Espresso/Recompiler/PPCRecompilerImlRanges.cpp
|
|
||||||
HW/Espresso/Recompiler/PPCRecompilerImlRanges.h
|
|
||||||
HW/Espresso/Recompiler/PPCRecompilerImlRegisterAllocator.cpp
|
|
||||||
HW/Espresso/Recompiler/PPCRecompilerIntermediate.cpp
|
HW/Espresso/Recompiler/PPCRecompilerIntermediate.cpp
|
||||||
HW/Espresso/Recompiler/PPCRecompilerX64AVX.cpp
|
HW/Espresso/Recompiler/PPCRecompilerX64AVX.cpp
|
||||||
HW/Espresso/Recompiler/PPCRecompilerX64BMI.cpp
|
HW/Espresso/Recompiler/PPCRecompilerX64BMI.cpp
|
||||||
|
|
|
@ -24,6 +24,9 @@ void PPCRecompiler_optimizeDirectIntegerCopies(ppcImlGenContext_t* ppcImlGenCont
|
||||||
void PPCRecompiler_optimizePSQLoadAndStore(ppcImlGenContext_t* ppcImlGenContext);
|
void PPCRecompiler_optimizePSQLoadAndStore(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
void PPCRecompiler_reorderConditionModifyInstructions(ppcImlGenContext_t* ppcImlGenContext);
|
void PPCRecompiler_reorderConditionModifyInstructions(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
|
|
||||||
|
// register allocator
|
||||||
|
void IMLRegisterAllocator_AllocateRegisters(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
|
|
||||||
// debug
|
// debug
|
||||||
void IMLDebug_DumpSegment(struct IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo = false);
|
void IMLDebug_DumpSegment(struct IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo = false);
|
||||||
void IMLDebug_Dump(struct ppcImlGenContext_t* ppcImlGenContext);
|
void IMLDebug_Dump(struct ppcImlGenContext_t* ppcImlGenContext);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "IML.h"
|
#include "IML.h"
|
||||||
#include "IMLInstruction.h"
|
#include "IMLInstruction.h"
|
||||||
#include "IMLSegment.h"
|
#include "IMLSegment.h"
|
||||||
|
#include "IMLRegisterAllocatorRanges.h"
|
||||||
#include "util/helpers/StringBuf.h"
|
#include "util/helpers/StringBuf.h"
|
||||||
|
|
||||||
#include "Cafe/HW/Espresso/Recompiler/PPCRecompilerImlRanges.h"
|
|
||||||
|
|
||||||
const char* IMLDebug_GetOpcodeName(const IMLInstruction* iml)
|
const char* IMLDebug_GetOpcodeName(const IMLInstruction* iml)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1118,8 +1118,8 @@ bool PPCRecompilerAnalyzer_checkForGPROverwrite(IMLUsedRegisters* registerRead,
|
||||||
|
|
||||||
void _reorderConditionModifyInstructions(IMLSegment* imlSegment)
|
void _reorderConditionModifyInstructions(IMLSegment* imlSegment)
|
||||||
{
|
{
|
||||||
IMLInstruction* lastInstruction = PPCRecompilerIML_getLastInstruction(imlSegment);
|
IMLInstruction* lastInstruction = imlSegment->GetLastInstruction();
|
||||||
// last instruction a conditional branch?
|
// last instruction is a conditional branch?
|
||||||
if (lastInstruction == nullptr || lastInstruction->type != PPCREC_IML_TYPE_CJUMP)
|
if (lastInstruction == nullptr || lastInstruction->type != PPCREC_IML_TYPE_CJUMP)
|
||||||
return;
|
return;
|
||||||
if (lastInstruction->op_conditionalJump.crRegisterIndex >= 8)
|
if (lastInstruction->op_conditionalJump.crRegisterIndex >= 8)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#include "./IML/IML.h"
|
#include "IML.h"
|
||||||
|
|
||||||
#include "PPCRecompiler.h"
|
#include "../PPCRecompiler.h"
|
||||||
#include "PPCRecompilerIml.h"
|
#include "../PPCRecompilerIml.h"
|
||||||
#include "PPCRecompilerX64.h"
|
#include "../PPCRecompilerX64.h"
|
||||||
#include "PPCRecompilerImlRanges.h"
|
#include "IMLRegisterAllocatorRanges.h"
|
||||||
|
|
||||||
uint32 recRACurrentIterationIndex = 0;
|
uint32 recRACurrentIterationIndex = 0;
|
||||||
|
|
||||||
|
@ -964,9 +964,9 @@ void PPCRecompilerImm_prepareForRegisterAllocation(ppcImlGenContext_t* ppcImlGen
|
||||||
IMLSegment* imlSegmentP0 = ppcImlGenContext->segmentList2[segmentIndex + 0];
|
IMLSegment* imlSegmentP0 = ppcImlGenContext->segmentList2[segmentIndex + 0];
|
||||||
IMLSegment* imlSegmentP1 = ppcImlGenContext->segmentList2[segmentIndex + 1];
|
IMLSegment* imlSegmentP1 = ppcImlGenContext->segmentList2[segmentIndex + 1];
|
||||||
IMLSegment* nextSegment = imlSegment->nextSegmentBranchNotTaken;
|
IMLSegment* nextSegment = imlSegment->nextSegmentBranchNotTaken;
|
||||||
PPCRecompilerIML_removeLink(imlSegmentP0, nextSegment);
|
IMLSegment_RemoveLink(imlSegmentP0, nextSegment);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegmentP1, nextSegment);
|
IMLSegment_SetLinkBranchNotTaken(imlSegmentP1, nextSegment);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegmentP0, imlSegmentP1);
|
IMLSegment_SetLinkBranchNotTaken(imlSegmentP0, imlSegmentP1);
|
||||||
segmentIndex++;
|
segmentIndex++;
|
||||||
}
|
}
|
||||||
// detect loops
|
// detect loops
|
||||||
|
@ -982,7 +982,7 @@ void PPCRecompilerImm_prepareForRegisterAllocation(ppcImlGenContext_t* ppcImlGen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerImm_allocateRegisters(ppcImlGenContext_t* ppcImlGenContext)
|
void IMLRegisterAllocator_AllocateRegisters(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
{
|
{
|
||||||
PPCRecompilerImm_prepareForRegisterAllocation(ppcImlGenContext);
|
PPCRecompilerImm_prepareForRegisterAllocation(ppcImlGenContext);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "PPCRecompiler.h"
|
#include "../PPCRecompiler.h"
|
||||||
#include "PPCRecompilerIml.h"
|
#include "../PPCRecompilerIml.h"
|
||||||
#include "PPCRecompilerX64.h"
|
#include "../PPCRecompilerX64.h"
|
||||||
#include "PPCRecompilerImlRanges.h"
|
#include "IMLRegisterAllocatorRanges.h"
|
||||||
#include "util/helpers/MemoryPool.h"
|
#include "util/helpers/MemoryPool.h"
|
||||||
|
|
||||||
void PPCRecRARange_addLink_perVirtualGPR(raLivenessSubrange_t** root, raLivenessSubrange_t* subrange)
|
void PPCRecRARange_addLink_perVirtualGPR(raLivenessSubrange_t** root, raLivenessSubrange_t* subrange)
|
|
@ -8,3 +8,91 @@ bool IMLSegment::HasSuffixInstruction() const
|
||||||
const IMLInstruction& imlInstruction = imlList.back();
|
const IMLInstruction& imlInstruction = imlList.back();
|
||||||
return imlInstruction.IsSuffixInstruction();
|
return imlInstruction.IsSuffixInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMLInstruction* IMLSegment::GetLastInstruction()
|
||||||
|
{
|
||||||
|
if (imlList.empty())
|
||||||
|
return nullptr;
|
||||||
|
return &imlList.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void IMLSegment_SetLinkBranchNotTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst)
|
||||||
|
{
|
||||||
|
// make sure segments aren't already linked
|
||||||
|
if (imlSegmentSrc->nextSegmentBranchNotTaken == imlSegmentDst)
|
||||||
|
return;
|
||||||
|
// add as next segment for source
|
||||||
|
if (imlSegmentSrc->nextSegmentBranchNotTaken != nullptr)
|
||||||
|
assert_dbg();
|
||||||
|
imlSegmentSrc->nextSegmentBranchNotTaken = imlSegmentDst;
|
||||||
|
// add as previous segment for destination
|
||||||
|
imlSegmentDst->list_prevSegments.push_back(imlSegmentSrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IMLSegment_SetLinkBranchTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst)
|
||||||
|
{
|
||||||
|
// make sure segments aren't already linked
|
||||||
|
if (imlSegmentSrc->nextSegmentBranchTaken == imlSegmentDst)
|
||||||
|
return;
|
||||||
|
// add as next segment for source
|
||||||
|
if (imlSegmentSrc->nextSegmentBranchTaken != nullptr)
|
||||||
|
assert_dbg();
|
||||||
|
imlSegmentSrc->nextSegmentBranchTaken = imlSegmentDst;
|
||||||
|
// add as previous segment for destination
|
||||||
|
imlSegmentDst->list_prevSegments.push_back(imlSegmentSrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IMLSegment_RemoveLink(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst)
|
||||||
|
{
|
||||||
|
if (imlSegmentSrc->nextSegmentBranchNotTaken == imlSegmentDst)
|
||||||
|
{
|
||||||
|
imlSegmentSrc->nextSegmentBranchNotTaken = nullptr;
|
||||||
|
}
|
||||||
|
else if (imlSegmentSrc->nextSegmentBranchTaken == imlSegmentDst)
|
||||||
|
{
|
||||||
|
imlSegmentSrc->nextSegmentBranchTaken = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
assert_dbg();
|
||||||
|
|
||||||
|
bool matchFound = false;
|
||||||
|
for (sint32 i = 0; i < imlSegmentDst->list_prevSegments.size(); i++)
|
||||||
|
{
|
||||||
|
if (imlSegmentDst->list_prevSegments[i] == imlSegmentSrc)
|
||||||
|
{
|
||||||
|
imlSegmentDst->list_prevSegments.erase(imlSegmentDst->list_prevSegments.begin() + i);
|
||||||
|
matchFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matchFound == false)
|
||||||
|
assert_dbg();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replaces all links to segment orig with linkts to segment new
|
||||||
|
*/
|
||||||
|
void IMLSegment_RelinkInputSegment(IMLSegment* imlSegmentOrig, IMLSegment* imlSegmentNew)
|
||||||
|
{
|
||||||
|
while (imlSegmentOrig->list_prevSegments.size() != 0)
|
||||||
|
{
|
||||||
|
IMLSegment* prevSegment = imlSegmentOrig->list_prevSegments[0];
|
||||||
|
if (prevSegment->nextSegmentBranchNotTaken == imlSegmentOrig)
|
||||||
|
{
|
||||||
|
IMLSegment_RemoveLink(prevSegment, imlSegmentOrig);
|
||||||
|
IMLSegment_SetLinkBranchNotTaken(prevSegment, imlSegmentNew);
|
||||||
|
}
|
||||||
|
else if (prevSegment->nextSegmentBranchTaken == imlSegmentOrig)
|
||||||
|
{
|
||||||
|
IMLSegment_RemoveLink(prevSegment, imlSegmentOrig);
|
||||||
|
IMLSegment_SetLinkBranchTaken(prevSegment, imlSegmentNew);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert_dbg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -42,4 +42,12 @@ struct IMLSegment
|
||||||
ppcRecompilerSegmentPoint_t* segmentPointList{};
|
ppcRecompilerSegmentPoint_t* segmentPointList{};
|
||||||
|
|
||||||
bool HasSuffixInstruction() const;
|
bool HasSuffixInstruction() const;
|
||||||
|
IMLInstruction* GetLastInstruction();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void IMLSegment_SetLinkBranchNotTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst);
|
||||||
|
void IMLSegment_SetLinkBranchTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst);
|
||||||
|
void IMLSegment_RelinkInputSegment(IMLSegment* imlSegmentOrig, IMLSegment* imlSegmentNew);
|
||||||
|
void IMLSegment_RemoveLink(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst);
|
||||||
|
|
|
@ -114,14 +114,5 @@ bool PPCRecompilerImlGen_PS_CMPU1(ppcImlGenContext_t* ppcImlGenContext, uint32 o
|
||||||
// IML general
|
// IML general
|
||||||
|
|
||||||
void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext);
|
void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
void PPCRecompilerIml_setLinkBranchNotTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst);
|
|
||||||
void PPCRecompilerIml_setLinkBranchTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst);
|
|
||||||
void PPCRecompilerIML_relinkInputSegment(IMLSegment* imlSegmentOrig, IMLSegment* imlSegmentNew);
|
|
||||||
void PPCRecompilerIML_removeLink(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst);
|
|
||||||
void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenContext);
|
void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
|
|
||||||
IMLInstruction* PPCRecompilerIML_getLastInstruction(IMLSegment* imlSegment);
|
|
||||||
|
|
||||||
// IML register allocator
|
|
||||||
void PPCRecompilerImm_allocateRegisters(ppcImlGenContext_t* ppcImlGenContext);
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterHelper.h"
|
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterHelper.h"
|
||||||
#include "PPCRecompiler.h"
|
#include "PPCRecompiler.h"
|
||||||
#include "PPCRecompilerIml.h"
|
#include "PPCRecompilerIml.h"
|
||||||
#include "PPCRecompilerImlRanges.h"
|
|
||||||
#include "IML/IML.h"
|
#include "IML/IML.h"
|
||||||
|
#include "IML/IMLRegisterAllocatorRanges.h"
|
||||||
|
|
||||||
bool PPCRecompiler_decodePPCInstruction(ppcImlGenContext_t* ppcImlGenContext);
|
bool PPCRecompiler_decodePPCInstruction(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
uint32 PPCRecompiler_iterateCurrentInstruction(ppcImlGenContext_t* ppcImlGenContext);
|
uint32 PPCRecompiler_iterateCurrentInstruction(ppcImlGenContext_t* ppcImlGenContext);
|
||||||
|
@ -4149,7 +4149,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
{
|
{
|
||||||
if (segIt->nextSegmentBranchNotTaken == nullptr || segIt->nextSegmentBranchTaken == nullptr)
|
if (segIt->nextSegmentBranchNotTaken == nullptr || segIt->nextSegmentBranchTaken == nullptr)
|
||||||
continue; // not a branching segment
|
continue; // not a branching segment
|
||||||
IMLInstruction* lastInstruction = PPCRecompilerIML_getLastInstruction(segIt);
|
IMLInstruction* lastInstruction = segIt->GetLastInstruction();
|
||||||
if (lastInstruction->type != PPCREC_IML_TYPE_CJUMP || lastInstruction->op_conditionalJump.crRegisterIndex != 0)
|
if (lastInstruction->type != PPCREC_IML_TYPE_CJUMP || lastInstruction->op_conditionalJump.crRegisterIndex != 0)
|
||||||
continue;
|
continue;
|
||||||
IMLSegment* conditionalSegment = segIt->nextSegmentBranchNotTaken;
|
IMLSegment* conditionalSegment = segIt->nextSegmentBranchNotTaken;
|
||||||
|
@ -4195,10 +4195,10 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
}
|
}
|
||||||
// update segment links
|
// update segment links
|
||||||
// source segment: imlSegment, conditional/removed segment: conditionalSegment, final segment: finalSegment
|
// source segment: imlSegment, conditional/removed segment: conditionalSegment, final segment: finalSegment
|
||||||
PPCRecompilerIML_removeLink(segIt, conditionalSegment);
|
IMLSegment_RemoveLink(segIt, conditionalSegment);
|
||||||
PPCRecompilerIML_removeLink(segIt, finalSegment);
|
IMLSegment_RemoveLink(segIt, finalSegment);
|
||||||
PPCRecompilerIML_removeLink(conditionalSegment, finalSegment);
|
IMLSegment_RemoveLink(conditionalSegment, finalSegment);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(segIt, finalSegment);
|
IMLSegment_SetLinkBranchNotTaken(segIt, finalSegment);
|
||||||
// remove all instructions from conditional segment
|
// remove all instructions from conditional segment
|
||||||
conditionalSegment->imlList.clear();
|
conditionalSegment->imlList.clear();
|
||||||
|
|
||||||
|
@ -4206,18 +4206,18 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
if (finalSegment->isEnterable == false && finalSegment->list_prevSegments.size() == 1)
|
if (finalSegment->isEnterable == false && finalSegment->list_prevSegments.size() == 1)
|
||||||
{
|
{
|
||||||
// todo: Clean this up and move into separate function PPCRecompilerIML_mergeSegments()
|
// todo: Clean this up and move into separate function PPCRecompilerIML_mergeSegments()
|
||||||
PPCRecompilerIML_removeLink(segIt, finalSegment);
|
IMLSegment_RemoveLink(segIt, finalSegment);
|
||||||
if (finalSegment->nextSegmentBranchNotTaken)
|
if (finalSegment->nextSegmentBranchNotTaken)
|
||||||
{
|
{
|
||||||
IMLSegment* tempSegment = finalSegment->nextSegmentBranchNotTaken;
|
IMLSegment* tempSegment = finalSegment->nextSegmentBranchNotTaken;
|
||||||
PPCRecompilerIML_removeLink(finalSegment, tempSegment);
|
IMLSegment_RemoveLink(finalSegment, tempSegment);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(segIt, tempSegment);
|
IMLSegment_SetLinkBranchNotTaken(segIt, tempSegment);
|
||||||
}
|
}
|
||||||
if (finalSegment->nextSegmentBranchTaken)
|
if (finalSegment->nextSegmentBranchTaken)
|
||||||
{
|
{
|
||||||
IMLSegment* tempSegment = finalSegment->nextSegmentBranchTaken;
|
IMLSegment* tempSegment = finalSegment->nextSegmentBranchTaken;
|
||||||
PPCRecompilerIML_removeLink(finalSegment, tempSegment);
|
IMLSegment_RemoveLink(finalSegment, tempSegment);
|
||||||
PPCRecompilerIml_setLinkBranchTaken(segIt, tempSegment);
|
IMLSegment_SetLinkBranchTaken(segIt, tempSegment);
|
||||||
}
|
}
|
||||||
// copy IML instructions
|
// copy IML instructions
|
||||||
cemu_assert_debug(segIt != finalSegment);
|
cemu_assert_debug(segIt != finalSegment);
|
||||||
|
@ -4296,10 +4296,10 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
PPCRecompilerIml_insertSegments(&ppcImlGenContext, ppcImlGenContext.segmentList2.size(), 1);
|
PPCRecompilerIml_insertSegments(&ppcImlGenContext, ppcImlGenContext.segmentList2.size(), 1);
|
||||||
IMLSegment* imlSegmentPEntry = ppcImlGenContext.segmentList2[ppcImlGenContext.segmentList2.size()-1];
|
IMLSegment* imlSegmentPEntry = ppcImlGenContext.segmentList2[ppcImlGenContext.segmentList2.size()-1];
|
||||||
// relink segments
|
// relink segments
|
||||||
PPCRecompilerIML_relinkInputSegment(imlSegmentP2, imlSegmentP0);
|
IMLSegment_RelinkInputSegment(imlSegmentP2, imlSegmentP0);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegmentP0, imlSegmentP1);
|
IMLSegment_SetLinkBranchNotTaken(imlSegmentP0, imlSegmentP1);
|
||||||
PPCRecompilerIml_setLinkBranchTaken(imlSegmentP0, imlSegmentP2);
|
IMLSegment_SetLinkBranchTaken(imlSegmentP0, imlSegmentP2);
|
||||||
PPCRecompilerIml_setLinkBranchTaken(imlSegmentPEntry, imlSegmentP0);
|
IMLSegment_SetLinkBranchTaken(imlSegmentPEntry, imlSegmentP0);
|
||||||
// update segments
|
// update segments
|
||||||
uint32 enterPPCAddress = imlSegmentP2->ppcAddrMin;
|
uint32 enterPPCAddress = imlSegmentP2->ppcAddrMin;
|
||||||
if (imlSegmentP2->isEnterable)
|
if (imlSegmentP2->isEnterable)
|
||||||
|
@ -4413,7 +4413,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCRecompilerImm_allocateRegisters(&ppcImlGenContext);
|
IMLRegisterAllocator_AllocateRegisters(&ppcImlGenContext);
|
||||||
|
|
||||||
// remove redundant name load and store instructions
|
// remove redundant name load and store instructions
|
||||||
PPCRecompiler_reorderConditionModifyInstructions(&ppcImlGenContext);
|
PPCRecompiler_reorderConditionModifyInstructions(&ppcImlGenContext);
|
||||||
|
|
|
@ -11,85 +11,7 @@ IMLSegment* PPCRecompiler_getSegmentByPPCJumpAddress(ppcImlGenContext_t* ppcImlG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug_printf("PPCRecompiler_getSegmentByPPCJumpAddress(): Unable to find segment (ppcOffset 0x%08x)\n", ppcOffset);
|
debug_printf("PPCRecompiler_getSegmentByPPCJumpAddress(): Unable to find segment (ppcOffset 0x%08x)\n", ppcOffset);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
void PPCRecompilerIml_setLinkBranchNotTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst)
|
|
||||||
{
|
|
||||||
// make sure segments aren't already linked
|
|
||||||
if (imlSegmentSrc->nextSegmentBranchNotTaken == imlSegmentDst)
|
|
||||||
return;
|
|
||||||
// add as next segment for source
|
|
||||||
if (imlSegmentSrc->nextSegmentBranchNotTaken != NULL)
|
|
||||||
assert_dbg();
|
|
||||||
imlSegmentSrc->nextSegmentBranchNotTaken = imlSegmentDst;
|
|
||||||
// add as previous segment for destination
|
|
||||||
imlSegmentDst->list_prevSegments.push_back(imlSegmentSrc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PPCRecompilerIml_setLinkBranchTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst)
|
|
||||||
{
|
|
||||||
// make sure segments aren't already linked
|
|
||||||
if (imlSegmentSrc->nextSegmentBranchTaken == imlSegmentDst)
|
|
||||||
return;
|
|
||||||
// add as next segment for source
|
|
||||||
if (imlSegmentSrc->nextSegmentBranchTaken != NULL)
|
|
||||||
assert_dbg();
|
|
||||||
imlSegmentSrc->nextSegmentBranchTaken = imlSegmentDst;
|
|
||||||
// add as previous segment for destination
|
|
||||||
imlSegmentDst->list_prevSegments.push_back(imlSegmentSrc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PPCRecompilerIML_removeLink(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst)
|
|
||||||
{
|
|
||||||
if (imlSegmentSrc->nextSegmentBranchNotTaken == imlSegmentDst)
|
|
||||||
{
|
|
||||||
imlSegmentSrc->nextSegmentBranchNotTaken = NULL;
|
|
||||||
}
|
|
||||||
else if (imlSegmentSrc->nextSegmentBranchTaken == imlSegmentDst)
|
|
||||||
{
|
|
||||||
imlSegmentSrc->nextSegmentBranchTaken = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
assert_dbg();
|
|
||||||
|
|
||||||
bool matchFound = false;
|
|
||||||
for (sint32 i = 0; i < imlSegmentDst->list_prevSegments.size(); i++)
|
|
||||||
{
|
|
||||||
if (imlSegmentDst->list_prevSegments[i] == imlSegmentSrc)
|
|
||||||
{
|
|
||||||
imlSegmentDst->list_prevSegments.erase(imlSegmentDst->list_prevSegments.begin()+i);
|
|
||||||
matchFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (matchFound == false)
|
|
||||||
assert_dbg();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Replaces all links to segment orig with linkts to segment new
|
|
||||||
*/
|
|
||||||
void PPCRecompilerIML_relinkInputSegment(IMLSegment* imlSegmentOrig, IMLSegment* imlSegmentNew)
|
|
||||||
{
|
|
||||||
while (imlSegmentOrig->list_prevSegments.size() != 0)
|
|
||||||
{
|
|
||||||
IMLSegment* prevSegment = imlSegmentOrig->list_prevSegments[0];
|
|
||||||
if (prevSegment->nextSegmentBranchNotTaken == imlSegmentOrig)
|
|
||||||
{
|
|
||||||
PPCRecompilerIML_removeLink(prevSegment, imlSegmentOrig);
|
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(prevSegment, imlSegmentNew);
|
|
||||||
}
|
|
||||||
else if (prevSegment->nextSegmentBranchTaken == imlSegmentOrig)
|
|
||||||
{
|
|
||||||
PPCRecompilerIML_removeLink(prevSegment, imlSegmentOrig);
|
|
||||||
PPCRecompilerIml_setLinkBranchTaken(prevSegment, imlSegmentNew);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert_dbg();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
|
@ -105,7 +27,7 @@ void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
if( imlSegment->imlList.empty())
|
if( imlSegment->imlList.empty())
|
||||||
{
|
{
|
||||||
if (isLastSegment == false)
|
if (isLastSegment == false)
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegment, ppcImlGenContext->segmentList2[s+1]); // continue execution to next segment
|
IMLSegment_SetLinkBranchNotTaken(imlSegment, ppcImlGenContext->segmentList2[s+1]); // continue execution to next segment
|
||||||
else
|
else
|
||||||
imlSegment->nextSegmentIsUncertain = true;
|
imlSegment->nextSegmentIsUncertain = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -119,8 +41,8 @@ void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
if( jumpDestSegment )
|
if( jumpDestSegment )
|
||||||
{
|
{
|
||||||
if (imlInstruction->op_conditionalJump.condition != PPCREC_JUMP_CONDITION_NONE)
|
if (imlInstruction->op_conditionalJump.condition != PPCREC_JUMP_CONDITION_NONE)
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegment, nextSegment);
|
IMLSegment_SetLinkBranchNotTaken(imlSegment, nextSegment);
|
||||||
PPCRecompilerIml_setLinkBranchTaken(imlSegment, jumpDestSegment);
|
IMLSegment_SetLinkBranchTaken(imlSegment, jumpDestSegment);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -135,7 +57,7 @@ void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// all other instruction types do not branch
|
// all other instruction types do not branch
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegment, nextSegment);
|
IMLSegment_SetLinkBranchNotTaken(imlSegment, nextSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,17 +78,10 @@ void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenCont
|
||||||
// create jump instruction
|
// create jump instruction
|
||||||
PPCRecompiler_pushBackIMLInstructions(entrySegment, 0, 1);
|
PPCRecompiler_pushBackIMLInstructions(entrySegment, 0, 1);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_jumpSegment(ppcImlGenContext, entrySegment->imlList.data() + 0);
|
PPCRecompilerImlGen_generateNewInstruction_jumpSegment(ppcImlGenContext, entrySegment->imlList.data() + 0);
|
||||||
PPCRecompilerIml_setLinkBranchTaken(entrySegment, imlSegment);
|
IMLSegment_SetLinkBranchTaken(entrySegment, imlSegment);
|
||||||
// remove enterable flag from original segment
|
// remove enterable flag from original segment
|
||||||
imlSegment->isEnterable = false;
|
imlSegment->isEnterable = false;
|
||||||
imlSegment->enterPPCAddress = 0;
|
imlSegment->enterPPCAddress = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMLInstruction* PPCRecompilerIML_getLastInstruction(IMLSegment* imlSegment)
|
|
||||||
{
|
|
||||||
if (imlSegment->imlList.empty())
|
|
||||||
return nullptr;
|
|
||||||
return imlSegment->imlList.data() + (imlSegment->imlList.size() - 1);
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue