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;
+