diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index 86d038af90..1a6ae41194 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -1013,7 +1013,7 @@ spu_function_t spu_runtime::find(const u32* ls, u32 addr) const return nullptr; } -spu_function_t spu_runtime::make_branch_patchpoint() const +spu_function_t spu_runtime::make_branch_patchpoint(u16 data) const { u8* const raw = jit_runtime::alloc(16, 16); @@ -1039,8 +1039,8 @@ spu_function_t spu_runtime::make_branch_patchpoint() const const s64 rel = reinterpret_cast(tr_branch) - reinterpret_cast(raw + 8) - 5; std::memcpy(raw + 9, &rel, 4); raw[13] = 0xcc; - raw[14] = 0; - raw[15] = 0; + raw[14] = data >> 8; + raw[15] = data & 0xff; return reinterpret_cast(raw); } @@ -1110,6 +1110,11 @@ void spu_recompiler_base::dispatch(spu_thread& spu, void*, u8* rip) void spu_recompiler_base::branch(spu_thread& spu, void*, u8* rip) { + if (const u32 ls_off = ((rip[6] << 8) | rip[7]) * 4) + { + LOG_TODO(SPU, "Special branch patchpoint hit.\nPlease report to the developer (0x%05x).", ls_off); + } + // Find function const auto func = spu.jit->get_runtime().find(static_cast(vm::base(spu.offset)), spu.pc); @@ -1144,8 +1149,8 @@ void spu_recompiler_base::branch(spu_thread& spu, void*, u8* rip) bytes[5] = 0xcc; } - bytes[6] = 0; - bytes[7] = 0; + bytes[6] = rip[6]; + bytes[7] = rip[7]; } else { @@ -4652,7 +4657,7 @@ public: if (g_cfg.core.spu_verification) { const std::string ppname = fmt::format("%s-chunkpp-0x%05x", m_hash, i); - m_engine->addGlobalMapping(ppname, (u64)m_spurt->make_branch_patchpoint()); + m_engine->addGlobalMapping(ppname, (u64)m_spurt->make_branch_patchpoint(i / 4)); const auto ppfunc = llvm::cast(m_module->getOrInsertFunction(ppname, m_finfo->chunk->getFunctionType()).getCallee()); ppfunc->setCallingConv(m_finfo->chunk->getCallingConv()); diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index d824170ba2..5a8fe3f136 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -115,7 +115,7 @@ public: spu_function_t find(const u32* ls, u32 addr) const; // Generate a patchable trampoline to spu_recompiler_base::branch - spu_function_t make_branch_patchpoint() const; + spu_function_t make_branch_patchpoint(u16 data = 0) const; // All dispatchers (array allocated in jit memory) static std::array, (1 << 20)>* const g_dispatcher;