mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-03-25 11:58:36 -06:00
rsx/cfg: Fix handling of instructions with literal input
- The hardware is pretty dumb about it, it just unconditionally skips the next instruction
This commit is contained in:
parent
2ba7756c0e
commit
67f69bb4b3
@ -165,6 +165,14 @@ namespace rsx::assembler
|
||||
|
||||
if (opcode == RSX_FP_OPCODE_NOP)
|
||||
{
|
||||
if (includes_literal_constant())
|
||||
{
|
||||
// Verified behavior on real hardware
|
||||
// If any input on a non-flow-control instruction is of literal type the next instruction is assumed to be data
|
||||
// You can actually use this behavior to mask off instructions completely
|
||||
pc++;
|
||||
}
|
||||
|
||||
pc++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -679,8 +679,7 @@ fragment_program_utils::fragment_program_metadata fragment_program_utils::analys
|
||||
break;
|
||||
}
|
||||
|
||||
if (rsx::assembler::FP::get_operand_count(opcode) > 0 &&
|
||||
is_any_src_constant(inst))
|
||||
if (is_any_src_constant(inst))
|
||||
{
|
||||
// Instruction references constant, skip one slot occupied by data
|
||||
index++;
|
||||
|
||||
@ -251,4 +251,29 @@ namespace rsx::assembler
|
||||
EXPECT_EQ(SRC0{ .HEX = graph.blocks.front().instructions[0].bytecode[1] }.exec_if_gr, 1);
|
||||
EXPECT_EQ(SRC0{ .HEX = graph.blocks.front().instructions[0].bytecode[1] }.exec_if_eq, 1);
|
||||
}
|
||||
|
||||
TEST(CFG, FpToCFG_SkipOverImmediateOperand)
|
||||
{
|
||||
auto ir = FPIR::from_source(
|
||||
"MOV R0, #{ 0.25 };" // NOP with real dst and one literal input
|
||||
"MOV R0, R1;" // False merge block.
|
||||
);
|
||||
|
||||
RSXFragmentProgram program{};
|
||||
auto bytecode = ir.compile();
|
||||
program.data = bytecode.data();
|
||||
|
||||
ASSERT_EQ(bytecode.size(), 12);
|
||||
|
||||
// Patch the first instruction to be a NOP with a literal as input
|
||||
const u32 decoded_d0 = ((bytecode[0] & 0xFF00FF00u) >> 16u) | ((bytecode[0] & 0x00FF00FFu) << 16u);
|
||||
OPDEST d0{ .HEX = decoded_d0 };
|
||||
d0.opcode = RSX_FP_OPCODE_NOP;
|
||||
bytecode[0] = ((d0.HEX & 0xFF00FF00u) >> 16u) | ((d0.HEX & 0x00FF00FFu) << 16u);
|
||||
|
||||
FlowGraph graph = deconstruct_fragment_program(program);
|
||||
|
||||
ASSERT_EQ(graph.blocks.size(), 1);
|
||||
ASSERT_EQ(graph.blocks.front().instructions.size(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user