mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-07-10 10:04:47 -06:00
Merge branch 'master' into i
This commit is contained in:
commit
8abdab5f28
@ -3694,11 +3694,22 @@ public:
|
||||
|
||||
// Infinite-precision shift left
|
||||
template <typename T, typename U, typename CT = llvm_common_t<T, U>>
|
||||
auto inf_shl(T&& a, U&& b)
|
||||
value_t<CT> inf_shl(T&& a, U&& b)
|
||||
{
|
||||
static constexpr u32 esz = llvm_value_t<CT>::esize;
|
||||
|
||||
return expr(select(b < esz, a << b, splat<CT>(0)), [](llvm::Value*& value, llvm::Module* _m) -> llvm_match_tuple<T, U>
|
||||
#ifdef ARCH_ARM64
|
||||
auto sh = eval(std::forward<U>(b));
|
||||
auto k = get_known_bits(sh);
|
||||
const auto max_shift = llvm::APInt(k.Zero.getBitWidth(), esz * 2 - 1);
|
||||
|
||||
if ((k.Zero | max_shift).isAllOnes())
|
||||
{
|
||||
return ushl(std::forward<T>(a), sh);
|
||||
}
|
||||
#endif
|
||||
|
||||
auto result = expr(select(b < esz, a << b, splat<CT>(0)), [](llvm::Value*& value, llvm::Module* _m) -> llvm_match_tuple<T, U>
|
||||
{
|
||||
static const auto M = match<CT>();
|
||||
|
||||
@ -3716,15 +3727,28 @@ public:
|
||||
value = nullptr;
|
||||
return {};
|
||||
});
|
||||
|
||||
return eval(result);
|
||||
}
|
||||
|
||||
// Infinite-precision logical shift right (unsigned)
|
||||
template <typename T, typename U, typename CT = llvm_common_t<T, U>>
|
||||
auto inf_lshr(T&& a, U&& b)
|
||||
value_t<CT> inf_lshr(T&& a, U&& b)
|
||||
{
|
||||
static constexpr u32 esz = llvm_value_t<CT>::esize;
|
||||
|
||||
return expr(select(b < esz, a >> b, splat<CT>(0)), [](llvm::Value*& value, llvm::Module* _m) -> llvm_match_tuple<T, U>
|
||||
#ifdef ARCH_ARM64
|
||||
auto sh = eval(std::forward<U>(b));
|
||||
auto k = get_known_bits(sh);
|
||||
const auto max_shift = llvm::APInt(k.Zero.getBitWidth(), esz * 2 - 1);
|
||||
|
||||
if ((k.Zero | max_shift).isAllOnes())
|
||||
{
|
||||
return ushl(std::forward<T>(a), -sh);
|
||||
}
|
||||
#endif
|
||||
|
||||
auto result = expr(select(b < esz, a >> b, splat<CT>(0)), [](llvm::Value*& value, llvm::Module* _m) -> llvm_match_tuple<T, U>
|
||||
{
|
||||
static const auto M = match<CT>();
|
||||
|
||||
@ -3742,6 +3766,8 @@ public:
|
||||
value = nullptr;
|
||||
return {};
|
||||
});
|
||||
|
||||
return eval(result);
|
||||
}
|
||||
|
||||
// Infinite-precision arithmetic shift right (signed)
|
||||
@ -4021,6 +4047,18 @@ template <typename T1, typename T2, typename T3>
|
||||
return sve_mlal<u32[4]>(llvm::Intrinsic::aarch64_sve_umlalt, acc, a, b);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T = llvm_common_t<T1, T2>>
|
||||
value_t<T> ushl(T1 a, T2 b)
|
||||
{
|
||||
value_t<T> result;
|
||||
|
||||
const auto data0 = a.eval(m_ir);
|
||||
const auto data1 = b.eval(m_ir);
|
||||
|
||||
result.value = m_ir->CreateCall(get_intrinsic<T>(llvm::Intrinsic::aarch64_neon_ushl), {data0, data1});
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
auto addp(T1 a, T2 b)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user