PPCRec: Use vector for instruction list

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

View file

@ -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{};

View file

@ -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);

View file

@ -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, &registersUsed); PPCRecompiler_checkRegisterUsage(nullptr, &instIt, &registersUsed);
if(registersUsed.writtenNamedReg1 < 0) if(registersUsed.writtenNamedReg1 < 0)
continue; continue;
list_modifiedRegisters.remove(registersUsed.writtenNamedReg1); list_modifiedRegisters.remove(registersUsed.writtenNamedReg1);

View file

@ -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, &registersUsed); PPCRecompiler_checkRegisterUsage(&ppcImlGenContext, segIt->imlList.data() + i, &registersUsed);
//PPCRecompilerImlGen_findRegisterByMappedName(ppcImlGenContext, registersUsed.readGPR1); //PPCRecompilerImlGen_findRegisterByMappedName(ppcImlGenContext, registersUsed.readGPR1);
sint32 accessedTempReg[5]; sint32 accessedTempReg[5];
// intermediate FPRs // intermediate FPRs

View file

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

View file

@ -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)

View file

@ -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);
} }

View file

@ -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 )
{ {