diff --git a/src/core/cpu_code_cache.cpp b/src/core/cpu_code_cache.cpp index c75245cc9..289382c13 100644 --- a/src/core/cpu_code_cache.cpp +++ b/src/core/cpu_code_cache.cpp @@ -496,6 +496,56 @@ CPU::CodeCache::Block* CPU::CodeCache::CreateBlock(u32 pc, const BlockInstructio // add it to the tracking list for its page AddBlockToPageList(block); +#if 0 + SmallString disasm; + u32 disasm_pc = block->pc; + for (u32 i = 0; i < block->size; i++) + { + const Instruction* inst = block->Instructions() + i; + const InstructionInfo* iinfo = block->InstructionsInfo() + i; + CPU::DisassembleInstruction(&disasm, disasm_pc, inst->bits); + DEBUG_LOG("[{} {} 0x{:08X}] {:08X} {}", iinfo->is_branch_delay_slot ? "BD" : " ", + iinfo->is_load_delay_slot ? "LD" : " ", disasm_pc, inst->bits, disasm); + disasm_pc += sizeof(Instruction); + + disasm.clear(); + for (u32 j = 0; j < static_cast(std::size(iinfo->read_reg)); j++) + { + if (iinfo->read_reg[j] != Reg::zero) + disasm.append_format("{}{}", disasm.empty() ? "" : ", ", GetRegName(iinfo->read_reg[j])); + } + if (!disasm.empty()) + DEBUG_LOG(" Reads: {}", disasm); + + disasm.clear(); + for (u32 j = 0; j < static_cast(std::size(iinfo->reg_flags)); j++) + { + if (iinfo->reg_flags[j] & RI_LIVE) + disasm.append_format("{}{}", disasm.empty() ? "" : ", ", GetRegName(static_cast(j))); + } + if (!disasm.empty()) + DEBUG_LOG(" Live: {}", disasm); + + disasm.clear(); + for (u32 j = 0; j < static_cast(std::size(iinfo->reg_flags)); j++) + { + if (iinfo->reg_flags[j] & RI_USED) + disasm.append_format("{}{}", disasm.empty() ? "" : ", ", GetRegName(static_cast(j))); + } + if (!disasm.empty()) + DEBUG_LOG(" Used: {}", disasm); + + disasm.clear(); + for (u32 j = 0; j < static_cast(std::size(iinfo->reg_flags)); j++) + { + if (iinfo->reg_flags[j] & RI_LASTUSE) + disasm.append_format("{}{}", disasm.empty() ? "" : ", ", GetRegName(static_cast(j))); + } + if (!disasm.empty()) + DEBUG_LOG(" Last-Use: {}", disasm); + } +#endif + return block; } @@ -1077,7 +1127,8 @@ void CPU::CodeCache::SetRegAccess(InstructionInfo* inst, Reg reg, bool write) { \ if (!(inst->reg_flags[static_cast(reg)] & RI_USED)) \ inst->reg_flags[static_cast(reg)] |= RI_LASTUSE; \ - prev->reg_flags[static_cast(reg)] |= RI_LIVE | RI_USED; \ + if (prev) \ + prev->reg_flags[static_cast(reg)] |= RI_LIVE | RI_USED; \ inst->reg_flags[static_cast(reg)] |= RI_USED; \ SetRegAccess(inst, reg, false); \ } while (0) @@ -1085,7 +1136,8 @@ void CPU::CodeCache::SetRegAccess(InstructionInfo* inst, Reg reg, bool write) #define BackpropSetWrites(reg) \ do \ { \ - prev->reg_flags[static_cast(reg)] &= ~(RI_LIVE | RI_USED); \ + if (prev) \ + prev->reg_flags[static_cast(reg)] &= ~(RI_LIVE | RI_USED); \ if (!(inst->reg_flags[static_cast(reg)] & RI_USED)) \ inst->reg_flags[static_cast(reg)] |= RI_LASTUSE; \ inst->reg_flags[static_cast(reg)] |= RI_USED; \ @@ -1104,10 +1156,11 @@ void CPU::CodeCache::FillBlockRegInfo(Block* block) std::memset(inst->read_reg, 0, sizeof(inst->read_reg)); // std::memset(inst->write_reg, 0, sizeof(inst->write_reg)); - while (inst != start) + for (;;) { - InstructionInfo* prev = inst - 1; - CopyRegInfo(prev, inst); + InstructionInfo* const prev = (inst == start) ? nullptr : inst - 1; + if (prev) + CopyRegInfo(prev, inst); const Reg rs = iinst->r.rs; const Reg rt = iinst->r.rt; @@ -1292,9 +1345,12 @@ void CPU::CodeCache::FillBlockRegInfo(Block* block) break; } // end switch + if (inst == start) + break; + inst--; iinst--; - } // end while + } // end for } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////