PPCRec: Partial support for typed registers in RA

This commit is contained in:
Exzap
2023-02-04 17:54:46 +01:00
parent cb619b143d
commit 6a63eb8871
6 changed files with 239 additions and 193 deletions
@@ -17,7 +17,8 @@ enum class IMLRegFormat : uint8
I8,
// I1 ?
F64,
F32
F32,
TYPE_COUNT,
};
class IMLReg
@@ -86,10 +87,9 @@ public:
return IsValid() && GetRegID() == regId;
}
// risky
// compare all fields
bool operator==(const IMLReg& other) const
{
//__debugbreak();
return m_raw == other.m_raw;
}
File diff suppressed because it is too large Load Diff
@@ -88,7 +88,12 @@ private:
struct IMLRegisterAllocatorParameters
{
IMLPhysRegisterSet physicalRegisterPool;
inline IMLPhysRegisterSet& GetPhysRegPool(IMLRegFormat regFormat)
{
return perTypePhysPool[stdx::to_underlying(regFormat)];
}
IMLPhysRegisterSet perTypePhysPool[stdx::to_underlying(IMLRegFormat::TYPE_COUNT)];// physicalRegisterPool;
};
void IMLRegisterAllocator_AllocateRegisters(ppcImlGenContext_t* ppcImlGenContext, IMLRegisterAllocatorParameters& raParam);
@@ -54,9 +54,9 @@ struct raLivenessSubrange_t
struct raLivenessRange_t
{
sint32 virtualRegister;
IMLRegID virtualRegister;
sint32 physicalRegister;
sint32 name;
IMLName name;
std::vector<raLivenessSubrange_t*> list_subranges;
};
@@ -70,16 +70,6 @@ struct PPCSegmentRegisterAllocatorInfo_t
raLivenessSubrange_t* linkedList_perVirtualGPR[IML_RA_VIRT_REG_COUNT_MAX]{};
};
struct PPCRecVGPRDistances_t
{
struct _RegArrayEntry
{
sint32 usageStart{};
sint32 usageEnd{};
}reg[IML_RA_VIRT_REG_COUNT_MAX];
bool isProcessed[IML_RA_VIRT_REG_COUNT_MAX]{};
};
struct IMLSegment
{
sint32 momentaryIndex{}; // index in segment list, generally not kept up to date except if needed (necessary for loop detection)
@@ -113,7 +103,7 @@ struct IMLSegment
uint32 crBitsWritten{}; // bits that are written in this segment
// register allocator info
PPCSegmentRegisterAllocatorInfo_t raInfo{};
PPCRecVGPRDistances_t raDistances{};
//PPCRecVGPRDistances_t raDistances{};
bool raRangeExtendProcessed{};
// segment state API
@@ -218,7 +218,6 @@ PPCRecFunction_t* PPCRecompiler_recompileFunction(PPCFunctionBoundaryTracker::PP
// collect list of PPC-->x64 entry points
cemuLog_log(LogType::Force, "[Recompiler] Successfully compiled {:08x} - {:08x} Segments: {}", ppcRecFunc->ppcAddress, ppcRecFunc->ppcAddress + ppcRecFunc->ppcSize, ppcImlGenContext.segmentList2.size());
cemu_assert_debug(ppcImlGenContext.imlListCount == 0);
entryPointsOut.clear();
for(IMLSegment* imlSegment : ppcImlGenContext.segmentList2)
@@ -295,18 +294,20 @@ bool PPCRecompiler_ApplyIMLPasses(ppcImlGenContext_t& ppcImlGenContext)
}
IMLRegisterAllocatorParameters raParam;
raParam.physicalRegisterPool.SetAvailable(X86_REG_RAX);
raParam.physicalRegisterPool.SetAvailable(X86_REG_RDX);
raParam.physicalRegisterPool.SetAvailable(X86_REG_RBX);
raParam.physicalRegisterPool.SetAvailable(X86_REG_RBP);
raParam.physicalRegisterPool.SetAvailable(X86_REG_RSI);
raParam.physicalRegisterPool.SetAvailable(X86_REG_RDI);
raParam.physicalRegisterPool.SetAvailable(X86_REG_R8);
raParam.physicalRegisterPool.SetAvailable(X86_REG_R9);
raParam.physicalRegisterPool.SetAvailable(X86_REG_R10);
raParam.physicalRegisterPool.SetAvailable(X86_REG_R11);
raParam.physicalRegisterPool.SetAvailable(X86_REG_R12);
raParam.physicalRegisterPool.SetAvailable(X86_REG_RCX);
auto& gprPhysPool = raParam.GetPhysRegPool(IMLRegFormat::I64);
gprPhysPool.SetAvailable(X86_REG_RAX);
gprPhysPool.SetAvailable(X86_REG_RDX);
gprPhysPool.SetAvailable(X86_REG_RBX);
gprPhysPool.SetAvailable(X86_REG_RBP);
gprPhysPool.SetAvailable(X86_REG_RSI);
gprPhysPool.SetAvailable(X86_REG_RDI);
gprPhysPool.SetAvailable(X86_REG_R8);
gprPhysPool.SetAvailable(X86_REG_R9);
gprPhysPool.SetAvailable(X86_REG_R10);
gprPhysPool.SetAvailable(X86_REG_R11);
gprPhysPool.SetAvailable(X86_REG_R12);
gprPhysPool.SetAvailable(X86_REG_RCX);
IMLRegisterAllocator_AllocateRegisters(&ppcImlGenContext, raParam);
@@ -45,10 +45,6 @@ struct ppcImlGenContext_t
uint32 mappedRegister[PPC_REC_MAX_VIRTUAL_GPR];
// temporary floating point registers (single and double precision)
uint32 mappedFPRRegister[256];
// list of intermediate instructions
IMLInstruction* imlList;
sint32 imlListSize;
sint32 imlListCount;
// list of segments
std::vector<IMLSegment*> segmentList2;
// code generation control
@@ -66,16 +62,8 @@ struct ppcImlGenContext_t
~ppcImlGenContext_t()
{
if (imlList)
{
free(imlList);
imlList = nullptr;
}
for (IMLSegment* imlSegment : segmentList2)
{
delete imlSegment;
}
segmentList2.clear();
}
@@ -117,6 +105,12 @@ struct ppcImlGenContext_t
segmentList2[i] = new IMLSegment();
return { segmentList2.data() + index, count};
}
void UpdateSegmentIndices()
{
for (size_t i = 0; i < segmentList2.size(); i++)
segmentList2[i]->momentaryIndex = (sint32)i;
}
};
typedef void ATTR_MS_ABI (*PPCREC_JUMP_ENTRY)();