diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 05b06e4e65c8..256440480fe1 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -2179,9 +2179,15 @@ bool spu_thread::process_mfc_cmd() std::this_thread::yield(); } - auto& dst = _ref(ch_mfc_cmd.lsa & 0x3ff80); + alignas(64) spu_rdata_t temp; u64 ntime; + if (raddr) + { + // Save rdata from previous reservation + mov_rdata(temp, rdata); + } + for (u64 i = 0;; [&]() { if (state & cpu_flag::pause) @@ -2216,7 +2222,7 @@ bool spu_thread::process_mfc_cmd() continue; } - mov_rdata(dst, data); + mov_rdata(rdata, data); if (u64 time0 = vm::reservation_acquire(addr, 128); ntime != time0) @@ -2226,7 +2232,7 @@ bool spu_thread::process_mfc_cmd() continue; } - if (g_cfg.core.spu_accurate_getllar && !cmp_rdata(dst, data)) + if (g_cfg.core.spu_accurate_getllar && !cmp_rdata(rdata, data)) { i += 2; continue; @@ -2238,7 +2244,7 @@ bool spu_thread::process_mfc_cmd() if (raddr && raddr != addr) { // Last check for event before we replace the reservation with a new one - if ((vm::reservation_acquire(raddr, 128) & (-128 | vm::dma_lockb)) != rtime || !cmp_rdata(rdata, vm::_ref(raddr))) + if ((vm::reservation_acquire(raddr, 128) & (-128 | vm::dma_lockb)) != rtime || !cmp_rdata(temp, vm::_ref(raddr))) { set_events(SPU_EVENT_LR); } @@ -2246,7 +2252,7 @@ bool spu_thread::process_mfc_cmd() else if (raddr == addr) { // Lost previous reservation on polling - if (ntime != rtime || !cmp_rdata(rdata, dst)) + if (ntime != rtime || !cmp_rdata(rdata, temp)) { set_events(SPU_EVENT_LR); } @@ -2254,7 +2260,7 @@ bool spu_thread::process_mfc_cmd() raddr = addr; rtime = ntime; - mov_rdata(rdata, dst); + mov_rdata(_ref(ch_mfc_cmd.lsa & 0x3ff80), rdata); ch_atomic_stat.set_value(MFC_GETLLAR_SUCCESS); return true;