mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-04-29 14:59:26 -04: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
|
@ -269,9 +269,7 @@ typedef struct _PPCRecImlSegment_t
|
||||||
uint32 x64Offset{}; // x64 code offset of segment start
|
uint32 x64Offset{}; // x64 code offset of segment start
|
||||||
uint32 cycleCount{}; // number of PPC cycles required to execute this segment (roughly)
|
uint32 cycleCount{}; // number of PPC cycles required to execute this segment (roughly)
|
||||||
// list of intermediate instructions in this segment
|
// list of intermediate instructions in this segment
|
||||||
PPCRecImlInstruction_t* imlList{};
|
std::vector<PPCRecImlInstruction_t> imlList;
|
||||||
sint32 imlListSize{};
|
|
||||||
sint32 imlListCount{};
|
|
||||||
// segment link
|
// segment link
|
||||||
_PPCRecImlSegment_t* nextSegmentBranchNotTaken{}; // this is also the default for segments where there is no branch
|
_PPCRecImlSegment_t* nextSegmentBranchNotTaken{}; // this is also the default for segments where there is no branch
|
||||||
_PPCRecImlSegment_t* nextSegmentBranchTaken{};
|
_PPCRecImlSegment_t* nextSegmentBranchTaken{};
|
||||||
|
|
|
@ -419,4 +419,4 @@ typedef struct
|
||||||
};
|
};
|
||||||
}PPCImlOptimizerUsedRegisters_t;
|
}PPCImlOptimizerUsedRegisters_t;
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -13,9 +13,9 @@ bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(PPCRecImlSegment_t* imlSegment)
|
||||||
if (imlSegment->nextSegmentBranchTaken != imlSegment)
|
if (imlSegment->nextSegmentBranchTaken != imlSegment)
|
||||||
return false;
|
return false;
|
||||||
// loops using BDNZ are assumed to always be finite
|
// loops using BDNZ are assumed to always be finite
|
||||||
for (sint32 t = 0; t < imlSegment->imlListCount; t++)
|
for(const PPCRecImlInstruction_t& instIt : imlSegment->imlList)
|
||||||
{
|
{
|
||||||
if (imlSegment->imlList[t].type == PPCREC_IML_TYPE_R_S32 && imlSegment->imlList[t].operation == PPCREC_IML_OP_SUB && imlSegment->imlList[t].crRegister == 8)
|
if (instIt.type == PPCREC_IML_TYPE_R_S32 && instIt.operation == PPCREC_IML_OP_SUB && instIt.crRegister == 8)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,11 @@ bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(PPCRecImlSegment_t* imlSegment)
|
||||||
// risky approach, look for ADD/SUB operations and assume that potential overflow means finite (does not include r_r_s32 ADD/SUB)
|
// risky approach, look for ADD/SUB operations and assume that potential overflow means finite (does not include r_r_s32 ADD/SUB)
|
||||||
// this catches most loops with load-update and store-update instructions, but also those with decrementing counters
|
// this catches most loops with load-update and store-update instructions, but also those with decrementing counters
|
||||||
FixedSizeList<sint32, 64, true> list_modifiedRegisters;
|
FixedSizeList<sint32, 64, true> list_modifiedRegisters;
|
||||||
for (sint32 t = 0; t < imlSegment->imlListCount; t++)
|
for (const PPCRecImlInstruction_t& instIt : imlSegment->imlList)
|
||||||
{
|
{
|
||||||
if (imlSegment->imlList[t].type == PPCREC_IML_TYPE_R_S32 && (imlSegment->imlList[t].operation == PPCREC_IML_OP_ADD || imlSegment->imlList[t].operation == PPCREC_IML_OP_SUB) )
|
if (instIt.type == PPCREC_IML_TYPE_R_S32 && (instIt.operation == PPCREC_IML_OP_ADD || instIt.operation == PPCREC_IML_OP_SUB) )
|
||||||
{
|
{
|
||||||
list_modifiedRegisters.addUnique(imlSegment->imlList[t].op_r_immS32.registerIndex);
|
list_modifiedRegisters.addUnique(instIt.op_r_immS32.registerIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list_modifiedRegisters.count > 0)
|
if (list_modifiedRegisters.count > 0)
|
||||||
|
@ -36,11 +36,11 @@ bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(PPCRecImlSegment_t* imlSegment)
|
||||||
// remove all registers from the list that are modified by non-ADD/SUB instructions
|
// remove all registers from the list that are modified by non-ADD/SUB instructions
|
||||||
// todo: We should also cover the case where ADD+SUB on the same register cancel the effect out
|
// todo: We should also cover the case where ADD+SUB on the same register cancel the effect out
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
for (sint32 t = 0; t < imlSegment->imlListCount; t++)
|
for (const PPCRecImlInstruction_t& instIt : imlSegment->imlList)
|
||||||
{
|
{
|
||||||
if (imlSegment->imlList[t].type == PPCREC_IML_TYPE_R_S32 && (imlSegment->imlList[t].operation == PPCREC_IML_OP_ADD || imlSegment->imlList[t].operation == PPCREC_IML_OP_SUB))
|
if (instIt.type == PPCREC_IML_TYPE_R_S32 && (instIt.operation == PPCREC_IML_OP_ADD || instIt.operation == PPCREC_IML_OP_SUB))
|
||||||
continue;
|
continue;
|
||||||
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList + t, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(nullptr, &instIt, ®istersUsed);
|
||||||
if(registersUsed.writtenNamedReg1 < 0)
|
if(registersUsed.writtenNamedReg1 < 0)
|
||||||
continue;
|
continue;
|
||||||
list_modifiedRegisters.remove(registersUsed.writtenNamedReg1);
|
list_modifiedRegisters.remove(registersUsed.writtenNamedReg1);
|
||||||
|
|
|
@ -2990,7 +2990,7 @@ uint32 PPCRecompiler_getPreviousInstruction(ppcImlGenContext_t* ppcImlGenContext
|
||||||
|
|
||||||
char _tempOpcodename[32];
|
char _tempOpcodename[32];
|
||||||
|
|
||||||
const char* PPCRecompiler_getOpcodeDebugName(PPCRecImlInstruction_t* iml)
|
const char* PPCRecompiler_getOpcodeDebugName(const PPCRecImlInstruction_t* iml)
|
||||||
{
|
{
|
||||||
uint32 op = iml->operation;
|
uint32 op = iml->operation;
|
||||||
if (op == PPCREC_IML_OP_ASSIGN)
|
if (op == PPCREC_IML_OP_ASSIGN)
|
||||||
|
@ -3115,294 +3115,295 @@ void PPCRecompiler_dumpIMLSegment(PPCRecImlSegment_t* imlSegment, sint32 segment
|
||||||
|
|
||||||
sint32 lineOffsetParameters = 18;
|
sint32 lineOffsetParameters = 18;
|
||||||
|
|
||||||
for(sint32 i=0; i<imlSegment->imlListCount; i++)
|
for(sint32 i=0; i<imlSegment->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
|
const PPCRecImlInstruction_t& inst = imlSegment->imlList[i];
|
||||||
// don't log NOP instructions unless they have an associated PPC address
|
// don't log NOP instructions unless they have an associated PPC address
|
||||||
if(imlSegment->imlList[i].type == PPCREC_IML_TYPE_NO_OP && imlSegment->imlList[i].associatedPPCAddress == MPTR_NULL)
|
if(inst.type == PPCREC_IML_TYPE_NO_OP && inst.associatedPPCAddress == MPTR_NULL)
|
||||||
continue;
|
continue;
|
||||||
strOutput.reset();
|
strOutput.reset();
|
||||||
strOutput.addFmt("{:08x} ", imlSegment->imlList[i].associatedPPCAddress);
|
strOutput.addFmt("{:08x} ", inst.associatedPPCAddress);
|
||||||
if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_NAME || imlSegment->imlList[i].type == PPCREC_IML_TYPE_NAME_R)
|
if( inst.type == PPCREC_IML_TYPE_R_NAME || inst.type == PPCREC_IML_TYPE_NAME_R)
|
||||||
{
|
{
|
||||||
if(imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_NAME)
|
if(inst.type == PPCREC_IML_TYPE_R_NAME)
|
||||||
strOutput.add("LD_NAME");
|
strOutput.add("LD_NAME");
|
||||||
else
|
else
|
||||||
strOutput.add("ST_NAME");
|
strOutput.add("ST_NAME");
|
||||||
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
||||||
strOutput.add(" ");
|
strOutput.add(" ");
|
||||||
|
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_r_name.registerIndex);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_r_name.registerIndex);
|
||||||
|
|
||||||
strOutput.addFmt("name_{} (", imlSegment->imlList[i].op_r_name.registerIndex, imlSegment->imlList[i].op_r_name.name);
|
strOutput.addFmt("name_{} (", inst.op_r_name.registerIndex, inst.op_r_name.name);
|
||||||
if( imlSegment->imlList[i].op_r_name.name >= PPCREC_NAME_R0 && imlSegment->imlList[i].op_r_name.name < (PPCREC_NAME_R0+999) )
|
if( inst.op_r_name.name >= PPCREC_NAME_R0 && inst.op_r_name.name < (PPCREC_NAME_R0+999) )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("r{}", imlSegment->imlList[i].op_r_name.name-PPCREC_NAME_R0);
|
strOutput.addFmt("r{}", inst.op_r_name.name-PPCREC_NAME_R0);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].op_r_name.name >= PPCREC_NAME_SPR0 && imlSegment->imlList[i].op_r_name.name < (PPCREC_NAME_SPR0+999) )
|
else if( inst.op_r_name.name >= PPCREC_NAME_SPR0 && inst.op_r_name.name < (PPCREC_NAME_SPR0+999) )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("spr{}", imlSegment->imlList[i].op_r_name.name-PPCREC_NAME_SPR0);
|
strOutput.addFmt("spr{}", inst.op_r_name.name-PPCREC_NAME_SPR0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strOutput.add("ukn");
|
strOutput.add("ukn");
|
||||||
strOutput.add(")");
|
strOutput.add(")");
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_R )
|
else if( inst.type == PPCREC_IML_TYPE_R_R )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(imlSegment->imlList+i));
|
strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(&inst));
|
||||||
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
||||||
strOutput.add(" ");
|
strOutput.add(" ");
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_r_r.registerResult);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r.registerResult);
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_r_r.registerA, true);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r.registerA, true);
|
||||||
|
|
||||||
if( imlSegment->imlList[i].crRegister != PPC_REC_INVALID_REGISTER )
|
if( inst.crRegister != PPC_REC_INVALID_REGISTER )
|
||||||
{
|
{
|
||||||
strOutput.addFmt(" -> CR{}", imlSegment->imlList[i].crRegister);
|
strOutput.addFmt(" -> CR{}", inst.crRegister);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_R_R )
|
else if( inst.type == PPCREC_IML_TYPE_R_R_R )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(imlSegment->imlList + i));
|
strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(&inst));
|
||||||
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
||||||
strOutput.add(" ");
|
strOutput.add(" ");
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_r_r_r.registerResult);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_r.registerResult);
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_r_r_r.registerA);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_r.registerA);
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_r_r_r.registerB, true);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_r.registerB, true);
|
||||||
if( imlSegment->imlList[i].crRegister != PPC_REC_INVALID_REGISTER )
|
if( inst.crRegister != PPC_REC_INVALID_REGISTER )
|
||||||
{
|
{
|
||||||
strOutput.addFmt(" -> CR{}", imlSegment->imlList[i].crRegister);
|
strOutput.addFmt(" -> CR{}", inst.crRegister);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_R_S32)
|
else if (inst.type == PPCREC_IML_TYPE_R_R_S32)
|
||||||
{
|
{
|
||||||
strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(imlSegment->imlList + i));
|
strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(&inst));
|
||||||
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
||||||
strOutput.add(" ");
|
strOutput.add(" ");
|
||||||
|
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_r_r_s32.registerResult);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_s32.registerResult);
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_r_r_s32.registerA);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_s32.registerA);
|
||||||
PPCRecDebug_addS32Param(strOutput, imlSegment->imlList[i].op_r_r_s32.immS32, true);
|
PPCRecDebug_addS32Param(strOutput, inst.op_r_r_s32.immS32, true);
|
||||||
|
|
||||||
if (imlSegment->imlList[i].crRegister != PPC_REC_INVALID_REGISTER)
|
if (inst.crRegister != PPC_REC_INVALID_REGISTER)
|
||||||
{
|
{
|
||||||
strOutput.addFmt(" -> CR{}", imlSegment->imlList[i].crRegister);
|
strOutput.addFmt(" -> CR{}", inst.crRegister);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_S32)
|
else if (inst.type == PPCREC_IML_TYPE_R_S32)
|
||||||
{
|
{
|
||||||
strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(imlSegment->imlList + i));
|
strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(&inst));
|
||||||
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
||||||
strOutput.add(" ");
|
strOutput.add(" ");
|
||||||
|
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_r_immS32.registerIndex);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_r_immS32.registerIndex);
|
||||||
PPCRecDebug_addS32Param(strOutput, imlSegment->imlList[i].op_r_immS32.immS32, true);
|
PPCRecDebug_addS32Param(strOutput, inst.op_r_immS32.immS32, true);
|
||||||
|
|
||||||
if (imlSegment->imlList[i].crRegister != PPC_REC_INVALID_REGISTER)
|
if (inst.crRegister != PPC_REC_INVALID_REGISTER)
|
||||||
{
|
{
|
||||||
strOutput.addFmt(" -> CR{}", imlSegment->imlList[i].crRegister);
|
strOutput.addFmt(" -> CR{}", inst.crRegister);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_JUMPMARK )
|
else if( inst.type == PPCREC_IML_TYPE_JUMPMARK )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("jm_{:08x}:", imlSegment->imlList[i].op_jumpmark.address);
|
strOutput.addFmt("jm_{:08x}:", inst.op_jumpmark.address);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_PPC_ENTER )
|
else if( inst.type == PPCREC_IML_TYPE_PPC_ENTER )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("ppcEnter_{:08x}:", imlSegment->imlList[i].op_ppcEnter.ppcAddress);
|
strOutput.addFmt("ppcEnter_{:08x}:", inst.op_ppcEnter.ppcAddress);
|
||||||
}
|
}
|
||||||
else if(imlSegment->imlList[i].type == PPCREC_IML_TYPE_LOAD || imlSegment->imlList[i].type == PPCREC_IML_TYPE_STORE ||
|
else if(inst.type == PPCREC_IML_TYPE_LOAD || inst.type == PPCREC_IML_TYPE_STORE ||
|
||||||
imlSegment->imlList[i].type == PPCREC_IML_TYPE_LOAD_INDEXED || imlSegment->imlList[i].type == PPCREC_IML_TYPE_STORE_INDEXED )
|
inst.type == PPCREC_IML_TYPE_LOAD_INDEXED || inst.type == PPCREC_IML_TYPE_STORE_INDEXED )
|
||||||
{
|
{
|
||||||
if(imlSegment->imlList[i].type == PPCREC_IML_TYPE_LOAD || imlSegment->imlList[i].type == PPCREC_IML_TYPE_LOAD_INDEXED)
|
if(inst.type == PPCREC_IML_TYPE_LOAD || inst.type == PPCREC_IML_TYPE_LOAD_INDEXED)
|
||||||
strOutput.add("LD_");
|
strOutput.add("LD_");
|
||||||
else
|
else
|
||||||
strOutput.add("ST_");
|
strOutput.add("ST_");
|
||||||
|
|
||||||
if (imlSegment->imlList[i].op_storeLoad.flags2.signExtend)
|
if (inst.op_storeLoad.flags2.signExtend)
|
||||||
strOutput.add("S");
|
strOutput.add("S");
|
||||||
else
|
else
|
||||||
strOutput.add("U");
|
strOutput.add("U");
|
||||||
strOutput.addFmt("{}", imlSegment->imlList[i].op_storeLoad.copyWidth);
|
strOutput.addFmt("{}", inst.op_storeLoad.copyWidth);
|
||||||
|
|
||||||
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
while ((sint32)strOutput.getLen() < lineOffsetParameters)
|
||||||
strOutput.add(" ");
|
strOutput.add(" ");
|
||||||
|
|
||||||
PPCRecDebug_addRegisterParam(strOutput, imlSegment->imlList[i].op_storeLoad.registerData);
|
PPCRecDebug_addRegisterParam(strOutput, inst.op_storeLoad.registerData);
|
||||||
|
|
||||||
if(imlSegment->imlList[i].type == PPCREC_IML_TYPE_LOAD_INDEXED || imlSegment->imlList[i].type == PPCREC_IML_TYPE_STORE_INDEXED)
|
if(inst.type == PPCREC_IML_TYPE_LOAD_INDEXED || inst.type == PPCREC_IML_TYPE_STORE_INDEXED)
|
||||||
strOutput.addFmt("[t{}+t{}]", imlSegment->imlList[i].op_storeLoad.registerMem, imlSegment->imlList[i].op_storeLoad.registerMem2);
|
strOutput.addFmt("[t{}+t{}]", inst.op_storeLoad.registerMem, inst.op_storeLoad.registerMem2);
|
||||||
else
|
else
|
||||||
strOutput.addFmt("[t{}+{}]", imlSegment->imlList[i].op_storeLoad.registerMem, imlSegment->imlList[i].op_storeLoad.immS32);
|
strOutput.addFmt("[t{}+{}]", inst.op_storeLoad.registerMem, inst.op_storeLoad.immS32);
|
||||||
}
|
}
|
||||||
else if (imlSegment->imlList[i].type == PPCREC_IML_TYPE_MEM2MEM)
|
else if (inst.type == PPCREC_IML_TYPE_MEM2MEM)
|
||||||
{
|
{
|
||||||
strOutput.addFmt("{} [t{}+{}] = [t{}+{}]", imlSegment->imlList[i].op_mem2mem.copyWidth, imlSegment->imlList[i].op_mem2mem.dst.registerMem, imlSegment->imlList[i].op_mem2mem.dst.immS32, imlSegment->imlList[i].op_mem2mem.src.registerMem, imlSegment->imlList[i].op_mem2mem.src.immS32);
|
strOutput.addFmt("{} [t{}+{}] = [t{}+{}]", inst.op_mem2mem.copyWidth, inst.op_mem2mem.dst.registerMem, inst.op_mem2mem.dst.immS32, inst.op_mem2mem.src.registerMem, inst.op_mem2mem.src.immS32);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_CJUMP )
|
else if( inst.type == PPCREC_IML_TYPE_CJUMP )
|
||||||
{
|
{
|
||||||
if (imlSegment->imlList[i].op_conditionalJump.condition == PPCREC_JUMP_CONDITION_E)
|
if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_E)
|
||||||
strOutput.add("JE");
|
strOutput.add("JE");
|
||||||
else if (imlSegment->imlList[i].op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NE)
|
else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NE)
|
||||||
strOutput.add("JNE");
|
strOutput.add("JNE");
|
||||||
else if (imlSegment->imlList[i].op_conditionalJump.condition == PPCREC_JUMP_CONDITION_G)
|
else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_G)
|
||||||
strOutput.add("JG");
|
strOutput.add("JG");
|
||||||
else if (imlSegment->imlList[i].op_conditionalJump.condition == PPCREC_JUMP_CONDITION_GE)
|
else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_GE)
|
||||||
strOutput.add("JGE");
|
strOutput.add("JGE");
|
||||||
else if (imlSegment->imlList[i].op_conditionalJump.condition == PPCREC_JUMP_CONDITION_L)
|
else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_L)
|
||||||
strOutput.add("JL");
|
strOutput.add("JL");
|
||||||
else if (imlSegment->imlList[i].op_conditionalJump.condition == PPCREC_JUMP_CONDITION_LE)
|
else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_LE)
|
||||||
strOutput.add("JLE");
|
strOutput.add("JLE");
|
||||||
else if (imlSegment->imlList[i].op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NONE)
|
else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NONE)
|
||||||
strOutput.add("JALW"); // jump always
|
strOutput.add("JALW"); // jump always
|
||||||
else
|
else
|
||||||
cemu_assert_unimplemented();
|
cemu_assert_unimplemented();
|
||||||
strOutput.addFmt(" jm_{:08x} (cr{})", imlSegment->imlList[i].op_conditionalJump.jumpmarkAddress, imlSegment->imlList[i].crRegister);
|
strOutput.addFmt(" jm_{:08x} (cr{})", inst.op_conditionalJump.jumpmarkAddress, inst.crRegister);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_NO_OP )
|
else if( inst.type == PPCREC_IML_TYPE_NO_OP )
|
||||||
{
|
{
|
||||||
strOutput.add("NOP");
|
strOutput.add("NOP");
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_MACRO )
|
else if( inst.type == PPCREC_IML_TYPE_MACRO )
|
||||||
{
|
{
|
||||||
if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_BLR )
|
if( inst.operation == PPCREC_IML_MACRO_BLR )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO BLR 0x{:08x} cycles (depr): {}", imlSegment->imlList[i].op_macro.param, (sint32)imlSegment->imlList[i].op_macro.paramU16);
|
strOutput.addFmt("MACRO BLR 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_BLRL )
|
else if( inst.operation == PPCREC_IML_MACRO_BLRL )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO BLRL 0x{:08x} cycles (depr): {}", imlSegment->imlList[i].op_macro.param, (sint32)imlSegment->imlList[i].op_macro.paramU16);
|
strOutput.addFmt("MACRO BLRL 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_BCTR )
|
else if( inst.operation == PPCREC_IML_MACRO_BCTR )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO BCTR 0x{:08x} cycles (depr): {}", imlSegment->imlList[i].op_macro.param, (sint32)imlSegment->imlList[i].op_macro.paramU16);
|
strOutput.addFmt("MACRO BCTR 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_BCTRL )
|
else if( inst.operation == PPCREC_IML_MACRO_BCTRL )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO BCTRL 0x{:08x} cycles (depr): {}", imlSegment->imlList[i].op_macro.param, (sint32)imlSegment->imlList[i].op_macro.paramU16);
|
strOutput.addFmt("MACRO BCTRL 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_BL )
|
else if( inst.operation == PPCREC_IML_MACRO_BL )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO BL 0x{:08x} -> 0x{:08x} cycles (depr): {}", imlSegment->imlList[i].op_macro.param, imlSegment->imlList[i].op_macro.param2, (sint32)imlSegment->imlList[i].op_macro.paramU16);
|
strOutput.addFmt("MACRO BL 0x{:08x} -> 0x{:08x} cycles (depr): {}", inst.op_macro.param, inst.op_macro.param2, (sint32)inst.op_macro.paramU16);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_B_FAR )
|
else if( inst.operation == PPCREC_IML_MACRO_B_FAR )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO B_FAR 0x{:08x} -> 0x{:08x} cycles (depr): {}", imlSegment->imlList[i].op_macro.param, imlSegment->imlList[i].op_macro.param2, (sint32)imlSegment->imlList[i].op_macro.paramU16);
|
strOutput.addFmt("MACRO B_FAR 0x{:08x} -> 0x{:08x} cycles (depr): {}", inst.op_macro.param, inst.op_macro.param2, (sint32)inst.op_macro.paramU16);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_LEAVE )
|
else if( inst.operation == PPCREC_IML_MACRO_LEAVE )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO LEAVE ppc: 0x{:08x}", imlSegment->imlList[i].op_macro.param);
|
strOutput.addFmt("MACRO LEAVE ppc: 0x{:08x}", inst.op_macro.param);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_HLE )
|
else if( inst.operation == PPCREC_IML_MACRO_HLE )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO HLE ppcAddr: 0x{:08x} funcId: 0x{:08x}", imlSegment->imlList[i].op_macro.param, imlSegment->imlList[i].op_macro.param2);
|
strOutput.addFmt("MACRO HLE ppcAddr: 0x{:08x} funcId: 0x{:08x}", inst.op_macro.param, inst.op_macro.param2);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_MFTB )
|
else if( inst.operation == PPCREC_IML_MACRO_MFTB )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO MFTB ppcAddr: 0x{:08x} sprId: 0x{:08x}", imlSegment->imlList[i].op_macro.param, imlSegment->imlList[i].op_macro.param2);
|
strOutput.addFmt("MACRO MFTB ppcAddr: 0x{:08x} sprId: 0x{:08x}", inst.op_macro.param, inst.op_macro.param2);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].operation == PPCREC_IML_MACRO_COUNT_CYCLES )
|
else if( inst.operation == PPCREC_IML_MACRO_COUNT_CYCLES )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO COUNT_CYCLES cycles: {}", imlSegment->imlList[i].op_macro.param);
|
strOutput.addFmt("MACRO COUNT_CYCLES cycles: {}", inst.op_macro.param);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strOutput.addFmt("MACRO ukn operation {}", imlSegment->imlList[i].operation);
|
strOutput.addFmt("MACRO ukn operation {}", inst.operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_FPR_R_NAME )
|
else if( inst.type == PPCREC_IML_TYPE_FPR_R_NAME )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("fpr_t{} = name_{} (", imlSegment->imlList[i].op_r_name.registerIndex, imlSegment->imlList[i].op_r_name.name);
|
strOutput.addFmt("fpr_t{} = name_{} (", inst.op_r_name.registerIndex, inst.op_r_name.name);
|
||||||
if( imlSegment->imlList[i].op_r_name.name >= PPCREC_NAME_FPR0 && imlSegment->imlList[i].op_r_name.name < (PPCREC_NAME_FPR0+999) )
|
if( inst.op_r_name.name >= PPCREC_NAME_FPR0 && inst.op_r_name.name < (PPCREC_NAME_FPR0+999) )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("fpr{}", imlSegment->imlList[i].op_r_name.name-PPCREC_NAME_FPR0);
|
strOutput.addFmt("fpr{}", inst.op_r_name.name-PPCREC_NAME_FPR0);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && imlSegment->imlList[i].op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0+999) )
|
else if( inst.op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && inst.op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0+999) )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("tempFpr{}", imlSegment->imlList[i].op_r_name.name-PPCREC_NAME_TEMPORARY_FPR0);
|
strOutput.addFmt("tempFpr{}", inst.op_r_name.name-PPCREC_NAME_TEMPORARY_FPR0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strOutput.add("ukn");
|
strOutput.add("ukn");
|
||||||
strOutput.add(")");
|
strOutput.add(")");
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_FPR_NAME_R )
|
else if( inst.type == PPCREC_IML_TYPE_FPR_NAME_R )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("name_{} (", imlSegment->imlList[i].op_r_name.name);
|
strOutput.addFmt("name_{} (", inst.op_r_name.name);
|
||||||
if( imlSegment->imlList[i].op_r_name.name >= PPCREC_NAME_FPR0 && imlSegment->imlList[i].op_r_name.name < (PPCREC_NAME_FPR0+999) )
|
if( inst.op_r_name.name >= PPCREC_NAME_FPR0 && inst.op_r_name.name < (PPCREC_NAME_FPR0+999) )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("fpr{}", imlSegment->imlList[i].op_r_name.name-PPCREC_NAME_FPR0);
|
strOutput.addFmt("fpr{}", inst.op_r_name.name-PPCREC_NAME_FPR0);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && imlSegment->imlList[i].op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0+999) )
|
else if( inst.op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && inst.op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0+999) )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("tempFpr{}", imlSegment->imlList[i].op_r_name.name-PPCREC_NAME_TEMPORARY_FPR0);
|
strOutput.addFmt("tempFpr{}", inst.op_r_name.name-PPCREC_NAME_TEMPORARY_FPR0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strOutput.add("ukn");
|
strOutput.add("ukn");
|
||||||
strOutput.addFmt(") = fpr_t{}", imlSegment->imlList[i].op_r_name.registerIndex);
|
strOutput.addFmt(") = fpr_t{}", inst.op_r_name.registerIndex);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_FPR_LOAD )
|
else if( inst.type == PPCREC_IML_TYPE_FPR_LOAD )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("fpr_t{} = ", imlSegment->imlList[i].op_storeLoad.registerData);
|
strOutput.addFmt("fpr_t{} = ", inst.op_storeLoad.registerData);
|
||||||
if( imlSegment->imlList[i].op_storeLoad.flags2.signExtend )
|
if( inst.op_storeLoad.flags2.signExtend )
|
||||||
strOutput.add("S");
|
strOutput.add("S");
|
||||||
else
|
else
|
||||||
strOutput.add("U");
|
strOutput.add("U");
|
||||||
strOutput.addFmt("{} [t{}+{}] mode {}", imlSegment->imlList[i].op_storeLoad.copyWidth / 8, imlSegment->imlList[i].op_storeLoad.registerMem, imlSegment->imlList[i].op_storeLoad.immS32, imlSegment->imlList[i].op_storeLoad.mode);
|
strOutput.addFmt("{} [t{}+{}] mode {}", inst.op_storeLoad.copyWidth / 8, inst.op_storeLoad.registerMem, inst.op_storeLoad.immS32, inst.op_storeLoad.mode);
|
||||||
if (imlSegment->imlList[i].op_storeLoad.flags2.notExpanded)
|
if (inst.op_storeLoad.flags2.notExpanded)
|
||||||
{
|
{
|
||||||
strOutput.addFmt(" <No expand>");
|
strOutput.addFmt(" <No expand>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_FPR_STORE )
|
else if( inst.type == PPCREC_IML_TYPE_FPR_STORE )
|
||||||
{
|
{
|
||||||
if( imlSegment->imlList[i].op_storeLoad.flags2.signExtend )
|
if( inst.op_storeLoad.flags2.signExtend )
|
||||||
strOutput.add("S");
|
strOutput.add("S");
|
||||||
else
|
else
|
||||||
strOutput.add("U");
|
strOutput.add("U");
|
||||||
strOutput.addFmt("{} [t{}+{}]", imlSegment->imlList[i].op_storeLoad.copyWidth/8, imlSegment->imlList[i].op_storeLoad.registerMem, imlSegment->imlList[i].op_storeLoad.immS32);
|
strOutput.addFmt("{} [t{}+{}]", inst.op_storeLoad.copyWidth/8, inst.op_storeLoad.registerMem, inst.op_storeLoad.immS32);
|
||||||
strOutput.addFmt("= fpr_t{} mode {}\n", imlSegment->imlList[i].op_storeLoad.registerData, imlSegment->imlList[i].op_storeLoad.mode);
|
strOutput.addFmt("= fpr_t{} mode {}\n", inst.op_storeLoad.registerData, inst.op_storeLoad.mode);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_FPR_R_R )
|
else if( inst.type == PPCREC_IML_TYPE_FPR_R_R )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("{:-6} ", PPCRecompiler_getOpcodeDebugName(&imlSegment->imlList[i]));
|
strOutput.addFmt("{:-6} ", PPCRecompiler_getOpcodeDebugName(&inst));
|
||||||
strOutput.addFmt("fpr{:02d}, fpr{:02d}", imlSegment->imlList[i].op_fpr_r_r.registerResult, imlSegment->imlList[i].op_fpr_r_r.registerOperand);
|
strOutput.addFmt("fpr{:02d}, fpr{:02d}", inst.op_fpr_r_r.registerResult, inst.op_fpr_r_r.registerOperand);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_FPR_R_R_R_R )
|
else if( inst.type == PPCREC_IML_TYPE_FPR_R_R_R_R )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("{:-6} ", PPCRecompiler_getOpcodeDebugName(&imlSegment->imlList[i]));
|
strOutput.addFmt("{:-6} ", PPCRecompiler_getOpcodeDebugName(&inst));
|
||||||
strOutput.addFmt("fpr{:02d}, fpr{:02d}, fpr{:02d}, fpr{:02d}", imlSegment->imlList[i].op_fpr_r_r_r_r.registerResult, imlSegment->imlList[i].op_fpr_r_r_r_r.registerOperandA, imlSegment->imlList[i].op_fpr_r_r_r_r.registerOperandB, imlSegment->imlList[i].op_fpr_r_r_r_r.registerOperandC);
|
strOutput.addFmt("fpr{:02d}, fpr{:02d}, fpr{:02d}, fpr{:02d}", inst.op_fpr_r_r_r_r.registerResult, inst.op_fpr_r_r_r_r.registerOperandA, inst.op_fpr_r_r_r_r.registerOperandB, inst.op_fpr_r_r_r_r.registerOperandC);
|
||||||
}
|
}
|
||||||
else if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_FPR_R_R_R )
|
else if( inst.type == PPCREC_IML_TYPE_FPR_R_R_R )
|
||||||
{
|
{
|
||||||
strOutput.addFmt("{:-6} ", PPCRecompiler_getOpcodeDebugName(&imlSegment->imlList[i]));
|
strOutput.addFmt("{:-6} ", PPCRecompiler_getOpcodeDebugName(&inst));
|
||||||
strOutput.addFmt("fpr{:02d}, fpr{:02d}, fpr{:02d}", imlSegment->imlList[i].op_fpr_r_r_r.registerResult, imlSegment->imlList[i].op_fpr_r_r_r.registerOperandA, imlSegment->imlList[i].op_fpr_r_r_r.registerOperandB);
|
strOutput.addFmt("fpr{:02d}, fpr{:02d}, fpr{:02d}", inst.op_fpr_r_r_r.registerResult, inst.op_fpr_r_r_r.registerOperandA, inst.op_fpr_r_r_r.registerOperandB);
|
||||||
}
|
}
|
||||||
else if (imlSegment->imlList[i].type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK)
|
else if (inst.type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK)
|
||||||
{
|
{
|
||||||
strOutput.addFmt("CYCLE_CHECK jm_{:08x}\n", imlSegment->imlList[i].op_conditionalJump.jumpmarkAddress);
|
strOutput.addFmt("CYCLE_CHECK jm_{:08x}\n", inst.op_conditionalJump.jumpmarkAddress);
|
||||||
}
|
}
|
||||||
else if (imlSegment->imlList[i].type == PPCREC_IML_TYPE_CONDITIONAL_R_S32)
|
else if (inst.type == PPCREC_IML_TYPE_CONDITIONAL_R_S32)
|
||||||
{
|
{
|
||||||
strOutput.addFmt("t{} ", imlSegment->imlList[i].op_conditional_r_s32.registerIndex);
|
strOutput.addFmt("t{} ", inst.op_conditional_r_s32.registerIndex);
|
||||||
bool displayAsHex = false;
|
bool displayAsHex = false;
|
||||||
if (imlSegment->imlList[i].operation == PPCREC_IML_OP_ASSIGN)
|
if (inst.operation == PPCREC_IML_OP_ASSIGN)
|
||||||
{
|
{
|
||||||
displayAsHex = true;
|
displayAsHex = true;
|
||||||
strOutput.add("=");
|
strOutput.add("=");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strOutput.addFmt("(unknown operation CONDITIONAL_R_S32 {})", imlSegment->imlList[i].operation);
|
strOutput.addFmt("(unknown operation CONDITIONAL_R_S32 {})", inst.operation);
|
||||||
if (displayAsHex)
|
if (displayAsHex)
|
||||||
strOutput.addFmt(" 0x{:x}", imlSegment->imlList[i].op_conditional_r_s32.immS32);
|
strOutput.addFmt(" 0x{:x}", inst.op_conditional_r_s32.immS32);
|
||||||
else
|
else
|
||||||
strOutput.addFmt(" {}", imlSegment->imlList[i].op_conditional_r_s32.immS32);
|
strOutput.addFmt(" {}", inst.op_conditional_r_s32.immS32);
|
||||||
strOutput.add(" (conditional)");
|
strOutput.add(" (conditional)");
|
||||||
if (imlSegment->imlList[i].crRegister != PPC_REC_INVALID_REGISTER)
|
if (inst.crRegister != PPC_REC_INVALID_REGISTER)
|
||||||
{
|
{
|
||||||
strOutput.addFmt(" -> and update CR{}", imlSegment->imlList[i].crRegister);
|
strOutput.addFmt(" -> and update CR{}", inst.crRegister);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strOutput.addFmt("Unknown iml type {}", imlSegment->imlList[i].type);
|
strOutput.addFmt("Unknown iml type {}", inst.type);
|
||||||
}
|
}
|
||||||
debug_printf("%s", strOutput.c_str());
|
debug_printf("%s", strOutput.c_str());
|
||||||
if (printLivenessRangeInfo)
|
if (printLivenessRangeInfo)
|
||||||
|
@ -3484,25 +3485,19 @@ void PPCRecompilerIml_removeSegmentPoint(ppcRecompilerSegmentPoint_t* segmentPoi
|
||||||
*/
|
*/
|
||||||
void PPCRecompiler_pushBackIMLInstructions(PPCRecImlSegment_t* imlSegment, sint32 index, sint32 shiftBackCount)
|
void PPCRecompiler_pushBackIMLInstructions(PPCRecImlSegment_t* imlSegment, sint32 index, sint32 shiftBackCount)
|
||||||
{
|
{
|
||||||
cemu_assert(index >= 0 && index <= imlSegment->imlListCount);
|
cemu_assert_debug(index >= 0 && index <= imlSegment->imlList.size());
|
||||||
|
|
||||||
|
imlSegment->imlList.insert(imlSegment->imlList.begin() + index, shiftBackCount, {});
|
||||||
|
|
||||||
|
memset(imlSegment->imlList.data() + index, 0, sizeof(PPCRecImlInstruction_t) * shiftBackCount);
|
||||||
|
|
||||||
if (imlSegment->imlListCount + shiftBackCount > imlSegment->imlListSize)
|
|
||||||
{
|
|
||||||
sint32 newSize = imlSegment->imlListCount + shiftBackCount + std::max(2, imlSegment->imlListSize/2);
|
|
||||||
imlSegment->imlList = (PPCRecImlInstruction_t*)realloc(imlSegment->imlList, sizeof(PPCRecImlInstruction_t)*newSize);
|
|
||||||
imlSegment->imlListSize = newSize;
|
|
||||||
}
|
|
||||||
for (sint32 i = (sint32)imlSegment->imlListCount - 1; i >= index; i--)
|
|
||||||
{
|
|
||||||
memcpy(imlSegment->imlList + (i + shiftBackCount), imlSegment->imlList + i, sizeof(PPCRecImlInstruction_t));
|
|
||||||
}
|
|
||||||
// fill empty space with NOP instructions
|
// fill empty space with NOP instructions
|
||||||
for (sint32 i = 0; i < shiftBackCount; i++)
|
for (sint32 i = 0; i < shiftBackCount; i++)
|
||||||
{
|
{
|
||||||
imlSegment->imlList[index + i].type = PPCREC_IML_TYPE_NONE;
|
imlSegment->imlList[index + i].type = PPCREC_IML_TYPE_NONE;
|
||||||
}
|
}
|
||||||
imlSegment->imlListCount += shiftBackCount;
|
|
||||||
|
|
||||||
|
// update position of segment points
|
||||||
if (imlSegment->segmentPointList)
|
if (imlSegment->segmentPointList)
|
||||||
{
|
{
|
||||||
ppcRecompilerSegmentPoint_t* segmentPoint = imlSegment->segmentPointList;
|
ppcRecompilerSegmentPoint_t* segmentPoint = imlSegment->segmentPointList;
|
||||||
|
@ -3519,32 +3514,18 @@ void PPCRecompiler_pushBackIMLInstructions(PPCRecImlSegment_t* imlSegment, sint3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Insert and return new instruction at index
|
|
||||||
* Warning: Can invalidate any previous instruction structs from the same segment
|
|
||||||
*/
|
|
||||||
PPCRecImlInstruction_t* PPCRecompiler_insertInstruction(PPCRecImlSegment_t* imlSegment, sint32 index)
|
PPCRecImlInstruction_t* PPCRecompiler_insertInstruction(PPCRecImlSegment_t* imlSegment, sint32 index)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, index, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, index, 1);
|
||||||
return imlSegment->imlList + index;
|
return imlSegment->imlList.data() + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Append and return new instruction at the end of the segment
|
|
||||||
* Warning: Can invalidate any previous instruction structs from the same segment
|
|
||||||
*/
|
|
||||||
PPCRecImlInstruction_t* PPCRecompiler_appendInstruction(PPCRecImlSegment_t* imlSegment)
|
PPCRecImlInstruction_t* PPCRecompiler_appendInstruction(PPCRecImlSegment_t* imlSegment)
|
||||||
{
|
{
|
||||||
sint32 index = imlSegment->imlListCount;
|
size_t index = imlSegment->imlList.size();
|
||||||
if (index >= imlSegment->imlListSize)
|
imlSegment->imlList.emplace_back();
|
||||||
{
|
memset(imlSegment->imlList.data() + index, 0, sizeof(PPCRecImlInstruction_t));
|
||||||
sint32 newSize = index+1;
|
return imlSegment->imlList.data() + index;
|
||||||
imlSegment->imlList = (PPCRecImlInstruction_t*)realloc(imlSegment->imlList, sizeof(PPCRecImlInstruction_t)*newSize);
|
|
||||||
imlSegment->imlListSize = newSize;
|
|
||||||
}
|
|
||||||
imlSegment->imlListCount++;
|
|
||||||
memset(imlSegment->imlList + index, 0, sizeof(PPCRecImlInstruction_t));
|
|
||||||
return imlSegment->imlList + index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCRecImlSegment_t* PPCRecompilerIml_appendSegment(ppcImlGenContext_t* ppcImlGenContext)
|
PPCRecImlSegment_t* PPCRecompilerIml_appendSegment(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
|
@ -3571,7 +3552,7 @@ void PPCRecompiler_freeContext(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
|
|
||||||
for (PPCRecImlSegment_t* imlSegment : ppcImlGenContext->segmentList2)
|
for (PPCRecImlSegment_t* imlSegment : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
free(imlSegment->imlList);
|
//free(imlSegment->imlList);
|
||||||
delete imlSegment;
|
delete imlSegment;
|
||||||
}
|
}
|
||||||
ppcImlGenContext->segmentList2.clear();
|
ppcImlGenContext->segmentList2.clear();
|
||||||
|
@ -4637,31 +4618,37 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
uint32 imlCount = segIt->count;
|
uint32 imlCount = segIt->count;
|
||||||
if( imlCount > 0 )
|
if( imlCount > 0 )
|
||||||
{
|
{
|
||||||
segIt->imlListSize = imlCount + 4;
|
//segIt->imlListSize = imlCount + 4;
|
||||||
segIt->imlList = (PPCRecImlInstruction_t*)malloc(sizeof(PPCRecImlInstruction_t)* segIt->imlListSize);
|
//segIt->imlList = (PPCRecImlInstruction_t*)malloc(sizeof(PPCRecImlInstruction_t) * segIt->imlListSize);
|
||||||
segIt->imlListCount = imlCount;
|
//segIt->imlListCount = imlCount;
|
||||||
memcpy(segIt->imlList, ppcImlGenContext.imlList+imlStartIndex, sizeof(PPCRecImlInstruction_t)*imlCount);
|
//memcpy(segIt->imlList, ppcImlGenContext.imlList+imlStartIndex, sizeof(PPCRecImlInstruction_t)*imlCount);
|
||||||
|
cemu_assert_debug(segIt->imlList.empty());
|
||||||
|
//segIt->imlList.resize(imlCount);
|
||||||
|
//segIt->imlList.insert(segIt->imlList.begin() + imlStartIndex, );
|
||||||
|
segIt->imlList.insert(segIt->imlList.begin(), ppcImlGenContext.imlList + imlStartIndex, ppcImlGenContext.imlList + imlStartIndex + imlCount);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// empty segments are allowed so we can handle multiple PPC entry addresses pointing to the same code
|
// empty segments are allowed so we can handle multiple PPC entry addresses pointing to the same code
|
||||||
segIt->imlList = nullptr;
|
cemu_assert_debug(segIt->imlList.empty());
|
||||||
segIt->imlListSize = 0;
|
//segIt->imlList = nullptr;
|
||||||
segIt->imlListCount = 0;
|
//segIt->imlListSize = 0;
|
||||||
|
//segIt->imlListCount = 0;
|
||||||
}
|
}
|
||||||
segIt->startOffset = 9999999;
|
segIt->startOffset = 9999999;
|
||||||
segIt->count = 9999999;
|
segIt->count = 9999999;
|
||||||
}
|
}
|
||||||
// clear segment-independent iml list
|
// clear segment-independent iml list
|
||||||
free(ppcImlGenContext.imlList);
|
free(ppcImlGenContext.imlList);
|
||||||
ppcImlGenContext.imlList = NULL;
|
ppcImlGenContext.imlList = nullptr;
|
||||||
ppcImlGenContext.imlListCount = 999999; // set to high number to force crash in case old code still uses ppcImlGenContext.imlList
|
ppcImlGenContext.imlListCount = 999999; // set to high number to force crash in case old code still uses ppcImlGenContext.imlList
|
||||||
// calculate PPC address of each segment based on iml instructions inside that segment (we need this info to calculate how many cpu cycles each segment takes)
|
// calculate PPC address of each segment based on iml instructions inside that segment (we need this info to calculate how many cpu cycles each segment takes)
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
uint32 segmentPPCAddrMin = 0xFFFFFFFF;
|
uint32 segmentPPCAddrMin = 0xFFFFFFFF;
|
||||||
uint32 segmentPPCAddrMax = 0x00000000;
|
uint32 segmentPPCAddrMax = 0x00000000;
|
||||||
for(sint32 i=0; i< segIt->imlListCount; i++)
|
for(sint32 i=0; i< segIt->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
if(segIt->imlList[i].associatedPPCAddress == 0 )
|
if(segIt->imlList[i].associatedPPCAddress == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
@ -4686,7 +4673,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
// jumpmarks mark the segment as a jump destination (within the same function)
|
// jumpmarks mark the segment as a jump destination (within the same function)
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
while (segIt->imlListCount > 0)
|
while (segIt->imlList.size() > 0)
|
||||||
{
|
{
|
||||||
if (segIt->imlList[0].type == PPCREC_IML_TYPE_PPC_ENTER)
|
if (segIt->imlList[0].type == PPCREC_IML_TYPE_PPC_ENTER)
|
||||||
{
|
{
|
||||||
|
@ -4735,7 +4722,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
PPCRecImlSegment_t* finalSegment = segIt->nextSegmentBranchTaken;
|
PPCRecImlSegment_t* finalSegment = segIt->nextSegmentBranchTaken;
|
||||||
if (segIt->nextSegmentBranchTaken != segIt->nextSegmentBranchNotTaken->nextSegmentBranchNotTaken)
|
if (segIt->nextSegmentBranchTaken != segIt->nextSegmentBranchNotTaken->nextSegmentBranchNotTaken)
|
||||||
continue;
|
continue;
|
||||||
if (segIt->nextSegmentBranchNotTaken->imlListCount > 4)
|
if (segIt->nextSegmentBranchNotTaken->imlList.size() > 4)
|
||||||
continue;
|
continue;
|
||||||
if (conditionalSegment->list_prevSegments.size() != 1)
|
if (conditionalSegment->list_prevSegments.size() != 1)
|
||||||
continue; // the reduced segment must not be the target of any other branch
|
continue; // the reduced segment must not be the target of any other branch
|
||||||
|
@ -4743,9 +4730,9 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
continue;
|
continue;
|
||||||
// check if the segment contains only iml instructions that can be turned into conditional moves (Value assignment, register assignment)
|
// check if the segment contains only iml instructions that can be turned into conditional moves (Value assignment, register assignment)
|
||||||
bool canReduceSegment = true;
|
bool canReduceSegment = true;
|
||||||
for (sint32 f = 0; f < conditionalSegment->imlListCount; f++)
|
for (sint32 f = 0; f < conditionalSegment->imlList.size(); f++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = conditionalSegment->imlList+f;
|
PPCRecImlInstruction_t* imlInstruction = conditionalSegment->imlList.data() + f;
|
||||||
if( imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
if( imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
||||||
continue;
|
continue;
|
||||||
// todo: Register to register copy
|
// todo: Register to register copy
|
||||||
|
@ -4764,9 +4751,9 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
PPCRecompilerImlGen_generateNewInstruction_noOp(&ppcImlGenContext, lastInstruction);
|
PPCRecompilerImlGen_generateNewInstruction_noOp(&ppcImlGenContext, lastInstruction);
|
||||||
|
|
||||||
// append conditional moves based on branch condition
|
// append conditional moves based on branch condition
|
||||||
for (sint32 f = 0; f < conditionalSegment->imlListCount; f++)
|
for (sint32 f = 0; f < conditionalSegment->imlList.size(); f++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = conditionalSegment->imlList + f;
|
PPCRecImlInstruction_t* imlInstruction = conditionalSegment->imlList.data() + f;
|
||||||
if (imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
if (imlInstruction->type == PPCREC_IML_TYPE_R_S32 && imlInstruction->operation == PPCREC_IML_OP_ASSIGN)
|
||||||
PPCRecompilerImlGen_generateNewInstruction_conditional_r_s32(&ppcImlGenContext, PPCRecompiler_appendInstruction(segIt), PPCREC_IML_OP_ASSIGN, imlInstruction->op_r_immS32.registerIndex, imlInstruction->op_r_immS32.immS32, branchCond_crRegisterIndex, branchCond_crBitIndex, !branchCond_bitMustBeSet);
|
PPCRecompilerImlGen_generateNewInstruction_conditional_r_s32(&ppcImlGenContext, PPCRecompiler_appendInstruction(segIt), PPCREC_IML_OP_ASSIGN, imlInstruction->op_r_immS32.registerIndex, imlInstruction->op_r_immS32.immS32, branchCond_crRegisterIndex, branchCond_crBitIndex, !branchCond_bitMustBeSet);
|
||||||
else
|
else
|
||||||
|
@ -4779,7 +4766,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
PPCRecompilerIML_removeLink(conditionalSegment, finalSegment);
|
PPCRecompilerIML_removeLink(conditionalSegment, finalSegment);
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(segIt, finalSegment);
|
PPCRecompilerIml_setLinkBranchNotTaken(segIt, finalSegment);
|
||||||
// remove all instructions from conditional segment
|
// remove all instructions from conditional segment
|
||||||
conditionalSegment->imlListCount = 0;
|
conditionalSegment->imlList.clear();
|
||||||
|
|
||||||
// if possible, merge imlSegment with finalSegment
|
// if possible, merge imlSegment with finalSegment
|
||||||
if (finalSegment->isEnterable == false && finalSegment->list_prevSegments.size() == 1)
|
if (finalSegment->isEnterable == false && finalSegment->list_prevSegments.size() == 1)
|
||||||
|
@ -4799,11 +4786,12 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
PPCRecompilerIml_setLinkBranchTaken(segIt, tempSegment);
|
PPCRecompilerIml_setLinkBranchTaken(segIt, tempSegment);
|
||||||
}
|
}
|
||||||
// copy IML instructions
|
// copy IML instructions
|
||||||
for (sint32 f = 0; f < finalSegment->imlListCount; f++)
|
cemu_assert_debug(segIt != finalSegment);
|
||||||
|
for (sint32 f = 0; f < finalSegment->imlList.size(); f++)
|
||||||
{
|
{
|
||||||
memcpy(PPCRecompiler_appendInstruction(segIt), finalSegment->imlList + f, sizeof(PPCRecImlInstruction_t));
|
memcpy(PPCRecompiler_appendInstruction(segIt), finalSegment->imlList.data() + f, sizeof(PPCRecImlInstruction_t));
|
||||||
}
|
}
|
||||||
finalSegment->imlListCount = 0;
|
finalSegment->imlList.clear();
|
||||||
|
|
||||||
//PPCRecompiler_dumpIML(ppcRecFunc, &ppcImlGenContext);
|
//PPCRecompiler_dumpIML(ppcRecFunc, &ppcImlGenContext);
|
||||||
}
|
}
|
||||||
|
@ -4820,7 +4808,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
// note: This algorithm correctly counts inlined functions but it doesn't count NO-OP instructions like ISYNC since they generate no IML instructions
|
// note: This algorithm correctly counts inlined functions but it doesn't count NO-OP instructions like ISYNC since they generate no IML instructions
|
||||||
uint32 lastPPCInstAddr = 0;
|
uint32 lastPPCInstAddr = 0;
|
||||||
uint32 ppcCount2 = 0;
|
uint32 ppcCount2 = 0;
|
||||||
for (sint32 i = 0; i < segIt->imlListCount; i++)
|
for (sint32 i = 0; i < segIt->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
if (segIt->imlList[i].associatedPPCAddress == 0)
|
if (segIt->imlList[i].associatedPPCAddress == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -4849,11 +4837,11 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
{
|
{
|
||||||
// todo: This currently uses segment->ppcAddrMin which isn't really reliable. (We already had a problem where function inlining would generate falsified segment ranges by omitting the branch instruction). Find a better solution (use jumpmark/enterable offsets?)
|
// todo: This currently uses segment->ppcAddrMin which isn't really reliable. (We already had a problem where function inlining would generate falsified segment ranges by omitting the branch instruction). Find a better solution (use jumpmark/enterable offsets?)
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext.segmentList2[s];
|
PPCRecImlSegment_t* imlSegment = ppcImlGenContext.segmentList2[s];
|
||||||
if( imlSegment->imlListCount == 0 )
|
if( imlSegment->imlList.empty() )
|
||||||
continue;
|
continue;
|
||||||
if (imlSegment->imlList[imlSegment->imlListCount - 1].type != PPCREC_IML_TYPE_CJUMP || imlSegment->imlList[imlSegment->imlListCount - 1].op_conditionalJump.jumpmarkAddress > imlSegment->ppcAddrMin)
|
if (imlSegment->imlList[imlSegment->imlList.size() - 1].type != PPCREC_IML_TYPE_CJUMP || imlSegment->imlList[imlSegment->imlList.size() - 1].op_conditionalJump.jumpmarkAddress > imlSegment->ppcAddrMin)
|
||||||
continue;
|
continue;
|
||||||
if (imlSegment->imlList[imlSegment->imlListCount - 1].type != PPCREC_IML_TYPE_CJUMP || imlSegment->imlList[imlSegment->imlListCount - 1].op_conditionalJump.jumpAccordingToSegment)
|
if (imlSegment->imlList[imlSegment->imlList.size() - 1].type != PPCREC_IML_TYPE_CJUMP || imlSegment->imlList[imlSegment->imlList.size() - 1].op_conditionalJump.jumpAccordingToSegment)
|
||||||
continue;
|
continue;
|
||||||
// exclude non-infinite tight loops
|
// exclude non-infinite tight loops
|
||||||
if (PPCRecompilerImlAnalyzer_isTightFiniteLoop(imlSegment))
|
if (PPCRecompilerImlAnalyzer_isTightFiniteLoop(imlSegment))
|
||||||
|
@ -4929,7 +4917,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
imlSegmentP0->imlList[0].associatedPPCAddress = imlSegmentP0->ppcAddrMin;
|
imlSegmentP0->imlList[0].associatedPPCAddress = imlSegmentP0->ppcAddrMin;
|
||||||
// jump instruction for PEntry
|
// jump instruction for PEntry
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegmentPEntry, 0, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegmentPEntry, 0, 1);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_jumpSegment(&ppcImlGenContext, imlSegmentPEntry->imlList + 0);
|
PPCRecompilerImlGen_generateNewInstruction_jumpSegment(&ppcImlGenContext, imlSegmentPEntry->imlList.data() + 0);
|
||||||
|
|
||||||
// skip the newly created segments
|
// skip the newly created segments
|
||||||
s += 2;
|
s += 2;
|
||||||
|
@ -4953,13 +4941,13 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
|
||||||
// insert name store instructions at the end of each segment but before branch instructions
|
// insert name store instructions at the end of each segment but before branch instructions
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
for (PPCRecImlSegment_t* segIt : ppcImlGenContext.segmentList2)
|
||||||
{
|
{
|
||||||
if(segIt->imlListCount == 0 )
|
if(segIt->imlList.size() == 0 )
|
||||||
continue; // ignore empty segments
|
continue; // ignore empty segments
|
||||||
// analyze segment for register usage
|
// analyze segment for register usage
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
for(sint32 i=0; i<segIt->imlListCount; i++)
|
for(sint32 i=0; i<segIt->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
PPCRecompiler_checkRegisterUsage(&ppcImlGenContext, segIt->imlList+i, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(&ppcImlGenContext, segIt->imlList.data() + i, ®istersUsed);
|
||||||
//PPCRecompilerImlGen_findRegisterByMappedName(ppcImlGenContext, registersUsed.readGPR1);
|
//PPCRecompilerImlGen_findRegisterByMappedName(ppcImlGenContext, registersUsed.readGPR1);
|
||||||
sint32 accessedTempReg[5];
|
sint32 accessedTempReg[5];
|
||||||
// intermediate FPRs
|
// intermediate FPRs
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "PPCRecompilerIml.h"
|
#include "PPCRecompilerIml.h"
|
||||||
#include "PPCRecompilerX64.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->readNamedReg1 = -1;
|
||||||
registersUsed->readNamedReg2 = -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)
|
bool PPCRecompiler_findAvailableRegisterDepr(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 imlIndexStart, replacedRegisterTracker_t* replacedRegisterTracker, sint32* registerIndex, sint32* registerName, bool* isUsed)
|
||||||
{
|
{
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList+imlIndexStart, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &imlSegment->imlList[imlIndexStart], ®istersUsed);
|
||||||
// mask all registers used by this instruction
|
// mask all registers used by this instruction
|
||||||
uint32 instructionReservedRegisterMask = 0;//(1<<(PPC_X64_GPR_USABLE_REGISTERS+1))-1;
|
uint32 instructionReservedRegisterMask = 0;//(1<<(PPC_X64_GPR_USABLE_REGISTERS+1))-1;
|
||||||
if( registersUsed.readNamedReg1 != -1 )
|
if( registersUsed.readNamedReg1 != -1 )
|
||||||
|
@ -957,20 +957,20 @@ bool PPCRecompiler_findAvailableRegisterDepr(ppcImlGenContext_t* ppcImlGenContex
|
||||||
|
|
||||||
bool PPCRecompiler_hasSuffixInstruction(PPCRecImlSegment_t* imlSegment)
|
bool PPCRecompiler_hasSuffixInstruction(PPCRecImlSegment_t* imlSegment)
|
||||||
{
|
{
|
||||||
if( imlSegment->imlListCount == 0 )
|
if (imlSegment->imlList.empty())
|
||||||
return false;
|
return false;
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+imlSegment->imlListCount-1;
|
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) ||
|
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_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_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_BLRL ||
|
||||||
imlInstruction->type == PPCREC_IML_TYPE_MACRO && imlInstruction->operation == PPCREC_IML_MACRO_BCTRL ||
|
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_LEAVE ||
|
||||||
imlInstruction->type == PPCREC_IML_TYPE_MACRO && imlInstruction->operation == PPCREC_IML_MACRO_HLE ||
|
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_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_MFTB ||
|
||||||
imlInstruction->type == PPCREC_IML_TYPE_PPC_ENTER ||
|
imlInstruction.type == PPCREC_IML_TYPE_PPC_ENTER ||
|
||||||
imlInstruction->type == PPCREC_IML_TYPE_CJUMP ||
|
imlInstruction.type == PPCREC_IML_TYPE_CJUMP ||
|
||||||
imlInstruction->type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK )
|
imlInstruction.type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK )
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -981,29 +981,29 @@ void PPCRecompiler_storeReplacedRegister(ppcImlGenContext_t* ppcImlGenContext, P
|
||||||
sint32 imlIndexEdit = *imlIndex;
|
sint32 imlIndexEdit = *imlIndex;
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
||||||
// name_unusedRegister = unusedRegister
|
// name_unusedRegister = unusedRegister
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList+(imlIndexEdit+0);
|
PPCRecImlInstruction_t& imlInstructionItr = imlSegment->imlList[imlIndexEdit + 0];
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(&imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_NAME_R;
|
imlInstructionItr.type = PPCREC_IML_TYPE_NAME_R;
|
||||||
imlInstructionItr->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstructionItr.crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr.operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].index;
|
imlInstructionItr.op_r_name.registerIndex = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].index;
|
||||||
imlInstructionItr->op_r_name.name = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].registerNewName;
|
imlInstructionItr.op_r_name.name = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].registerNewName;
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
imlInstructionItr.op_r_name.copyWidth = 32;
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
imlInstructionItr.op_r_name.flags = 0;
|
||||||
imlIndexEdit++;
|
imlIndexEdit++;
|
||||||
// load new register if required
|
// load new register if required
|
||||||
if( replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].nameMustBeMaintained )
|
if( replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].nameMustBeMaintained )
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, imlIndexEdit, 1);
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList+(imlIndexEdit+0);
|
PPCRecImlInstruction_t& imlInstructionItr = imlSegment->imlList[imlIndexEdit];
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(&imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_R_NAME;
|
imlInstructionItr.type = PPCREC_IML_TYPE_R_NAME;
|
||||||
imlInstructionItr->crRegister = PPC_REC_INVALID_REGISTER;
|
imlInstructionItr.crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr.operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].index;
|
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.name = replacedRegisterTracker->replacedRegisterEntry[registerTrackerIndex].registerPreviousName;//ppcImlGenContext->mappedRegister[replacedRegisterTracker.replacedRegisterEntry[i].index];
|
||||||
imlInstructionItr->op_r_name.copyWidth = 32;
|
imlInstructionItr.op_r_name.copyWidth = 32;
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
imlInstructionItr.op_r_name.flags = 0;
|
||||||
imlIndexEdit += 1;
|
imlIndexEdit += 1;
|
||||||
}
|
}
|
||||||
// move last entry to current one
|
// 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
|
// first we remove all name load and store instructions that involve out-of-bounds registers
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
sint32 imlIndex = 0;
|
size_t imlIndex = 0;
|
||||||
while( imlIndex < segIt->imlListCount )
|
while( imlIndex < segIt->imlList.size() )
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = segIt->imlList+imlIndex;
|
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.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
|
// convert to NO-OP instruction
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_NO_OP;
|
imlInstructionItr.type = PPCREC_IML_TYPE_NO_OP;
|
||||||
imlInstructionItr->associatedPPCAddress = 0;
|
imlInstructionItr.associatedPPCAddress = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imlIndex++;
|
imlIndex++;
|
||||||
|
@ -1040,13 +1040,13 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
||||||
// replace registers
|
// replace registers
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
sint32 imlIndex = 0;
|
size_t imlIndex = 0;
|
||||||
while( imlIndex < segIt->imlListCount )
|
while( imlIndex < segIt->imlList.size() )
|
||||||
{
|
{
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
while( true )
|
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 )
|
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
|
// get index of register to replace
|
||||||
|
@ -1092,13 +1092,13 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
||||||
replacedRegisterIsUsed = segIt->ppcFPRUsed[unusedRegisterName-PPCREC_NAME_FPR0];
|
replacedRegisterIsUsed = segIt->ppcFPRUsed[unusedRegisterName-PPCREC_NAME_FPR0];
|
||||||
}
|
}
|
||||||
// replace registers that are out of range
|
// 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
|
// add load/store name after instruction
|
||||||
PPCRecompiler_pushBackIMLInstructions(segIt, imlIndex+1, 2);
|
PPCRecompiler_pushBackIMLInstructions(segIt, imlIndex+1, 2);
|
||||||
// add load/store before current instruction
|
// add load/store before current instruction
|
||||||
PPCRecompiler_pushBackIMLInstructions(segIt, imlIndex, 2);
|
PPCRecompiler_pushBackIMLInstructions(segIt, imlIndex, 2);
|
||||||
// name_unusedRegister = unusedRegister
|
// name_unusedRegister = unusedRegister
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = segIt->imlList+(imlIndex+0);
|
PPCRecImlInstruction_t* imlInstructionItr = segIt->imlList.data() + (imlIndex + 0);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
if( replacedRegisterIsUsed )
|
if( replacedRegisterIsUsed )
|
||||||
{
|
{
|
||||||
|
@ -1111,7 +1111,7 @@ bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenConte
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_NO_OP;
|
imlInstructionItr->type = PPCREC_IML_TYPE_NO_OP;
|
||||||
imlInstructionItr = segIt->imlList+(imlIndex+1);
|
imlInstructionItr = segIt->imlList.data() + (imlIndex + 1);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
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.copyWidth = 32;
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
imlInstructionItr->op_r_name.flags = 0;
|
||||||
// name_gprToReplace = unusedRegister
|
// name_gprToReplace = unusedRegister
|
||||||
imlInstructionItr = segIt->imlList+(imlIndex+3);
|
imlInstructionItr = segIt->imlList.data() + (imlIndex + 3);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
imlInstructionItr->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
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.copyWidth = 32;
|
||||||
imlInstructionItr->op_r_name.flags = 0;
|
imlInstructionItr->op_r_name.flags = 0;
|
||||||
// unusedRegister = name_unusedRegister
|
// unusedRegister = name_unusedRegister
|
||||||
imlInstructionItr = segIt->imlList+(imlIndex+4);
|
imlInstructionItr = segIt->imlList.data() + (imlIndex + 4);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
if( replacedRegisterIsUsed )
|
if( replacedRegisterIsUsed )
|
||||||
{
|
{
|
||||||
|
@ -1222,14 +1222,15 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
||||||
for (sint32 i = 0; i < 64; i++)
|
for (sint32 i = 0; i < 64; i++)
|
||||||
rCtx.ppcRegToMapping[i] = -1;
|
rCtx.ppcRegToMapping[i] = -1;
|
||||||
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[segmentIndex];
|
PPCRecImlSegment_t* imlSegment = ppcImlGenContext->segmentList2[segmentIndex];
|
||||||
sint32 idx = 0;
|
size_t idx = 0;
|
||||||
sint32 currentUseIndex = 0;
|
sint32 currentUseIndex = 0;
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
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;
|
break;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList + idx, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &idxInst, ®istersUsed);
|
||||||
sint32 fprMatch[4];
|
sint32 fprMatch[4];
|
||||||
sint32 fprReplace[4];
|
sint32 fprReplace[4];
|
||||||
fprMatch[0] = -1;
|
fprMatch[0] = -1;
|
||||||
|
@ -1276,7 +1277,7 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
||||||
unloadLockedMask |= (1<<(unloadRegMapping- rCtx.currentMapping));
|
unloadLockedMask |= (1<<(unloadRegMapping- rCtx.currentMapping));
|
||||||
// create unload instruction
|
// create unload instruction
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
||||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList + idx;
|
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
||||||
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||||
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
|
@ -1294,7 +1295,7 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
||||||
}
|
}
|
||||||
// create load instruction
|
// create load instruction
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, idx, 1);
|
||||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList + idx;
|
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
||||||
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_R_NAME;
|
||||||
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
|
@ -1336,7 +1337,7 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
||||||
}
|
}
|
||||||
if (numReplacedOperands > 0)
|
if (numReplacedOperands > 0)
|
||||||
{
|
{
|
||||||
PPCRecompiler_replaceFPRRegisterUsageMultiple(ppcImlGenContext, imlSegment->imlList + idx, fprMatch, fprReplace);
|
PPCRecompiler_replaceFPRRegisterUsageMultiple(ppcImlGenContext, imlSegment->imlList.data() + idx, fprMatch, fprReplace);
|
||||||
}
|
}
|
||||||
// next
|
// next
|
||||||
idx++;
|
idx++;
|
||||||
|
@ -1356,7 +1357,7 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon
|
||||||
{
|
{
|
||||||
if (rCtx.currentMapping[i].isActive == false)
|
if (rCtx.currentMapping[i].isActive == false)
|
||||||
continue;
|
continue;
|
||||||
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList + idx;
|
PPCRecImlInstruction_t* imlInstructionTemp = imlSegment->imlList.data() + idx;
|
||||||
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionTemp, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
imlInstructionTemp->type = PPCREC_IML_TYPE_FPR_NAME_R;
|
||||||
imlInstructionTemp->operation = PPCREC_IML_OP_ASSIGN;
|
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)
|
bool PPCRecompiler_trackRedundantNameLoadInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
||||||
{
|
{
|
||||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
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
|
//nameStoreInstruction->op_r_name.registerIndex
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
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 )
|
if( registersUsed.readNamedReg1 == registerIndex || registersUsed.readNamedReg2 == registerIndex || registersUsed.readNamedReg3 == registerIndex )
|
||||||
return false;
|
return false;
|
||||||
if( registersUsed.writtenNamedReg1 == registerIndex )
|
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)
|
bool PPCRecompiler_trackRedundantFPRNameLoadInstruction(ppcImlGenContext_t* ppcImlGenContext, PPCRecImlSegment_t* imlSegment, sint32 startIndex, PPCRecImlInstruction_t* nameStoreInstruction, sint32 scanDepth)
|
||||||
{
|
{
|
||||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
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;
|
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)
|
if( registersUsed.readFPR1 == registerIndex || registersUsed.readFPR2 == registerIndex || registersUsed.readFPR3 == registerIndex || registersUsed.readFPR4 == registerIndex)
|
||||||
return false;
|
return false;
|
||||||
if( registersUsed.writtenFPR1 == registerIndex )
|
if( registersUsed.writtenFPR1 == registerIndex )
|
||||||
|
@ -1430,9 +1431,9 @@ bool PPCRecompiler_trackRedundantNameStoreInstruction(ppcImlGenContext_t* ppcIml
|
||||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||||
for(sint32 i=startIndex; i>=0; i--)
|
for(sint32 i=startIndex; i>=0; i--)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+i;
|
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList+i, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||||
if( registersUsed.writtenNamedReg1 == registerIndex )
|
if( registersUsed.writtenNamedReg1 == registerIndex )
|
||||||
{
|
{
|
||||||
if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_NAME )
|
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)
|
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;
|
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;
|
const PPCRecImlInstruction_t& imlInstruction = imlSegment->imlList[i];
|
||||||
if( imlSegment->imlList[i].type == PPCREC_IML_TYPE_R_NAME )
|
if(imlInstruction.type == PPCREC_IML_TYPE_R_NAME )
|
||||||
{
|
{
|
||||||
// name is loaded before being written
|
// name is loaded before being written
|
||||||
if( imlSegment->imlList[i].op_r_name.name == name )
|
if (imlInstruction.op_r_name.name == name)
|
||||||
return false;
|
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
|
// name is written before being loaded
|
||||||
if( imlSegment->imlList[i].op_r_name.name == name )
|
if (imlInstruction.op_r_name.name == name)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1476,7 +1476,7 @@ bool PPCRecompiler_trackOverwrittenNameStoreInstruction(ppcImlGenContext_t* ppcI
|
||||||
return false;
|
return false;
|
||||||
if( imlSegment->nextSegmentBranchNotTaken && PPCRecompiler_trackOverwrittenNameStoreInstruction(ppcImlGenContext, imlSegment->nextSegmentBranchNotTaken, 0, nameStoreInstruction, scanDepth+1) == false )
|
if( imlSegment->nextSegmentBranchNotTaken && PPCRecompiler_trackOverwrittenNameStoreInstruction(ppcImlGenContext, imlSegment->nextSegmentBranchNotTaken, 0, nameStoreInstruction, scanDepth+1) == false )
|
||||||
return false;
|
return false;
|
||||||
if( imlSegment->nextSegmentBranchTaken == NULL && imlSegment->nextSegmentBranchNotTaken == NULL )
|
if( imlSegment->nextSegmentBranchTaken == nullptr && imlSegment->nextSegmentBranchNotTaken == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1490,12 +1490,12 @@ bool PPCRecompiler_trackRedundantFPRNameStoreInstruction(ppcImlGenContext_t* ppc
|
||||||
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
sint16 registerIndex = nameStoreInstruction->op_r_name.registerIndex;
|
||||||
for(sint32 i=startIndex; i>=0; i--)
|
for(sint32 i=startIndex; i>=0; i--)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+i;
|
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlSegment->imlList+i, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||||
if( registersUsed.writtenFPR1 == registerIndex )
|
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 true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1568,60 +1568,59 @@ void PPCRecompiler_removeRedundantCRUpdates(ppcImlGenContext_t* ppcImlGenContext
|
||||||
{
|
{
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
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 (instIt.type == PPCREC_IML_TYPE_CJUMP)
|
||||||
if (imlInstruction->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->crBitsInput |= (crBitFlag&~segIt->crBitsWritten); // flag bits that have not already been written
|
||||||
segIt->crBitsRead |= (crBitFlag);
|
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->crBitsInput |= (crBitFlag&~segIt->crBitsWritten); // flag bits that have not already been written
|
||||||
segIt->crBitsRead |= (crBitFlag);
|
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;
|
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 ||
|
if (instIt.operation == PPCREC_IML_OP_CR_CLEAR ||
|
||||||
imlInstruction->operation == PPCREC_IML_OP_CR_SET)
|
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);
|
segIt->crBitsWritten |= (crBitFlag & ~segIt->crBitsWritten);
|
||||||
}
|
}
|
||||||
else if (imlInstruction->operation == PPCREC_IML_OP_CR_OR ||
|
else if (instIt.operation == PPCREC_IML_OP_CR_OR ||
|
||||||
imlInstruction->operation == PPCREC_IML_OP_CR_ORC ||
|
instIt.operation == PPCREC_IML_OP_CR_ORC ||
|
||||||
imlInstruction->operation == PPCREC_IML_OP_CR_AND ||
|
instIt.operation == PPCREC_IML_OP_CR_AND ||
|
||||||
imlInstruction->operation == PPCREC_IML_OP_CR_ANDC)
|
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);
|
segIt->crBitsWritten |= (crBitFlag & ~segIt->crBitsWritten);
|
||||||
crBitFlag = 1 << (imlInstruction->op_cr.crA);
|
crBitFlag = 1 << (instIt.op_cr.crA);
|
||||||
segIt->crBitsRead |= (crBitFlag & ~segIt->crBitsRead);
|
segIt->crBitsRead |= (crBitFlag & ~segIt->crBitsRead);
|
||||||
crBitFlag = 1 << (imlInstruction->op_cr.crB);
|
crBitFlag = 1 << (instIt.op_cr.crB);
|
||||||
segIt->crBitsRead |= (crBitFlag & ~segIt->crBitsRead);
|
segIt->crBitsRead |= (crBitFlag & ~segIt->crBitsRead);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cemu_assert_unimplemented();
|
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
|
// overwrites CR0
|
||||||
segIt->crBitsWritten |= (0xF<<0);
|
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
|
// flag instructions that write to CR where we can ignore individual CR bits
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
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(&instIt) && instIt.crRegister >= 0 && instIt.crRegister <= 7 )
|
||||||
if( PPCRecompilerImlAnalyzer_canTypeWriteCR(imlInstruction) && imlInstruction->crRegister >= 0 && imlInstruction->crRegister <= 7 )
|
|
||||||
{
|
{
|
||||||
uint32 crBitFlags = 0xF<<((uint32)imlInstruction->crRegister*4);
|
uint32 crBitFlags = 0xF<<((uint32)instIt.crRegister*4);
|
||||||
uint32 crOverwriteMask = PPCRecompiler_getCROverwriteMask(ppcImlGenContext, segIt);
|
uint32 crOverwriteMask = PPCRecompiler_getCROverwriteMask(ppcImlGenContext, segIt);
|
||||||
uint32 crIgnoreMask = crOverwriteMask & ~segIt->crBitsRead;
|
uint32 crIgnoreMask = crOverwriteMask & ~segIt->crBitsRead;
|
||||||
imlInstruction->crIgnoreMask = crIgnoreMask;
|
instIt.crIgnoreMask = crIgnoreMask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1650,7 +1648,7 @@ bool PPCRecompiler_checkIfGPRIsModifiedInRange(ppcImlGenContext_t* ppcImlGenCont
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
PPCImlOptimizerUsedRegisters_t registersUsed;
|
||||||
for (sint32 i = startIndex; i <= endIndex; i++)
|
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);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, imlInstruction, ®istersUsed);
|
||||||
if (registersUsed.writtenNamedReg1 == vreg)
|
if (registersUsed.writtenNamedReg1 == vreg)
|
||||||
return true;
|
return true;
|
||||||
|
@ -1688,7 +1686,7 @@ sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcIml
|
||||||
if (currentSegment->list_prevSegments.size() != 1)
|
if (currentSegment->list_prevSegments.size() != 1)
|
||||||
return -1;
|
return -1;
|
||||||
currentSegment = currentSegment->list_prevSegments[0];
|
currentSegment = currentSegment->list_prevSegments[0];
|
||||||
currentIndex = currentSegment->imlListCount - 1;
|
currentIndex = currentSegment->imlList.size() - 1;
|
||||||
segmentIterateCount++;
|
segmentIterateCount++;
|
||||||
}
|
}
|
||||||
// scan again to make sure the register is not modified inbetween
|
// scan again to make sure the register is not modified inbetween
|
||||||
|
@ -1701,13 +1699,12 @@ sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcIml
|
||||||
while (currentIndex >= 0)
|
while (currentIndex >= 0)
|
||||||
{
|
{
|
||||||
// check if register is modified
|
// check if register is modified
|
||||||
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, currentSegment->imlList+currentIndex, ®istersUsed);
|
PPCRecompiler_checkRegisterUsage(ppcImlGenContext, currentSegment->imlList.data() + currentIndex, ®istersUsed);
|
||||||
if (registersUsed.writtenNamedReg1 == foundRegister)
|
if (registersUsed.writtenNamedReg1 == foundRegister)
|
||||||
return -1;
|
return -1;
|
||||||
// check if end of scan reached
|
// check if end of scan reached
|
||||||
if (currentSegment->imlList[currentIndex].type == PPCREC_IML_TYPE_NAME_R && currentSegment->imlList[currentIndex].op_r_name.name == name)
|
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;
|
return foundRegister;
|
||||||
}
|
}
|
||||||
// previous instruction
|
// previous instruction
|
||||||
|
@ -1719,7 +1716,7 @@ sint32 PPCRecompiler_scanBackwardsForReusableRegister(ppcImlGenContext_t* ppcIml
|
||||||
if (currentSegment->list_prevSegments.size() != 1)
|
if (currentSegment->list_prevSegments.size() != 1)
|
||||||
return -1;
|
return -1;
|
||||||
currentSegment = currentSegment->list_prevSegments[0];
|
currentSegment = currentSegment->list_prevSegments[0];
|
||||||
currentIndex = currentSegment->imlListCount - 1;
|
currentIndex = currentSegment->imlList.size() - 1;
|
||||||
segmentIterateCount++;
|
segmentIterateCount++;
|
||||||
}
|
}
|
||||||
return -1;
|
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)
|
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)
|
if (imlInstructionLoad->op_storeLoad.flags2.notExpanded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
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;
|
bool foundMatch = false;
|
||||||
sint32 lastStore = -1;
|
sint32 lastStore = -1;
|
||||||
for (sint32 i = imlIndexLoad + 1; i < scanRangeEnd; i++)
|
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))
|
if (PPCRecompiler_isSuffixInstruction(imlInstruction))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -1802,9 +1799,9 @@ void PPCRecompiler_optimizeDirectFloatCopies(ppcImlGenContext_t* ppcImlGenContex
|
||||||
{
|
{
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
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)
|
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);
|
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)
|
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 )
|
if ( imlInstructionLoad->op_storeLoad.flags2.swapEndian == false )
|
||||||
return;
|
return;
|
||||||
bool foundMatch = false;
|
bool foundMatch = false;
|
||||||
PPCImlOptimizerUsedRegisters_t registersUsed;
|
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;
|
sint32 i = imlIndexLoad + 1;
|
||||||
for (; i < scanRangeEnd; i++)
|
for (; i < scanRangeEnd; i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList + i;
|
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + i;
|
||||||
if (PPCRecompiler_isSuffixInstruction(imlInstruction))
|
if (PPCRecompiler_isSuffixInstruction(imlInstruction))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -1886,9 +1883,9 @@ void PPCRecompiler_optimizeDirectIntegerCopies(ppcImlGenContext_t* ppcImlGenCont
|
||||||
{
|
{
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
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 )
|
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);
|
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 (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 (instIt.type == PPCREC_IML_TYPE_FPR_LOAD || instIt.type == PPCREC_IML_TYPE_FPR_LOAD_INDEXED)
|
||||||
if (imlInstruction->type == PPCREC_IML_TYPE_FPR_LOAD || imlInstruction->type == PPCREC_IML_TYPE_FPR_LOAD_INDEXED)
|
|
||||||
{
|
{
|
||||||
if(imlInstruction->op_storeLoad.mode != PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0 &&
|
if(instIt.op_storeLoad.mode != PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0 &&
|
||||||
imlInstruction->op_storeLoad.mode != PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0_PS1 )
|
instIt.op_storeLoad.mode != PPCREC_FPR_LD_MODE_PSQ_GENERIC_PS0_PS1 )
|
||||||
continue;
|
continue;
|
||||||
// get GQR value
|
// get GQR value
|
||||||
cemu_assert_debug(imlInstruction->op_storeLoad.registerGQR != PPC_REC_INVALID_REGISTER);
|
cemu_assert_debug(instIt.op_storeLoad.registerGQR != PPC_REC_INVALID_REGISTER);
|
||||||
sint32 gqrIndex = _getGQRIndexFromRegister(ppcImlGenContext, imlInstruction->op_storeLoad.registerGQR);
|
sint32 gqrIndex = _getGQRIndexFromRegister(ppcImlGenContext, instIt.op_storeLoad.registerGQR);
|
||||||
cemu_assert(gqrIndex >= 0);
|
cemu_assert(gqrIndex >= 0);
|
||||||
if (ppcImlGenContext->tracking.modifiesGQR[gqrIndex])
|
if (ppcImlGenContext->tracking.modifiesGQR[gqrIndex])
|
||||||
continue;
|
continue;
|
||||||
//uint32 gqrValue = ppcInterpreterCurrentInstance->sprNew.UGQR[gqrIndex];
|
|
||||||
uint32 gqrValue;
|
uint32 gqrValue;
|
||||||
if (!PPCRecompiler_isUGQRValueKnown(ppcImlGenContext, gqrIndex, gqrValue))
|
if (!PPCRecompiler_isUGQRValueKnown(ppcImlGenContext, gqrIndex, gqrValue))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1956,41 +1951,41 @@ void PPCRecompiler_optimizePSQLoadAndStore(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
uint32 scale = (gqrValue >> 24) & 0x3F;
|
uint32 scale = (gqrValue >> 24) & 0x3F;
|
||||||
if (scale != 0)
|
if (scale != 0)
|
||||||
continue; // only generic handler supports scale
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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 &&
|
if(instIt.op_storeLoad.mode != PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0 &&
|
||||||
imlInstruction->op_storeLoad.mode != PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0_PS1)
|
instIt.op_storeLoad.mode != PPCREC_FPR_ST_MODE_PSQ_GENERIC_PS0_PS1)
|
||||||
continue;
|
continue;
|
||||||
// get GQR value
|
// get GQR value
|
||||||
cemu_assert_debug(imlInstruction->op_storeLoad.registerGQR != PPC_REC_INVALID_REGISTER);
|
cemu_assert_debug(instIt.op_storeLoad.registerGQR != PPC_REC_INVALID_REGISTER);
|
||||||
sint32 gqrIndex = _getGQRIndexFromRegister(ppcImlGenContext, imlInstruction->op_storeLoad.registerGQR);
|
sint32 gqrIndex = _getGQRIndexFromRegister(ppcImlGenContext, instIt.op_storeLoad.registerGQR);
|
||||||
cemu_assert(gqrIndex >= 0);
|
cemu_assert(gqrIndex >= 0);
|
||||||
if (ppcImlGenContext->tracking.modifiesGQR[gqrIndex])
|
if (ppcImlGenContext->tracking.modifiesGQR[gqrIndex])
|
||||||
continue;
|
continue;
|
||||||
|
@ -2001,31 +1996,31 @@ void PPCRecompiler_optimizePSQLoadAndStore(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
uint32 scale = (gqrValue >> 24) & 0x3F;
|
uint32 scale = (gqrValue >> 24) & 0x3F;
|
||||||
if (scale != 0)
|
if (scale != 0)
|
||||||
continue; // only generic handler supports scale
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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
|
// scan backwards until we find the instruction that sets the CR
|
||||||
sint32 crSetterInstructionIndex = -1;
|
sint32 crSetterInstructionIndex = -1;
|
||||||
sint32 unsafeInstructionIndex = -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);
|
PPCRecompilerImlAnalyzer_getCRTracking(imlInstruction, &crTracking);
|
||||||
if (crTracking.readCRBits != 0)
|
if (crTracking.readCRBits != 0)
|
||||||
return; // dont handle complex cases for now
|
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
|
// check if we can move the CR setter instruction to after unsafeInstructionIndex
|
||||||
PPCRecCRTracking_t crTrackingSetter = crTracking;
|
PPCRecCRTracking_t crTrackingSetter = crTracking;
|
||||||
PPCImlOptimizerUsedRegisters_t regTrackingCRSetter;
|
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)
|
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
|
return; // we don't handle FPR dependency yet so just ignore FPR instructions
|
||||||
PPCImlOptimizerUsedRegisters_t registerTracking;
|
PPCImlOptimizerUsedRegisters_t registerTracking;
|
||||||
|
@ -2110,7 +2105,7 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
||||||
// CR setter does write GPR
|
// CR setter does write GPR
|
||||||
for (sint32 i = crSetterInstructionIndex + 1; i <= unsafeInstructionIndex; i++)
|
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?
|
// reads register written by CR setter?
|
||||||
if (PPCRecompilerAnalyzer_checkForGPROverwrite(®isterTracking, ®TrackingCRSetter))
|
if (PPCRecompilerAnalyzer_checkForGPROverwrite(®isterTracking, ®TrackingCRSetter))
|
||||||
{
|
{
|
||||||
|
@ -2131,7 +2126,7 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
||||||
// CR setter does not write GPR
|
// CR setter does not write GPR
|
||||||
for (sint32 i = crSetterInstructionIndex + 1; i <= unsafeInstructionIndex; i++)
|
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?
|
// writes register read by CR setter?
|
||||||
if (PPCRecompilerAnalyzer_checkForGPROverwrite(®TrackingCRSetter, ®isterTracking))
|
if (PPCRecompilerAnalyzer_checkForGPROverwrite(®TrackingCRSetter, ®isterTracking))
|
||||||
{
|
{
|
||||||
|
@ -2146,8 +2141,8 @@ void _reorderConditionModifyInstructions(PPCRecImlSegment_t* imlSegment)
|
||||||
assert_dbg();
|
assert_dbg();
|
||||||
#endif
|
#endif
|
||||||
PPCRecImlInstruction_t* newCRSetterInstruction = PPCRecompiler_insertInstruction(imlSegment, unsafeInstructionIndex+1);
|
PPCRecImlInstruction_t* newCRSetterInstruction = PPCRecompiler_insertInstruction(imlSegment, unsafeInstructionIndex+1);
|
||||||
memcpy(newCRSetterInstruction, imlSegment->imlList + crSetterInstructionIndex, sizeof(PPCRecImlInstruction_t));
|
memcpy(newCRSetterInstruction, imlSegment->imlList.data() + crSetterInstructionIndex, sizeof(PPCRecImlInstruction_t));
|
||||||
PPCRecompilerImlGen_generateNewInstruction_noOp(NULL, imlSegment->imlList + crSetterInstructionIndex);
|
PPCRecompilerImlGen_generateNewInstruction_noOp(nullptr, imlSegment->imlList.data() + crSetterInstructionIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -123,7 +123,7 @@ typedef struct
|
||||||
void PPCRecRA_insertGPRLoadInstruction(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, sint32 registerIndex, sint32 registerName)
|
void PPCRecRA_insertGPRLoadInstruction(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, sint32 registerIndex, sint32 registerName)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, 1);
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList + (insertIndex + 0);
|
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + 0);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_R_NAME;
|
imlInstructionItr->type = PPCREC_IML_TYPE_R_NAME;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
|
@ -136,10 +136,10 @@ void PPCRecRA_insertGPRLoadInstruction(PPCRecImlSegment_t* imlSegment, sint32 in
|
||||||
void PPCRecRA_insertGPRLoadInstructions(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, raLoadStoreInfo_t* loadList, sint32 loadCount)
|
void PPCRecRA_insertGPRLoadInstructions(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, raLoadStoreInfo_t* loadList, sint32 loadCount)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, loadCount);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, loadCount);
|
||||||
memset(imlSegment->imlList + (insertIndex + 0), 0x00, sizeof(PPCRecImlInstruction_t)*loadCount);
|
memset(imlSegment->imlList.data() + (insertIndex + 0), 0x00, sizeof(PPCRecImlInstruction_t)*loadCount);
|
||||||
for (sint32 i = 0; i < loadCount; i++)
|
for (sint32 i = 0; i < loadCount; i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList + (insertIndex + i);
|
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + i);
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_R_NAME;
|
imlInstructionItr->type = PPCREC_IML_TYPE_R_NAME;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
imlInstructionItr->op_r_name.registerIndex = (uint8)loadList[i].registerIndex;
|
imlInstructionItr->op_r_name.registerIndex = (uint8)loadList[i].registerIndex;
|
||||||
|
@ -152,7 +152,7 @@ void PPCRecRA_insertGPRLoadInstructions(PPCRecImlSegment_t* imlSegment, sint32 i
|
||||||
void PPCRecRA_insertGPRStoreInstruction(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, sint32 registerIndex, sint32 registerName)
|
void PPCRecRA_insertGPRStoreInstruction(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, sint32 registerIndex, sint32 registerName)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, 1);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, 1);
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList + (insertIndex + 0);
|
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + 0);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_NAME_R;
|
imlInstructionItr->type = PPCREC_IML_TYPE_NAME_R;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
|
@ -165,10 +165,10 @@ void PPCRecRA_insertGPRStoreInstruction(PPCRecImlSegment_t* imlSegment, sint32 i
|
||||||
void PPCRecRA_insertGPRStoreInstructions(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, raLoadStoreInfo_t* storeList, sint32 storeCount)
|
void PPCRecRA_insertGPRStoreInstructions(PPCRecImlSegment_t* imlSegment, sint32 insertIndex, raLoadStoreInfo_t* storeList, sint32 storeCount)
|
||||||
{
|
{
|
||||||
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, storeCount);
|
PPCRecompiler_pushBackIMLInstructions(imlSegment, insertIndex, storeCount);
|
||||||
memset(imlSegment->imlList + (insertIndex + 0), 0x00, sizeof(PPCRecImlInstruction_t)*storeCount);
|
memset(imlSegment->imlList.data() + (insertIndex + 0), 0x00, sizeof(PPCRecImlInstruction_t)*storeCount);
|
||||||
for (sint32 i = 0; i < storeCount; i++)
|
for (sint32 i = 0; i < storeCount; i++)
|
||||||
{
|
{
|
||||||
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList + (insertIndex + i);
|
PPCRecImlInstruction_t* imlInstructionItr = imlSegment->imlList.data() + (insertIndex + i);
|
||||||
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
memset(imlInstructionItr, 0x00, sizeof(PPCRecImlInstruction_t));
|
||||||
imlInstructionItr->type = PPCREC_IML_TYPE_NAME_R;
|
imlInstructionItr->type = PPCREC_IML_TYPE_NAME_R;
|
||||||
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
imlInstructionItr->operation = PPCREC_IML_OP_ASSIGN;
|
||||||
|
@ -767,7 +767,7 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
raLiveRangeInfo_t liveInfo;
|
raLiveRangeInfo_t liveInfo;
|
||||||
liveInfo.liveRangesCount = 0;
|
liveInfo.liveRangesCount = 0;
|
||||||
sint32 index = 0;
|
sint32 index = 0;
|
||||||
sint32 suffixInstructionCount = (imlSegment->imlListCount > 0 && PPCRecompiler_isSuffixInstruction(imlSegment->imlList + imlSegment->imlListCount - 1)) ? 1 : 0;
|
sint32 suffixInstructionCount = (imlSegment->imlList.size() > 0 && PPCRecompiler_isSuffixInstruction(imlSegment->imlList.data() + imlSegment->imlList.size() - 1)) ? 1 : 0;
|
||||||
// load register ranges that are supplied from previous segments
|
// load register ranges that are supplied from previous segments
|
||||||
raLivenessSubrange_t* subrangeItr = imlSegment->raInfo.linkedList_allSubranges;
|
raLivenessSubrange_t* subrangeItr = imlSegment->raInfo.linkedList_allSubranges;
|
||||||
//for (auto& subrange : imlSegment->raInfo.list_subranges)
|
//for (auto& subrange : imlSegment->raInfo.list_subranges)
|
||||||
|
@ -793,7 +793,7 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
subrangeItr = subrangeItr->link_segmentSubrangesGPR.next;
|
subrangeItr = subrangeItr->link_segmentSubrangesGPR.next;
|
||||||
}
|
}
|
||||||
// process instructions
|
// process instructions
|
||||||
while(index < imlSegment->imlListCount+1)
|
while(index < imlSegment->imlList.size() + 1)
|
||||||
{
|
{
|
||||||
// expire ranges
|
// expire ranges
|
||||||
for (sint32 f = 0; f < liveInfo.liveRangesCount; f++)
|
for (sint32 f = 0; f < liveInfo.liveRangesCount; f++)
|
||||||
|
@ -808,7 +808,7 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
// store GPR
|
// store GPR
|
||||||
if (liverange->hasStore)
|
if (liverange->hasStore)
|
||||||
{
|
{
|
||||||
PPCRecRA_insertGPRStoreInstruction(imlSegment, std::min(index, imlSegment->imlListCount - suffixInstructionCount), liverange->range->physicalRegister, liverange->range->name);
|
PPCRecRA_insertGPRStoreInstruction(imlSegment, std::min<sint32>(index, imlSegment->imlList.size() - suffixInstructionCount), liverange->range->physicalRegister, liverange->range->name);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
// remove entry
|
// remove entry
|
||||||
|
@ -828,7 +828,7 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
// load GPR
|
// load GPR
|
||||||
if (subrangeItr->_noLoad == false)
|
if (subrangeItr->_noLoad == false)
|
||||||
{
|
{
|
||||||
PPCRecRA_insertGPRLoadInstruction(imlSegment, std::min(index, imlSegment->imlListCount - suffixInstructionCount), subrangeItr->range->physicalRegister, subrangeItr->range->name);
|
PPCRecRA_insertGPRLoadInstruction(imlSegment, std::min<sint32>(index, imlSegment->imlList.size() - suffixInstructionCount), subrangeItr->range->physicalRegister, subrangeItr->range->name);
|
||||||
index++;
|
index++;
|
||||||
subrangeItr->start.index--;
|
subrangeItr->start.index--;
|
||||||
}
|
}
|
||||||
|
@ -839,10 +839,10 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
subrangeItr = subrangeItr->link_segmentSubrangesGPR.next;
|
subrangeItr = subrangeItr->link_segmentSubrangesGPR.next;
|
||||||
}
|
}
|
||||||
// replace registers
|
// replace registers
|
||||||
if (index < imlSegment->imlListCount)
|
if (index < imlSegment->imlList.size())
|
||||||
{
|
{
|
||||||
PPCImlOptimizerUsedRegisters_t gprTracking;
|
PPCImlOptimizerUsedRegisters_t gprTracking;
|
||||||
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList + index, &gprTracking);
|
PPCRecompiler_checkRegisterUsage(nullptr, imlSegment->imlList.data() + index, &gprTracking);
|
||||||
|
|
||||||
sint32 inputGpr[4];
|
sint32 inputGpr[4];
|
||||||
inputGpr[0] = gprTracking.gpr[0];
|
inputGpr[0] = gprTracking.gpr[0];
|
||||||
|
@ -863,7 +863,7 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
replaceGpr[f] = virtualReg2PhysReg[virtualRegister];
|
replaceGpr[f] = virtualReg2PhysReg[virtualRegister];
|
||||||
cemu_assert_debug(replaceGpr[f] >= 0);
|
cemu_assert_debug(replaceGpr[f] >= 0);
|
||||||
}
|
}
|
||||||
PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext, imlSegment->imlList + index, inputGpr, replaceGpr);
|
PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext, imlSegment->imlList.data() + index, inputGpr, replaceGpr);
|
||||||
}
|
}
|
||||||
// next iml instruction
|
// next iml instruction
|
||||||
index++;
|
index++;
|
||||||
|
@ -898,7 +898,7 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
}
|
}
|
||||||
if (storeLoadListLength > 0)
|
if (storeLoadListLength > 0)
|
||||||
{
|
{
|
||||||
PPCRecRA_insertGPRStoreInstructions(imlSegment, imlSegment->imlListCount - suffixInstructionCount, loadStoreList, storeLoadListLength);
|
PPCRecRA_insertGPRStoreInstructions(imlSegment, imlSegment->imlList.size() - suffixInstructionCount, loadStoreList, storeLoadListLength);
|
||||||
}
|
}
|
||||||
// load subranges for next segments
|
// load subranges for next segments
|
||||||
subrangeItr = imlSegment->raInfo.linkedList_allSubranges;
|
subrangeItr = imlSegment->raInfo.linkedList_allSubranges;
|
||||||
|
@ -925,7 +925,7 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
}
|
}
|
||||||
if (storeLoadListLength > 0)
|
if (storeLoadListLength > 0)
|
||||||
{
|
{
|
||||||
PPCRecRA_insertGPRLoadInstructions(imlSegment, imlSegment->imlListCount - suffixInstructionCount, loadStoreList, storeLoadListLength);
|
PPCRecRA_insertGPRLoadInstructions(imlSegment, imlSegment->imlList.size() - suffixInstructionCount, loadStoreList, storeLoadListLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -998,7 +998,6 @@ void PPCRecompilerImm_allocateRegisters(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
|
|
||||||
ppcImlGenContext->raInfo.list_ranges = std::vector<raLivenessRange_t*>();
|
ppcImlGenContext->raInfo.list_ranges = std::vector<raLivenessRange_t*>();
|
||||||
|
|
||||||
// calculate liveness
|
|
||||||
PPCRecRA_calculateLivenessRangesV2(ppcImlGenContext);
|
PPCRecRA_calculateLivenessRangesV2(ppcImlGenContext);
|
||||||
PPCRecRA_processFlowAndCalculateLivenessRangesV2(ppcImlGenContext);
|
PPCRecRA_processFlowAndCalculateLivenessRangesV2(ppcImlGenContext);
|
||||||
|
|
||||||
|
@ -1024,23 +1023,23 @@ void PPCRecRA_calculateSegmentMinMaxRanges(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
imlSegment->raDistances.reg[i].usageEnd = INT_MIN;
|
imlSegment->raDistances.reg[i].usageEnd = INT_MIN;
|
||||||
}
|
}
|
||||||
// scan instructions for usage range
|
// scan instructions for usage range
|
||||||
sint32 index = 0;
|
size_t index = 0;
|
||||||
PPCImlOptimizerUsedRegisters_t gprTracking;
|
PPCImlOptimizerUsedRegisters_t gprTracking;
|
||||||
while (index < imlSegment->imlListCount)
|
while (index < imlSegment->imlList.size())
|
||||||
{
|
{
|
||||||
// end loop at suffix instruction
|
// end loop at suffix instruction
|
||||||
if (PPCRecompiler_isSuffixInstruction(imlSegment->imlList + index))
|
if (PPCRecompiler_isSuffixInstruction(imlSegment->imlList.data() + index))
|
||||||
break;
|
break;
|
||||||
// get accessed GPRs
|
// get accessed GPRs
|
||||||
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList + index, &gprTracking);
|
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList.data() + index, &gprTracking);
|
||||||
for (sint32 t = 0; t < 4; t++)
|
for (sint32 t = 0; t < 4; t++)
|
||||||
{
|
{
|
||||||
sint32 virtualRegister = gprTracking.gpr[t];
|
sint32 virtualRegister = gprTracking.gpr[t];
|
||||||
if (virtualRegister < 0)
|
if (virtualRegister < 0)
|
||||||
continue;
|
continue;
|
||||||
cemu_assert_debug(virtualRegister < PPC_REC_MAX_VIRTUAL_GPR);
|
cemu_assert_debug(virtualRegister < PPC_REC_MAX_VIRTUAL_GPR);
|
||||||
imlSegment->raDistances.reg[virtualRegister].usageStart = std::min(imlSegment->raDistances.reg[virtualRegister].usageStart, index); // index before/at instruction
|
imlSegment->raDistances.reg[virtualRegister].usageStart = std::min<sint32>(imlSegment->raDistances.reg[virtualRegister].usageStart, index); // index before/at instruction
|
||||||
imlSegment->raDistances.reg[virtualRegister].usageEnd = std::max(imlSegment->raDistances.reg[virtualRegister].usageEnd, index + 1); // index after instruction
|
imlSegment->raDistances.reg[virtualRegister].usageEnd = std::max<sint32>(imlSegment->raDistances.reg[virtualRegister].usageEnd, index + 1); // index after instruction
|
||||||
}
|
}
|
||||||
// next instruction
|
// next instruction
|
||||||
index++;
|
index++;
|
||||||
|
@ -1117,15 +1116,15 @@ void PPCRecRA_createSegmentLivenessRanges(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// parse instructions and convert to locations
|
// parse instructions and convert to locations
|
||||||
sint32 index = 0;
|
size_t index = 0;
|
||||||
PPCImlOptimizerUsedRegisters_t gprTracking;
|
PPCImlOptimizerUsedRegisters_t gprTracking;
|
||||||
while (index < imlSegment->imlListCount)
|
while (index < imlSegment->imlList.size())
|
||||||
{
|
{
|
||||||
// end loop at suffix instruction
|
// end loop at suffix instruction
|
||||||
if (PPCRecompiler_isSuffixInstruction(imlSegment->imlList + index))
|
if (PPCRecompiler_isSuffixInstruction(imlSegment->imlList.data() + index))
|
||||||
break;
|
break;
|
||||||
// get accessed GPRs
|
// get accessed GPRs
|
||||||
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList + index, &gprTracking);
|
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList.data() + index, &gprTracking);
|
||||||
// handle accessed GPR
|
// handle accessed GPR
|
||||||
for (sint32 t = 0; t < 4; t++)
|
for (sint32 t = 0; t < 4; t++)
|
||||||
{
|
{
|
||||||
|
@ -1136,9 +1135,9 @@ void PPCRecRA_createSegmentLivenessRanges(ppcImlGenContext_t* ppcImlGenContext,
|
||||||
// add location
|
// add location
|
||||||
PPCRecRA_updateOrAddSubrangeLocation(vGPR2Subrange[virtualRegister], index, isWrite == false, isWrite);
|
PPCRecRA_updateOrAddSubrangeLocation(vGPR2Subrange[virtualRegister], index, isWrite == false, isWrite);
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
if (index < vGPR2Subrange[virtualRegister]->start.index)
|
if ((sint32)index < vGPR2Subrange[virtualRegister]->start.index)
|
||||||
assert_dbg();
|
assert_dbg();
|
||||||
if (index + 1 > vGPR2Subrange[virtualRegister]->end.index)
|
if ((sint32)index + 1 > vGPR2Subrange[virtualRegister]->end.index)
|
||||||
assert_dbg();
|
assert_dbg();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1205,7 +1204,7 @@ void _PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, PPCR
|
||||||
if (currentSegment->raDistances.reg[vGPR].usageStart == INT_MAX)
|
if (currentSegment->raDistances.reg[vGPR].usageStart == INT_MAX)
|
||||||
{
|
{
|
||||||
// measure distance to end of segment
|
// measure distance to end of segment
|
||||||
distanceLeft -= currentSegment->imlListCount;
|
distanceLeft -= (sint32)currentSegment->imlList.size();
|
||||||
if (distanceLeft > 0)
|
if (distanceLeft > 0)
|
||||||
{
|
{
|
||||||
if (currentSegment->nextSegmentBranchNotTaken)
|
if (currentSegment->nextSegmentBranchNotTaken)
|
||||||
|
@ -1220,7 +1219,7 @@ void _PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, PPCR
|
||||||
// measure distance to range
|
// measure distance to range
|
||||||
if (currentSegment->raDistances.reg[vGPR].usageStart == RA_INTER_RANGE_END)
|
if (currentSegment->raDistances.reg[vGPR].usageStart == RA_INTER_RANGE_END)
|
||||||
{
|
{
|
||||||
if (distanceLeft < currentSegment->imlListCount)
|
if (distanceLeft < (sint32)currentSegment->imlList.size())
|
||||||
return; // range too far away
|
return; // range too far away
|
||||||
}
|
}
|
||||||
else if (currentSegment->raDistances.reg[vGPR].usageStart != RA_INTER_RANGE_START && currentSegment->raDistances.reg[vGPR].usageStart > distanceLeft)
|
else if (currentSegment->raDistances.reg[vGPR].usageStart != RA_INTER_RANGE_START && currentSegment->raDistances.reg[vGPR].usageStart > distanceLeft)
|
||||||
|
@ -1243,7 +1242,7 @@ void PPCRecRA_checkAndTryExtendRange(ppcImlGenContext_t* ppcImlGenContext, PPCRe
|
||||||
if (currentSegment->raDistances.reg[vGPR].usageEnd == RA_INTER_RANGE_END)
|
if (currentSegment->raDistances.reg[vGPR].usageEnd == RA_INTER_RANGE_END)
|
||||||
instructionsUntilEndOfSeg = 0;
|
instructionsUntilEndOfSeg = 0;
|
||||||
else
|
else
|
||||||
instructionsUntilEndOfSeg = currentSegment->imlListCount - currentSegment->raDistances.reg[vGPR].usageEnd;
|
instructionsUntilEndOfSeg = (sint32)currentSegment->imlList.size() - currentSegment->raDistances.reg[vGPR].usageEnd;
|
||||||
|
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
if (instructionsUntilEndOfSeg < 0)
|
if (instructionsUntilEndOfSeg < 0)
|
||||||
|
|
|
@ -102,7 +102,7 @@ void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
bool isLastSegment = (s+1)>=ppcImlGenContext->segmentList2.size();
|
bool isLastSegment = (s+1)>=ppcImlGenContext->segmentList2.size();
|
||||||
PPCRecImlSegment_t* nextSegment = isLastSegment?nullptr:ppcImlGenContext->segmentList2[s+1];
|
PPCRecImlSegment_t* nextSegment = isLastSegment?nullptr:ppcImlGenContext->segmentList2[s+1];
|
||||||
// handle empty segment
|
// handle empty segment
|
||||||
if( imlSegment->imlListCount == 0 )
|
if( imlSegment->imlList.empty())
|
||||||
{
|
{
|
||||||
if (isLastSegment == false)
|
if (isLastSegment == false)
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegment, ppcImlGenContext->segmentList2[s+1]); // continue execution to next segment
|
PPCRecompilerIml_setLinkBranchNotTaken(imlSegment, ppcImlGenContext->segmentList2[s+1]); // continue execution to next segment
|
||||||
|
@ -111,7 +111,7 @@ void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// check last instruction of segment
|
// check last instruction of segment
|
||||||
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList+(imlSegment->imlListCount-1);
|
PPCRecImlInstruction_t* imlInstruction = imlSegment->imlList.data() + (imlSegment->imlList.size() - 1);
|
||||||
if( imlInstruction->type == PPCREC_IML_TYPE_CJUMP || imlInstruction->type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK )
|
if( imlInstruction->type == PPCREC_IML_TYPE_CJUMP || imlInstruction->type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK )
|
||||||
{
|
{
|
||||||
// find destination segment by ppc jump address
|
// find destination segment by ppc jump address
|
||||||
|
@ -135,9 +135,7 @@ void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// all other instruction types do not branch
|
// all other instruction types do not branch
|
||||||
//imlSegment->nextSegment[0] = nextSegment;
|
|
||||||
PPCRecompilerIml_setLinkBranchNotTaken(imlSegment, nextSegment);
|
PPCRecompilerIml_setLinkBranchNotTaken(imlSegment, nextSegment);
|
||||||
//imlSegment->nextSegmentIsUncertain = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +155,7 @@ void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenCont
|
||||||
entrySegment->enterPPCAddress = imlSegment->enterPPCAddress;
|
entrySegment->enterPPCAddress = imlSegment->enterPPCAddress;
|
||||||
// create jump instruction
|
// create jump instruction
|
||||||
PPCRecompiler_pushBackIMLInstructions(entrySegment, 0, 1);
|
PPCRecompiler_pushBackIMLInstructions(entrySegment, 0, 1);
|
||||||
PPCRecompilerImlGen_generateNewInstruction_jumpSegment(ppcImlGenContext, entrySegment->imlList + 0);
|
PPCRecompilerImlGen_generateNewInstruction_jumpSegment(ppcImlGenContext, entrySegment->imlList.data() + 0);
|
||||||
PPCRecompilerIml_setLinkBranchTaken(entrySegment, imlSegment);
|
PPCRecompilerIml_setLinkBranchTaken(entrySegment, imlSegment);
|
||||||
// remove enterable flag from original segment
|
// remove enterable flag from original segment
|
||||||
imlSegment->isEnterable = false;
|
imlSegment->isEnterable = false;
|
||||||
|
@ -168,7 +166,7 @@ void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenCont
|
||||||
|
|
||||||
PPCRecImlInstruction_t* PPCRecompilerIML_getLastInstruction(PPCRecImlSegment_t* imlSegment)
|
PPCRecImlInstruction_t* PPCRecompilerIML_getLastInstruction(PPCRecImlSegment_t* imlSegment)
|
||||||
{
|
{
|
||||||
if (imlSegment->imlListCount == 0)
|
if (imlSegment->imlList.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return imlSegment->imlList + (imlSegment->imlListCount - 1);
|
return imlSegment->imlList.data() + (imlSegment->imlList.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2302,9 +2302,9 @@ bool PPCRecompiler_generateX64Code(PPCRecFunction_t* PPCRecFunction, ppcImlGenCo
|
||||||
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
for (PPCRecImlSegment_t* segIt : ppcImlGenContext->segmentList2)
|
||||||
{
|
{
|
||||||
segIt->x64Offset = x64GenContext.codeBufferIndex;
|
segIt->x64Offset = x64GenContext.codeBufferIndex;
|
||||||
for(sint32 i=0; i<segIt->imlListCount; i++)
|
for(size_t 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_R_NAME )
|
if( imlInstruction->type == PPCREC_IML_TYPE_R_NAME )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue