diff --git a/rpcs3/Emu/Cell/Modules/cellSync.h b/rpcs3/Emu/Cell/Modules/cellSync.h index b329d958c1..920d82d64d 100644 --- a/rpcs3/Emu/Cell/Modules/cellSync.h +++ b/rpcs3/Emu/Cell/Modules/cellSync.h @@ -4,6 +4,8 @@ #include "Utilities/BitField.h" +#include "Emu/Cell/ErrorCodes.h" + // Return Codes enum CellSyncError : u32 { diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index 20e435d42d..09f91be969 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -13,6 +13,8 @@ #include "util/init_mutex.hpp" #include "util/shared_ptr.hpp" +#include "Emu/Cell/Modules/cellSync.h" + #include "SPUThread.h" #include "SPUAnalyser.h" #include "SPUInterpreter.h" @@ -6422,6 +6424,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s u32 data; bf_t type; bf_t runtime16_select; + bf_t no_notify; bf_t reg; bf_t off18; bf_t reg2; @@ -6435,6 +6438,25 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s v_reg2 = 3, }; + for (auto it = infos.lower_bound(utils::sub_saturate(pattern.put_pc, 512)); it != infos.end() && it->first < pattern.put_pc + 512; it++) + { + for (auto& state : it->second->end_reg_state) + { + if (state.is_const() && (state.value & -0x20) == (CELL_SYNC_ERROR_ALIGN & -0x20)) + { + // Do not notify if it is a cellSync function + value.no_notify = 1; + spu_log.success("Detected cellSync function at 0x%x, disabling reservation notification.", pattern.put_pc); + break; + } + } + + if (value.no_notify) + { + break; + } + } + value.runtime16_select = pattern.select_16_or_0_at_runtime; value.reg = s_reg_max; diff --git a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp index b11f439fda..41bec40591 100644 --- a/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPULLVMRecompiler.cpp @@ -1122,6 +1122,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator u32 data; bf_t type; bf_t runtime16_select; + bf_t no_notify; bf_t reg; bf_t off18; bf_t reg2; @@ -1244,7 +1245,12 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator // Unlock and notify m_ir->SetInsertPoint(_success_and_unlock); m_ir->CreateAlignedStore(m_ir->CreateAdd(rval, m_ir->getInt64(128)), rptr, llvm::MaybeAlign{8}); - call("atomic_wait_engine::notify_all", static_cast(atomic_wait_engine::notify_all), rptr); + + if (!info.no_notify) + { + call("atomic_wait_engine::notify_all", static_cast(atomic_wait_engine::notify_all), rptr); + } + m_ir->CreateBr(_success); // Perform unlocked vm::reservation_update if no physical memory changes needed diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 9dc241a993..27edcc5466 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -976,6 +976,7 @@ enum CellSpursCoreError : u32; enum CellSpursPolicyModuleError : u32; enum CellSpursTaskError : u32; enum CellSpursJobError : u32; +enum CellSyncError : u32; enum CellGameError : u32; enum CellGameDataError : u32; @@ -999,6 +1000,7 @@ const std::map s_error_codes_formatting_by_type formatter_of<0x8002b260, CellAudioInError>, formatter_of<0x8002b220, CellVideoOutError>, + formatter_of<0x80410100, CellSyncError>, formatter_of<0x80410700, CellSpursCoreError>, formatter_of<0x80410800, CellSpursPolicyModuleError>, formatter_of<0x80410900, CellSpursTaskError>,