diff --git a/3rdparty/llvm.cmake b/3rdparty/llvm.cmake index 3886f0fbcd..2f695f26f5 100644 --- a/3rdparty/llvm.cmake +++ b/3rdparty/llvm.cmake @@ -11,7 +11,6 @@ if(WITH_LLVM) option(LLVM_INCLUDE_TESTS OFF) option(LLVM_INCLUDE_TOOLS OFF) option(LLVM_INCLUDE_UTILS OFF) - option(WITH_POLLY OFF) option(LLVM_CCACHE_BUILD ON) set(CXX_FLAGS_OLD ${CMAKE_CXX_FLAGS}) diff --git a/Utilities/JIT.cpp b/Utilities/JIT.cpp index e4e58f2429..73ba3a7159 100644 --- a/Utilities/JIT.cpp +++ b/Utilities/JIT.cpp @@ -285,6 +285,7 @@ asmjit::Runtime& asmjit::get_global_runtime() #endif #include "llvm/Support/TargetSelect.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/Host.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/ExecutionEngine/ObjectCache.h" diff --git a/Vulkan/glslang-build/glslang-build.vcxproj b/Vulkan/glslang-build/glslang-build.vcxproj index 0c770670a1..b6c7d05ee0 100644 --- a/Vulkan/glslang-build/glslang-build.vcxproj +++ b/Vulkan/glslang-build/glslang-build.vcxproj @@ -38,7 +38,7 @@ "Visual Studio $(VisualStudioVersion.Substring(0,2))" - cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang + cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../glslang $(CmakeCLI) diff --git a/Vulkan/spirv-tools-build/spirv-tools-build.vcxproj b/Vulkan/spirv-tools-build/spirv-tools-build.vcxproj index 21431f4092..ba6dea1f94 100644 --- a/Vulkan/spirv-tools-build/spirv-tools-build.vcxproj +++ b/Vulkan/spirv-tools-build/spirv-tools-build.vcxproj @@ -38,7 +38,7 @@ "Visual Studio $(VisualStudioVersion.Substring(0,2))" - cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DSPIRV-Headers_SOURCE_DIR=$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../spirv-headers')) ../spirv-tools + cmake -G $(CmakeGenerator) -A x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT -DSPIRV-Headers_SOURCE_DIR=$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../spirv-headers')) ../spirv-tools $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\common_default.props')) diff --git a/llvm b/llvm index f5679565d3..8c02f52a12 160000 --- a/llvm +++ b/llvm @@ -1 +1 @@ -Subproject commit f5679565d34863e2f5917f6bb6d3867760862a1e +Subproject commit 8c02f52a12550c2044fef262c9864ca2e3cc193e diff --git a/llvm_build/UpdateProjectFiles.bat b/llvm_build/UpdateProjectFiles.bat index 1f2026a6de..c2b80811aa 100644 --- a/llvm_build/UpdateProjectFiles.bat +++ b/llvm_build/UpdateProjectFiles.bat @@ -1,7 +1,7 @@ REM You need cmake and python to update the project files REM this script relies on CWD being the path that this script is in -cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=8.1 ../llvm +cmake -G "Visual Studio 16 2019 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_DEFAULT_TARGET_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_HOST_TRIPLE:STRING=x86_64-pc-windows-msvc -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_INCLUDE_UTILS=OFF -DLLVM_USE_INTEL_JITEVENTS=ON -DLLVM_ENABLE_Z3_SOLVER=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=10.0 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../llvm RD /S /Q cmake RD /S /Q CMakeFiles diff --git a/llvm_build/llvm_build.vcxproj b/llvm_build/llvm_build.vcxproj index a11f691755..31a1b4ab99 100644 --- a/llvm_build/llvm_build.vcxproj +++ b/llvm_build/llvm_build.vcxproj @@ -39,7 +39,7 @@ "Visual Studio $(VisualStudioVersion.Substring(0,2))" - cmake -G $(CmakeGenerator) -A x64 -Thost=x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DWITH_POLLY=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DCMAKE_CXX_STANDARD=20 -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../llvm + cmake -G $(CmakeGenerator) -A x64 -Thost=x64 -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_RUNTIME=OFF -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_DOCS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_TOOLS=OFF -DLLVM_INCLUDE_UTILS=OFF -DCMAKE_SYSTEM_VERSION=6.1 -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON -DCMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=$(WindowsTargetPlatformVersion) -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_USE_CRT_RELEASE=MT ../llvm diff --git a/rpcs3/Emu/CPU/CPUTranslator.cpp b/rpcs3/Emu/CPU/CPUTranslator.cpp index 5b653be6fe..3052d72d5d 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.cpp +++ b/rpcs3/Emu/CPU/CPUTranslator.cpp @@ -74,9 +74,9 @@ llvm::Value* cpu_translator::bitcast(llvm::Value* val, llvm::Type* type) uint s2 = val->getType()->getScalarSizeInBits(); if (type->isVectorTy()) - s1 *= type->getVectorNumElements(); + s1 *= llvm::cast(type)->getNumElements(); if (val->getType()->isVectorTy()) - s2 *= val->getType()->getVectorNumElements(); + s2 *= llvm::cast(val->getType())->getNumElements(); if (s1 != s2) { @@ -120,9 +120,9 @@ std::pair cpu_translator::get_const_vector(llvm::Value* c, u32 fmt::throw_exception("[0x%x, %u] Not a vector" HERE, a, b); } - if (uint sz = llvm::cast(t)->getBitWidth() - 128) + if (auto v = llvm::cast(t); v->getScalarSizeInBits() * v->getNumElements() != 128) { - fmt::throw_exception("[0x%x, %u] Bad vector size: %u" HERE, a, b, sz + 128); + fmt::throw_exception("[0x%x, %u] Bad vector size: i%ux%u" HERE, a, b, v->getScalarSizeInBits(), v->getNumElements()); } const auto cv = llvm::dyn_cast(c); @@ -203,7 +203,8 @@ llvm::Constant* cpu_translator::make_const_vector(v128 v, llvm::Type* t) return llvm::ConstantInt::get(t, llvm::APInt(128, llvm::makeArrayRef(reinterpret_cast(v._bytes), 2))); } - verify(HERE), t->isVectorTy() && llvm::cast(t)->getBitWidth() == 128; + verify(HERE), t->isVectorTy(); + verify(HERE), 128 == t->getScalarSizeInBits() * llvm::cast(t)->getNumElements(); const auto sct = t->getScalarType(); diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index 60b273eedb..97aa9fc03e 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -363,7 +363,7 @@ struct llvm_value_t : llvm_value_t > } else if constexpr (N > 1) { - return llvm::VectorType::get(base::get_type(context), N); + return llvm::VectorType::get(base::get_type(context), N, false); } else { @@ -2283,9 +2283,11 @@ struct llvm_splat if (auto i = llvm::dyn_cast_or_null(value)) { - if (llvm::isa(i->getOperand(2))) + if (llvm::isa(i->getOperand(1)) || llvm::isa(i->getOperand(1))) { - if (auto j = llvm::dyn_cast(i->getOperand(0))) + static constexpr int zero_array[llvm_value_t::is_vector]{}; + + if (auto j = llvm::dyn_cast(i->getOperand(0)); j && i->getShuffleMask().equals(zero_array)) { if (llvm::cast(j->getOperand(2))->isZero()) { @@ -2311,7 +2313,7 @@ struct llvm_zshuffle using type = std::remove_extent_t[N]; llvm_expr_t a1; - u32 index_array[N]; + int index_array[N]; static_assert(llvm_value_t::is_vector, "llvm_zshuffle<>: invalid type"); @@ -2334,7 +2336,7 @@ struct llvm_zshuffle if (auto z = llvm::dyn_cast(i->getOperand(1)); z && z->getType() == v1->getType()) { - if (llvm::ConstantDataVector::get(value->getContext(), index_array) == i->getOperand(2)) + if (i->getShuffleMask().equals(index_array)) { if (auto r1 = a1.match(v1); v1) { @@ -2356,7 +2358,7 @@ struct llvm_shuffle2 llvm_expr_t a1; llvm_expr_t a2; - u32 index_array[N]; + int index_array[N]; static_assert(llvm_value_t::is_vector, "llvm_shuffle2<>: invalid type"); @@ -2382,7 +2384,7 @@ struct llvm_shuffle2 if (v1->getType() == v2->getType() && v1->getType() == llvm_value_t::get_type(v1->getContext())) { - if (llvm::ConstantDataVector::get(value->getContext(), index_array) == i->getOperand(2)) + if (i->getShuffleMask().equals(index_array)) { if (auto r1 = a1.match(v1); v1) { @@ -2423,7 +2425,7 @@ protected: // Allow FMA bool m_use_fma = false; - // Allow Icelake tier AVX-512 + // Allow Icelake tier AVX-512 bool m_use_avx512_icl = false; // IR builder @@ -2665,13 +2667,13 @@ public: template ::is_ok>> static auto zshuffle(T&& v, Args... indices) { - return llvm_zshuffle{std::forward(v), {static_cast(indices)...}}; + return llvm_zshuffle{std::forward(v), {static_cast(indices)...}}; } template ::is_ok>> static auto shuffle2(T&& v1, U&& v2, Args... indices) { - return llvm_shuffle2{std::forward(v1), std::forward(v2), {static_cast(indices)...}}; + return llvm_shuffle2{std::forward(v1), std::forward(v2), {static_cast(indices)...}}; } // Average: (a + b + 1) >> 1 @@ -2685,7 +2687,7 @@ public: const auto cast_op = result.is_sint ? llvm::Instruction::SExt : llvm::Instruction::ZExt; llvm::Type* cast_to = m_ir->getIntNTy(result.esize * 2); if constexpr (result.is_vector != 0) - cast_to = llvm::VectorType::get(cast_to, result.is_vector); + cast_to = llvm::VectorType::get(cast_to, result.is_vector, false); const auto axt = m_ir->CreateCast(cast_op, a.eval(m_ir), cast_to); const auto bxt = m_ir->CreateCast(cast_op, b.eval(m_ir), cast_to); @@ -2752,7 +2754,7 @@ public: { value_t result; const auto av = a.eval(m_ir); - result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rcp.ps", av->getType(), av->getType()).getCallee(), {av}); + result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rcp.ps", av->getType(), av->getType()), {av}); return result; } @@ -2761,7 +2763,7 @@ public: { value_t result; const auto av = a.eval(m_ir); - result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rsqrt.ps", av->getType(), av->getType()).getCallee(), {av}); + result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.rsqrt.ps", av->getType(), av->getType()), {av}); return result; } @@ -2771,7 +2773,7 @@ public: value_t result; const auto av = a.eval(m_ir); const auto bv = b.eval(m_ir); - result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.max.ps", av->getType(), av->getType(), av->getType()).getCallee(), {av, bv}); + result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.max.ps", av->getType(), av->getType(), av->getType()), {av, bv}); return result; } @@ -2781,7 +2783,7 @@ public: value_t result; const auto av = a.eval(m_ir); const auto bv = b.eval(m_ir); - result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.min.ps", av->getType(), av->getType(), av->getType()).getCallee(), {av, bv}); + result.value = m_ir->CreateCall(m_module->getOrInsertFunction("llvm.x86.sse.min.ps", av->getType(), av->getType(), av->getType()), {av, bv}); return result; } @@ -2930,7 +2932,7 @@ struct fmt_unveil template <> inline llvm::Type* cpu_translator::get_type<__m128i>() { - return llvm::VectorType::get(llvm::Type::getInt8Ty(m_context), 16); + return llvm::VectorType::get(llvm::Type::getInt8Ty(m_context), 16, false); } #ifndef _MSC_VER diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 31fb111868..c4c60cdd5e 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -30,6 +30,7 @@ #endif #include "llvm/Support/FormattedStream.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Host.h" #include "llvm/Object/ObjectFile.h" #include "llvm/ADT/Triple.h" #include "llvm/IR/LLVMContext.h" diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 68631fdf8d..7124e3c399 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -237,7 +237,7 @@ Value* PPUTranslator::VecHandleDenormal(Value* val) const auto type = val->getType(); const auto value = bitcast(val, GetType()); - const auto mask = SExt(m_ir->CreateICmpEQ(m_ir->CreateAnd(value, Broadcast(RegLoad(m_jm_mask), 4)), ConstantVector::getSplat(4, m_ir->getInt32(0))), GetType()); + const auto mask = SExt(m_ir->CreateICmpEQ(m_ir->CreateAnd(value, Broadcast(RegLoad(m_jm_mask), 4)), ConstantAggregateZero::get(value->getType())), GetType()); const auto nz = m_ir->CreateLShr(mask, 1); const auto result = m_ir->CreateAnd(m_ir->CreateNot(nz), value); @@ -282,7 +282,8 @@ Type* PPUTranslator::ScaleType(Type* type, s32 pow2) verify(HERE), (scaled != 0); const auto new_type = m_ir->getIntNTy(scaled); - return type->isVectorTy() ? VectorType::get(new_type, type->getVectorNumElements()) : cast(new_type); + const auto vec_type = dyn_cast(type); + return vec_type ? VectorType::get(new_type, vec_type->getNumElements(), false) : cast(new_type); } Value* PPUTranslator::DuplicateExt(Value* arg) @@ -308,6 +309,8 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect) const auto type = FunctionType::get(GetType(), {m_thread_type->getPointerTo()}, false); const auto block = m_ir->GetInsertBlock(); + FunctionCallee callee; + if (!indirect) { if ((!m_reloc && target < 0x10000) || target >= u64{} - 0x10000) @@ -316,7 +319,7 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect) return; } - indirect = m_module->getOrInsertFunction(fmt::format("__0x%llx", target), type).getCallee(); + callee = m_module->getOrInsertFunction(fmt::format("__0x%llx", target), type); } else { @@ -333,11 +336,11 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect) const auto pos = m_ir->CreateLShr(indirect, 2, "", true); const auto ptr = m_ir->CreateGEP(m_ir->CreateLoad(m_call), {m_ir->getInt64(0), pos}); - indirect = m_ir->CreateIntToPtr(m_ir->CreateLoad(ptr), type->getPointerTo()); + callee = FunctionCallee(type, m_ir->CreateIntToPtr(m_ir->CreateLoad(ptr), type->getPointerTo())); } m_ir->SetInsertPoint(block); - m_ir->CreateCall(indirect, {m_thread})->setTailCallKind(llvm::CallInst::TCK_Tail); + m_ir->CreateCall(callee, {m_thread})->setTailCallKind(llvm::CallInst::TCK_Tail); m_ir->CreateRetVoid(); } @@ -455,7 +458,7 @@ Value* PPUTranslator::Broadcast(Value* value, u32 count) { if (const auto cv = dyn_cast(value)) { - return ConstantVector::getSplat(count, cv); + return ConstantVector::getSplat({count, false}, cv); } return m_ir->CreateVectorSplat(count, value); @@ -464,10 +467,10 @@ Value* PPUTranslator::Broadcast(Value* value, u32 count) std::pair PPUTranslator::Saturate(Value* value, CmpInst::Predicate inst, Value* extreme) { // Modify args - if (value->getType()->isVectorTy() && !extreme->getType()->isVectorTy()) - extreme = Broadcast(extreme, value->getType()->getVectorNumElements()); - if (extreme->getType()->isVectorTy() && !value->getType()->isVectorTy()) - value = Broadcast(value, extreme->getType()->getVectorNumElements()); + if (auto v = dyn_cast(value->getType()); v && !extreme->getType()->isVectorTy()) + extreme = Broadcast(extreme, v->getNumElements()); + if (auto e = dyn_cast(extreme->getType()); e && !value->getType()->isVectorTy()) + value = Broadcast(value, e->getNumElements()); // Compare args const auto cmp = m_ir->CreateICmp(inst, value, extreme); @@ -493,9 +496,9 @@ Value* PPUTranslator::Scale(Value* value, s32 scale) const auto type = value->getType(); const auto power = std::pow(2, scale); - if (type->isVectorTy()) + if (auto v = dyn_cast(type)) { - return m_ir->CreateFMul(value, ConstantVector::getSplat(type->getVectorNumElements(), ConstantFP::get(type->getVectorElementType(), power))); + return m_ir->CreateFMul(value, ConstantVector::getSplat({v->getNumElements(), false}, ConstantFP::get(v->getElementType(), power))); } else { @@ -519,7 +522,7 @@ Value* PPUTranslator::Shuffle(Value* left, Value* right, std::initializer_list data; data.reserve(indices.size()); - const u32 mask = type->getVectorNumElements() - 1; + const u32 mask = cast(type)->getNumElements() - 1; // Transform indices (works for vectors with size 2^N) for (std::size_t i = 0; i < indices.size(); i++) @@ -623,7 +626,7 @@ void PPUTranslator::CompilationError(const std::string& error) void PPUTranslator::MFVSCR(ppu_opcode_t op) { const auto vscr = m_ir->CreateOr(ZExt(RegLoad(m_sat), GetType()), m_ir->CreateShl(ZExt(RegLoad(m_nj), GetType()), 16)); - SetVr(op.vd, m_ir->CreateInsertElement(ConstantVector::getSplat(4, m_ir->getInt32(0)), vscr, m_ir->getInt32(m_is_be ? 3 : 0))); + SetVr(op.vd, m_ir->CreateInsertElement(ConstantAggregateZero::get(GetType()), vscr, m_ir->getInt32(m_is_be ? 3 : 0))); } void PPUTranslator::MTVSCR(ppu_opcode_t op) @@ -909,12 +912,12 @@ void PPUTranslator::VCTSXS(ppu_opcode_t op) const auto b = GetVr(op.vb, VrType::vf); const auto scaled = Scale(b, op.vuimm); //const auto const0 = ConstantVector::getSplat(4, ConstantFP::get(GetType(), 0.0)); - const auto const1 = ConstantVector::getSplat(4, ConstantFP::get(GetType(), -std::pow(2, 31))); + const auto const1 = ConstantVector::getSplat({4, false}, ConstantFP::get(GetType(), -std::pow(2, 31))); //const auto is_nan = m_ir->CreateFCmpUNO(b, const0); // NaN -> 0.0 const auto sat_l = m_ir->CreateFCmpOLT(scaled, const1); // TODO ??? - const auto sat_h = m_ir->CreateFCmpOGE(scaled, ConstantVector::getSplat(4, ConstantFP::get(GetType(), std::pow(2, 31)))); + const auto sat_h = m_ir->CreateFCmpOGE(scaled, ConstantVector::getSplat({4, false}, ConstantFP::get(GetType(), std::pow(2, 31)))); const auto converted = m_ir->CreateFPToSI(m_ir->CreateSelect(sat_l, const1, scaled), GetType()); - SetVr(op.vd, m_ir->CreateSelect(sat_h, ConstantVector::getSplat(4, m_ir->getInt32(0x7fffffff)), converted)); + SetVr(op.vd, m_ir->CreateSelect(sat_h, ConstantVector::getSplat({4, false}, m_ir->getInt32(0x7fffffff)), converted)); SetSat(IsNotZero(m_ir->CreateOr(sat_l, sat_h))); } @@ -922,12 +925,12 @@ void PPUTranslator::VCTUXS(ppu_opcode_t op) { const auto b = GetVr(op.vb, VrType::vf); const auto scaled = Scale(b, op.vuimm); - const auto const0 = ConstantVector::getSplat(4, ConstantFP::get(GetType(), 0.0)); + const auto const0 = ConstantVector::getSplat({4, false}, ConstantFP::get(GetType(), 0.0)); //const auto is_nan = m_ir->CreateFCmpUNO(b, const0); // NaN -> 0.0 const auto sat_l = m_ir->CreateFCmpOLT(scaled, const0); - const auto sat_h = m_ir->CreateFCmpOGE(scaled, ConstantVector::getSplat(4, ConstantFP::get(GetType(), std::pow(2, 32)))); // TODO ??? + const auto sat_h = m_ir->CreateFCmpOGE(scaled, ConstantVector::getSplat({4, false}, ConstantFP::get(GetType(), std::pow(2, 32)))); // TODO ??? const auto converted = m_ir->CreateFPToUI(m_ir->CreateSelect(sat_l, const0, scaled), GetType()); - SetVr(op.vd, m_ir->CreateSelect(sat_h, ConstantVector::getSplat(4, m_ir->getInt32(0xffffffff)), converted)); + SetVr(op.vd, m_ir->CreateSelect(sat_h, ConstantVector::getSplat({4, false}, m_ir->getInt32(0xffffffff)), converted)); SetSat(IsNotZero(m_ir->CreateOr(sat_l, sat_h))); } @@ -1044,7 +1047,7 @@ void PPUTranslator::VMHADDSHS(ppu_opcode_t op) void PPUTranslator::VMHRADDSHS(ppu_opcode_t op) { const auto abc = SExt(GetVrs(VrType::vi16, op.va, op.vb, op.vc)); - const auto result = m_ir->CreateAdd(m_ir->CreateAShr(m_ir->CreateAdd(m_ir->CreateMul(abc[0], abc[1]), ConstantVector::getSplat(8, m_ir->getInt32(0x4000))), 15), abc[2]); + const auto result = m_ir->CreateAdd(m_ir->CreateAShr(m_ir->CreateAdd(m_ir->CreateMul(abc[0], abc[1]), ConstantVector::getSplat({8, false}, m_ir->getInt32(0x4000))), 15), abc[2]); const auto saturated = SaturateSigned(result, -0x8000, 0x7fff); SetVr(op.vd, saturated.first); SetSat(IsNotZero(saturated.second)); @@ -1309,7 +1312,7 @@ void PPUTranslator::VPERM(ppu_opcode_t op) const auto a = get_vr(op.va); const auto b = get_vr(op.vb); const auto c = get_vr(op.vc); - + if (m_use_avx512_icl && op.ra != op.rb) { const auto i = eval(~c); @@ -1401,7 +1404,7 @@ void PPUTranslator::VPKUWUS(ppu_opcode_t op) void PPUTranslator::VREFP(ppu_opcode_t op) { - const auto result = VecHandleResult(m_ir->CreateFDiv(ConstantVector::getSplat(4, ConstantFP::get(GetType(), 1.0)), GetVr(op.vb, VrType::vf))); + const auto result = VecHandleResult(m_ir->CreateFDiv(ConstantVector::getSplat({4, false}, ConstantFP::get(GetType(), 1.0)), GetVr(op.vb, VrType::vf))); SetVr(op.vd, result); } @@ -1445,7 +1448,7 @@ void PPUTranslator::VRLW(ppu_opcode_t op) void PPUTranslator::VRSQRTEFP(ppu_opcode_t op) { - const auto result = m_ir->CreateFDiv(ConstantVector::getSplat(4, ConstantFP::get(GetType(), 1.0)), Call(GetType(), "llvm.sqrt.v4f32", GetVr(op.vb, VrType::vf))); + const auto result = m_ir->CreateFDiv(ConstantVector::getSplat({4, false}, ConstantFP::get(GetType(), 1.0)), Call(GetType(), "llvm.sqrt.v4f32", GetVr(op.vb, VrType::vf))); SetVr(op.vd, VecHandleResult(result)); } @@ -1472,7 +1475,7 @@ void PPUTranslator::VSEL(ppu_opcode_t op) set_vr(op.vd, select(noncast(c) != 0, get_vr(op.vb), get_vr(op.va))); return; } - + bool sel_16 = true; for (u32 i = 0; i < 8; i++) { @@ -1488,7 +1491,7 @@ void PPUTranslator::VSEL(ppu_opcode_t op) set_vr(op.vd, select(bitcast(c) != 0, get_vr(op.vb), get_vr(op.va))); return; } - + bool sel_8 = true; for (u32 i = 0; i < 16; i++) @@ -1582,17 +1585,17 @@ void PPUTranslator::VSPLTH(ppu_opcode_t op) void PPUTranslator::VSPLTISB(ppu_opcode_t op) { - SetVr(op.vd, ConstantVector::getSplat(16, m_ir->getInt8(op.vsimm))); + SetVr(op.vd, ConstantVector::getSplat({16, false}, m_ir->getInt8(op.vsimm))); } void PPUTranslator::VSPLTISH(ppu_opcode_t op) { - SetVr(op.vd, ConstantVector::getSplat(8, m_ir->getInt16(op.vsimm))); + SetVr(op.vd, ConstantVector::getSplat({8, false}, m_ir->getInt16(op.vsimm))); } void PPUTranslator::VSPLTISW(ppu_opcode_t op) { - SetVr(op.vd, ConstantVector::getSplat(4, m_ir->getInt32(op.vsimm))); + SetVr(op.vd, ConstantVector::getSplat({4, false}, m_ir->getInt32(op.vsimm))); } void PPUTranslator::VSPLTW(ppu_opcode_t op) @@ -1800,7 +1803,7 @@ void PPUTranslator::VSUM4UBS(ppu_opcode_t op) const auto e3 = Shuffle(a, nullptr, { 3, 7, 11, 15 }); const auto r = Add({ b, e0, e1, e2, e3 }); // Summ, (e0+e1+e2+e3) is small const auto s = m_ir->CreateICmpULT(r, b); // Carry (saturation) - SetVr(op.vd, m_ir->CreateSelect(s, ConstantVector::getSplat(4, m_ir->getInt32(0xffffffff)), r)); + SetVr(op.vd, m_ir->CreateSelect(s, ConstantVector::getSplat({4, false}, m_ir->getInt32(0xffffffff)), r)); SetSat(IsNotZero(s)); } @@ -1843,7 +1846,7 @@ void PPUTranslator::VXOR(ppu_opcode_t op) if (op.va == op.vb) { // Assign zero, break dependencies - SetVr(op.vd, ConstantVector::getSplat(4, m_ir->getInt32(0))); + SetVr(op.vd, ConstantAggregateZero::get(GetType())); return; } diff --git a/rpcs3/Emu/Cell/PPUTranslator.h b/rpcs3/Emu/Cell/PPUTranslator.h index 179a4fded6..da024793b2 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.h +++ b/rpcs3/Emu/Cell/PPUTranslator.h @@ -317,7 +317,7 @@ public: llvm::CallInst* Call(llvm::Type* ret, llvm::AttributeList attr, llvm::StringRef name, Args... args) { // Call the function - return m_ir->CreateCall(m_module->getOrInsertFunction(name, attr, ret, args->getType()...).getCallee(), {args...}); + return m_ir->CreateCall(m_module->getOrInsertFunction(name, attr, ret, args->getType()...), {args...}); } // Call a function diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index fe3822fbd7..96f68f1b20 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -3418,14 +3418,14 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator } // Create tail call to the function chunk (non-tail calls are just out of question) - void tail_chunk(llvm::Value* chunk, llvm::Value* base_pc = nullptr) + void tail_chunk(llvm::FunctionCallee callee, llvm::Value* base_pc = nullptr) { - if (!chunk && !g_cfg.core.spu_verification) + if (!callee && !g_cfg.core.spu_verification) { // Disable patchpoints if verification is disabled - chunk = m_dispatch; + callee = m_dispatch; } - else if (!chunk) + else if (!callee) { // Create branch patchpoint if chunk == nullptr verify(HERE), m_finfo, !m_finfo->fn || m_function == m_finfo->chunk; @@ -3444,12 +3444,13 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator return; } - chunk = ppfunc; + callee = ppfunc; base_pc = m_ir->getInt32(0); } - auto call = m_ir->CreateCall(chunk, {m_thread, m_lsptr, base_pc ? base_pc : m_base_pc}); - auto func = m_finfo ? m_finfo->chunk : llvm::cast(chunk); + verify(HERE), callee; + auto call = m_ir->CreateCall(callee, {m_thread, m_lsptr, base_pc ? base_pc : m_base_pc}); + auto func = m_finfo ? m_finfo->chunk : llvm::dyn_cast(callee.getCallee()); call->setCallingConv(func->getCallingConv()); call->setTailCall(); @@ -4341,7 +4342,7 @@ public: for (u32 j = starta; j < end; j += 32) { - u32 indices[8]; + int indices[8]; bool holes = false; bool data = false; @@ -4373,7 +4374,7 @@ public: // Mask if necessary if (holes) { - vls = m_ir->CreateShuffleVector(vls, ConstantVector::getSplat(8, m_ir->getInt32(0)), indices); + vls = m_ir->CreateShuffleVector(vls, ConstantAggregateZero::get(vls->getType()), indices); } // Perform bitwise comparison and accumulate @@ -4419,7 +4420,8 @@ public: // Proceed to the next code if (entry_chunk->chunk->getReturnType() != get_type()) { - const auto next_call = m_ir->CreateCall(m_ir->CreateBitCast(entry_call, main_func->getType()), {m_thread, m_lsptr, m_ir->getInt64(0)}); + const auto f_ptr = m_ir->CreateBitCast(entry_call, main_func->getType()); + const auto next_call = m_ir->CreateCall({main_func->getFunctionType(), f_ptr}, {m_thread, m_lsptr, m_ir->getInt64(0)}); next_call->setCallingConv(main_func->getCallingConv()); next_call->setTailCall(); } @@ -4456,7 +4458,8 @@ public: if (entry_chunk->chunk->getReturnType() == get_type()) { - const auto next_call = m_ir->CreateCall(m_ir->CreateBitCast(dispatcher, main_func->getType()), {m_thread, m_lsptr, m_ir->getInt64(0)}); + const auto f_ptr = m_ir->CreateBitCast(dispatcher, main_func->getType()); + const auto next_call = m_ir->CreateCall({main_func->getFunctionType(), f_ptr}, {m_thread, m_lsptr, m_ir->getInt64(0)}); next_call->setCallingConv(main_func->getCallingConv()); next_call->setTailCall(); m_ir->CreateRetVoid(); @@ -4911,7 +4914,7 @@ public: // Decode (shift) and load function pointer const auto first = m_ir->CreateLoad(m_ir->CreateGEP(m_ir->CreateBitCast(m_interp_table, if_pptr), m_ir->CreateLShr(m_interp_op, 32u - m_interp_magn))); - const auto call0 = m_ir->CreateCall(first, {m_lsptr, m_thread, m_interp_pc, m_interp_op, m_interp_table, m_interp_7f0, m_interp_regs}); + const auto call0 = m_ir->CreateCall({if_type, first}, {m_lsptr, m_thread, m_interp_pc, m_interp_op, m_interp_table, m_interp_7f0, m_interp_regs}); call0->setCallingConv(CallingConv::GHC); m_ir->CreateRetVoid(); @@ -5125,7 +5128,7 @@ public: } const auto arg3 = UndefValue::get(get_type()); - const auto _ret = m_ir->CreateCall(fret, {m_lsptr, m_thread, m_interp_pc, arg3, m_interp_table, m_interp_7f0, m_interp_regs}); + const auto _ret = m_ir->CreateCall({if_type, fret}, {m_lsptr, m_thread, m_interp_pc, arg3, m_interp_table, m_interp_7f0, m_interp_regs}); _ret->setCallingConv(CallingConv::GHC); _ret->setTailCall(); m_ir->CreateRetVoid(); @@ -5149,7 +5152,7 @@ public: m_interp_regs = _ptr(m_thread, get_reg_offset(0)); } - const auto ncall = m_ir->CreateCall(next_if, {m_lsptr, m_thread, m_interp_pc, next_op, m_interp_table, m_interp_7f0, m_interp_regs}); + const auto ncall = m_ir->CreateCall({if_type, next_if}, {m_lsptr, m_thread, m_interp_pc, next_op, m_interp_table, m_interp_7f0, m_interp_regs}); ncall->setCallingConv(CallingConv::GHC); ncall->setTailCall(); m_ir->CreateRetVoid(); @@ -8405,7 +8408,9 @@ public: // Clear stack mirror and return by tail call to the provided return address m_ir->CreateStore(splat(-1).eval(m_ir), m_ir->CreateBitCast(m_ir->CreateGEP(m_thread, stack0.value), get_type())); const auto targ = m_ir->CreateAdd(m_ir->CreateLShr(_ret, 32), get_segment_base()); - tail_chunk(m_ir->CreateIntToPtr(targ, m_finfo->chunk->getFunctionType()->getPointerTo()), m_ir->CreateTrunc(m_ir->CreateLShr(link, 32), get_type())); + const auto type = m_finfo->chunk->getFunctionType(); + const auto fval = m_ir->CreateIntToPtr(targ, type->getPointerTo()); + tail_chunk({type, fval}, m_ir->CreateTrunc(m_ir->CreateLShr(link, 32), get_type())); m_ir->SetInsertPoint(fail); } @@ -8420,7 +8425,7 @@ public: const auto ad64 = m_ir->CreateZExt(ad32, get_type()); const auto pptr = m_ir->CreateGEP(m_function_table, {m_ir->getInt64(0), m_ir->CreateLShr(ad64, 2, "", true)}); - tail_chunk(m_ir->CreateLoad(pptr)); + tail_chunk({m_dispatch->getFunctionType(), m_ir->CreateLoad(pptr)}); m_ir->SetInsertPoint(fail); } diff --git a/rpcs3/main.cpp b/rpcs3/main.cpp index e6731b91d4..a90cf83530 100644 --- a/rpcs3/main.cpp +++ b/rpcs3/main.cpp @@ -521,3 +521,55 @@ int main(int argc, char** argv) // run event loop (maybe only needed for the gui application) return app->exec(); } + +// Temporarily, this is code from std for prebuilt LLVM. I don't understand why this is necessary. +// From the same MSVC 19.27.29112.0, LLVM libs depend on these, but RPCS3 gets linker errors. +#ifdef _WIN32 +extern "C" +{ + int __stdcall __std_init_once_begin_initialize(void** ppinit, ulong f, int* fp, void** lpc) noexcept + { + return InitOnceBeginInitialize(reinterpret_cast(ppinit), f, fp, lpc); + } + + int __stdcall __std_init_once_complete(void** ppinit, ulong f, void* lpc) noexcept + { + return InitOnceComplete(reinterpret_cast(ppinit), f, lpc); + } + + size_t __stdcall __std_get_string_size_without_trailing_whitespace(const char* str, size_t size) noexcept + { + while (size) + { + switch (str[size - 1]) + { + case 0: + case ' ': + case '\n': + case '\r': + case '\t': + { + size--; + continue; + } + } + + break; + } + + return size; + } + + size_t __stdcall __std_system_error_allocate_message(const unsigned long msg_id, char** ptr_str) noexcept + { + return __std_get_string_size_without_trailing_whitespace(*ptr_str, FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, msg_id, 0, reinterpret_cast(ptr_str), 0, nullptr)); + } + + void __stdcall __std_system_error_deallocate_message(char* s) noexcept + { + LocalFree(s); + } +} +#endif diff --git a/rpcs3_llvm.props b/rpcs3_llvm.props index 8a491e8dcd..0b5ef65999 100644 --- a/rpcs3_llvm.props +++ b/rpcs3_llvm.props @@ -10,7 +10,53 @@ %(AdditionalLibraryDirectories);..\llvm_build\Debug\lib %(AdditionalLibraryDirectories);..\llvm_build\Release\lib - %(AdditionalDependencies);LLVMProfileData.lib;LLVMDebugInfoCodeView.lib;LLVMDebugInfoMSF.lib;LLVMInstrumentation.lib;LLVMMCJIT.lib;LLVMRuntimeDyld.lib;LLVMVectorize.lib;LLVMX86CodeGen.lib;LLVMGlobalISel.lib;LLVMX86Disassembler.lib;LLVMExecutionEngine.lib;LLVMAsmPrinter.lib;LLVMSelectionDAG.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMAnalysis.lib;LLVMTarget.lib;LLVMX86Desc.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMCore.lib;LLVMX86Utils.lib;LLVMMC.lib;LLVMX86Info.lib;LLVMSupport.lib;LLVMMCDisassembler.lib;LLVMipo.lib;LLVMBinaryFormat.lib;LLVMPasses.lib;LLVMIRReader.lib;LLVMLinker.lib;LLVMAsmParser.lib;LLVMX86AsmParser.lib;LLVMDemangle.lib;LLVMDebugInfoDWARF.lib;LLVMRemarks.lib;LLVMBitstreamReader.lib;LLVMTextAPI.lib;LLVMCFGuard.lib + %(AdditionalDependencies); + LLVMProfileData.lib; + LLVMDebugInfoCodeView.lib; + LLVMDebugInfoMSF.lib; + LLVMInstrumentation.lib; + LLVMMCJIT.lib; + LLVMRuntimeDyld.lib; + LLVMVectorize.lib; + LLVMX86CodeGen.lib; + LLVMGlobalISel.lib; + LLVMX86Disassembler.lib; + LLVMExecutionEngine.lib; + LLVMAsmPrinter.lib; + LLVMSelectionDAG.lib; + LLVMCodeGen.lib; + LLVMScalarOpts.lib; + LLVMInstCombine.lib; + LLVMTransformUtils.lib; + LLVMAnalysis.lib; + LLVMTarget.lib; + LLVMX86Desc.lib; + LLVMObject.lib; + LLVMMCParser.lib; + LLVMBitReader.lib; + LLVMCore.lib; + LLVMMC.lib; + LLVMX86Info.lib; + LLVMSupport.lib; + LLVMMCDisassembler.lib; + LLVMipo.lib; + LLVMBinaryFormat.lib; + LLVMPasses.lib; + LLVMIRReader.lib; + LLVMLinker.lib; + LLVMAsmParser.lib; + LLVMX86AsmParser.lib; + LLVMDemangle.lib; + LLVMDebugInfoDWARF.lib; + LLVMRemarks.lib; + LLVMBitstreamReader.lib; + LLVMTextAPI.lib; + LLVMCFGuard.lib; + LLVMAggressiveInstCombine.lib; + LLVMBitWriter.lib; + LLVMCoroutines.lib; + LLVMObjCARCOpts.lib; +