diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index cc34903816..df08606adb 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -9232,6 +9232,20 @@ public: { if (m_block) m_block->block_end = m_ir->GetInsertBlock(); + const auto rt = get_vr(op.rt); + + // Checking for zero doeesn't care about the order of the bytes, + // so load the data before it's byteswapped + if (auto [ok, as] = match_expr(rt, byteswap(match())); ok) + { + m_block->block_end = m_ir->GetInsertBlock(); + const auto cond = eval(extract(bitcast(as), 0) == 0); + const auto addr = eval(extract(get_vr(op.ra), 3) & 0x3fffc); + const auto target = add_block_indirect(op, addr); + m_ir->CreateCondBr(cond.value, target, add_block_next()); + return; + } + // Check sign bit instead (optimization) if (match_vr(op.rt, [&](auto c, auto MP) { @@ -9263,6 +9277,21 @@ public: { if (m_block) m_block->block_end = m_ir->GetInsertBlock(); + const auto rt = get_vr(op.rt); + + // Checking for zero doeesn't care about the order of the bytes, + // so load the data before it's byteswapped + if (auto [ok, as] = match_expr(rt, byteswap(match())); ok) + { + m_block->block_end = m_ir->GetInsertBlock(); + const auto cond = eval(extract(bitcast(as), 0) != 0); + const auto addr = eval(extract(get_vr(op.ra), 3) & 0x3fffc); + const auto target = add_block_indirect(op, addr); + m_ir->CreateCondBr(cond.value, target, add_block_next()); + return; + } + + // Check sign bit instead (optimization) if (match_vr(op.rt, [&](auto c, auto MP) { @@ -9483,6 +9512,21 @@ public: const u32 target = spu_branch_target(m_pos, op.i16); + const auto rt = get_vr(op.rt); + + // Checking for zero doeesn't care about the order of the bytes, + // so load the data before it's byteswapped + if (auto [ok, as] = match_expr(rt, byteswap(match())); ok) + { + if (target != m_pos + 4) + { + m_block->block_end = m_ir->GetInsertBlock(); + const auto cond = eval(extract(bitcast(as), 0) == 0); + m_ir->CreateCondBr(cond.value, add_block(target), add_block(m_pos + 4)); + return; + } + } + // Check sign bit instead (optimization) if (match_vr(op.rt, [&](auto c, auto MP) { @@ -9527,6 +9571,21 @@ public: const u32 target = spu_branch_target(m_pos, op.i16); + const auto rt = get_vr(op.rt); + + // Checking for zero doeesn't care about the order of the bytes, + // so load the data before it's byteswapped + if (auto [ok, as] = match_expr(rt, byteswap(match())); ok) + { + if (target != m_pos + 4) + { + m_block->block_end = m_ir->GetInsertBlock(); + const auto cond = eval(extract(bitcast(as), 0) != 0); + m_ir->CreateCondBr(cond.value, add_block(target), add_block(m_pos + 4)); + return; + } + } + // Check sign bit instead (optimization) if (match_vr(op.rt, [&](auto c, auto MP) { @@ -9583,7 +9642,6 @@ public: m_block->block_end = m_ir->GetInsertBlock(); const auto a = get_vr(op.rt); const auto cond = eval((bitcast(trunc(a)) & 0x3000) == 0); - //const auto cond = eval((m & 0x3000) == 0); m_ir->CreateCondBr(cond.value, add_block(target), add_block(m_pos + 4)); return true; }