PPCRec: Make register pool for RA configurable

This commit is contained in:
Exzap 2022-12-13 19:19:29 +01:00
parent c4fb7b74f8
commit d420622da7
8 changed files with 330 additions and 362 deletions

View file

@ -6,104 +6,6 @@
#include "../PPCRecompilerIml.h"
#include "../BackendX64/BackendX64.h"
struct replacedRegisterTracker_t
{
struct
{
sint32 instructionIndex;
sint32 registerPreviousName;
sint32 registerNewName;
sint32 index; // new index
sint32 previousIndex; // previous index (always out of range)
bool nameMustBeMaintained; // must be stored before replacement and loaded after replacement ends
}replacedRegisterEntry[PPC_X64_GPR_USABLE_REGISTERS];
sint32 count;
};
bool PPCRecompiler_findAvailableRegisterDepr(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, sint32 imlIndexStart, replacedRegisterTracker_t* replacedRegisterTracker, sint32* registerIndex, sint32* registerName, bool* isUsed)
{
IMLUsedRegisters registersUsed;
imlSegment->imlList[imlIndexStart].CheckRegisterUsage(&registersUsed);
// mask all registers used by this instruction
uint32 instructionReservedRegisterMask = 0;
if( registersUsed.readNamedReg1 != -1 )
instructionReservedRegisterMask |= (1<<(registersUsed.readNamedReg1));
if( registersUsed.readNamedReg2 != -1 )
instructionReservedRegisterMask |= (1<<(registersUsed.readNamedReg2));
if( registersUsed.readNamedReg3 != -1 )
instructionReservedRegisterMask |= (1<<(registersUsed.readNamedReg3));
if( registersUsed.writtenNamedReg1 != -1 )
instructionReservedRegisterMask |= (1<<(registersUsed.writtenNamedReg1));
// mask all registers that are reserved for other replacements
uint32 replacementReservedRegisterMask = 0;
for(sint32 i=0; i<replacedRegisterTracker->count; i++)
{
replacementReservedRegisterMask |= (1<<replacedRegisterTracker->replacedRegisterEntry[i].index);
}
// potential improvement: Scan ahead a few instructions and look for registers that are the least used (or ideally never used)
// pick available register
const uint32 allRegisterMask = (1<<(PPC_X64_GPR_USABLE_REGISTERS+1))-1; // mask with set bit for every register
uint32 reservedRegisterMask = instructionReservedRegisterMask | replacementReservedRegisterMask;
cemu_assert(instructionReservedRegisterMask != allRegisterMask); // no usable register! (Need to store a register from the replacedRegisterTracker)
sint32 usedRegisterIndex = -1;
for(sint32 i=0; i<PPC_X64_GPR_USABLE_REGISTERS; i++)
{
if( (reservedRegisterMask&(1<<i)) == 0 )
{
if( (instructionReservedRegisterMask&(1<<i)) == 0 && ppcImlGenContext->mappedRegister[i] != -1 )
{
// register is reserved by segment -> In use
*isUsed = true;
*registerName = ppcImlGenContext->mappedRegister[i];
}
else
{
*isUsed = false;
*registerName = -1;
}
*registerIndex = i;
return true;
}
}
return false;
}
void PPCRecompiler_storeReplacedRegister(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, replacedRegisterTracker_t* replacedRegisterTracker, sint32 registerTrackerIndex, sint32* imlIndex)
{
// store register
sint32 imlIndexEdit = *imlIndex;
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
// name_unusedRegister = unusedRegister
IMLInstruction& imlInstructionItr = imlSegment->imlList[imlIndexEdit + 0];
memset(&imlInstructionItr, 0x00, sizeof(IMLInstruction));
imlInstructionItr.type = PPCREC_IML_TYPE_NAME_R;
imlInstructionItr.crRegister = PPC_REC_INVALID_REGISTER;
imlInstructionItr.operation = PPCREC_IML_OP_ASSIGN;
imlInstructionItr.op_r_name.registerIndex = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].index;
imlInstructionItr.op_r_name.name = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].registerNewName;
imlIndexEdit++;
// load new register if required
if( replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].nameMustBeMaintained )
{
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
IMLInstruction& imlInstructionItr = imlSegment->imlList[imlIndexEdit];
memset(&imlInstructionItr, 0x00, sizeof(IMLInstruction));
imlInstructionItr.type = PPCREC_IML_TYPE_R_NAME;
imlInstructionItr.crRegister = PPC_REC_INVALID_REGISTER;
imlInstructionItr.operation = PPCREC_IML_OP_ASSIGN;
imlInstructionItr.op_r_name.registerIndex = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].index;
imlInstructionItr.op_r_name.name = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].registerPreviousName;//ppcImlGenContext->mappedRegister[replacedRegisterTracker.replacedRegisterEntry[i].index];
imlIndexEdit += 1;
}
// move last entry to current one
memcpy(replacedRegisterTracker->replacedRegisterEntry+registerTrackerIndex, replacedRegisterTracker->replacedRegisterEntry+replacedRegisterTracker->count-1, sizeof(replacedRegisterTracker->replacedRegisterEntry[0]));
replacedRegisterTracker->count--;
*imlIndex = imlIndexEdit;
}
bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenContext)
{
// only xmm0 to xmm14 may be used, xmm15 is reserved