diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index 3a0bc1c5d749..ab743d8d45df 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -2680,12 +2680,13 @@ reg_state_t reg_state_t::merge(const reg_state_t& rhs, u32 current_pc) const res.tag = reg_state_t::alloc_tag(); res.origin = current_pc; res.is_instruction = false; + res.is_phi = true; return res; } } } - return make_unknown(current_pc); + return make_unknown(current_pc, current_pc, true); } reg_state_t reg_state_t::build_on_top_of(const reg_state_t& rhs) const @@ -4190,23 +4191,6 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s for (u32 i = 0; i < s_reg_max; i++) { - if (tb.chunk == block.chunk && tb.reg_origin[i] + 1) - { - const u32 expected = block.reg_mod[i] ? addr : block.reg_origin[i]; - - if (tb.reg_origin[i] == 0x80000000) - { - tb.reg_origin[i] = expected; - } - else if (tb.reg_origin[i] != expected) - { - // Set -1 if multiple origins merged (requires PHI node) - tb.reg_origin[i] = -1; - - must_repeat |= !tb.targets.empty(); - } - } - if (g_cfg.core.spu_block_size == spu_block_size_type::giga && tb.func == block.func && tb.reg_origin_abs[i] + 2) { const u32 expected = block.reg_mod[i] ? addr : block.reg_origin_abs[i]; @@ -5793,7 +5777,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s } case MFC_Cmd: { - const auto [af, av, atagg, _3, _5, apc, ainst] = get_reg(op.rt); + const auto [af, av, atagg, _3, _5, apc, ainst, aphi] = get_reg(op.rt); if (!is_pattern_match) { @@ -6591,7 +6575,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s case spu_itype::HBR: { hbr_loc = spu_branch_target(pos, op.roh << 7 | op.rt); - const auto [af, av, at, ao, az, apc, ainst] = get_reg(op.ra); + const auto [af, av, at, ao, az, apc, ainst, aphi] = get_reg(op.ra); hbr_tg = af & vf::is_const && !op.c ? av & 0x3fffc : -1; break; } @@ -6659,8 +6643,8 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s const auto ra = get_reg(op.ra); const auto rb = get_reg(op.rb); - const auto [af, av, at, ao, az, apc, ainst] = ra; - const auto [bf, bv, bt, bo, bz, bpc, binst] = rb; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; + const auto [bf, bv, bt, bo, bz, bpc, binst, bphi] = rb; inherit_const_value(op.rt, ra, rb, av | bv, pos); break; @@ -6675,7 +6659,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s const auto ra = get_reg(op.ra); - const auto [af, av, at, ao, az, apc, ainst] = ra; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; inherit_const_value(op.rt, ra, ra, av ^ op.si10, pos); break; @@ -6691,8 +6675,8 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s const auto ra = get_reg(op.ra); const auto rb = get_reg(op.rb); - const auto [af, av, at, ao, az, apc, ainst] = ra; - const auto [bf, bv, bt, bo, bz, bpc, binst] = rb; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; + const auto [bf, bv, bt, bo, bz, bpc, binst, bphi] = rb; inherit_const_value(op.rt, ra, rb, bv ^ av, pos); break; @@ -6702,8 +6686,8 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s const auto ra = get_reg(op.ra); const auto rb = get_reg(op.rb); - const auto [af, av, at, ao, az, apc, ainst] = ra; - const auto [bf, bv, bt, bo, bz, bpc, binst] = rb; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; + const auto [bf, bv, bt, bo, bz, bpc, binst, bphi] = rb; inherit_const_value(op.rt, ra, rb, ~(bv | av), pos); break; @@ -6725,8 +6709,8 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s const auto ra = get_reg(op.ra); const auto rb = get_reg(op.rb); - const auto [af, av, at, ao, az, apc, ainst] = ra; - const auto [bf, bv, bt, bo, bz, bpc, binst] = rb; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; + const auto [bf, bv, bt, bo, bz, bpc, binst, bphi] = rb; inherit_const_value(op.rt, ra, rb, bv & av, pos); break; @@ -6740,7 +6724,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s } const auto ra = get_reg(op.ra); - const auto [af, av, at, ao, az, apc, ainst] = ra; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; inherit_const_value(op.rt, ra, ra, av + op.si10, pos); @@ -6757,8 +6741,8 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s const auto ra = get_reg(op.ra); const auto rb = get_reg(op.rb); - const auto [af, av, at, ao, az, apc, ainst] = ra; - const auto [bf, bv, bt, bo, bz, bpc, binst] = rb; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; + const auto [bf, bv, bt, bo, bz, bpc, binst, bphi] = rb; inherit_const_value(op.rt, ra, rb, bv + av, pos); @@ -6773,7 +6757,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s case spu_itype::SFI: { const auto ra = get_reg(op.ra); - const auto [af, av, at, ao, az, apc, ainst] = get_reg(op.ra); + const auto [af, av, at, ao, az, apc, ainst, aphi] = get_reg(op.ra); inherit_const_value(op.rt, ra, ra, op.si10 - av, pos); break; @@ -6783,8 +6767,8 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s const auto ra = get_reg(op.ra); const auto rb = get_reg(op.rb); - const auto [af, av, at, ao, az, apc, ainst] = ra; - const auto [bf, bv, bt, bo, bz, bpc, binst] = rb; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; + const auto [bf, bv, bt, bo, bz, bpc, binst, bphi] = rb; inherit_const_value(op.rt, ra, rb, bv - av, pos); @@ -6823,7 +6807,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s } const auto ra = get_reg(op.ra); - const auto [af, av, at, ao, az, apc, ainst] = get_reg(op.ra); + const auto [af, av, at, ao, az, apc, ainst, aphi] = get_reg(op.ra); inherit_const_value(op.rt, ra, ra, av >> ((0 - op.i7) & 0x1f), pos); break; @@ -6843,7 +6827,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s } const auto ra = get_reg(op.ra); - const auto [af, av, at, ao, az, apc, ainst] = ra; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; inherit_const_value(op.rt, ra, ra, av << (op.i7 & 0x1f), pos); break; @@ -6860,7 +6844,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s case spu_itype::CEQI: { const auto ra = get_reg(op.ra); - const auto [af, av, at, ao, az, apc, ainst] = ra; + const auto [af, av, at, ao, az, apc, ainst, aphi] = ra; inherit_const_value(op.rt, ra, ra, av == op.si10 + 0u, pos); @@ -6995,7 +6979,15 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s { bb.reg_const[i] = true; bb.reg_val32[i] = reg.value; - } + } + else if (reg.is_instruction) + { + bb.reg_origin[i] = reg.origin; + } + else if (reg.is_phi) + { + bb.reg_origin[i] = -1; + } } } diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index 968fab287cac..5dcaaaf9561c 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -210,6 +210,7 @@ class spu_recompiler_base u32 known_zeroes{}; u32 origin = SPU_LS_SIZE; bool is_instruction = false; + bool is_phi = false; bool is_const() const; @@ -243,7 +244,7 @@ class spu_recompiler_base void invalidate_if_created(u32 current_pc); template - static std::conditional_t> make_unknown(u32 pc, u32 current_pc = SPU_LS_SIZE) noexcept + static std::conditional_t> make_unknown(u32 pc, u32 current_pc = SPU_LS_SIZE, bool is_phi = false) noexcept { if constexpr (Count == 1) { @@ -252,6 +253,7 @@ class spu_recompiler_base v.flag = {}; v.origin = pc; v.is_instruction = pc == current_pc; + v.is_phi = is_phi; return v; } else @@ -260,7 +262,7 @@ class spu_recompiler_base for (reg_state_t& state : result) { - state = make_unknown<1>(pc, current_pc); + state = make_unknown<1>(pc, current_pc, is_phi); } return result;