mirror of https://github.com/RPCS3/rpcs3.git
LLVM: progress dialog
This commit is contained in:
parent
6cf006b02b
commit
78ecb115f3
|
@ -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 sys_initialize_tls(ppu_thread&, u64, u32, u32, u32);
|
||||||
|
|
||||||
extern void ppu_initialize(const std::string& name, const std::vector<ppu_function>& set);
|
|
||||||
|
|
||||||
extern u32 g_ps3_sdk_version;
|
extern u32 g_ps3_sdk_version;
|
||||||
|
|
||||||
// Function lookup table. Not supposed to grow after emulation start.
|
// 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
|
// Analyse executable
|
||||||
const auto funcs = ppu_analyse(segments, sections, 0);
|
std::vector<ppu_function> 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)
|
// Append
|
||||||
{
|
exec_set.insert(exec_set.cend(),
|
||||||
exec_set.emplace_back(pair);
|
std::make_move_iterator(main_funcs.begin()),
|
||||||
}
|
std::make_move_iterator(main_funcs.end()));
|
||||||
|
|
||||||
// Initialize interpreter/recompiler
|
// Share function list
|
||||||
ppu_initialize("", exec_set);
|
fxm::make<std::vector<ppu_function>>(std::move(exec_set));
|
||||||
|
|
||||||
// Set SDK version
|
// Set SDK version
|
||||||
g_ps3_sdk_version = sdk_version;
|
g_ps3_sdk_version = sdk_version;
|
||||||
|
@ -1315,6 +1313,8 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
||||||
// Initialize main thread
|
// Initialize main thread
|
||||||
auto ppu = idm::make_ptr<ppu_thread>("main_thread", primary_prio, primary_stacksize);
|
auto ppu = idm::make_ptr<ppu_thread>("main_thread", primary_prio, primary_stacksize);
|
||||||
|
|
||||||
|
ppu->cmd_push({ppu_cmd::initialize, 0});
|
||||||
|
|
||||||
// TODO: adjust for liblv2 loading option
|
// TODO: adjust for liblv2 loading option
|
||||||
if (!g_cfg_load_liblv2)
|
if (!g_cfg_load_liblv2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#include "Utilities/JIT.h"
|
#include "Utilities/JIT.h"
|
||||||
#include "PPUTranslator.h"
|
#include "PPUTranslator.h"
|
||||||
|
#include "Modules/cellMsgDialog.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum class ppu_decoder_type
|
enum class ppu_decoder_type
|
||||||
|
@ -57,6 +58,7 @@ cfg::map_entry<ppu_decoder_type> g_cfg_ppu_decoder(cfg::root.core, "PPU Decoder"
|
||||||
const ppu_decoder<ppu_interpreter_precise> s_ppu_interpreter_precise;
|
const ppu_decoder<ppu_interpreter_precise> s_ppu_interpreter_precise;
|
||||||
const ppu_decoder<ppu_interpreter_fast> s_ppu_interpreter_fast;
|
const ppu_decoder<ppu_interpreter_fast> s_ppu_interpreter_fast;
|
||||||
|
|
||||||
|
static void ppu_initialize();
|
||||||
extern void ppu_execute_syscall(ppu_thread& ppu, u64 code);
|
extern void ppu_execute_syscall(ppu_thread& ppu, u64 code);
|
||||||
extern void ppu_execute_function(ppu_thread& ppu, u32 index);
|
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);
|
cmd_pop(), ppu_execute_function(*this, arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ppu_cmd::initialize:
|
||||||
|
{
|
||||||
|
cmd_pop(), ppu_initialize();
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Unknown ppu_cmd(0x%x)" HERE, (u32)type);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void ppu_initialize(const std::string& name, const std::vector<ppu_function>& funcs)
|
static void ppu_initialize()
|
||||||
{
|
{
|
||||||
if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm || funcs.empty())
|
const auto _funcs = fxm::get_always<std::vector<ppu_function>>();
|
||||||
|
|
||||||
|
if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm || _funcs->empty())
|
||||||
{
|
{
|
||||||
if (!Emu.GetCPUThreadStop())
|
if (!Emu.GetCPUThreadStop())
|
||||||
{
|
{
|
||||||
|
@ -555,7 +564,7 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
// Create LLVM module
|
// Create LLVM module
|
||||||
std::unique_ptr<Module> module = std::make_unique<Module>(name, g_llvm_ctx);
|
std::unique_ptr<Module> module = std::make_unique<Module>("", g_llvm_ctx);
|
||||||
|
|
||||||
// Initialize target
|
// Initialize target
|
||||||
module->setTargetTriple(Triple::normalize(sys::getProcessTriple()));
|
module->setTargetTriple(Triple::normalize(sys::getProcessTriple()));
|
||||||
|
@ -568,7 +577,7 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
|
||||||
const auto _func = FunctionType::get(_void, { translator->GetContextType()->getPointerTo() }, false);
|
const auto _func = FunctionType::get(_void, { translator->GetContextType()->getPointerTo() }, false);
|
||||||
|
|
||||||
// Initialize function list
|
// Initialize function list
|
||||||
for (const auto& info : funcs)
|
for (const auto& info : *_funcs)
|
||||||
{
|
{
|
||||||
if (info.size)
|
if (info.size)
|
||||||
{
|
{
|
||||||
|
@ -608,11 +617,48 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
|
||||||
pm.add(createCFGSimplificationPass());
|
pm.add(createCFGSimplificationPass());
|
||||||
//pm.add(createLintPass()); // Check
|
//pm.add(createLintPass()); // Check
|
||||||
|
|
||||||
// Translate functions
|
// Initialize message dialog
|
||||||
for (const auto& info : funcs)
|
const auto dlg = Emu.GetCallbacks().get_msg_dialog();
|
||||||
|
dlg->type.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)
|
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<u32>(info.addr));
|
const auto func = translator->TranslateToIR(info, vm::_ptr<u32>(info.addr));
|
||||||
|
|
||||||
// Run optimization passes
|
// Run optimization passes
|
||||||
|
@ -699,6 +745,13 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
|
||||||
mpm.add(createDeadInstEliminationPass());
|
mpm.add(createDeadInstEliminationPass());
|
||||||
mpm.run(*module);
|
mpm.run(*module);
|
||||||
|
|
||||||
|
// Update dialog
|
||||||
|
Emu.CallAfter([=]()
|
||||||
|
{
|
||||||
|
dlg->ProgressBarSetMsg(0, "Generating code...");
|
||||||
|
dlg->ProgressBarInc(0, 100);
|
||||||
|
});
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
raw_string_ostream out(result);
|
raw_string_ostream out(result);
|
||||||
|
|
||||||
|
@ -711,7 +764,7 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
|
||||||
if (verifyModule(*module, &out))
|
if (verifyModule(*module, &out))
|
||||||
{
|
{
|
||||||
out.flush();
|
out.flush();
|
||||||
LOG_ERROR(PPU, "{%s} LLVM: Translation failed:\n%s", name, result);
|
LOG_ERROR(PPU, "LLVM: Translation failed:\n%s", result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,7 +783,7 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
|
||||||
memory_helper::free_reserved_memory(s_ppu_compiled, 0x100000000); // TODO
|
memory_helper::free_reserved_memory(s_ppu_compiled, 0x100000000); // TODO
|
||||||
|
|
||||||
// Get and install function addresses
|
// Get and install function addresses
|
||||||
for (const auto& info : funcs)
|
for (const auto& info : *_funcs)
|
||||||
{
|
{
|
||||||
if (info.size)
|
if (info.size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,7 @@ enum class ppu_cmd : u32
|
||||||
set_args, // Set general-purpose args (+arg cmd)
|
set_args, // Set general-purpose args (+arg cmd)
|
||||||
lle_call, // Load addr and rtoc at *arg or *gpr[arg] and execute
|
lle_call, // Load addr and rtoc at *arg or *gpr[arg] and execute
|
||||||
hle_call, // Execute function by index (arg)
|
hle_call, // Execute function by index (arg)
|
||||||
|
initialize, // ppu_initialize()
|
||||||
};
|
};
|
||||||
|
|
||||||
class ppu_thread : public cpu_thread
|
class ppu_thread : public cpu_thread
|
||||||
|
|
Loading…
Reference in New Issue