diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index a6371f27a9..ae509ce080 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -7133,8 +7133,9 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s value.reg2 = pattern.reg2; } - if (true) + if (g_cfg.core.spu_accurate_reservations) { + // Because enabling it is a hack, as it turns out continue; } diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index 8ffa9c2aeb..1dc58a2e40 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -1196,7 +1196,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator if (g_cfg.core.rsx_accurate_res_access) { - call("spu_putllc16_rsx_res", +[](spu_thread* _spu, u32 ls_dst, u32 lsa, u32 eal, u32 notify) + const auto success = call("spu_putllc16_rsx_res", +[](spu_thread* _spu, u32 ls_dst, u32 lsa, u32 eal, u32 notify) -> bool { const u32 raddr = eal; @@ -1207,71 +1207,53 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator 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))) { vm::reservation_update(raddr); _spu->ch_atomic_stat.set_value(MFC_PUTLLC_SUCCESS); _spu->raddr = 0; - return; + return true; } - const u64 rtime = _spu->rtime; auto& res = vm::reservation_acquire(eal); - if (res != rtime) + if (res % 128) { - _spu->ch_atomic_stat.set_value(MFC_PUTLLC_FAILURE); - _spu->set_events(SPU_EVENT_LR); - _spu->raddr = 0; - return; + return false; } - rsx::reservation_lock rsx_lock(raddr, 128); - - // Touch memory - utils::trigger_write_page_fault(vm::base(dest ^ (4096 / 2))); - - auto [old_res, ok] = res.fetch_op([&](u64& rval) { - if (rtime != rval) + rsx::reservation_lock rsx_lock(raddr, 128); + + // Touch memory + utils::trigger_write_page_fault(vm::base(dest ^ (4096 / 2))); + + auto [old_res, ok] = res.fetch_op([&](u64& rval) + { + if (rval % 128) + { + return false; + } + + rval |= 127; + return true; + }); + + if (!ok) { return false; } - rval |= 127; - return true; - }); + if (!_dest->compare_and_swap_test(rdata, to_write)) + { + res.release(old_res); + return false; + } - if (!ok) - { - _spu->ch_atomic_stat.set_value(MFC_PUTLLC_FAILURE); - _spu->set_events(SPU_EVENT_LR); - _spu->raddr = 0; - return; + // Success + res.release(old_res + 128); } - if (!_dest->compare_and_swap_test(rdata, to_write)) - { - res.release(old_res); - _spu->ch_atomic_stat.set_value(MFC_PUTLLC_FAILURE); - _spu->set_events(SPU_EVENT_LR); - _spu->raddr = 0; - return; - } - - // Success - res.release(old_res + 128); - _spu->ch_atomic_stat.set_value(MFC_PUTLLC_SUCCESS); _spu->raddr = 0; @@ -1279,10 +1261,12 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator { res.notify_all(); } + + return true; }, m_thread, dest, _lsa, _eal, m_ir->getInt32(!info.no_notify)); - m_ir->CreateBr(_final); + m_ir->CreateCondBr(success, _final, _fail); m_ir->SetInsertPoint(_fail); call("PUTLLC16_fail", +on_fail, m_thread, _eal);