From 1880a17f792edf232788b1707e013feaa48fe908 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 18 Mar 2019 19:40:51 +0300 Subject: [PATCH] SPU recs: implement spu_runtime::find Use this function to link to existing functions from branch patchpoints. Don't compile from branch patchpoints. --- rpcs3/Emu/Cell/SPURecompiler.cpp | 45 ++++++++++++++++++++++++++++++-- rpcs3/Emu/Cell/SPURecompiler.h | 3 +++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index f32ffba696..0caf05a9bf 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -551,6 +551,42 @@ void spu_runtime::add(std::pair, spu_function_t>& where, m_cond.notify_all(); } +spu_function_t spu_runtime::find(const se_t* ls, u32 addr) +{ + std::unique_lock lock(m_mutex); + + const u32 start = addr * (g_cfg.core.spu_block_size != spu_block_size_type::giga); + + addrv[0] = addr; + const auto beg = m_map.lower_bound(addrv); + addrv[0] += 4; + const auto _end = m_map.lower_bound(addrv); + + for (auto it = beg; it != _end; ++it) + { + bool bad = false; + + for (u32 i = 1; i < it->first.size(); ++i) + { + const u32 x = it->first[i]; + const u32 y = ls[start / 4 + i - 1]; + + if (x && x != y) + { + bad = true; + break; + } + } + + if (!bad) + { + return it->second; + } + } + + return nullptr; +} + spu_function_t spu_runtime::make_branch_patchpoint(u32 target) const { u8* const raw = jit_runtime::alloc(16, 16); @@ -649,8 +685,13 @@ void spu_recompiler_base::dispatch(spu_thread& spu, void*, u8* rip) void spu_recompiler_base::branch(spu_thread& spu, void*, u8* rip) { - // Compile (TODO: optimize search of the existing functions) - const auto func = verify(HERE, spu.jit->compile(spu.jit->block(spu._ptr(0), *(u16*)(rip + 6) * 4))); + // Find function + const auto func = spu.jit->get_runtime().find(spu._ptr>(0), *(u16*)(rip + 6) * 4); + + if (!func) + { + return; + } // Overwrite jump to this function with jump to the compiled function const s64 rel = reinterpret_cast(func) - reinterpret_cast(rip) - 5; diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index a0323b9739..b66cd5aad3 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -76,6 +76,9 @@ public: // Add compiled function and generate trampoline if necessary void add(std::pair, spu_function_t>& where, spu_function_t compiled); + // Find existing function + spu_function_t find(const se_t* ls, u32 addr); + // Generate a patchable trampoline to spu_recompiler_base::branch spu_function_t make_branch_patchpoint(u32 target) const;