rsx/fp: Fix pre-branch epilogue emit

This commit is contained in:
kd-11 2025-12-08 02:44:20 +03:00 committed by kd-11
parent 98a12de256
commit 5688573b3d
2 changed files with 31 additions and 24 deletions

View File

@ -139,6 +139,7 @@ namespace rsx::assembler
default: default:
// Missing an edge type? // Missing an edge type?
rsx_log.error("CFG: Unexpected block exit. Report to developers."); rsx_log.error("CFG: Unexpected block exit. Report to developers.");
break;
} }
} }
else if (bb->pred.empty()) else if (bb->pred.empty())
@ -221,6 +222,7 @@ namespace rsx::assembler
ir_inst.length += 4; ir_inst.length += 4;
pc++; pc++;
} }
break;
} }
pc++; pc++;

View File

@ -1276,7 +1276,7 @@ std::string FragmentProgramDecompiler::Decompile()
// The RSX CFG is missing the output block. We inject a fake tail block that ingests the ROP outputs. // The RSX CFG is missing the output block. We inject a fake tail block that ingests the ROP outputs.
BasicBlock* rop_block = nullptr; BasicBlock* rop_block = nullptr;
BasicBlock* tail_block = &graph.blocks.back(); BasicBlock* tail_block = &graph.blocks.back();
if (tail_block->instructions.size() == 0) if (tail_block->instructions.empty())
{ {
// Merge block. Use this directly // Merge block. Use this directly
rop_block = tail_block; rop_block = tail_block;
@ -1326,6 +1326,20 @@ std::string FragmentProgramDecompiler::Decompile()
block_data[block] = { level, loop }; block_data[block] = { level, loop };
}; };
auto emit_block = [&](const std::vector<Instruction>& instructions)
{
for (auto& inst : instructions)
{
m_instruction = &inst;
dst.HEX = inst.bytecode[0];
src0.HEX = inst.bytecode[1];
src1.HEX = inst.bytecode[2];
src2.HEX = inst.bytecode[3];
ensure(handle_tex_srb(inst.opcode) || handle_sct_scb(inst.opcode), "Unsupported operation");
}
};
for (const auto &block : graph.blocks) for (const auto &block : graph.blocks)
{ {
auto found = block_data.find(&block); auto found = block_data.find(&block);
@ -1376,21 +1390,22 @@ std::string FragmentProgramDecompiler::Decompile()
if (!block.prologue.empty()) if (!block.prologue.empty())
{ {
AddCode("// Prologue"); AddCode("// Prologue");
emit_block(block.prologue);
for (auto& inst : block.prologue)
{
m_instruction = &inst;
dst.HEX = inst.bytecode[0];
src0.HEX = inst.bytecode[1];
src1.HEX = inst.bytecode[2];
src2.HEX = inst.bytecode[3];
ensure(handle_tex_srb(inst.opcode) || handle_sct_scb(inst.opcode), "Unsupported operation");
}
} }
const bool early_epilogue =
!block.epilogue.empty() &&
!block.succ.empty() &&
(block.succ.front().type == EdgeType::IF || block.succ.front().type == EdgeType::LOOP);
for (const auto& inst : block.instructions) for (const auto& inst : block.instructions)
{ {
if (early_epilogue && &inst == &block.instructions.back())
{
AddCode("// Epilogue");
emit_block(block.epilogue);
}
m_instruction = &inst; m_instruction = &inst;
dst.HEX = inst.bytecode[0]; dst.HEX = inst.bytecode[0];
@ -1459,20 +1474,10 @@ std::string FragmentProgramDecompiler::Decompile()
if (dst.end) break; if (dst.end) break;
} }
if (!block.epilogue.empty()) if (!early_epilogue && !block.epilogue.empty())
{ {
AddCode("// Epilogue"); AddCode("// Epilogue");
emit_block(block.epilogue);
for (auto& inst : block.epilogue)
{
m_instruction = &inst;
dst.HEX = inst.bytecode[0];
src0.HEX = inst.bytecode[1];
src1.HEX = inst.bytecode[2];
src2.HEX = inst.bytecode[3];
ensure(handle_tex_srb(inst.opcode) || handle_sct_scb(inst.opcode), "Unsupported operation");
}
} }
for (auto& succ : block.succ) for (auto& succ : block.succ)