mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-07 15:31:18 +12:00
PPCRec: Use vector for instruction list
This commit is contained in:
parent
d42ea6e5a8
commit
ce5d010611
8 changed files with 379 additions and 401 deletions
|
@ -3,7 +3,7 @@
|
|||
#include "PPCRecompilerIml.h"
|
||||
#include "PPCRecompilerX64.h"
|
||||
|
||||
void PPCRecompiler_checkRegisterUsage(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlInstruction_t* imlInstruction, PPCImlOptimizerUsedRegisters_t* registersUsed)
|
||||
void PPCRecompiler_checkRegisterUsage(ppcImlGenContext_t* ppcImlGenContext, const PPCRecImlInstruction_t* imlInstruction, PPCImlOptimizerUsedRegisters_t* registersUsed)
|
||||
{
|
||||
registersUsed->readNamedReg1 = -1;
|
||||
registersUsed->readNamedReg2 = -1;
|
||||
|
@ -907,7 +907,7 @@ sint32 PPCRecompiler_getNextRegisterToReplace(PPCImlOptimizerUsedRegisters_t* re
|
|||
bool PPCRecompiler_findAvailableRegisterDepr(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 imlIndexStart, replacedRegisterTracker_t* replacedRegisterTracker, sint32* registerIndex, sint32* registerName, bool* isUsed)
|
||||
{
|
||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList+imlIndexStart, ®istersUsed);
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &imlSegment->imlList[imlIndexStart], ®istersUsed);
|
||||
// mask all registers used by this instruction
|
||||
uint32 instructionReservedRegisterMask = 0;//(1<<(PPC_X64_GPR_USABLE_REGISTERS+1))-1;
|
||||
if( registersUsed.readNamedReg1 != -1 )
|
||||
|
@ -957,20 +957,20 @@ bool PPCRecompiler_findAvailableRegisterDepr(ppcImlGenContext_t* ppcImlGenContex
|
|||
|
||||
bool PPCRecompiler_hasSuffixInstruction(PPCRecImlSegment_t* imlSegment)
|
||||
{
|
||||
if( imlSegment->imlListCount == 0 )
|
||||
if (imlSegment->imlList.empty())
|
||||
return false;
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+imlSegment->imlListCount-1;
|
||||
if( imlInstruction->type == PPCREC_IML_TYPE_MACRO && (imlInstruction->operation == PPCREC_IML_MACRO_BLR || imlInstruction->operation == PPCREC_IML_MACRO_BCTR) ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_MACRO && imlInstruction->operation == PPCREC_IML_MACRO_BL ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_MACRO && imlInstruction->operation == PPCREC_IML_MACRO_B_FAR ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_MACRO && imlInstruction->operation == PPCREC_IML_MACRO_BLRL ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_MACRO && imlInstruction->operation == PPCREC_IML_MACRO_BCTRL ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_MACRO && imlInstruction->operation == PPCREC_IML_MACRO_LEAVE ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_MACRO && imlInstruction->operation == PPCREC_IML_MACRO_HLE ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_MACRO && imlInstruction->operation == PPCREC_IML_MACRO_MFTB ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_PPC_ENTER ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_CJUMP ||
|
||||
imlInstruction->type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK )
|
||||
const PPCRecImlInstruction_t& imlInstruction = imlSegment->imlList.back();
|
||||
if( imlInstruction.type == PPCREC_IML_TYPE_MACRO && (imlInstruction.operation == PPCREC_IML_MACRO_BLR || imlInstruction.operation == PPCREC_IML_MACRO_BCTR) ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_BL ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_B_FAR ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_BLRL ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_BCTRL ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_LEAVE ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_HLE ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_MFTB ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_PPC_ENTER ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_CJUMP ||
|
||||
imlInstruction.type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -981,29 +981,29 @@ void PPCRecompiler_storeReplacedRegister(ppcImlGenContext_t* ppcImlGenContext, P
|
|||
sint32 imlIndexEdit = *imlIndex;
|
||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
||||
// name_unusedRegister = unusedRegister
|
||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList+(imlIndexEdit+0);
|
||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
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;
|
||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
||||
imlInstructionItr->op_r_name.flags = 0;
|
||||
PPCRecImlInstruction_t& imlInstructionItr = imlSegment->imlList[imlIndexEdit + 0];
|
||||
memset(&imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
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;
|
||||
imlInstructionItr.op_r_name.copyWidth = 32;
|
||||
imlInstructionItr.op_r_name.flags = 0;
|
||||
imlIndexEdit++;
|
||||
// load new register if required
|
||||
if( replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].nameMustBeMaintained )
|
||||
{
|
||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList+(imlIndexEdit+0);
|
||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
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];
|
||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
||||
imlInstructionItr->op_r_name.flags = 0;
|
||||
PPCRecImlInstruction_t& imlInstructionItr = imlSegment->imlList[imlIndexEdit];
|
||||
memset(&imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
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];
|
||||
imlInstructionItr.op_r_name.copyWidth = 32;
|
||||
imlInstructionItr.op_r_name.flags = 0;
|
||||
imlIndexEdit += 1;
|
||||
}
|
||||
// move last entry to current one
|
||||
|
@ -1021,17 +1021,17 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
|||
// first we remove all name load and store instructions that involve out-of-bounds registers
|
||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||
{
|
||||
sint32 imlIndex = 0;
|
||||
while( imlIndex < segIt->imlListCount )
|
||||
size_t imlIndex = 0;
|
||||
while( imlIndex < segIt->imlList.size() )
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstructionItr = segIt->imlList+imlIndex;
|
||||
if( imlInstructionItr->type == PPCREC_IML_TYPE_FPR_R_NAME || imlInstructionItr->type == PPCREC_IML_TYPE_FPR_NAME_R )
|
||||
PPCRecImlInstruction_t& imlInstructionItr = segIt->imlList[imlIndex];
|
||||
if( imlInstructionItr.type == PPCREC_IML_TYPE_FPR_R_NAME || imlInstructionItr.type == PPCREC_IML_TYPE_FPR_NAME_R )
|
||||
{
|
||||
if( imlInstructionItr->op_r_name.registerIndex >= PPC_X64_FPR_USABLE_REGISTERS )
|
||||
if( imlInstructionItr.op_r_name.registerIndex >= PPC_X64_FPR_USABLE_REGISTERS )
|
||||
{
|
||||
// convert to NO-OP instruction
|
||||
imlInstructionItr->type = PPCREC_IML_TYPE_NO_OP;
|
||||
imlInstructionItr->associatedPPCAddress = 0;
|
||||
imlInstructionItr.type = PPCREC_IML_TYPE_NO_OP;
|
||||
imlInstructionItr.associatedPPCAddress = 0;
|
||||
}
|
||||
}
|
||||
imlIndex++;
|
||||
|
@ -1040,13 +1040,13 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
|||
// replace registers
|
||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||
{
|
||||
sint32 imlIndex = 0;
|
||||
while( imlIndex < segIt->imlListCount )
|
||||
size_t imlIndex = 0;
|
||||
while( imlIndex < segIt->imlList.size() )
|
||||
{
|
||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
while( true )
|
||||
{
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, segIt->imlList+imlIndex, ®istersUsed);
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, segIt->imlList.data()+imlIndex, ®istersUsed);
|
||||
if( registersUsed.readFPR1 >= PPC_X64_FPR_USABLE_REGISTERS || registersUsed.readFPR2 >= PPC_X64_FPR_USABLE_REGISTERS || registersUsed.readFPR3 >= PPC_X64_FPR_USABLE_REGISTERS || registersUsed.readFPR4 >= PPC_X64_FPR_USABLE_REGISTERS || registersUsed.writtenFPR1 >= PPC_X64_FPR_USABLE_REGISTERS )
|
||||
{
|
||||
// get index of register to replace
|
||||
|
@ -1092,13 +1092,13 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
|||
replacedRegisterIsUsed = segIt->ppcFPRUsed[unusedRegisterName-PPCREC_NAME_FPR0];
|
||||
}
|
||||
// replace registers that are out of range
|
||||
PPCRecompiler_replaceFPRRegisterUsage(ppcImlGenContext, segIt->imlList+imlIndex, fprToReplace, unusedRegisterIndex);
|
||||
PPCRecompiler_replaceFPRRegisterUsage(ppcImlGenContext, segIt->imlList.data() + imlIndex, fprToReplace, unusedRegisterIndex);
|
||||
// add load/store name after instruction
|
||||
PPCRecompiler_pushBackIMLInstructions(segIt, imlIndex+1, 2);
|
||||
// add load/store before current instruction
|
||||
PPCRecompiler_pushBackIMLInstructions(segIt, imlIndex, 2);
|
||||
// name_unusedRegister = unusedRegister
|
||||
PPCRecImlInstruction_t* imlInstructionItr = segIt->imlList+(imlIndex+0);
|
||||
PPCRecImlInstruction_t* imlInstructionItr = segIt->imlList.data() + (imlIndex + 0);
|
||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
if( replacedRegisterIsUsed )
|
||||
{
|
||||
|
@ -1111,7 +1111,7 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
|||
}
|
||||
else
|
||||
imlInstructionItr->type = PPCREC_IML_TYPE_NO_OP;
|
||||
imlInstructionItr = segIt->imlList+(imlIndex+1);
|
||||
imlInstructionItr = segIt->imlList.data() + (imlIndex + 1);
|
||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||
|
@ -1120,7 +1120,7 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
|||
imlInstructionItr->op_r_name.copyWidth = 32;
|
||||
imlInstructionItr->op_r_name.flags = 0;
|
||||
// name_gprToReplace = unusedRegister
|
||||
imlInstructionItr = segIt->imlList+(imlIndex+3);
|
||||
imlInstructionItr = segIt->imlList.data() + (imlIndex + 3);
|
||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||
|
@ -1129,7 +1129,7 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
|||
imlInstructionItr->op_r_name.copyWidth = 32;
|
||||
imlInstructionItr->op_r_name.flags = 0;
|
||||
// unusedRegister = name_unusedRegister
|
||||
imlInstructionItr = segIt->imlList+(imlIndex+4);
|
||||
imlInstructionItr = segIt->imlList.data() + (imlIndex + 4);
|
||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
if( replacedRegisterIsUsed )
|
||||
{
|
||||
|
@ -1222,14 +1222,15 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
|||
for (sint32 i = 0; i < 64; i++)
|
||||
rCtx.ppcRegToMapping[i] = -1;
|
||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[segmentIndex];
|
||||
sint32 idx = 0;
|
||||
size_t idx = 0;
|
||||
sint32 currentUseIndex = 0;
|
||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
while (idx < imlSegment->imlListCount)
|
||||
while (idx < imlSegment->imlList.size())
|
||||
{
|
||||
if ( PPCRecompiler_isSuffixInstruction(imlSegment->imlList + idx) )
|
||||
PPCRecImlInstruction_t& idxInst = imlSegment->imlList[idx];
|
||||
if ( PPCRecompiler_isSuffixInstruction(&idxInst) )
|
||||
break;
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList + idx, ®istersUsed);
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &idxInst, ®istersUsed);
|
||||
sint32 fprMatch[4];
|
||||
sint32 fprReplace[4];
|
||||
fprMatch[0] = -1;
|
||||
|
@ -1276,7 +1277,7 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
|||
unloadLockedMask |= (1<<(unloadRegMapping- rCtx.currentMapping));
|
||||
// create unload instruction
|
||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList + idx;
|
||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
||||
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
||||
|
@ -1294,7 +1295,7 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
|||
}
|
||||
// create load instruction
|
||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList + idx;
|
||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
||||
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
||||
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
||||
|
@ -1336,7 +1337,7 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
|||
}
|
||||
if (numReplacedOperands > 0)
|
||||
{
|
||||
PPCRecompiler_replaceFPRRegisterUsageMultiple(ppcImlGenContext, imlSegment->imlList + idx, fprMatch, fprReplace);
|
||||
PPCRecompiler_replaceFPRRegisterUsageMultiple(ppcImlGenContext, imlSegment->imlList.data() + idx, fprMatch, fprReplace);
|
||||
}
|
||||
// next
|
||||
idx++;
|
||||
|
@ -1356,7 +1357,7 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
|||
{
|
||||
if (rCtx.currentMapping[i].isActive == false)
|
||||
continue;
|
||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList + idx;
|
||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
||||
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
||||
|
@ -1387,12 +1388,12 @@ bool PPCRecompiler_manageFPRRegisters(ppcImlGenContext_t* ppcImlGenContext)
|
|||
bool PPCRecompiler_trackRedundantNameLoadInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
||||
{
|
||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||
for(sint32 i=startIndex; i<imlSegment->imlListCount; i++)
|
||||
for(size_t i=startIndex; i<imlSegment->imlList.size(); i++)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+i;
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||
//nameStoreInstruction->op_r_name.registerIndex
|
||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList+i, ®istersUsed);
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||
if( registersUsed.readNamedReg1 == registerIndex || registersUsed.readNamedReg2 == registerIndex || registersUsed.readNamedReg3 == registerIndex )
|
||||
return false;
|
||||
if( registersUsed.writtenNamedReg1 == registerIndex )
|
||||
|
@ -1408,11 +1409,11 @@ bool PPCRecompiler_trackRedundantNameLoadInstruction(ppcImlGenContext_t* ppcImlG
|
|||
bool PPCRecompiler_trackRedundantFPRNameLoadInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
||||
{
|
||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||
for(sint32 i=startIndex; i<imlSegment->imlListCount; i++)
|
||||
for(size_t i=startIndex; i<imlSegment->imlList.size(); i++)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+i;
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList+i, ®istersUsed);
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||
if( registersUsed.readFPR1 == registerIndex || registersUsed.readFPR2 == registerIndex || registersUsed.readFPR3 == registerIndex || registersUsed.readFPR4 == registerIndex)
|
||||
return false;
|
||||
if( registersUsed.writtenFPR1 == registerIndex )
|
||||
|
@ -1430,9 +1431,9 @@ bool PPCRecompiler_trackRedundantNameStoreInstruction(ppcImlGenContext_t* ppcIml
|
|||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||
for(sint32 i=startIndex; i>=0; i--)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+i;
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList+i, ®istersUsed);
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||
if( registersUsed.writtenNamedReg1 == registerIndex )
|
||||
{
|
||||
if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_NAME )
|
||||
|
@ -1450,21 +1451,20 @@ sint32 debugCallCounter1 = 0;
|
|||
*/
|
||||
bool PPCRecompiler_trackOverwrittenNameStoreInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
||||
{
|
||||
//sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||
uint32 name = nameStoreInstruction->op_r_name.name;
|
||||
for(sint32 i=startIndex; i<imlSegment->imlListCount; i++)
|
||||
for(size_t i=startIndex; i<imlSegment->imlList.size(); i++)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+i;
|
||||
if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_NAME )
|
||||
const PPCRecImlInstruction_t& imlInstruction = imlSegment->imlList[i];
|
||||
if(imlInstruction.type == PPCREC_IML_TYPE_R_NAME )
|
||||
{
|
||||
// name is loaded before being written
|
||||
if( imlSegment->imlList[i].op_r_name.name == name )
|
||||
if (imlInstruction.op_r_name.name == name)
|
||||
return false;
|
||||
}
|
||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_NAME_R )
|
||||
else if(imlInstruction.type == PPCREC_IML_TYPE_NAME_R )
|
||||
{
|
||||
// name is written before being loaded
|
||||
if( imlSegment->imlList[i].op_r_name.name == name )
|
||||
if (imlInstruction.op_r_name.name == name)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1476,7 +1476,7 @@ bool PPCRecompiler_trackOverwrittenNameStoreInstruction(ppcImlGenContext_t* ppcI
|
|||
return false;
|
||||
if( imlSegment->nextSegmentBranchNotTaken && PPCRecompiler_trackOverwrittenNameStoreInstruction(ppcImlGenContext, imlSegment->nextSegmentBranchNotTaken, 0, nameStoreInstruction, scanDepth+1) == false )
|
||||
return false;
|
||||
if( imlSegment->nextSegmentBranchTaken == NULL && imlSegment->nextSegmentBranchNotTaken == NULL )
|
||||
if( imlSegment->nextSegmentBranchTaken == nullptr && imlSegment->nextSegmentBranchNotTaken == nullptr)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -1490,12 +1490,12 @@ bool PPCRecompiler_trackRedundantFPRNameStoreInstruction(ppcImlGenContext_t* ppc
|
|||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||
for(sint32 i=startIndex; i>=0; i--)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+i;
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList+i, ®istersUsed);
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||
if( registersUsed.writtenFPR1 == registerIndex )
|
||||
{
|
||||
if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_FPR_R_NAME )
|
||||
if(imlInstruction->type == PPCREC_IML_TYPE_FPR_R_NAME )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -1568,60 +1568,59 @@ void PPCRecompiler_removeRedundantCRUpdates(ppcImlGenContext_t* ppcImlGenContext
|
|||
{
|
||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||
{
|
||||
for(sint32 i=0; i<segIt->imlListCount; i++)
|
||||
for(PPCRecImlInstruction_t& instIt : segIt->imlList)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList+i;
|
||||
if (imlInstruction->type == PPCREC_IML_TYPE_CJUMP)
|
||||
if (instIt.type == PPCREC_IML_TYPE_CJUMP)
|
||||
{
|
||||
if (imlInstruction->op_conditionalJump.condition != PPCREC_JUMP_CONDITION_NONE)
|
||||
if (instIt.op_conditionalJump.condition != PPCREC_JUMP_CONDITION_NONE)
|
||||
{
|
||||
uint32 crBitFlag = 1 << (imlInstruction->op_conditionalJump.crRegisterIndex * 4 + imlInstruction->op_conditionalJump.crBitIndex);
|
||||
uint32 crBitFlag = 1 << (instIt.op_conditionalJump.crRegisterIndex * 4 + instIt.op_conditionalJump.crBitIndex);
|
||||
segIt->crBitsInput |= (crBitFlag&~segIt->crBitsWritten); // flag bits that have not already been written
|
||||
segIt->crBitsRead |= (crBitFlag);
|
||||
}
|
||||
}
|
||||
else if (imlInstruction->type == PPCREC_IML_TYPE_CONDITIONAL_R_S32)
|
||||
else if (instIt.type == PPCREC_IML_TYPE_CONDITIONAL_R_S32)
|
||||
{
|
||||
uint32 crBitFlag = 1 << (imlInstruction->op_conditional_r_s32.crRegisterIndex * 4 + imlInstruction->op_conditional_r_s32.crBitIndex);
|
||||
uint32 crBitFlag = 1 << (instIt.op_conditional_r_s32.crRegisterIndex * 4 + instIt.op_conditional_r_s32.crBitIndex);
|
||||
segIt->crBitsInput |= (crBitFlag&~segIt->crBitsWritten); // flag bits that have not already been written
|
||||
segIt->crBitsRead |= (crBitFlag);
|
||||
}
|
||||
else if (imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_MFCR)
|
||||
else if (instIt.type == PPCREC_IML_TYPE_R_S32 && instIt.operation == PPCREC_IML_OP_MFCR)
|
||||
{
|
||||
segIt->crBitsRead |= 0xFFFFFFFF;
|
||||
}
|
||||
else if (imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_MTCRF)
|
||||
else if (instIt.type == PPCREC_IML_TYPE_R_S32 && instIt.operation == PPCREC_IML_OP_MTCRF)
|
||||
{
|
||||
segIt->crBitsWritten |= ppc_MTCRFMaskToCRBitMask((uint32)imlInstruction->op_r_immS32.immS32);
|
||||
segIt->crBitsWritten |= ppc_MTCRFMaskToCRBitMask((uint32)instIt.op_r_immS32.immS32);
|
||||
}
|
||||
else if( imlInstruction->type == PPCREC_IML_TYPE_CR )
|
||||
else if( instIt.type == PPCREC_IML_TYPE_CR )
|
||||
{
|
||||
if (imlInstruction->operation == PPCREC_IML_OP_CR_CLEAR ||
|
||||
imlInstruction->operation == PPCREC_IML_OP_CR_SET)
|
||||
if (instIt.operation == PPCREC_IML_OP_CR_CLEAR ||
|
||||
instIt.operation == PPCREC_IML_OP_CR_SET)
|
||||
{
|
||||
uint32 crBitFlag = 1 << (imlInstruction->op_cr.crD);
|
||||
uint32 crBitFlag = 1 << (instIt.op_cr.crD);
|
||||
segIt->crBitsWritten |= (crBitFlag & ~segIt->crBitsWritten);
|
||||
}
|
||||
else if (imlInstruction->operation == PPCREC_IML_OP_CR_OR ||
|
||||
imlInstruction->operation == PPCREC_IML_OP_CR_ORC ||
|
||||
imlInstruction->operation == PPCREC_IML_OP_CR_AND ||
|
||||
imlInstruction->operation == PPCREC_IML_OP_CR_ANDC)
|
||||
else if (instIt.operation == PPCREC_IML_OP_CR_OR ||
|
||||
instIt.operation == PPCREC_IML_OP_CR_ORC ||
|
||||
instIt.operation == PPCREC_IML_OP_CR_AND ||
|
||||
instIt.operation == PPCREC_IML_OP_CR_ANDC)
|
||||
{
|
||||
uint32 crBitFlag = 1 << (imlInstruction->op_cr.crD);
|
||||
uint32 crBitFlag = 1 << (instIt.op_cr.crD);
|
||||
segIt->crBitsWritten |= (crBitFlag & ~segIt->crBitsWritten);
|
||||
crBitFlag = 1 << (imlInstruction->op_cr.crA);
|
||||
crBitFlag = 1 << (instIt.op_cr.crA);
|
||||
segIt->crBitsRead |= (crBitFlag & ~segIt->crBitsRead);
|
||||
crBitFlag = 1 << (imlInstruction->op_cr.crB);
|
||||
crBitFlag = 1 << (instIt.op_cr.crB);
|
||||
segIt->crBitsRead |= (crBitFlag & ~segIt->crBitsRead);
|
||||
}
|
||||
else
|
||||
cemu_assert_unimplemented();
|
||||
}
|
||||
else if( PPCRecompilerImlAnalyzer_canTypeWriteCR(imlInstruction) && imlInstruction->crRegister >= 0 && imlInstruction->crRegister <= 7 )
|
||||
else if( PPCRecompilerImlAnalyzer_canTypeWriteCR(&instIt) && instIt.crRegister >= 0 && instIt.crRegister <= 7 )
|
||||
{
|
||||
segIt->crBitsWritten |= (0xF<<(imlInstruction->crRegister*4));
|
||||
segIt->crBitsWritten |= (0xF<<(instIt.crRegister*4));
|
||||
}
|
||||
else if( (imlInstruction->type == PPCREC_IML_TYPE_STORE || imlInstruction->type == PPCREC_IML_TYPE_STORE_INDEXED) && imlInstruction->op_storeLoad.copyWidth == PPC_REC_STORE_STWCX_MARKER )
|
||||
else if( (instIt.type == PPCREC_IML_TYPE_STORE || instIt.type == PPCREC_IML_TYPE_STORE_INDEXED) && instIt.op_storeLoad.copyWidth == PPC_REC_STORE_STWCX_MARKER )
|
||||
{
|
||||
// overwrites CR0
|
||||
segIt->crBitsWritten |= (0xF<<0);
|
||||
|
@ -1631,15 +1630,14 @@ void PPCRecompiler_removeRedundantCRUpdates(ppcImlGenContext_t* ppcImlGenContext
|
|||
// flag instructions that write to CR where we can ignore individual CR bits
|
||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||
{
|
||||
for(sint32 i=0; i<segIt->imlListCount; i++)
|
||||
for (PPCRecImlInstruction_t& instIt : segIt->imlList)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList+i;
|
||||
if( PPCRecompilerImlAnalyzer_canTypeWriteCR(imlInstruction) && imlInstruction->crRegister >= 0 && imlInstruction->crRegister <= 7 )
|
||||
if( PPCRecompilerImlAnalyzer_canTypeWriteCR(&instIt) && instIt.crRegister >= 0 && instIt.crRegister <= 7 )
|
||||
{
|
||||
uint32 crBitFlags = 0xF<<((uint32)imlInstruction->crRegister*4);
|
||||
uint32 crBitFlags = 0xF<<((uint32)instIt.crRegister*4);
|
||||
uint32 crOverwriteMask = PPCRecompiler_getCROverwriteMask(ppcImlGenContext, segIt);
|
||||
uint32 crIgnoreMask = crOverwriteMask & ~segIt->crBitsRead;
|
||||
imlInstruction->crIgnoreMask = crIgnoreMask;
|
||||
instIt.crIgnoreMask = crIgnoreMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1650,7 +1648,7 @@ bool PPCRecompiler_checkIfGPRIsModifiedInRange(ppcImlGenContext_t* ppcImlGenCont
|
|||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
for (sint32 i = startIndex; i <= endIndex; i++)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList + i;
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||
if (registersUsed.writtenNamedReg1 == vreg)
|
||||
return true;
|
||||
|
@ -1688,7 +1686,7 @@ sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcIml
|
|||
if (currentSegment->list_prevSegments.size() != 1)
|
||||
return -1;
|
||||
currentSegment = currentSegment->list_prevSegments[0];
|
||||
currentIndex = currentSegment->imlListCount - 1;
|
||||
currentIndex = currentSegment->imlList.size() - 1;
|
||||
segmentIterateCount++;
|
||||
}
|
||||
// scan again to make sure the register is not modified inbetween
|
||||
|
@ -1701,13 +1699,12 @@ sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcIml
|
|||
while (currentIndex >= 0)
|
||||
{
|
||||
// check if register is modified
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, currentSegment->imlList+currentIndex, ®istersUsed);
|
||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, currentSegment->imlList.data() + currentIndex, ®istersUsed);
|
||||
if (registersUsed.writtenNamedReg1 == foundRegister)
|
||||
return -1;
|
||||
// check if end of scan reached
|
||||
if (currentSegment->imlList[currentIndex].type == PPCREC_IML_TYPE_NAME_R && currentSegment->imlList[currentIndex].op_r_name.name == name)
|
||||
{
|
||||
//foundRegister = currentSegment->imlList[currentIndex].op_r_name.registerIndex;
|
||||
return foundRegister;
|
||||
}
|
||||
// previous instruction
|
||||
|
@ -1719,7 +1716,7 @@ sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcIml
|
|||
if (currentSegment->list_prevSegments.size() != 1)
|
||||
return -1;
|
||||
currentSegment = currentSegment->list_prevSegments[0];
|
||||
currentIndex = currentSegment->imlListCount - 1;
|
||||
currentIndex = currentSegment->imlList.size() - 1;
|
||||
segmentIterateCount++;
|
||||
}
|
||||
return -1;
|
||||
|
@ -1727,17 +1724,17 @@ sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcIml
|
|||
|
||||
void PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 imlIndexLoad, sint32 fprIndex)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstructionLoad = imlSegment->imlList + imlIndexLoad;
|
||||
PPCRecImlInstruction_t* imlInstructionLoad = imlSegment->imlList.data() + imlIndexLoad;
|
||||
if (imlInstructionLoad->op_storeLoad.flags2.notExpanded)
|
||||
return;
|
||||
|
||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
sint32 scanRangeEnd = std::min(imlIndexLoad + 25, imlSegment->imlListCount); // don't scan too far (saves performance and also the chances we can merge the load+store become low at high distances)
|
||||
sint32 scanRangeEnd = std::min<sint32>(imlIndexLoad + 25, imlSegment->imlList.size()); // don't scan too far (saves performance and also the chances we can merge the load+store become low at high distances)
|
||||
bool foundMatch = false;
|
||||
sint32 lastStore = -1;
|
||||
for (sint32 i = imlIndexLoad + 1; i < scanRangeEnd; i++)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList + i;
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||
if (PPCRecompiler_isSuffixInstruction(imlInstruction))
|
||||
{
|
||||
break;
|
||||
|
@ -1802,9 +1799,9 @@ void PPCRecompiler_optimizeDirectFloatCopies(ppcImlGenContext_t* ppcImlGenContex
|
|||
{
|
||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||
{
|
||||
for (sint32 i = 0; i < segIt->imlListCount; i++)
|
||||
for (sint32 i = 0; i < segIt->imlList.size(); i++)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList + i;
|
||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList.data() + i;
|
||||
if (imlInstruction->type == PPCREC_IML_TYPE_FPR_LOAD && imlInstruction->op_storeLoad.mode == PPCREC_FPR_LD_MODE_SINGLE_INTO_PS0_PS1)
|
||||
{
|
||||
PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext, segIt, i, imlInstruction->op_storeLoad.registerData);
|
||||
|
@ -1819,16 +1816,16 @@ void PPCRecompiler_optimizeDirectFloatCopies(ppcImlGenContext_t* ppcImlGenContex
|
|||
|
||||
void PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 imlIndexLoad, sint32 gprIndex)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstructionLoad = imlSegment->imlList + imlIndexLoad;
|
||||
PPCRecImlInstruction_t* imlInstructionLoad = imlSegment->imlList.data() + imlIndexLoad;
|
||||
if ( imlInstructionLoad->op_storeLoad.flags2.swapEndian == false )
|
||||
return;
|
||||
bool foundMatch = false;
|
||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||
sint32 scanRangeEnd = std::min(imlIndexLoad + 25, imlSegment->imlListCount); // don't scan too far (saves performance and also the chances we can merge the load+store become low at high distances)
|
||||
sint32 scanRangeEnd = std::min<sint32>(imlIndexLoad + 25, imlSegment->imlList.size()); // don't scan too far (saves performance and also the chances we can merge the load+store become low at high distances)
|
||||
sint32 i = imlIndexLoad + 1;
|
||||
for (; i < scanRangeEnd; i++)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList + i;
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||
if (PPCRecompiler_isSuffixInstruction(imlInstruction))
|
||||
{
|
||||
break;
|
||||
|
@ -1886,9 +1883,9 @@ void PPCRecompiler_optimizeDirectIntegerCopies(ppcImlGenContext_t* ppcImlGenCont
|
|||
{
|
||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||
{
|
||||
for (sint32 i = 0; i < segIt->imlListCount; i++)
|
||||
for (sint32 i = 0; i < segIt->imlList.size(); i++)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList + i;
|
||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList.data() + i;
|
||||
if (imlInstruction->type == PPCREC_IML_TYPE_LOAD && imlInstruction->op_storeLoad.copyWidth == 32 && imlInstruction->op_storeLoad.flags2.swapEndian )
|
||||
{
|
||||
PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext, segIt, i, imlInstruction->op_storeLoad.registerData);
|
||||
|
@ -1933,21 +1930,19 @@ void PPCRecompiler_optimizePSQLoadAndStore(ppcImlGenContext_t* ppcImlGenContext)
|
|||
{
|
||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||
{
|
||||
for (sint32 i = 0; i < segIt->imlListCount; i++)
|
||||
for(PPCRecImlInstruction_t& instIt : segIt->imlList)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = segIt->imlList + i;
|
||||
if (imlInstruction->type == PPCREC_IML_TYPE_FPR_LOAD || imlInstruction->type == PPCREC_IML_TYPE_FPR_LOAD_INDEXED)
|
||||
if (instIt.type == PPCREC_IML_TYPE_FPR_LOAD || instIt.type == PPCREC_IML_TYPE_FPR_LOAD_INDEXED)
|
||||
{
|
||||
if(imlInstruction->op_storeLoad.mode != PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0 &&
|
||||
imlInstruction->op_storeLoad.mode != PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0_PS1 )
|
||||
if(instIt.op_storeLoad.mode != PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0 &&
|
||||
instIt.op_storeLoad.mode != PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0_PS1 )
|
||||
continue;
|
||||
// get GQR value
|
||||
cemu_assert_debug(imlInstruction->op_storeLoad.registerGQR != PPC_REC_INVALID_REGISTER);
|
||||
sint32 gqrIndex = _getGQRIndexFromRegister(ppcImlGenContext, imlInstruction->op_storeLoad.registerGQR);
|
||||
cemu_assert_debug(instIt.op_storeLoad.registerGQR != PPC_REC_INVALID_REGISTER);
|
||||
sint32 gqrIndex = _getGQRIndexFromRegister(ppcImlGenContext, instIt.op_storeLoad.registerGQR);
|
||||
cemu_assert(gqrIndex >= 0);
|
||||
if (ppcImlGenContext->tracking.modifiesGQR[gqrIndex])
|
||||
continue;
|
||||
//uint32 gqrValue = ppcInterpreterCurrentInstance->sprNew.UGQR[gqrIndex];
|
||||
uint32 gqrValue;
|
||||
if (!PPCRecompiler_isUGQRValueKnown(ppcImlGenContext, gqrIndex, gqrValue))
|
||||
continue;
|
||||
|
@ -1956,41 +1951,41 @@ void PPCRecompiler_optimizePSQLoadAndStore(ppcImlGenContext_t* ppcImlGenContext)
|
|||
uint32 scale = (gqrValue >> 24) & 0x3F;
|
||||
if (scale != 0)
|
||||
continue; // only generic handler supports scale
|
||||
if (imlInstruction->op_storeLoad.mode == PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0)
|
||||
if (instIt.op_storeLoad.mode == PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0)
|
||||
{
|
||||
if (formatType == 0)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_FLOAT_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_FLOAT_PS0;
|
||||
else if (formatType == 4)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_U8_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_U8_PS0;
|
||||
else if (formatType == 5)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_U16_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_U16_PS0;
|
||||
else if (formatType == 6)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_S8_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_S8_PS0;
|
||||
else if (formatType == 7)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_S16_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_S16_PS0;
|
||||
}
|
||||
else if (imlInstruction->op_storeLoad.mode == PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0_PS1)
|
||||
else if (instIt.op_storeLoad.mode == PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0_PS1)
|
||||
{
|
||||
if (formatType == 0)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_FLOAT_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_FLOAT_PS0_PS1;
|
||||
else if (formatType == 4)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_U8_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_U8_PS0_PS1;
|
||||
else if (formatType == 5)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_U16_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_U16_PS0_PS1;
|
||||
else if (formatType == 6)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_S8_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_S8_PS0_PS1;
|
||||
else if (formatType == 7)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_S16_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_LD_MODE_PSQ_S16_PS0_PS1;
|
||||
}
|
||||
}
|
||||
else if (imlInstruction->type == PPCREC_IML_TYPE_FPR_STORE || imlInstruction->type == PPCREC_IML_TYPE_FPR_STORE_INDEXED)
|
||||
else if (instIt.type == PPCREC_IML_TYPE_FPR_STORE || instIt.type == PPCREC_IML_TYPE_FPR_STORE_INDEXED)
|
||||
{
|
||||
if(imlInstruction->op_storeLoad.mode != PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0 &&
|
||||
imlInstruction->op_storeLoad.mode != PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0_PS1)
|
||||
if(instIt.op_storeLoad.mode != PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0 &&
|
||||
instIt.op_storeLoad.mode != PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0_PS1)
|
||||
continue;
|
||||
// get GQR value
|
||||
cemu_assert_debug(imlInstruction->op_storeLoad.registerGQR != PPC_REC_INVALID_REGISTER);
|
||||
sint32 gqrIndex = _getGQRIndexFromRegister(ppcImlGenContext, imlInstruction->op_storeLoad.registerGQR);
|
||||
cemu_assert_debug(instIt.op_storeLoad.registerGQR != PPC_REC_INVALID_REGISTER);
|
||||
sint32 gqrIndex = _getGQRIndexFromRegister(ppcImlGenContext, instIt.op_storeLoad.registerGQR);
|
||||
cemu_assert(gqrIndex >= 0);
|
||||
if (ppcImlGenContext->tracking.modifiesGQR[gqrIndex])
|
||||
continue;
|
||||
|
@ -2001,31 +1996,31 @@ void PPCRecompiler_optimizePSQLoadAndStore(ppcImlGenContext_t* ppcImlGenContext)
|
|||
uint32 scale = (gqrValue >> 24) & 0x3F;
|
||||
if (scale != 0)
|
||||
continue; // only generic handler supports scale
|
||||
if (imlInstruction->op_storeLoad.mode == PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0)
|
||||
if (instIt.op_storeLoad.mode == PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0)
|
||||
{
|
||||
if (formatType == 0)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_FLOAT_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_FLOAT_PS0;
|
||||
else if (formatType == 4)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_U8_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_U8_PS0;
|
||||
else if (formatType == 5)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_U16_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_U16_PS0;
|
||||
else if (formatType == 6)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_S8_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_S8_PS0;
|
||||
else if (formatType == 7)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_S16_PS0;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_S16_PS0;
|
||||
}
|
||||
else if (imlInstruction->op_storeLoad.mode == PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0_PS1)
|
||||
else if (instIt.op_storeLoad.mode == PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0_PS1)
|
||||
{
|
||||
if (formatType == 0)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_FLOAT_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_FLOAT_PS0_PS1;
|
||||
else if (formatType == 4)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_U8_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_U8_PS0_PS1;
|
||||
else if (formatType == 5)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_U16_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_U16_PS0_PS1;
|
||||
else if (formatType == 6)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_S8_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_S8_PS0_PS1;
|
||||
else if (formatType == 7)
|
||||
imlInstruction->op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_S16_PS0_PS1;
|
||||
instIt.op_storeLoad.mode = PPCREC_FPR_ST_MODE_PSQ_S16_PS0_PS1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2065,9 +2060,9 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
|||
// scan backwards until we find the instruction that sets the CR
|
||||
sint32 crSetterInstructionIndex = -1;
|
||||
sint32 unsafeInstructionIndex = -1;
|
||||
for (sint32 i = imlSegment->imlListCount-2; i >= 0; i--)
|
||||
for (sint32 i = imlSegment->imlList.size() - 2; i >= 0; i--)
|
||||
{
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList + i;
|
||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||
PPCRecompilerImlAnalyzer_getCRTracking(imlInstruction, &crTracking);
|
||||
if (crTracking.readCRBits != 0)
|
||||
return; // dont handle complex cases for now
|
||||
|
@ -2101,7 +2096,7 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
|||
// check if we can move the CR setter instruction to after unsafeInstructionIndex
|
||||
PPCRecCRTracking_t crTrackingSetter = crTracking;
|
||||
PPCImlOptimizerUsedRegisters_t regTrackingCRSetter;
|
||||
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList+crSetterInstructionIndex, ®TrackingCRSetter);
|
||||
PPCRecompiler_checkRegisterUsage(nullptr, imlSegment->imlList.data() + crSetterInstructionIndex, ®TrackingCRSetter);
|
||||
if (regTrackingCRSetter.writtenFPR1 >= 0 || regTrackingCRSetter.readFPR1 >= 0 || regTrackingCRSetter.readFPR2 >= 0 || regTrackingCRSetter.readFPR3 >= 0 || regTrackingCRSetter.readFPR4 >= 0)
|
||||
return; // we don't handle FPR dependency yet so just ignore FPR instructions
|
||||
PPCImlOptimizerUsedRegisters_t registerTracking;
|
||||
|
@ -2110,7 +2105,7 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
|||
// CR setter does write GPR
|
||||
for (sint32 i = crSetterInstructionIndex + 1; i <= unsafeInstructionIndex; i++)
|
||||
{
|
||||
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList + i, ®isterTracking);
|
||||
PPCRecompiler_checkRegisterUsage(nullptr, imlSegment->imlList.data() + i, ®isterTracking);
|
||||
// reads register written by CR setter?
|
||||
if (PPCRecompilerAnalyzer_checkForGPROverwrite(®isterTracking, ®TrackingCRSetter))
|
||||
{
|
||||
|
@ -2131,7 +2126,7 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
|||
// CR setter does not write GPR
|
||||
for (sint32 i = crSetterInstructionIndex + 1; i <= unsafeInstructionIndex; i++)
|
||||
{
|
||||
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList + i, ®isterTracking);
|
||||
PPCRecompiler_checkRegisterUsage(nullptr, imlSegment->imlList.data() + i, ®isterTracking);
|
||||
// writes register read by CR setter?
|
||||
if (PPCRecompilerAnalyzer_checkForGPROverwrite(®TrackingCRSetter, ®isterTracking))
|
||||
{
|
||||
|
@ -2146,8 +2141,8 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
|||
assert_dbg();
|
||||
#endif
|
||||
PPCRecImlInstruction_t* newCRSetterInstruction = PPCRecompiler_insertInstruction(imlSegment, unsafeInstructionIndex+1);
|
||||
memcpy(newCRSetterInstruction, imlSegment->imlList + crSetterInstructionIndex, sizeof(PPCRecImlInstruction_t));
|
||||
PPCRecompilerImlGen_generateNewInstruction_noOp(NULL, imlSegment->imlList + crSetterInstructionIndex);
|
||||
memcpy(newCRSetterInstruction, imlSegment->imlList.data() + crSetterInstructionIndex, sizeof(PPCRecImlInstruction_t));
|
||||
PPCRecompilerImlGen_generateNewInstruction_noOp(nullptr, imlSegment->imlList.data() + crSetterInstructionIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue