diff --git a/src/Cafe/CMakeLists.txt b/src/Cafe/CMakeLists.txt index 6cb13acb..91badaf5 100644 --- a/src/Cafe/CMakeLists.txt +++ b/src/Cafe/CMakeLists.txt @@ -67,10 +67,12 @@ add_library(CemuCafe HW/Espresso/Recompiler/PPCFunctionBoundaryTracker.h HW/Espresso/Recompiler/PPCRecompiler.cpp HW/Espresso/Recompiler/PPCRecompiler.h + HW/Espresso/Recompiler/IML/IML.h HW/Espresso/Recompiler/IML/IMLSegment.cpp HW/Espresso/Recompiler/IML/IMLSegment.h HW/Espresso/Recompiler/IML/IMLInstruction.cpp HW/Espresso/Recompiler/IML/IMLInstruction.h + HW/Espresso/Recompiler/IML/IMLDebug.cpp HW/Espresso/Recompiler/PPCRecompilerImlAnalyzer.cpp HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp HW/Espresso/Recompiler/PPCRecompilerImlGenFPU.cpp diff --git a/src/Cafe/HW/Espresso/Recompiler/IML/IML.h b/src/Cafe/HW/Espresso/Recompiler/IML/IML.h new file mode 100644 index 00000000..6f103087 --- /dev/null +++ b/src/Cafe/HW/Espresso/Recompiler/IML/IML.h @@ -0,0 +1,4 @@ + +// debug +void IMLDebug_DumpSegment(struct IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo = false); +void IMLDebug_Dump(struct ppcImlGenContext_t* ppcImlGenContext); diff --git a/src/Cafe/HW/Espresso/Recompiler/IML/IMLDebug.cpp b/src/Cafe/HW/Espresso/Recompiler/IML/IMLDebug.cpp new file mode 100644 index 00000000..b8094bb8 --- /dev/null +++ b/src/Cafe/HW/Espresso/Recompiler/IML/IMLDebug.cpp @@ -0,0 +1,471 @@ +#include "IML.h" +#include "IMLInstruction.h" +#include "IMLSegment.h" +#include "util/helpers/StringBuf.h" + +#include "Cafe/HW/Espresso/Recompiler/PPCRecompilerImlRanges.h" + +const char* IMLDebug_GetOpcodeName(const IMLInstruction* iml) +{ + static char _tempOpcodename[32]; + uint32 op = iml->operation; + if (op == PPCREC_IML_OP_ASSIGN) + return "MOV"; + else if (op == PPCREC_IML_OP_ADD) + return "ADD"; + else if (op == PPCREC_IML_OP_SUB) + return "SUB"; + else if (op == PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY) + return "ADDCSC"; + else if (op == PPCREC_IML_OP_OR) + return "OR"; + else if (op == PPCREC_IML_OP_AND) + return "AND"; + else if (op == PPCREC_IML_OP_XOR) + return "XOR"; + else if (op == PPCREC_IML_OP_LEFT_SHIFT) + return "LSH"; + else if (op == PPCREC_IML_OP_RIGHT_SHIFT) + return "RSH"; + else if (op == PPCREC_IML_OP_MULTIPLY_SIGNED) + return "MULS"; + else if (op == PPCREC_IML_OP_DIVIDE_SIGNED) + return "DIVS"; + + sprintf(_tempOpcodename, "OP0%02x_T%d", iml->operation, iml->type); + return _tempOpcodename; +} + +void IMLDebug_AppendRegisterParam(StringBuf& strOutput, sint32 virtualRegister, bool isLast = false) +{ + if (isLast) + { + if (virtualRegister < 10) + strOutput.addFmt("t{} ", virtualRegister); + else + strOutput.addFmt("t{}", virtualRegister); + return; + } + if (virtualRegister < 10) + strOutput.addFmt("t{} , ", virtualRegister); + else + strOutput.addFmt("t{}, ", virtualRegister); +} + +void IMLDebug_AppendS32Param(StringBuf& strOutput, sint32 val, bool isLast = false) +{ + if (isLast) + { + strOutput.addFmt("0x{:08x}", val); + return; + } + strOutput.addFmt("0x{:08x}, ", val); +} + +void IMLDebug_PrintLivenessRangeInfo(StringBuf& currentLineText, IMLSegment* imlSegment, sint32 offset) +{ + // pad to 70 characters + sint32 index = currentLineText.getLen(); + while (index < 70) + { + debug_printf(" "); + index++; + } + raLivenessSubrange_t* subrangeItr = imlSegment->raInfo.linkedList_allSubranges; + while (subrangeItr) + { + if (offset == subrangeItr->start.index) + { + if (false)//subrange->isDirtied && i == subrange->becomesDirtyAtIndex.index) + { + debug_printf("*%-2d", subrangeItr->range->virtualRegister); + } + else + { + debug_printf("|%-2d", subrangeItr->range->virtualRegister); + } + } + else if (false)//subrange->isDirtied && i == subrange->becomesDirtyAtIndex.index ) + { + debug_printf("* "); + } + else if (offset >= subrangeItr->start.index && offset < subrangeItr->end.index) + { + debug_printf("| "); + } + else + { + debug_printf(" "); + } + index += 3; + // next + subrangeItr = subrangeItr->link_segmentSubrangesGPR.next; + } +} + +void IMLDebug_DumpSegment(IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo) +{ + StringBuf strOutput(1024); + + strOutput.addFmt("SEGMENT 0x{:04x} 0x{:08x} PPC 0x{:08x} - 0x{:08x} Loop-depth {}", segmentIndex, imlSegment->ppcAddress, imlSegment->ppcAddrMin, imlSegment->ppcAddrMax, imlSegment->loopDepth); + if (imlSegment->isEnterable) + { + strOutput.addFmt(" ENTERABLE (0x{:08x})", imlSegment->enterPPCAddress); + } + else if (imlSegment->isJumpDestination) + { + strOutput.addFmt(" JUMP-DEST (0x{:08x})", imlSegment->jumpDestinationPPCAddress); + } + + debug_printf("%s\n", strOutput.c_str()); + + strOutput.reset(); + strOutput.addFmt("SEGMENT NAME 0x{:016x}", (uintptr_t)imlSegment); + debug_printf("%s", strOutput.c_str()); + + if (printLivenessRangeInfo) + { + IMLDebug_PrintLivenessRangeInfo(strOutput, imlSegment, RA_INTER_RANGE_START); + } + debug_printf("\n"); + + sint32 lineOffsetParameters = 18; + + for (sint32 i = 0; i < imlSegment->imlList.size(); i++) + { + const IMLInstruction& inst = imlSegment->imlList[i]; + // don't log NOP instructions unless they have an associated PPC address + if (inst.type == PPCREC_IML_TYPE_NO_OP && inst.associatedPPCAddress == MPTR_NULL) + continue; + strOutput.reset(); + strOutput.addFmt("{:08x} ", inst.associatedPPCAddress); + if (inst.type == PPCREC_IML_TYPE_R_NAME || inst.type == PPCREC_IML_TYPE_NAME_R) + { + if (inst.type == PPCREC_IML_TYPE_R_NAME) + strOutput.add("LD_NAME"); + else + strOutput.add("ST_NAME"); + while ((sint32)strOutput.getLen() < lineOffsetParameters) + strOutput.add(" "); + + IMLDebug_AppendRegisterParam(strOutput, inst.op_r_name.registerIndex); + + strOutput.addFmt("name_{} (", inst.op_r_name.registerIndex, inst.op_r_name.name); + if (inst.op_r_name.name >= PPCREC_NAME_R0 && inst.op_r_name.name < (PPCREC_NAME_R0 + 999)) + { + strOutput.addFmt("r{}", inst.op_r_name.name - PPCREC_NAME_R0); + } + else if (inst.op_r_name.name >= PPCREC_NAME_SPR0 && inst.op_r_name.name < (PPCREC_NAME_SPR0 + 999)) + { + strOutput.addFmt("spr{}", inst.op_r_name.name - PPCREC_NAME_SPR0); + } + else + strOutput.add("ukn"); + strOutput.add(")"); + } + else if (inst.type == PPCREC_IML_TYPE_R_R) + { + strOutput.addFmt("{}", IMLDebug_GetOpcodeName(&inst)); + while ((sint32)strOutput.getLen() < lineOffsetParameters) + strOutput.add(" "); + IMLDebug_AppendRegisterParam(strOutput, inst.op_r_r.registerResult); + IMLDebug_AppendRegisterParam(strOutput, inst.op_r_r.registerA, true); + + if (inst.crRegister != PPC_REC_INVALID_REGISTER) + { + strOutput.addFmt(" -> CR{}", inst.crRegister); + } + } + else if (inst.type == PPCREC_IML_TYPE_R_R_R) + { + strOutput.addFmt("{}", IMLDebug_GetOpcodeName(&inst)); + while ((sint32)strOutput.getLen() < lineOffsetParameters) + strOutput.add(" "); + IMLDebug_AppendRegisterParam(strOutput, inst.op_r_r_r.registerResult); + IMLDebug_AppendRegisterParam(strOutput, inst.op_r_r_r.registerA); + IMLDebug_AppendRegisterParam(strOutput, inst.op_r_r_r.registerB, true); + if (inst.crRegister != PPC_REC_INVALID_REGISTER) + { + strOutput.addFmt(" -> CR{}", inst.crRegister); + } + } + else if (inst.type == PPCREC_IML_TYPE_R_R_S32) + { + strOutput.addFmt("{}", IMLDebug_GetOpcodeName(&inst)); + while ((sint32)strOutput.getLen() < lineOffsetParameters) + strOutput.add(" "); + + IMLDebug_AppendRegisterParam(strOutput, inst.op_r_r_s32.registerResult); + IMLDebug_AppendRegisterParam(strOutput, inst.op_r_r_s32.registerA); + IMLDebug_AppendS32Param(strOutput, inst.op_r_r_s32.immS32, true); + + if (inst.crRegister != PPC_REC_INVALID_REGISTER) + { + strOutput.addFmt(" -> CR{}", inst.crRegister); + } + } + else if (inst.type == PPCREC_IML_TYPE_R_S32) + { + strOutput.addFmt("{}", IMLDebug_GetOpcodeName(&inst)); + while ((sint32)strOutput.getLen() < lineOffsetParameters) + strOutput.add(" "); + + IMLDebug_AppendRegisterParam(strOutput, inst.op_r_immS32.registerIndex); + IMLDebug_AppendS32Param(strOutput, inst.op_r_immS32.immS32, true); + + if (inst.crRegister != PPC_REC_INVALID_REGISTER) + { + strOutput.addFmt(" -> CR{}", inst.crRegister); + } + } + else if (inst.type == PPCREC_IML_TYPE_JUMPMARK) + { + strOutput.addFmt("jm_{:08x}:", inst.op_jumpmark.address); + } + else if (inst.type == PPCREC_IML_TYPE_PPC_ENTER) + { + strOutput.addFmt("ppcEnter_{:08x}:", inst.op_ppcEnter.ppcAddress); + } + else if (inst.type == PPCREC_IML_TYPE_LOAD || inst.type == PPCREC_IML_TYPE_STORE || + inst.type == PPCREC_IML_TYPE_LOAD_INDEXED || inst.type == PPCREC_IML_TYPE_STORE_INDEXED) + { + if (inst.type == PPCREC_IML_TYPE_LOAD || inst.type == PPCREC_IML_TYPE_LOAD_INDEXED) + strOutput.add("LD_"); + else + strOutput.add("ST_"); + + if (inst.op_storeLoad.flags2.signExtend) + strOutput.add("S"); + else + strOutput.add("U"); + strOutput.addFmt("{}", inst.op_storeLoad.copyWidth); + + while ((sint32)strOutput.getLen() < lineOffsetParameters) + strOutput.add(" "); + + IMLDebug_AppendRegisterParam(strOutput, inst.op_storeLoad.registerData); + + if (inst.type == PPCREC_IML_TYPE_LOAD_INDEXED || inst.type == PPCREC_IML_TYPE_STORE_INDEXED) + strOutput.addFmt("[t{}+t{}]", inst.op_storeLoad.registerMem, inst.op_storeLoad.registerMem2); + else + strOutput.addFmt("[t{}+{}]", inst.op_storeLoad.registerMem, inst.op_storeLoad.immS32); + } + else if (inst.type == PPCREC_IML_TYPE_CJUMP) + { + if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_E) + strOutput.add("JE"); + else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NE) + strOutput.add("JNE"); + else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_G) + strOutput.add("JG"); + else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_GE) + strOutput.add("JGE"); + else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_L) + strOutput.add("JL"); + else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_LE) + strOutput.add("JLE"); + else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NONE) + strOutput.add("JALW"); // jump always + else + cemu_assert_unimplemented(); + strOutput.addFmt(" jm_{:08x} (cr{})", inst.op_conditionalJump.jumpmarkAddress, inst.crRegister); + } + else if (inst.type == PPCREC_IML_TYPE_NO_OP) + { + strOutput.add("NOP"); + } + else if (inst.type == PPCREC_IML_TYPE_MACRO) + { + if (inst.operation == PPCREC_IML_MACRO_BLR) + { + strOutput.addFmt("MACRO BLR 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16); + } + else if (inst.operation == PPCREC_IML_MACRO_BLRL) + { + strOutput.addFmt("MACRO BLRL 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16); + } + else if (inst.operation == PPCREC_IML_MACRO_BCTR) + { + strOutput.addFmt("MACRO BCTR 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16); + } + else if (inst.operation == PPCREC_IML_MACRO_BCTRL) + { + strOutput.addFmt("MACRO BCTRL 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16); + } + else if (inst.operation == PPCREC_IML_MACRO_BL) + { + 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 (inst.operation == PPCREC_IML_MACRO_B_FAR) + { + 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 (inst.operation == PPCREC_IML_MACRO_LEAVE) + { + strOutput.addFmt("MACRO LEAVE ppc: 0x{:08x}", inst.op_macro.param); + } + else if (inst.operation == PPCREC_IML_MACRO_HLE) + { + strOutput.addFmt("MACRO HLE ppcAddr: 0x{:08x} funcId: 0x{:08x}", inst.op_macro.param, inst.op_macro.param2); + } + else if (inst.operation == PPCREC_IML_MACRO_MFTB) + { + strOutput.addFmt("MACRO MFTB ppcAddr: 0x{:08x} sprId: 0x{:08x}", inst.op_macro.param, inst.op_macro.param2); + } + else if (inst.operation == PPCREC_IML_MACRO_COUNT_CYCLES) + { + strOutput.addFmt("MACRO COUNT_CYCLES cycles: {}", inst.op_macro.param); + } + else + { + strOutput.addFmt("MACRO ukn operation {}", inst.operation); + } + } + else if (inst.type == PPCREC_IML_TYPE_FPR_R_NAME) + { + strOutput.addFmt("fpr_t{} = name_{} (", inst.op_r_name.registerIndex, inst.op_r_name.name); + if (inst.op_r_name.name >= PPCREC_NAME_FPR0 && inst.op_r_name.name < (PPCREC_NAME_FPR0 + 999)) + { + strOutput.addFmt("fpr{}", inst.op_r_name.name - PPCREC_NAME_FPR0); + } + else if (inst.op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && inst.op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0 + 999)) + { + strOutput.addFmt("tempFpr{}", inst.op_r_name.name - PPCREC_NAME_TEMPORARY_FPR0); + } + else + strOutput.add("ukn"); + strOutput.add(")"); + } + else if (inst.type == PPCREC_IML_TYPE_FPR_NAME_R) + { + strOutput.addFmt("name_{} (", inst.op_r_name.name); + if (inst.op_r_name.name >= PPCREC_NAME_FPR0 && inst.op_r_name.name < (PPCREC_NAME_FPR0 + 999)) + { + strOutput.addFmt("fpr{}", inst.op_r_name.name - PPCREC_NAME_FPR0); + } + else if (inst.op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && inst.op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0 + 999)) + { + strOutput.addFmt("tempFpr{}", inst.op_r_name.name - PPCREC_NAME_TEMPORARY_FPR0); + } + else + strOutput.add("ukn"); + strOutput.addFmt(") = fpr_t{}", inst.op_r_name.registerIndex); + } + else if (inst.type == PPCREC_IML_TYPE_FPR_LOAD) + { + strOutput.addFmt("fpr_t{} = ", inst.op_storeLoad.registerData); + if (inst.op_storeLoad.flags2.signExtend) + strOutput.add("S"); + else + strOutput.add("U"); + strOutput.addFmt("{} [t{}+{}] mode {}", inst.op_storeLoad.copyWidth / 8, inst.op_storeLoad.registerMem, inst.op_storeLoad.immS32, inst.op_storeLoad.mode); + if (inst.op_storeLoad.flags2.notExpanded) + { + strOutput.addFmt(" "); + } + } + else if (inst.type == PPCREC_IML_TYPE_FPR_STORE) + { + if (inst.op_storeLoad.flags2.signExtend) + strOutput.add("S"); + else + strOutput.add("U"); + strOutput.addFmt("{} [t{}+{}]", inst.op_storeLoad.copyWidth / 8, inst.op_storeLoad.registerMem, inst.op_storeLoad.immS32); + strOutput.addFmt("= fpr_t{} mode {}\n", inst.op_storeLoad.registerData, inst.op_storeLoad.mode); + } + else if (inst.type == PPCREC_IML_TYPE_FPR_R_R) + { + strOutput.addFmt("{:-6} ", IMLDebug_GetOpcodeName(&inst)); + strOutput.addFmt("fpr{:02d}, fpr{:02d}", inst.op_fpr_r_r.registerResult, inst.op_fpr_r_r.registerOperand); + } + else if (inst.type == PPCREC_IML_TYPE_FPR_R_R_R_R) + { + strOutput.addFmt("{:-6} ", IMLDebug_GetOpcodeName(&inst)); + 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 (inst.type == PPCREC_IML_TYPE_FPR_R_R_R) + { + strOutput.addFmt("{:-6} ", IMLDebug_GetOpcodeName(&inst)); + 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 (inst.type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK) + { + strOutput.addFmt("CYCLE_CHECK jm_{:08x}\n", inst.op_conditionalJump.jumpmarkAddress); + } + else if (inst.type == PPCREC_IML_TYPE_CONDITIONAL_R_S32) + { + strOutput.addFmt("t{} ", inst.op_conditional_r_s32.registerIndex); + bool displayAsHex = false; + if (inst.operation == PPCREC_IML_OP_ASSIGN) + { + displayAsHex = true; + strOutput.add("="); + } + else + strOutput.addFmt("(unknown operation CONDITIONAL_R_S32 {})", inst.operation); + if (displayAsHex) + strOutput.addFmt(" 0x{:x}", inst.op_conditional_r_s32.immS32); + else + strOutput.addFmt(" {}", inst.op_conditional_r_s32.immS32); + strOutput.add(" (conditional)"); + if (inst.crRegister != PPC_REC_INVALID_REGISTER) + { + strOutput.addFmt(" -> and update CR{}", inst.crRegister); + } + } + else + { + strOutput.addFmt("Unknown iml type {}", inst.type); + } + debug_printf("%s", strOutput.c_str()); + if (printLivenessRangeInfo) + { + IMLDebug_PrintLivenessRangeInfo(strOutput, imlSegment, i); + } + debug_printf("\n"); + } + // all ranges + if (printLivenessRangeInfo) + { + debug_printf("Ranges-VirtReg "); + raLivenessSubrange_t* subrangeItr = imlSegment->raInfo.linkedList_allSubranges; + while (subrangeItr) + { + debug_printf("v%-2d", subrangeItr->range->virtualRegister); + subrangeItr = subrangeItr->link_segmentSubrangesGPR.next; + } + debug_printf("\n"); + debug_printf("Ranges-PhysReg "); + subrangeItr = imlSegment->raInfo.linkedList_allSubranges; + while (subrangeItr) + { + debug_printf("p%-2d", subrangeItr->range->physicalRegister); + subrangeItr = subrangeItr->link_segmentSubrangesGPR.next; + } + debug_printf("\n"); + } + // branch info + debug_printf("Links from: "); + for (sint32 i = 0; i < imlSegment->list_prevSegments.size(); i++) + { + if (i) + debug_printf(", "); + debug_printf("%p", (void*)imlSegment->list_prevSegments[i]); + } + debug_printf("\n"); + debug_printf("Links to: "); + if (imlSegment->nextSegmentBranchNotTaken) + debug_printf("%p (no branch), ", (void*)imlSegment->nextSegmentBranchNotTaken); + if (imlSegment->nextSegmentBranchTaken) + debug_printf("%p (branch)", (void*)imlSegment->nextSegmentBranchTaken); + debug_printf("\n"); +} + +void IMLDebug_Dump(ppcImlGenContext_t* ppcImlGenContext) +{ + for (size_t i = 0; i < ppcImlGenContext->segmentList2.size(); i++) + { + IMLDebug_DumpSegment(ppcImlGenContext->segmentList2[i], i); + debug_printf("\n"); + } +} diff --git a/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h b/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h index e92fc611..34733c4f 100644 --- a/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h +++ b/src/Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h @@ -367,6 +367,23 @@ struct IMLInstruction }op_conditional_r_s32; }; + bool IsSuffixInstruction() const + { + if (type == PPCREC_IML_TYPE_MACRO && (operation == PPCREC_IML_MACRO_BLR || operation == PPCREC_IML_MACRO_BCTR) || + type == PPCREC_IML_TYPE_MACRO && operation == PPCREC_IML_MACRO_BL || + type == PPCREC_IML_TYPE_MACRO && operation == PPCREC_IML_MACRO_B_FAR || + type == PPCREC_IML_TYPE_MACRO && operation == PPCREC_IML_MACRO_BLRL || + type == PPCREC_IML_TYPE_MACRO && operation == PPCREC_IML_MACRO_BCTRL || + type == PPCREC_IML_TYPE_MACRO && operation == PPCREC_IML_MACRO_LEAVE || + type == PPCREC_IML_TYPE_MACRO && operation == PPCREC_IML_MACRO_HLE || + type == PPCREC_IML_TYPE_MACRO && operation == PPCREC_IML_MACRO_MFTB || + type == PPCREC_IML_TYPE_PPC_ENTER || + type == PPCREC_IML_TYPE_CJUMP || + type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK) + return true; + return false; + } + // instruction setters void make_jumpmark(uint32 address) { diff --git a/src/Cafe/HW/Espresso/Recompiler/IML/IMLSegment.cpp b/src/Cafe/HW/Espresso/Recompiler/IML/IMLSegment.cpp index e69de29b..e7eb3b32 100644 --- a/src/Cafe/HW/Espresso/Recompiler/IML/IMLSegment.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/IML/IMLSegment.cpp @@ -0,0 +1,10 @@ +#include "IMLInstruction.h" +#include "IMLSegment.h" + +bool IMLSegment::HasSuffixInstruction() const +{ + if (imlList.empty()) + return false; + const IMLInstruction& imlInstruction = imlList.back(); + return imlInstruction.IsSuffixInstruction(); +} diff --git a/src/Cafe/HW/Espresso/Recompiler/IML/IMLSegment.h b/src/Cafe/HW/Espresso/Recompiler/IML/IMLSegment.h index f95aa159..216e1748 100644 --- a/src/Cafe/HW/Espresso/Recompiler/IML/IMLSegment.h +++ b/src/Cafe/HW/Espresso/Recompiler/IML/IMLSegment.h @@ -1,4 +1,7 @@ #pragma once +#include "IMLInstruction.h" + +#include "Cafe/HW/Espresso/Recompiler/PPCRecompiler.h" // remove once dependency is gone struct IMLSegment { @@ -37,4 +40,6 @@ struct IMLSegment bool raRangeExtendProcessed{}; // segment points ppcRecompilerSegmentPoint_t* segmentPointList{}; + + bool HasSuffixInstruction() const; }; diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.h b/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.h index bf774384..88bd1d94 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.h +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.h @@ -1,4 +1,4 @@ -#include +#pragma once #define PPC_REC_CODE_AREA_START (0x00000000) // lower bound of executable memory area. Recompiler expects this address to be 0 #define PPC_REC_CODE_AREA_END (0x10000000) // upper bound of executable memory area @@ -8,23 +8,21 @@ #define PPC_REC_MAX_VIRTUAL_GPR (40) // enough to store 32 GPRs + a few SPRs + temp registers (usually only 1-2) -typedef struct +struct ppcRecRange_t { uint32 ppcAddress; uint32 ppcSize; - //void* x86Start; - //size_t x86Size; void* storedRange; -}ppcRecRange_t; +}; -typedef struct +struct PPCRecFunction_t { uint32 ppcAddress; uint32 ppcSize; // ppc code size of function void* x86Code; // pointer to x86 code size_t x86Size; std::vector list_ranges; -}PPCRecFunction_t; +}; #include "Cafe/HW/Espresso/Recompiler/IML/IMLInstruction.h" diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerIml.h b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerIml.h index e06bf6cf..7ee5dffc 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerIml.h +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerIml.h @@ -113,7 +113,6 @@ bool PPCRecompilerImlGen_PS_CMPU1(ppcImlGenContext_t* ppcImlGenContext, uint32 o // IML general -bool PPCRecompiler_isSuffixInstruction(IMLInstruction* iml); void PPCRecompilerIML_linkSegments(ppcImlGenContext_t* ppcImlGenContext); void PPCRecompilerIml_setLinkBranchNotTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst); void PPCRecompilerIml_setLinkBranchTaken(IMLSegment* imlSegmentSrc, IMLSegment* imlSegmentDst); @@ -151,11 +150,6 @@ void PPCRecompilerImm_allocateRegisters(ppcImlGenContext_t* ppcImlGenContext); // late optimizations void PPCRecompiler_reorderConditionModifyInstructions(ppcImlGenContext_t* ppcImlGenContext); -// debug - -void PPCRecompiler_dumpIMLSegment(IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo = false); - - typedef struct { union diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp index 9d2cef0c..7fdbff17 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp @@ -4,7 +4,6 @@ #include "PPCRecompilerIml.h" #include "PPCRecompilerX64.h" #include "PPCRecompilerImlRanges.h" -#include "util/helpers/StringBuf.h" bool PPCRecompiler_decodePPCInstruction(ppcImlGenContext_t* ppcImlGenContext); uint32 PPCRecompiler_iterateCurrentInstruction(ppcImlGenContext_t* ppcImlGenContext); @@ -25,40 +24,6 @@ IMLInstruction* PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext ppcImlGenContext->imlListCount++; return imlInstruction; } -// -//void PPCRecompilerImlGen_generateNewInstruction_jumpmark(ppcImlGenContext_t* ppcImlGenContext, uint32 address) -//{ -// // no-op that indicates possible destination of a jump -// IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext); -// imlInstruction->type = PPCREC_IML_TYPE_JUMPMARK; -// imlInstruction->op_jumpmark.address = address; -//} -// -//void PPCRecompilerImlGen_generateNewInstruction_macro(ppcImlGenContext_t* ppcImlGenContext, uint32 macroId, uint32 param, uint32 param2, uint16 paramU16) -//{ -// // no-op that indicates possible destination of a jump -// IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext); -// imlInstruction->type = PPCREC_IML_TYPE_MACRO; -// imlInstruction->operation = macroId; -// imlInstruction->op_macro.param = param; -// imlInstruction->op_macro.param2 = param2; -// imlInstruction->op_macro.paramU16 = paramU16; -//} - -///* -// * Generates a marker for Interpreter -> Recompiler entrypoints -// * PPC_ENTER iml instructions have no associated PPC address but the instruction itself has one -// */ -//void PPCRecompilerImlGen_generateNewInstruction_ppcEnter(ppcImlGenContext_t* ppcImlGenContext, uint32 ppcAddress) -//{ -// // no-op that indicates possible destination of a jump -// IMLInstruction* imlInstruction = PPCRecompilerImlGen_generateNewEmptyInstruction(ppcImlGenContext); -// imlInstruction->type = PPCREC_IML_TYPE_PPC_ENTER; -// imlInstruction->operation = 0; -// imlInstruction->op_ppcEnter.ppcAddress = ppcAddress; -// imlInstruction->op_ppcEnter.x64Offset = 0; -// imlInstruction->associatedPPCAddress = 0; -//} void PPCRecompilerImlGen_generateNewInstruction_r_r(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, uint32 operation, uint8 registerResult, uint8 registerA, uint8 crRegister, uint8 crMode) { @@ -2968,472 +2933,6 @@ uint32 PPCRecompiler_getPreviousInstruction(ppcImlGenContext_t* ppcImlGenContext return v; } -char _tempOpcodename[32]; - -const char* PPCRecompiler_getOpcodeDebugName(const IMLInstruction* iml) -{ - uint32 op = iml->operation; - if (op == PPCREC_IML_OP_ASSIGN) - return "MOV"; - else if (op == PPCREC_IML_OP_ADD) - return "ADD"; - else if (op == PPCREC_IML_OP_SUB) - return "SUB"; - else if (op == PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY) - return "ADDCSC"; - else if (op == PPCREC_IML_OP_OR) - return "OR"; - else if (op == PPCREC_IML_OP_AND) - return "AND"; - else if (op == PPCREC_IML_OP_XOR) - return "XOR"; - else if (op == PPCREC_IML_OP_LEFT_SHIFT) - return "LSH"; - else if (op == PPCREC_IML_OP_RIGHT_SHIFT) - return "RSH"; - else if (op == PPCREC_IML_OP_MULTIPLY_SIGNED) - return "MULS"; - else if (op == PPCREC_IML_OP_DIVIDE_SIGNED) - return "DIVS"; - - sprintf(_tempOpcodename, "OP0%02x_T%d", iml->operation, iml->type); - return _tempOpcodename; -} - -void PPCRecDebug_addRegisterParam(StringBuf& strOutput, sint32 virtualRegister, bool isLast = false) -{ - if (isLast) - { - if (virtualRegister < 10) - strOutput.addFmt("t{} ", virtualRegister); - else - strOutput.addFmt("t{}", virtualRegister); - return; - } - if (virtualRegister < 10) - strOutput.addFmt("t{} , ", virtualRegister); - else - strOutput.addFmt("t{}, ", virtualRegister); -} - -void PPCRecDebug_addS32Param(StringBuf& strOutput, sint32 val, bool isLast = false) -{ - if (isLast) - { - strOutput.addFmt("0x{:08x}", val); - return; - } - strOutput.addFmt("0x{:08x}, ", val); -} - -void PPCRecompilerDebug_printLivenessRangeInfo(StringBuf& currentLineText, IMLSegment* imlSegment, sint32 offset) -{ - // pad to 70 characters - sint32 index = currentLineText.getLen(); - while (index < 70) - { - debug_printf(" "); - index++; - } - raLivenessSubrange_t* subrangeItr = imlSegment->raInfo.linkedList_allSubranges; - while (subrangeItr) - { - if (offset == subrangeItr->start.index) - { - if (false)//subrange->isDirtied && i == subrange->becomesDirtyAtIndex.index) - { - debug_printf("*%-2d", subrangeItr->range->virtualRegister); - } - else - { - debug_printf("|%-2d", subrangeItr->range->virtualRegister); - } - } - else if (false)//subrange->isDirtied && i == subrange->becomesDirtyAtIndex.index ) - { - debug_printf("* "); - } - else if (offset >= subrangeItr->start.index && offset < subrangeItr->end.index) - { - debug_printf("| "); - } - else - { - debug_printf(" "); - } - index += 3; - // next - subrangeItr = subrangeItr->link_segmentSubrangesGPR.next; - } -} - -void PPCRecompiler_dumpIMLSegment(IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo) -{ - StringBuf strOutput(1024); - - strOutput.addFmt("SEGMENT 0x{:04x} 0x{:08x} PPC 0x{:08x} - 0x{:08x} Loop-depth {}", segmentIndex, imlSegment->ppcAddress, imlSegment->ppcAddrMin, imlSegment->ppcAddrMax, imlSegment->loopDepth); - if (imlSegment->isEnterable) - { - strOutput.addFmt(" ENTERABLE (0x{:08x})", imlSegment->enterPPCAddress); - } - else if( imlSegment->isJumpDestination ) - { - strOutput.addFmt(" JUMP-DEST (0x{:08x})", imlSegment->jumpDestinationPPCAddress); - } - - debug_printf("%s\n", strOutput.c_str()); - - strOutput.reset(); - strOutput.addFmt("SEGMENT NAME 0x{:016x}", (uintptr_t)imlSegment); - debug_printf("%s", strOutput.c_str()); - - if (printLivenessRangeInfo) - { - PPCRecompilerDebug_printLivenessRangeInfo(strOutput, imlSegment, RA_INTER_RANGE_START); - } - debug_printf("\n"); - - sint32 lineOffsetParameters = 18; - - for(sint32 i=0; iimlList.size(); i++) - { - const IMLInstruction& inst = imlSegment->imlList[i]; - // don't log NOP instructions unless they have an associated PPC address - if(inst.type == PPCREC_IML_TYPE_NO_OP && inst.associatedPPCAddress == MPTR_NULL) - continue; - strOutput.reset(); - strOutput.addFmt("{:08x} ", inst.associatedPPCAddress); - if( inst.type == PPCREC_IML_TYPE_R_NAME || inst.type == PPCREC_IML_TYPE_NAME_R) - { - if(inst.type == PPCREC_IML_TYPE_R_NAME) - strOutput.add("LD_NAME"); - else - strOutput.add("ST_NAME"); - while ((sint32)strOutput.getLen() < lineOffsetParameters) - strOutput.add(" "); - - PPCRecDebug_addRegisterParam(strOutput, inst.op_r_name.registerIndex); - - strOutput.addFmt("name_{} (", inst.op_r_name.registerIndex, inst.op_r_name.name); - if( inst.op_r_name.name >= PPCREC_NAME_R0 && inst.op_r_name.name < (PPCREC_NAME_R0+999) ) - { - strOutput.addFmt("r{}", inst.op_r_name.name-PPCREC_NAME_R0); - } - else if( inst.op_r_name.name >= PPCREC_NAME_SPR0 && inst.op_r_name.name < (PPCREC_NAME_SPR0+999) ) - { - strOutput.addFmt("spr{}", inst.op_r_name.name-PPCREC_NAME_SPR0); - } - else - strOutput.add("ukn"); - strOutput.add(")"); - } - else if( inst.type == PPCREC_IML_TYPE_R_R ) - { - strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(&inst)); - while ((sint32)strOutput.getLen() < lineOffsetParameters) - strOutput.add(" "); - PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r.registerResult); - PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r.registerA, true); - - if( inst.crRegister != PPC_REC_INVALID_REGISTER ) - { - strOutput.addFmt(" -> CR{}", inst.crRegister); - } - } - else if( inst.type == PPCREC_IML_TYPE_R_R_R ) - { - strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(&inst)); - while ((sint32)strOutput.getLen() < lineOffsetParameters) - strOutput.add(" "); - PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_r.registerResult); - PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_r.registerA); - PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_r.registerB, true); - if( inst.crRegister != PPC_REC_INVALID_REGISTER ) - { - strOutput.addFmt(" -> CR{}", inst.crRegister); - } - } - else if (inst.type == PPCREC_IML_TYPE_R_R_S32) - { - strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(&inst)); - while ((sint32)strOutput.getLen() < lineOffsetParameters) - strOutput.add(" "); - - PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_s32.registerResult); - PPCRecDebug_addRegisterParam(strOutput, inst.op_r_r_s32.registerA); - PPCRecDebug_addS32Param(strOutput, inst.op_r_r_s32.immS32, true); - - if (inst.crRegister != PPC_REC_INVALID_REGISTER) - { - strOutput.addFmt(" -> CR{}", inst.crRegister); - } - } - else if (inst.type == PPCREC_IML_TYPE_R_S32) - { - strOutput.addFmt("{}", PPCRecompiler_getOpcodeDebugName(&inst)); - while ((sint32)strOutput.getLen() < lineOffsetParameters) - strOutput.add(" "); - - PPCRecDebug_addRegisterParam(strOutput, inst.op_r_immS32.registerIndex); - PPCRecDebug_addS32Param(strOutput, inst.op_r_immS32.immS32, true); - - if (inst.crRegister != PPC_REC_INVALID_REGISTER) - { - strOutput.addFmt(" -> CR{}", inst.crRegister); - } - } - else if( inst.type == PPCREC_IML_TYPE_JUMPMARK ) - { - strOutput.addFmt("jm_{:08x}:", inst.op_jumpmark.address); - } - else if( inst.type == PPCREC_IML_TYPE_PPC_ENTER ) - { - strOutput.addFmt("ppcEnter_{:08x}:", inst.op_ppcEnter.ppcAddress); - } - else if(inst.type == PPCREC_IML_TYPE_LOAD || inst.type == PPCREC_IML_TYPE_STORE || - inst.type == PPCREC_IML_TYPE_LOAD_INDEXED || inst.type == PPCREC_IML_TYPE_STORE_INDEXED ) - { - if(inst.type == PPCREC_IML_TYPE_LOAD || inst.type == PPCREC_IML_TYPE_LOAD_INDEXED) - strOutput.add("LD_"); - else - strOutput.add("ST_"); - - if (inst.op_storeLoad.flags2.signExtend) - strOutput.add("S"); - else - strOutput.add("U"); - strOutput.addFmt("{}", inst.op_storeLoad.copyWidth); - - while ((sint32)strOutput.getLen() < lineOffsetParameters) - strOutput.add(" "); - - PPCRecDebug_addRegisterParam(strOutput, inst.op_storeLoad.registerData); - - if(inst.type == PPCREC_IML_TYPE_LOAD_INDEXED || inst.type == PPCREC_IML_TYPE_STORE_INDEXED) - strOutput.addFmt("[t{}+t{}]", inst.op_storeLoad.registerMem, inst.op_storeLoad.registerMem2); - else - strOutput.addFmt("[t{}+{}]", inst.op_storeLoad.registerMem, inst.op_storeLoad.immS32); - } - else if( inst.type == PPCREC_IML_TYPE_CJUMP ) - { - if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_E) - strOutput.add("JE"); - else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NE) - strOutput.add("JNE"); - else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_G) - strOutput.add("JG"); - else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_GE) - strOutput.add("JGE"); - else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_L) - strOutput.add("JL"); - else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_LE) - strOutput.add("JLE"); - else if (inst.op_conditionalJump.condition == PPCREC_JUMP_CONDITION_NONE) - strOutput.add("JALW"); // jump always - else - cemu_assert_unimplemented(); - strOutput.addFmt(" jm_{:08x} (cr{})", inst.op_conditionalJump.jumpmarkAddress, inst.crRegister); - } - else if( inst.type == PPCREC_IML_TYPE_NO_OP ) - { - strOutput.add("NOP"); - } - else if( inst.type == PPCREC_IML_TYPE_MACRO ) - { - if( inst.operation == PPCREC_IML_MACRO_BLR ) - { - strOutput.addFmt("MACRO BLR 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16); - } - else if( inst.operation == PPCREC_IML_MACRO_BLRL ) - { - strOutput.addFmt("MACRO BLRL 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16); - } - else if( inst.operation == PPCREC_IML_MACRO_BCTR ) - { - strOutput.addFmt("MACRO BCTR 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16); - } - else if( inst.operation == PPCREC_IML_MACRO_BCTRL ) - { - strOutput.addFmt("MACRO BCTRL 0x{:08x} cycles (depr): {}", inst.op_macro.param, (sint32)inst.op_macro.paramU16); - } - else if( inst.operation == PPCREC_IML_MACRO_BL ) - { - 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( inst.operation == PPCREC_IML_MACRO_B_FAR ) - { - 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( inst.operation == PPCREC_IML_MACRO_LEAVE ) - { - strOutput.addFmt("MACRO LEAVE ppc: 0x{:08x}", inst.op_macro.param); - } - else if( inst.operation == PPCREC_IML_MACRO_HLE ) - { - strOutput.addFmt("MACRO HLE ppcAddr: 0x{:08x} funcId: 0x{:08x}", inst.op_macro.param, inst.op_macro.param2); - } - else if( inst.operation == PPCREC_IML_MACRO_MFTB ) - { - strOutput.addFmt("MACRO MFTB ppcAddr: 0x{:08x} sprId: 0x{:08x}", inst.op_macro.param, inst.op_macro.param2); - } - else if( inst.operation == PPCREC_IML_MACRO_COUNT_CYCLES ) - { - strOutput.addFmt("MACRO COUNT_CYCLES cycles: {}", inst.op_macro.param); - } - else - { - strOutput.addFmt("MACRO ukn operation {}", inst.operation); - } - } - else if( inst.type == PPCREC_IML_TYPE_FPR_R_NAME ) - { - strOutput.addFmt("fpr_t{} = name_{} (", inst.op_r_name.registerIndex, inst.op_r_name.name); - if( inst.op_r_name.name >= PPCREC_NAME_FPR0 && inst.op_r_name.name < (PPCREC_NAME_FPR0+999) ) - { - strOutput.addFmt("fpr{}", inst.op_r_name.name-PPCREC_NAME_FPR0); - } - else if( inst.op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && inst.op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0+999) ) - { - strOutput.addFmt("tempFpr{}", inst.op_r_name.name-PPCREC_NAME_TEMPORARY_FPR0); - } - else - strOutput.add("ukn"); - strOutput.add(")"); - } - else if( inst.type == PPCREC_IML_TYPE_FPR_NAME_R ) - { - strOutput.addFmt("name_{} (", inst.op_r_name.name); - if( inst.op_r_name.name >= PPCREC_NAME_FPR0 && inst.op_r_name.name < (PPCREC_NAME_FPR0+999) ) - { - strOutput.addFmt("fpr{}", inst.op_r_name.name-PPCREC_NAME_FPR0); - } - else if( inst.op_r_name.name >= PPCREC_NAME_TEMPORARY_FPR0 && inst.op_r_name.name < (PPCREC_NAME_TEMPORARY_FPR0+999) ) - { - strOutput.addFmt("tempFpr{}", inst.op_r_name.name-PPCREC_NAME_TEMPORARY_FPR0); - } - else - strOutput.add("ukn"); - strOutput.addFmt(") = fpr_t{}", inst.op_r_name.registerIndex); - } - else if( inst.type == PPCREC_IML_TYPE_FPR_LOAD ) - { - strOutput.addFmt("fpr_t{} = ", inst.op_storeLoad.registerData); - if( inst.op_storeLoad.flags2.signExtend ) - strOutput.add("S"); - else - strOutput.add("U"); - strOutput.addFmt("{} [t{}+{}] mode {}", inst.op_storeLoad.copyWidth / 8, inst.op_storeLoad.registerMem, inst.op_storeLoad.immS32, inst.op_storeLoad.mode); - if (inst.op_storeLoad.flags2.notExpanded) - { - strOutput.addFmt(" "); - } - } - else if( inst.type == PPCREC_IML_TYPE_FPR_STORE ) - { - if( inst.op_storeLoad.flags2.signExtend ) - strOutput.add("S"); - else - strOutput.add("U"); - strOutput.addFmt("{} [t{}+{}]", inst.op_storeLoad.copyWidth/8, inst.op_storeLoad.registerMem, inst.op_storeLoad.immS32); - strOutput.addFmt("= fpr_t{} mode {}\n", inst.op_storeLoad.registerData, inst.op_storeLoad.mode); - } - else if( inst.type == PPCREC_IML_TYPE_FPR_R_R ) - { - strOutput.addFmt("{:-6} ", PPCRecompiler_getOpcodeDebugName(&inst)); - strOutput.addFmt("fpr{:02d}, fpr{:02d}", inst.op_fpr_r_r.registerResult, inst.op_fpr_r_r.registerOperand); - } - else if( inst.type == PPCREC_IML_TYPE_FPR_R_R_R_R ) - { - strOutput.addFmt("{:-6} ", PPCRecompiler_getOpcodeDebugName(&inst)); - 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( inst.type == PPCREC_IML_TYPE_FPR_R_R_R ) - { - strOutput.addFmt("{:-6} ", PPCRecompiler_getOpcodeDebugName(&inst)); - 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 (inst.type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK) - { - strOutput.addFmt("CYCLE_CHECK jm_{:08x}\n", inst.op_conditionalJump.jumpmarkAddress); - } - else if (inst.type == PPCREC_IML_TYPE_CONDITIONAL_R_S32) - { - strOutput.addFmt("t{} ", inst.op_conditional_r_s32.registerIndex); - bool displayAsHex = false; - if (inst.operation == PPCREC_IML_OP_ASSIGN) - { - displayAsHex = true; - strOutput.add("="); - } - else - strOutput.addFmt("(unknown operation CONDITIONAL_R_S32 {})", inst.operation); - if (displayAsHex) - strOutput.addFmt(" 0x{:x}", inst.op_conditional_r_s32.immS32); - else - strOutput.addFmt(" {}", inst.op_conditional_r_s32.immS32); - strOutput.add(" (conditional)"); - if (inst.crRegister != PPC_REC_INVALID_REGISTER) - { - strOutput.addFmt(" -> and update CR{}", inst.crRegister); - } - } - else - { - strOutput.addFmt("Unknown iml type {}", inst.type); - } - debug_printf("%s", strOutput.c_str()); - if (printLivenessRangeInfo) - { - PPCRecompilerDebug_printLivenessRangeInfo(strOutput, imlSegment, i); - } - debug_printf("\n"); - } - // all ranges - if (printLivenessRangeInfo) - { - debug_printf("Ranges-VirtReg "); - raLivenessSubrange_t* subrangeItr = imlSegment->raInfo.linkedList_allSubranges; - while(subrangeItr) - { - debug_printf("v%-2d", subrangeItr->range->virtualRegister); - subrangeItr = subrangeItr->link_segmentSubrangesGPR.next; - } - debug_printf("\n"); - debug_printf("Ranges-PhysReg "); - subrangeItr = imlSegment->raInfo.linkedList_allSubranges; - while (subrangeItr) - { - debug_printf("p%-2d", subrangeItr->range->physicalRegister); - subrangeItr = subrangeItr->link_segmentSubrangesGPR.next; - } - debug_printf("\n"); - } - // branch info - debug_printf("Links from: "); - for (sint32 i = 0; i < imlSegment->list_prevSegments.size(); i++) - { - if (i) - debug_printf(", "); - debug_printf("%p", (void*)imlSegment->list_prevSegments[i]); - } - debug_printf("\n"); - debug_printf("Links to: "); - if (imlSegment->nextSegmentBranchNotTaken) - debug_printf("%p (no branch), ", (void*)imlSegment->nextSegmentBranchNotTaken); - if (imlSegment->nextSegmentBranchTaken) - debug_printf("%p (branch)", (void*)imlSegment->nextSegmentBranchTaken); - debug_printf("\n"); -} - -void PPCRecompiler_dumpIML(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext) -{ - for (size_t i = 0; i < ppcImlGenContext->segmentList2.size(); i++) - { - PPCRecompiler_dumpIMLSegment(ppcImlGenContext->segmentList2[i], i); - debug_printf("\n"); - } -} - void PPCRecompilerIml_setSegmentPoint(ppcRecompilerSegmentPoint_t* segmentPoint, IMLSegment* imlSegment, sint32 index) { segmentPoint->imlSegment = imlSegment; @@ -3528,39 +3027,9 @@ void PPCRecompiler_freeContext(ppcImlGenContext_t* ppcImlGenContext) for (IMLSegment* imlSegment : ppcImlGenContext->segmentList2) { - //free(imlSegment->imlList); delete imlSegment; } ppcImlGenContext->segmentList2.clear(); - - //for(sint32 i=0; isegmentListCount; i++) - //{ - // free(ppcImlGenContext->segmentList[i]->imlList); - // delete ppcImlGenContext->segmentList[i]; - //} - //ppcImlGenContext->segmentListCount = 0; - //if (ppcImlGenContext->segmentList) - //{ - // free(ppcImlGenContext->segmentList); - // ppcImlGenContext->segmentList = nullptr; - //} -} - -bool PPCRecompiler_isSuffixInstruction(IMLInstruction* iml) -{ - if (iml->type == PPCREC_IML_TYPE_MACRO && (iml->operation == PPCREC_IML_MACRO_BLR || iml->operation == PPCREC_IML_MACRO_BCTR) || - iml->type == PPCREC_IML_TYPE_MACRO && iml->operation == PPCREC_IML_MACRO_BL || - iml->type == PPCREC_IML_TYPE_MACRO && iml->operation == PPCREC_IML_MACRO_B_FAR || - iml->type == PPCREC_IML_TYPE_MACRO && iml->operation == PPCREC_IML_MACRO_BLRL || - iml->type == PPCREC_IML_TYPE_MACRO && iml->operation == PPCREC_IML_MACRO_BCTRL || - iml->type == PPCREC_IML_TYPE_MACRO && iml->operation == PPCREC_IML_MACRO_LEAVE || - iml->type == PPCREC_IML_TYPE_MACRO && iml->operation == PPCREC_IML_MACRO_HLE || - iml->type == PPCREC_IML_TYPE_MACRO && iml->operation == PPCREC_IML_MACRO_MFTB || - iml->type == PPCREC_IML_TYPE_PPC_ENTER || - iml->type == PPCREC_IML_TYPE_CJUMP || - iml->type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK) - return true; - return false; } bool PPCRecompiler_decodePPCInstruction(ppcImlGenContext_t* ppcImlGenContext) @@ -4758,8 +4227,6 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext memcpy(PPCRecompiler_appendInstruction(segIt), finalSegment->imlList.data() + f, sizeof(IMLInstruction)); } finalSegment->imlList.clear(); - - //PPCRecompiler_dumpIML(ppcRecFunc, &ppcImlGenContext); } // todo: If possible, merge with the segment following conditionalSegment (merging is only possible if the segment is not an entry point or has no other jump sources) @@ -4820,7 +4287,6 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext // All segments are considered to be part of the same PPC instruction range // The first segment also retains the jump destination and enterable properties from the original segment. //debug_printf("--- Insert cycle counter check ---\n"); - //PPCRecompiler_dumpIML(ppcRecFunc, &ppcImlGenContext); PPCRecompilerIml_insertSegments(&ppcImlGenContext, s, 2); imlSegment = NULL; diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlOptimizer.cpp b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlOptimizer.cpp index 4ea28062..9edbc6ff 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlOptimizer.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlOptimizer.cpp @@ -942,26 +942,6 @@ bool PPCRecompiler_findAvailableRegisterDepr(ppcImlGenContext_t* ppcImlGenContex } -bool PPCRecompiler_hasSuffixInstruction(IMLSegment* imlSegment) -{ - if (imlSegment->imlList.empty()) - return false; - const IMLInstruction& imlInstruction = imlSegment->imlList.back(); - if( imlInstruction.type == PPCREC_IML_TYPE_MACRO && (imlInstruction.operation == PPCREC_IML_MACRO_BLR || imlInstruction.operation == PPCREC_IML_MACRO_BCTR) || - imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_BL || - imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_B_FAR || - imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_BLRL || - imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_BCTRL || - imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_LEAVE || - imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_HLE || - imlInstruction.type == PPCREC_IML_TYPE_MACRO && imlInstruction.operation == PPCREC_IML_MACRO_MFTB || - imlInstruction.type == PPCREC_IML_TYPE_PPC_ENTER || - imlInstruction.type == PPCREC_IML_TYPE_CJUMP || - imlInstruction.type == PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK ) - return true; - return false; -} - void PPCRecompiler_storeReplacedRegister(ppcImlGenContext_t* ppcImlGenContext, IMLSegment* imlSegment, replacedRegisterTracker_t* replacedRegisterTracker, sint32 registerTrackerIndex, sint32* imlIndex) { // store register @@ -1203,7 +1183,7 @@ bool PPCRecompiler_manageFPRRegistersForSegment(ppcImlGenContext_t* ppcImlGenCon while (idx < imlSegment->imlList.size()) { IMLInstruction& idxInst = imlSegment->imlList[idx]; - if ( PPCRecompiler_isSuffixInstruction(&idxInst) ) + if (idxInst.IsSuffixInstruction()) break; PPCRecompiler_checkRegisterUsage(ppcImlGenContext, &idxInst, ®istersUsed); sint32 fprMatch[4]; @@ -1704,11 +1684,8 @@ void PPCRecompiler_optimizeDirectFloatCopiesScanForward(ppcImlGenContext_t* ppcI for (sint32 i = imlIndexLoad + 1; i < scanRangeEnd; i++) { IMLInstruction* imlInstruction = imlSegment->imlList.data() + i; - if (PPCRecompiler_isSuffixInstruction(imlInstruction)) - { + if (imlInstruction->IsSuffixInstruction()) break; - } - // check if FPR is stored if ((imlInstruction->type == PPCREC_IML_TYPE_FPR_STORE && imlInstruction->op_storeLoad.mode == PPCREC_FPR_ST_MODE_SINGLE_FROM_PS0) || (imlInstruction->type == PPCREC_IML_TYPE_FPR_STORE_INDEXED && imlInstruction->op_storeLoad.mode == PPCREC_FPR_ST_MODE_SINGLE_FROM_PS0)) @@ -1795,10 +1772,8 @@ void PPCRecompiler_optimizeDirectIntegerCopiesScanForward(ppcImlGenContext_t* pp for (; i < scanRangeEnd; i++) { IMLInstruction* imlInstruction = imlSegment->imlList.data() + i; - if (PPCRecompiler_isSuffixInstruction(imlInstruction)) - { + if (imlInstruction->IsSuffixInstruction()) break; - } // check if GPR is stored if ((imlInstruction->type == PPCREC_IML_TYPE_STORE && imlInstruction->op_storeLoad.copyWidth == 32 ) ) { diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlRegisterAllocator.cpp b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlRegisterAllocator.cpp index 3d4546c1..afe6d943 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlRegisterAllocator.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerImlRegisterAllocator.cpp @@ -5,8 +5,6 @@ void PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, sint32 gprRegisterSearched[4], sint32 gprRegisterReplaced[4]); -bool PPCRecompiler_isSuffixInstruction(IMLInstruction* iml); - uint32 recRACurrentIterationIndex = 0; uint32 PPCRecRA_getNextIterationIndex() @@ -759,7 +757,7 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext, raLiveRangeInfo_t liveInfo; liveInfo.liveRangesCount = 0; sint32 index = 0; - sint32 suffixInstructionCount = (imlSegment->imlList.size() > 0 && PPCRecompiler_isSuffixInstruction(imlSegment->imlList.data() + imlSegment->imlList.size() - 1)) ? 1 : 0; + sint32 suffixInstructionCount = imlSegment->HasSuffixInstruction() ? 1 : 0; // load register ranges that are supplied from previous segments raLivenessSubrange_t* subrangeItr = imlSegment->raInfo.linkedList_allSubranges; //for (auto& subrange : imlSegment->raInfo.list_subranges) @@ -1020,7 +1018,7 @@ void PPCRecRA_calculateSegmentMinMaxRanges(ppcImlGenContext_t* ppcImlGenContext, while (index < imlSegment->imlList.size()) { // end loop at suffix instruction - if (PPCRecompiler_isSuffixInstruction(imlSegment->imlList.data() + index)) + if (imlSegment->imlList[index].IsSuffixInstruction()) break; // get accessed GPRs PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList.data() + index, &gprTracking); @@ -1113,7 +1111,7 @@ void PPCRecRA_createSegmentLivenessRanges(ppcImlGenContext_t* ppcImlGenContext, while (index < imlSegment->imlList.size()) { // end loop at suffix instruction - if (PPCRecompiler_isSuffixInstruction(imlSegment->imlList.data() + index)) + if (imlSegment->imlList[index].IsSuffixInstruction()) break; // get accessed GPRs PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList.data() + index, &gprTracking); diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerX64.cpp b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerX64.cpp index 21edc810..6a3dd39d 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerX64.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompilerX64.cpp @@ -2266,8 +2266,6 @@ uint8* PPCRecompilerX86_allocateExecutableMemory(sint32 size) return codeMem; } -void PPCRecompiler_dumpIML(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext); - bool PPCRecompiler_generateX64Code(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext) { x64GenContext_t x64GenContext = {0};