From eafbc77c0d2b7fecb6e055a1c13230c7beff500d Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 15 Oct 2019 17:43:33 +0300 Subject: [PATCH] SPU LLVM: Always use linux-gnu target triple (affects Windows) Unify internal code generation to make better use of GHC calling convention. Ideally, it would just work on Windows as well, but some random bug appeared. This bug was causing freezes on SPU LLVM compilation. This commit desperately attempts to workaround it. --- Utilities/JIT.cpp | 7 +++++-- rpcs3/Emu/CPU/CPUTranslator.h | 10 +++++++++- rpcs3/Emu/Cell/SPURecompiler.cpp | 15 ++++++++++----- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Utilities/JIT.cpp b/Utilities/JIT.cpp index cb95477330..0c991de479 100644 --- a/Utilities/JIT.cpp +++ b/Utilities/JIT.cpp @@ -743,6 +743,8 @@ jit_compiler::jit_compiler(const std::unordered_map& _link, co { std::string result; + auto null_mod = std::make_unique ("null_", m_context); + if (m_link.empty()) { std::unique_ptr mem; @@ -754,10 +756,11 @@ jit_compiler::jit_compiler(const std::unordered_map& _link, co else { mem = std::make_unique(); + null_mod->setTargetTriple(llvm::Triple::normalize("x86_64-unknown-linux-gnu")); } // Auxiliary JIT (does not use custom memory manager, only writes the objects) - m_engine.reset(llvm::EngineBuilder(std::make_unique("null_", m_context)) + m_engine.reset(llvm::EngineBuilder(std::move(null_mod)) .setErrorStr(&result) .setEngineKind(llvm::EngineKind::JIT) .setMCJITMemoryManager(std::move(mem)) @@ -772,7 +775,7 @@ jit_compiler::jit_compiler(const std::unordered_map& _link, co auto mem = std::make_unique(m_link); m_jit_el = std::make_unique(*mem); - m_engine.reset(llvm::EngineBuilder(std::make_unique("null", m_context)) + m_engine.reset(llvm::EngineBuilder(std::move(null_mod)) .setErrorStr(&result) .setEngineKind(llvm::EngineKind::JIT) .setMCJITMemoryManager(std::move(mem)) diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index 800f6f963c..3d42419cf3 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -2455,8 +2455,16 @@ public: static_assert(sizeof...(FArgs) == sizeof...(Args), "spu_llvm_recompiler::call(): unexpected arg number"); const auto type = llvm::FunctionType::get(get_type(), {args->getType()...}, false); const auto func = llvm::cast(m_module->getOrInsertFunction({lame.data(), lame.size()}, type).getCallee()); +#ifdef _WIN32 + func->setCallingConv(llvm::CallingConv::Win64); +#endif m_engine->addGlobalMapping({lame.data(), lame.size()}, reinterpret_cast(_func)); - return m_ir->CreateCall(func, {args...}); + + const auto inst = m_ir->CreateCall(func, {args...}); +#ifdef _WIN32 + inst->setCallingConv(llvm::CallingConv::Win64); +#endif + return inst; } // Bitcast with immediate constant folding diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index 1b8c300177..5d02885782 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -3410,7 +3410,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator // 1. Thread context // 2. Local storage pointer // 3. -#ifdef _WIN32 +#if 0 const auto chunk_type = get_ftype(); #else const auto chunk_type = get_ftype(); @@ -3424,7 +3424,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator result->setLinkage(llvm::GlobalValue::InternalLinkage); result->addAttribute(1, llvm::Attribute::NoAlias); result->addAttribute(2, llvm::Attribute::NoAlias); -#ifndef _WIN32 +#if 1 result->setCallingConv(llvm::CallingConv::GHC); #endif @@ -3448,7 +3448,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator fn->setLinkage(llvm::GlobalValue::InternalLinkage); fn->addAttribute(1, llvm::Attribute::NoAlias); fn->addAttribute(2, llvm::Attribute::NoAlias); -#ifndef _WIN32 +#if 1 fn->setCallingConv(llvm::CallingConv::GHC); #endif empl.first->second.fn = fn; @@ -4298,7 +4298,7 @@ public: // Create LLVM module std::unique_ptr module = std::make_unique(m_hash + ".obj", m_context); - module->setTargetTriple(Triple::normalize(sys::getProcessTriple())); + module->setTargetTriple(Triple::normalize("x86_64-unknown-linux-gnu")); module->setDataLayout(m_jit.get_engine().getTargetMachine()->createDataLayout()); m_module = module.get(); @@ -4451,6 +4451,7 @@ public: const auto dispatcher = llvm::cast(m_module->getOrInsertFunction("spu_dispatcher", main_func->getType()).getCallee()); m_engine->addGlobalMapping("spu_dispatcher", reinterpret_cast(spu_runtime::tr_all)); + dispatcher->setCallingConv(main_func->getCallingConv()); // Proceed to the next code if (entry_chunk->chunk->getReturnType() != get_type()) @@ -5887,7 +5888,11 @@ public: else { // TODO - m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::memcpy), {dst, src, zext(size).eval(m_ir), m_ir->getTrue()}); + auto spu_memcpy = [](u8* dst, const u8* src, u32 size) + { + std::memcpy(dst, src, size); + }; + call("spu_memcpy", +spu_memcpy, dst, src, zext(size).eval(m_ir)); } m_ir->CreateBr(next);