From 73ea02052537378bac64b69e5d7ee73273953fdb Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 21 Jun 2016 23:30:12 +0300 Subject: [PATCH] PPU LLVM: Thread context argument --- rpcs3/Emu/Cell/PPUThread.cpp | 33 +++++++++++++++----------------- rpcs3/Emu/Cell/PPUTranslator.cpp | 30 +++++++++++------------------ rpcs3/Emu/Cell/PPUTranslator.h | 5 ++++- 3 files changed, 30 insertions(+), 38 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index ef1655b7a4..93033fed96 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -33,7 +33,7 @@ struct ppu_addr_hash } }; -static std::unordered_map s_ppu_compiled; +static std::unordered_map s_ppu_compiled; @@ -109,7 +109,7 @@ void PPUThread::cpu_task() if (found != s_ppu_compiled.end()) { - return found->second(); + return found->second(*this); } } @@ -430,7 +430,7 @@ static std::vector s_unwind; struct MemoryManager final : llvm::RTDyldMemoryManager { - static PPUThread* context(u64 addr) + static PPUThread* context(u64 addr) // Unused { //trace(addr); return static_cast(get_current_cpu_thread()); @@ -447,16 +447,14 @@ struct MemoryManager final : llvm::RTDyldMemoryManager LOG_NOTICE(PPU, "Trace: 0x%llx", addr); } - static void hack(u32 index) + static void hlecall(PPUThread& ppu, u32 index) { - PPUThread& ppu = static_cast(*get_current_cpu_thread()); ppu_execute_function(ppu, index); if (ppu.state.load() && ppu.check_status()) throw cpu_state::ret; // Temporarily } - static void syscall(u64 code) + static void syscall(PPUThread& ppu, u64 code) { - PPUThread& ppu = static_cast(*get_current_cpu_thread()); ppu_execute_syscall(ppu, code); if (ppu.state.load() && ppu.check_status()) throw cpu_state::ret; // Temporarily } @@ -466,13 +464,13 @@ struct MemoryManager final : llvm::RTDyldMemoryManager return (u32)get_timebased_time(); } - static void call(u32 addr) + static void call(PPUThread& ppu, u32 addr) { const auto found = s_ppu_compiled.find(addr); if (found != s_ppu_compiled.end()) { - return found->second(); + return found->second(ppu); } const auto op = vm::read32(addr).value(); @@ -481,7 +479,7 @@ struct MemoryManager final : llvm::RTDyldMemoryManager // Allow HLE callbacks without compiling them if (itype == ppu_itype::HACK && vm::read32(addr + 4) == ppu_instructions::BLR()) { - return hack(op & 0x3ffffff); + return hlecall(ppu, op & 0x3ffffff); } trap(addr); @@ -683,10 +681,9 @@ struct MemoryManager final : llvm::RTDyldMemoryManager std::unordered_map table { { "__memory", (u64)vm::base(0) }, - { "__context", (u64)&context }, { "__trap", (u64)&trap }, { "__trace", (u64)&trace }, - { "__hlecall", (u64)&hack }, + { "__hlecall", (u64)&hlecall }, { "__syscall", (u64)&syscall }, { "__get_tbl", (u64)&tbl }, { "__call", (u64)&call }, @@ -839,15 +836,11 @@ extern void ppu_initialize(const std::string& name, const std::vector module = std::make_unique(name, g_context); @@ -857,6 +850,10 @@ extern void ppu_initialize(const std::string& name, const std::vector translator = std::make_unique(g_context, module.get(), 0, entry); + // Define some types + const auto _void = Type::getVoidTy(g_context); + const auto _func = FunctionType::get(_void, { translator->GetContextType()->getPointerTo() }, false); + // Initialize function list for (const auto& info : funcs) { @@ -971,7 +968,7 @@ extern void ppu_initialize(const std::string& name, const std::vectorgetFunctionAddress(fmt::format("__sub_%x", info.first)); - s_ppu_compiled.emplace(info.first, (void(*)())link); + s_ppu_compiled.emplace(info.first, (void(*)(PPUThread&))link); LOG_NOTICE(PPU, "** Function __sub_%x -> 0x%llx (addr=0x%x, size=0x%x)", info.first, link, info.first, info.second); } diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 41db86b163..054418cae4 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -88,6 +88,11 @@ PPUTranslator::~PPUTranslator() { } +Type* PPUTranslator::GetContextType() +{ + return m_thread_type; +} + void PPUTranslator::AddFunction(u64 addr, Function* func, FunctionType* type) { if (!m_func_types.emplace(addr, type).second || !m_func_list.emplace(addr, func).second) @@ -114,7 +119,8 @@ Function* PPUTranslator::TranslateToIR(u64 start_addr, u64 end_addr, be_t* m_ir = &builder; /* Create context variables */ - m_thread = Call(m_thread_type->getPointerTo(), AttributeSet::get(m_context, AttributeSet::FunctionIndex, {Attribute::NoUnwind, Attribute::ReadOnly}), "__context", m_ir->getInt64(start_addr)); + //m_thread = Call(m_thread_type->getPointerTo(), AttributeSet::get(m_context, AttributeSet::FunctionIndex, {Attribute::NoUnwind, Attribute::ReadOnly}), "__context", m_ir->getInt64(start_addr)); + m_thread = &*m_function->getArgumentList().begin(); // Non-volatile registers with special meaning (TODO) m_g_gpr[1] = m_ir->CreateConstGEP2_32(nullptr, m_thread, 0, 1 + 1, ".sp"); @@ -259,7 +265,7 @@ Function* PPUTranslator::TranslateToIR(u64 start_addr, u64 end_addr, be_t* } m_ir->SetInsertPoint(_default); - Call(GetType(), "__call", _ctr); + Call(GetType(), "__call", m_thread, _ctr); m_ir->CreateRetVoid(); } @@ -315,27 +321,13 @@ void PPUTranslator::CallFunction(u64 target, bool tail, Value* indirect) const auto callee_type = func ? m_func_types[target] : nullptr; - // Prepare function arguments - std::vector args; - - if (!callee_type) - { - // Prepare args for untyped function - } - - // Call the function - const auto result = func ? m_ir->CreateCall(func, args) : Call(GetType(), "__call", indirect ? indirect : m_ir->getInt64(target)); + const auto result = func ? m_ir->CreateCall(func, {m_thread}) : Call(GetType(), "__call", m_thread, indirect ? indirect : m_ir->getInt64(target)); if (!tail) { UndefineVolatileRegisters(); } - if (!callee_type) - { - // Get result from untyped function - } - if (tail) { m_ir->CreateRetVoid(); @@ -1746,13 +1738,13 @@ void PPUTranslator::BC(ppu_opcode_t op) void PPUTranslator::HACK(ppu_opcode_t op) { - Call(GetType(), "__hlecall", m_ir->getInt32(op.opcode & 0x3ffffff)); + Call(GetType(), "__hlecall", m_thread, m_ir->getInt32(op.opcode & 0x3ffffff)); UndefineVolatileRegisters(); } void PPUTranslator::SC(ppu_opcode_t op) { - Call(GetType(), fmt::format(op.lev == 0 ? "__syscall" : "__lv%ucall", +op.lev), m_ir->CreateLoad(m_gpr[11])); + Call(GetType(), fmt::format(op.lev == 0 ? "__syscall" : "__lv%ucall", +op.lev), m_thread, m_ir->CreateLoad(m_gpr[11])); UndefineVolatileRegisters(); } diff --git a/rpcs3/Emu/Cell/PPUTranslator.h b/rpcs3/Emu/Cell/PPUTranslator.h index 10f8969fbe..8fa4664b20 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.h +++ b/rpcs3/Emu/Cell/PPUTranslator.h @@ -152,7 +152,7 @@ class PPUTranslator final //: public CPUTranslator // Memory base llvm::Value* m_base; - // Thread context (obtained by __context) + // Thread context llvm::Value* m_thread; // Thread context struct @@ -433,6 +433,9 @@ public: PPUTranslator(llvm::LLVMContext& context, llvm::Module* module, u64 base, u64 entry); ~PPUTranslator(); + // Get thread context struct type + llvm::Type* GetContextType(); + // Add function void AddFunction(u64 addr, llvm::Function* func, llvm::FunctionType* type = nullptr);