mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-07 23:41:18 +12:00
PPCRec: Make register pool for RA configurable
This commit is contained in:
parent
c4fb7b74f8
commit
d420622da7
8 changed files with 330 additions and 362 deletions
|
@ -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(®istersUsed);
|
||||
// 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue