diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index a215f963be..4f6bf2475d 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -5086,7 +5086,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s std::vector to_pop; usz stackframe_it = wi; - usz stackframe_pc = SPU_LS_SIZE; + u32 stackframe_pc = SPU_LS_SIZE; usz entry_index = umax; auto get_block_targets = [&](u32 pc) -> std::basic_string_view @@ -5565,11 +5565,6 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s } case spu_itype::IRET: - { - next_block(); - break; - } - case spu_itype::BI: case spu_itype::BISL: case spu_itype::BISLED: @@ -5578,7 +5573,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s case spu_itype::BIHZ: case spu_itype::BIHNZ: { - if (op.e) + if (op.e || op.d) { break_putllc16(27, atomic16.discard()); } @@ -5665,14 +5660,16 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s { case MFC_GETLLAR_CMD: { + auto lsa = get_reg(s_reg_mfc_lsa); + inherit_const_mask_value(s_reg_mfc_lsa, lsa, 0, ~SPU_LS_MASK_128); + lsa = get_reg(s_reg_mfc_lsa); const u32 lsa_pc = atomic16.lsa_last_pc == SPU_LS_SIZE ? bpc : atomic16.lsa_last_pc; if (atomic16.active) { - if (atomic16.lsa_pc != lsa_pc || atomic16.get_pc != pos) + if (atomic16.lsa_pc != lsa_pc || atomic16.get_pc != pos || atomic16.lsa != lsa) { break_putllc16(30, atomic16.discard()); - break; } } @@ -5681,9 +5678,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s atomic16.get_pc = pos; atomic16.active = true; - const auto lsa = get_reg(s_reg_mfc_lsa); - inherit_const_mask_value(s_reg_mfc_lsa, lsa, 0, ~SPU_LS_MASK_128); - atomic16.lsa = get_reg(s_reg_mfc_lsa); + atomic16.lsa = lsa; if (likely_putllc_loop) { diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index cfae00f572..c739536eca 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -1200,6 +1200,18 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator const v128 to_write = _spu->_ref>(ls_dst); const auto dest = raddr | (ls_dst & 127); + const auto _dest = vm::get_super_ptr>>(dest); + using spu_rdata_t = decltype(spu_thread::rdata); + + extern bool cmp_rdata(const spu_rdata_t& _lhs, const spu_rdata_t& _rhs); + + // if (!cmp_rdata(*reinterpret_castrdata)*>(_dest), _spu->rdata)) + // { + // _spu->ch_atomic_stat.set_value(MFC_PUTLLC_FAILURE); + // _spu->set_events(SPU_EVENT_LR); + // _spu->raddr = 0; + // return; + // } if (rdata == to_write || ((lsa ^ ls_dst) & (SPU_LS_SIZE - 128))) { @@ -1219,14 +1231,15 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator return; } + const u64 rtime = _spu->rtime; rsx::reservation_lock rsx_lock(raddr, 128); - // Tocuh memory + // Touch memory vm::_ref>(dest).compare_and_swap_test(0, 0); - auto [old_res, ok] = res.fetch_op([](u64& rval) + auto [old_res, ok] = res.fetch_op([&](u64& rval) { - if (rval & 127) + if (rval & 127)// || rtime != rval) { return false; } @@ -1243,7 +1256,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator return; } - if (!vm::get_super_ptr>>(dest)->compare_and_swap_test(rdata, to_write)) + if (!_dest->compare_and_swap_test(rdata, to_write)) { res.release(old_res); _spu->ch_atomic_stat.set_value(MFC_PUTLLC_FAILURE);