diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index fd7c703ffe..7bed03d821 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -116,8 +116,6 @@ extern std::string ppu_get_variable_name(const std::string& module, u32 vnid); extern void sys_initialize_tls(ppu_thread&, u64, u32, u32, u32); -extern void ppu_initialize(const std::string& name, const std::vector& set); - extern u32 g_ps3_sdk_version; // Function lookup table. Not supposed to grow after emulation start. @@ -1278,17 +1276,17 @@ void ppu_load_exec(const ppu_exec_object& elf) } // Analyse executable - const auto funcs = ppu_analyse(segments, sections, 0); + std::vector main_funcs = ppu_analyse(segments, sections, 0); - ppu_validate(vfs::get(Emu.GetPath()), funcs, 0); + ppu_validate(vfs::get(Emu.GetPath()), main_funcs, 0); - for (const auto& pair : funcs) - { - exec_set.emplace_back(pair); - } + // Append + exec_set.insert(exec_set.cend(), + std::make_move_iterator(main_funcs.begin()), + std::make_move_iterator(main_funcs.end())); - // Initialize interpreter/recompiler - ppu_initialize("", exec_set); + // Share function list + fxm::make>(std::move(exec_set)); // Set SDK version g_ps3_sdk_version = sdk_version; @@ -1315,6 +1313,8 @@ void ppu_load_exec(const ppu_exec_object& elf) // Initialize main thread auto ppu = idm::make_ptr("main_thread", primary_prio, primary_stacksize); + ppu->cmd_push({ppu_cmd::initialize, 0}); + // TODO: adjust for liblv2 loading option if (!g_cfg_load_liblv2) { diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 9dd10e543a..d54dd422b5 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -38,6 +38,7 @@ #include "Utilities/JIT.h" #include "PPUTranslator.h" +#include "Modules/cellMsgDialog.h" #endif enum class ppu_decoder_type @@ -57,6 +58,7 @@ cfg::map_entry g_cfg_ppu_decoder(cfg::root.core, "PPU Decoder" const ppu_decoder s_ppu_interpreter_precise; const ppu_decoder s_ppu_interpreter_fast; +static void ppu_initialize(); extern void ppu_execute_syscall(ppu_thread& ppu, u64 code); extern void ppu_execute_function(ppu_thread& ppu, u32 index); @@ -164,6 +166,11 @@ void ppu_thread::cpu_task() cmd_pop(), ppu_execute_function(*this, arg); break; } + case ppu_cmd::initialize: + { + cmd_pop(), ppu_initialize(); + break; + } default: { fmt::throw_exception("Unknown ppu_cmd(0x%x)" HERE, (u32)type); @@ -510,9 +517,11 @@ static bool adde_carry(u64 a, u64 b, bool c) #endif } -extern void ppu_initialize(const std::string& name, const std::vector& funcs) +static void ppu_initialize() { - if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm || funcs.empty()) + const auto _funcs = fxm::get_always>(); + + if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm || _funcs->empty()) { if (!Emu.GetCPUThreadStop()) { @@ -555,7 +564,7 @@ extern void ppu_initialize(const std::string& name, const std::vector module = std::make_unique(name, g_llvm_ctx); + std::unique_ptr module = std::make_unique("", g_llvm_ctx); // Initialize target module->setTargetTriple(Triple::normalize(sys::getProcessTriple())); @@ -568,7 +577,7 @@ extern void ppu_initialize(const std::string& name, const std::vectorGetContextType()->getPointerTo() }, false); // Initialize function list - for (const auto& info : funcs) + for (const auto& info : *_funcs) { if (info.size) { @@ -608,11 +617,48 @@ extern void ppu_initialize(const std::string& name, const std::vectortype.se_normal = true; + dlg->type.bg_invisible = true; + dlg->type.progress_bar_count = 1; + dlg->on_close = [](s32 status) { + Emu.CallAfter([]() + { + // Abort everything + Emu.Stop(); + }); + }; + + Emu.CallAfter([=]() + { + dlg->Create("Recompiling PPU executable.\nPlease wait..."); + }); + + // Translate functions + for (size_t fi = 0; fi < _funcs->size(); fi++) + { + if (Emu.IsStopped()) + { + LOG_SUCCESS(PPU, "LLVM: Translation cancelled"); + return; + } + + auto& info = _funcs->at(fi); + if (info.size) { + // Update dialog + Emu.CallAfter([=, max = _funcs->size()]() + { + dlg->ProgressBarSetMsg(0, fmt::format("Compiling %u of %u", fi + 1, max)); + + if (fi * 100 / max != (fi + 1) * 100 / max) + dlg->ProgressBarInc(0, 1); + }); + + // Translate const auto func = translator->TranslateToIR(info, vm::_ptr(info.addr)); // Run optimization passes @@ -699,6 +745,13 @@ extern void ppu_initialize(const std::string& name, const std::vectorProgressBarSetMsg(0, "Generating code..."); + dlg->ProgressBarInc(0, 100); + }); + std::string result; raw_string_ostream out(result); @@ -711,7 +764,7 @@ extern void ppu_initialize(const std::string& name, const std::vector