PPCRec: Use vector for instruction list

This commit is contained in:
Exzap 2022-11-04 21:33:03 +01:00
parent d42ea6e5a8
commit ce5d010611
8 changed files with 379 additions and 401 deletions

View file

@ -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, &registersUsed);
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &imlSegment->imlList[imlIndexStart], &registersUsed);
// 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, &registersUsed);
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, segIt->imlList.data()+imlIndex, &registersUsed);
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, &registersUsed);
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &idxInst, &registersUsed);
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, &registersUsed);
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, &registersUsed);
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, &registersUsed);
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, &registersUsed);
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, &registersUsed);
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, &registersUsed);
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, &registersUsed);
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, &registersUsed);
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, &registersUsed);
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, &registersUsed);
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, currentSegment->imlList.data() + currentIndex, &registersUsed);
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, &regTrackingCRSetter);
PPCRecompiler_checkRegisterUsage(nullptr, imlSegment->imlList.data() + crSetterInstructionIndex, &regTrackingCRSetter);
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, &registerTracking);
PPCRecompiler_checkRegisterUsage(nullptr, imlSegment->imlList.data() + i, &registerTracking);
// reads register written by CR setter?
if (PPCRecompilerAnalyzer_checkForGPROverwrite(&registerTracking, &regTrackingCRSetter))
{
@ -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, &registerTracking);
PPCRecompiler_checkRegisterUsage(nullptr, imlSegment->imlList.data() + i, &registerTracking);
// writes register read by CR setter?
if (PPCRecompilerAnalyzer_checkForGPROverwrite(&regTrackingCRSetter, &registerTracking))
{
@ -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);
}
/*