Route guarded BLTZ winding consumers through original polarity

This commit is contained in:
Matthew Stanley
2026-10-10 21:17:23 -07:00
parent 29967312c9
commit ac17775e0b
2 changed files with 18 additions and 2 deletions
+3 -2
View File
@@ -839,8 +839,9 @@ std::string CodeGenerator::generate_branch_condition(uint32_t instr, uint32_t ad
check_explicit_branch_site(addr, instr);
if (config_.ws_cull_nclip_exact_sites.count(addr) &&
(opcode == 0x06 || opcode == 0x07 ||
(opcode == 0x01 && ((instr >> 16) & 31) == 1))) {
const char* compare = opcode == 0x06 ? "<= 0" : opcode == 0x07 ? "> 0" : ">= 0";
(opcode == 0x01 && ((instr >> 16) & 31) <= 1))) {
const char* compare = opcode == 0x06 ? "<= 0" : opcode == 0x07 ? "> 0" :
((instr >> 16) & 1) ? ">= 0" : "< 0";
return fmt::format("psx_ws_nclip_branch(0x{:08X}u, 0x{:08X}u, (int32_t){}, ((int32_t){} {})) /* guarded wide nclip */",
addr, instr, reg_name(rs), reg_name(rs), compare);
}
@@ -415,6 +415,20 @@ reject_mask = "0xFFFF0000"
"overlay with another instruction stays vanilla");
}
void guarded_nclip_branches() {
PSXRecomp::CodeGenConfig config{};
config.ws_cull_nclip_exact_sites.insert(kBase);
const auto left = generate_first_instruction(kBltzV0, config).full_code;
const auto right = generate_first_instruction(kBgezV0, config).full_code;
check(left.find("psx_ws_nclip_branch(") != std::string::npos &&
left.find("gte_nclip_exact_sign(") == std::string::npos &&
left.find("cpu->gpr[2] < 0") != std::string::npos,
"BLTZ uses the word-guarded handedness consumer and vanilla fallback");
check(right.find("psx_ws_nclip_branch(") != std::string::npos &&
right.find("cpu->gpr[2] >= 0") != std::string::npos,
"BGEZ uses the same word-guarded handedness consumer");
}
void runtime_math() {
// Identity at 4:3 (margin 0) for every input.
for (int32_t v : {-1000, -54, -53, -1, 0, 1, 98, 222, 319, 320, 321, 1000}) {
@@ -460,6 +474,7 @@ int main(int argc, char** argv) {
shared_decls_include_new_helpers();
runtime_math();
masked_reject_sites();
guarded_nclip_branches();
if (g_exit_probe >= 0) return 3; // no call had that probe index
if (failures != 0) {