mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-03-29 06:39:48 -06:00
rsx/cfg: Handle IF-ELSE aliasing statement as inverted condition
- If there is no IF block but ELSE block exists, treat the branch as being inverted and the ELSE block as the main IF body - Rare but seen in some games
This commit is contained in:
parent
2f3b66985e
commit
d54e54b66d
@ -459,4 +459,12 @@ namespace rsx::assembler::FP
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Invert execution mask on an instruction
|
||||
void invert_conditional_execution_mask(Instruction* instruction)
|
||||
{
|
||||
// We want to invert src0.exec_if_gt|lt|eq which should be at bit offset 18-20
|
||||
constexpr u32 inv_mask = (0b111 << 18u);
|
||||
instruction->bytecode[1] = instruction->bytecode[1] ^ inv_mask;
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,5 +131,8 @@ namespace rsx::assembler
|
||||
|
||||
// Compile a register file annotated blob to register references
|
||||
std::vector<RegisterRef> compile_register_file(const std::array<char, 48 * 8>& file);
|
||||
|
||||
// Invert execution mask on an instruction
|
||||
void invert_conditional_execution_mask(Instruction* instruction);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "CFG.h"
|
||||
#include "FPOpcodes.h"
|
||||
|
||||
#include "Emu/RSX/Common/simple_array.hpp"
|
||||
#include "Emu/RSX/Program/RSXFragmentProgram.h"
|
||||
@ -211,7 +212,14 @@ namespace rsx::assembler
|
||||
|
||||
auto parent = bb;
|
||||
bb = safe_insert_block(parent, pc + 1u, EdgeType::IF);
|
||||
if (end_addr != else_addr)
|
||||
|
||||
if (else_addr == pc + 1u)
|
||||
{
|
||||
// Empty IF block. We co-opt the ELSE block as the IF and invert the condition.
|
||||
auto& inst = parent->instructions.back();
|
||||
FP::invert_conditional_execution_mask(&inst);
|
||||
}
|
||||
else if (end_addr != else_addr)
|
||||
{
|
||||
else_blocks.push_back(safe_insert_block(parent, else_addr, EdgeType::ELSE));
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user