From 3c064439b3edf17eb64cf5fee520c92f59308066 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 29 Jun 2017 17:25:39 +0300 Subject: [PATCH] PPU LLVM: new mptr/cptr format --- Utilities/JIT.cpp | 6 ++++-- Utilities/JIT.h | 6 ++++++ rpcs3/Emu/Cell/PPUThread.cpp | 16 ++++++++++++++++ rpcs3/Emu/Cell/PPUTranslator.cpp | 8 ++++++-- rpcs3/Emu/Cell/PPUTranslator.h | 4 ++-- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Utilities/JIT.cpp b/Utilities/JIT.cpp index 0b5160e748..aa65008133 100644 --- a/Utilities/JIT.cpp +++ b/Utilities/JIT.cpp @@ -375,6 +375,7 @@ jit_compiler::jit_compiler(const std::unordered_map if (m_link.empty()) { + // Auxiliary JIT (does not use custom memory manager, only writes the objects) m_engine.reset(llvm::EngineBuilder(std::make_unique("null_", m_context)) .setErrorStr(&result) .setOptLevel(llvm::CodeGenOpt::Aggressive) @@ -384,6 +385,7 @@ jit_compiler::jit_compiler(const std::unordered_map } else { + // Primary JIT auto mem = std::make_unique(m_link); m_jit_el = std::make_unique(*mem); @@ -433,9 +435,9 @@ void jit_compiler::fin() m_engine->finalizeObject(); } -u64 jit_compiler::get(const std::string & name) +u64 jit_compiler::get(const std::string& name) { - return m_engine->getFunctionAddress(name); + return m_engine->getGlobalValueAddress(name); } std::unordered_map jit_compiler::add(std::unordered_map data) diff --git a/Utilities/JIT.h b/Utilities/JIT.h index 3c2f940687..fc1fdfb9f1 100644 --- a/Utilities/JIT.h +++ b/Utilities/JIT.h @@ -66,6 +66,12 @@ public: { return m_cpu; } + + // Check JIT purpose + bool is_primary() const + { + return !m_link.empty(); + } }; #endif diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 7ce3e7dfee..a6295bf032 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -982,6 +982,9 @@ extern void ppu_initialize(const ppu_module& info) // Worker threads std::vector jthreads; + // Global variables (pointers) to initialize + std::vector> globals; + // Split module into fragments <= 1 MiB std::size_t fpos = 0; @@ -1078,6 +1081,9 @@ extern void ppu_initialize(const ppu_module& info) break; } + globals.emplace_back(fmt::format("__mptr%x", part.funcs[0].addr), vm::g_base_addr); + globals.emplace_back(fmt::format("__cptr%x", part.funcs[0].addr), vm::g_exec_addr); + // Check object file if (fs::is_file(Emu.GetCachePath() + obj_name)) { @@ -1143,6 +1149,15 @@ extern void ppu_initialize(const ppu_module& info) } } } + + // Initialize global variables + for (auto& var : globals) + { + if (u64 addr = jit.get(var.first)) + { + *reinterpret_cast(addr) = var.second; + } + } #endif } @@ -1277,6 +1292,7 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module& module_part, co { out.flush(); LOG_ERROR(PPU, "LLVM: Verification failed for %s:\n%s", obj_name, result); + Emu.CallAfter([]{ Emu.Stop(); }); return; } diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 44dc68a7f7..648cf7f758 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -19,7 +19,9 @@ PPUTranslator::PPUTranslator(LLVMContext& context, Module* module, const ppu_mod , m_pure_attr(AttributeSet::get(m_context, AttributeSet::FunctionIndex, {Attribute::NoUnwind, Attribute::ReadNone})) { // Memory base - m_base = new GlobalVariable(*module, ArrayType::get(GetType(), 0x100000000)->getPointerTo(), true, GlobalValue::ExternalLinkage, 0, "__mptr"); + m_base = new GlobalVariable(*module, ArrayType::get(GetType(), 0x100000000)->getPointerTo(), true, GlobalValue::ExternalLinkage, 0, fmt::format("__mptr%x", info.funcs[0].addr)); + m_base->setInitializer(ConstantPointerNull::get(cast(m_base->getType()->getPointerElementType()))); + m_base->setExternallyInitialized(true); // Thread context struct (TODO: safer member access) const u32 off0 = offset32(&ppu_thread::state); @@ -42,7 +44,9 @@ PPUTranslator::PPUTranslator(LLVMContext& context, Module* module, const ppu_mod m_thread_type = StructType::create(m_context, thread_struct, "context_t"); // Callable - m_call = new GlobalVariable(*module, ArrayType::get(GetType(), 0x40000000)->getPointerTo(), true, GlobalValue::ExternalLinkage, 0, "__cptr"); + m_call = new GlobalVariable(*module, ArrayType::get(GetType(), 0x40000000)->getPointerTo(), true, GlobalValue::ExternalLinkage, 0, fmt::format("__cptr%x", info.funcs[0].addr)); + m_call->setInitializer(ConstantPointerNull::get(cast(m_call->getType()->getPointerElementType()))); + m_call->setExternallyInitialized(true); const auto md_name = MDString::get(m_context, "branch_weights"); const auto md_low = ValueAsMetadata::get(ConstantInt::get(GetType(), 1)); diff --git a/rpcs3/Emu/Cell/PPUTranslator.h b/rpcs3/Emu/Cell/PPUTranslator.h index ae125daf69..24f8f70b81 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.h +++ b/rpcs3/Emu/Cell/PPUTranslator.h @@ -134,14 +134,14 @@ class PPUTranslator final //: public CPUTranslator /* Variables */ // Memory base - llvm::Value* m_base; + llvm::GlobalVariable* m_base; llvm::Value* m_base_loaded; // Thread context llvm::Value* m_thread; // Callable functions - llvm::Value* m_call; + llvm::GlobalVariable* m_call; // Main block llvm::BasicBlock* m_body;