diff --git a/Utilities/JIT.cpp b/Utilities/JIT.cpp index 4f7e72e2c4..8f69e68c90 100644 --- a/Utilities/JIT.cpp +++ b/Utilities/JIT.cpp @@ -231,7 +231,7 @@ jit_compiler::jit_compiler(std::unique_ptr&& _module, std::unorder .setErrorStr(&result) .setMCJITMemoryManager(std::make_unique(std::move(table))) .setOptLevel(llvm::CodeGenOpt::Aggressive) - .setCodeModel((u64)s_memory <= 0x60000000 ? llvm::CodeModel::Medium : llvm::CodeModel::Large) // TODO + .setCodeModel((u64)s_memory <= 0x60000000 ? llvm::CodeModel::Small : llvm::CodeModel::Large) // TODO .setMCPU(llvm::sys::getHostCPUName()) .create()); diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index fec61e08fc..20f273569c 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -57,14 +57,14 @@ 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; -const auto s_ppu_compiled = static_cast(memory_helper::reserve_memory(0x200000000)); +const auto s_ppu_compiled = static_cast(memory_helper::reserve_memory(0x100000000)); extern void ppu_register_function_at(u32 addr, ppu_function_t ptr) { if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm) { - memory_helper::commit_page_memory(s_ppu_compiled + addr / 4, sizeof(ppu_function_t)); - s_ppu_compiled[addr / 4] = ptr; + memory_helper::commit_page_memory(s_ppu_compiled + addr / 4, sizeof(s_ppu_compiled[0])); + s_ppu_compiled[addr / 4] = (u32)(std::uintptr_t)ptr; } } @@ -134,7 +134,7 @@ void PPUThread::cpu_task_main() { if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm) { - return s_ppu_compiled[pc / 4](*this); + return reinterpret_cast((std::uintptr_t)s_ppu_compiled[pc / 4])(*this); } g_tls_log_prefix = [] @@ -451,15 +451,14 @@ extern void ppu_initialize(const std::string& name, const std::vector link_table { - { "__memory", (u64)vm::g_base_addr }, - { "__memptr", (u64)&vm::g_base_addr }, + { "__mptr", (u64)&vm::g_base_addr }, + { "__cptr", (u64)&s_ppu_compiled }, { "__trap", (u64)&ppu_trap }, { "__end", (u64)&ppu_unreachable }, { "__trace", (u64)&ppu_trace }, { "__hlecall", (u64)&ppu_execute_function }, { "__syscall", (u64)&ppu_execute_syscall }, { "__get_tbl", (u64)&get_timebased_time }, - { "__call", (u64)s_ppu_compiled }, { "__lwarx", (u64)&ppu_lwarx }, { "__ldarx", (u64)&ppu_ldarx }, { "__stwcx", (u64)&ppu_stwcx }, diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 8149e2e7c5..d80e506a9c 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -71,7 +71,7 @@ PPUTranslator::PPUTranslator(LLVMContext& context, Module* module, u64 base, u64 , m_pure_attr(AttributeSet::get(m_context, AttributeSet::FunctionIndex, {Attribute::NoUnwind, Attribute::ReadNone})) { // Memory base - m_base = new GlobalVariable(*module, ArrayType::get(GetType(), 0x100000000), false, GlobalValue::ExternalLinkage, 0, "__memory"); + m_base = new GlobalVariable(*module, ArrayType::get(GetType(), 0x100000000)->getPointerTo(), true, GlobalValue::ExternalLinkage, 0, "__mptr"); // Thread context struct (TODO: safer member access) std::vector thread_struct{ArrayType::get(GetType(), OFFSET_32(PPUThread, GPR))}; @@ -84,7 +84,7 @@ PPUTranslator::PPUTranslator(LLVMContext& context, Module* module, u64 base, u64 m_thread_type = StructType::create(m_context, thread_struct, "context_t"); // Callable - m_call = new GlobalVariable(*module, ArrayType::get(FunctionType::get(GetType(), {m_thread_type->getPointerTo()}, false)->getPointerTo(), 0x40000000), true, GlobalValue::ExternalLinkage, 0, "__call"); + m_call = new GlobalVariable(*module, ArrayType::get(GetType(), 0x40000000)->getPointerTo(), true, GlobalValue::ExternalLinkage, 0, "__cptr"); } PPUTranslator::~PPUTranslator() @@ -125,6 +125,7 @@ Function* PPUTranslator::TranslateToIR(const ppu_function& info, be_t* bin, /* Create context variables */ //m_thread = Call(m_thread_type->getPointerTo(), AttributeSet::get(m_context, AttributeSet::FunctionIndex, {Attribute::NoUnwind, Attribute::ReadOnly}), "__context", m_ir->getInt64(info.addr)); m_thread = &*m_function->getArgumentList().begin(); + m_base_loaded = m_ir->CreateLoad(m_base); // Non-volatile registers with special meaning (TODO) if (info.attr & ppu_attr::uses_r0) m_g_gpr[0] = m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 1 + 0, ".r0g"); @@ -319,8 +320,8 @@ void PPUTranslator::CallFunction(u64 target, bool tail, Value* indirect) { const auto addr = indirect ? indirect : (Value*)m_ir->getInt64(target); const auto pos = m_ir->CreateLShr(addr, 2, "", true); - const auto ptr = m_ir->CreateGEP(m_call, {m_ir->getInt64(0), pos}); - m_ir->CreateCall(m_ir->CreateLoad(ptr), {m_thread}); + const auto ptr = m_ir->CreateGEP(m_ir->CreateLoad(m_call), {m_ir->getInt64(0), pos}); + m_ir->CreateCall(m_ir->CreateIntToPtr(m_ir->CreateLoad(ptr), FunctionType::get(GetType(), {m_thread_type->getPointerTo()}, false)->getPointerTo()), {m_thread}); } if (!tail) @@ -545,7 +546,7 @@ void PPUTranslator::UseCondition(Value* cond) llvm::Value* PPUTranslator::GetMemory(llvm::Value* addr, llvm::Type* type) { - return m_ir->CreateBitCast(m_ir->CreateGEP(m_base, {m_ir->getInt64(0), addr}), type->getPointerTo()); + return m_ir->CreateBitCast(m_ir->CreateGEP(m_base_loaded, {m_ir->getInt64(0), addr}), type->getPointerTo()); } Value* PPUTranslator::ReadMemory(Value* addr, Type* type, bool is_be, u32 align) diff --git a/rpcs3/Emu/Cell/PPUTranslator.h b/rpcs3/Emu/Cell/PPUTranslator.h index 542b406c60..780e9e7e81 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.h +++ b/rpcs3/Emu/Cell/PPUTranslator.h @@ -151,6 +151,7 @@ class PPUTranslator final //: public CPUTranslator // Memory base llvm::Value* m_base; + llvm::Value* m_base_loaded; // Thread context llvm::Value* m_thread;