mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-31 12:31:45 +01:00
SPU LLVM: add match_vr<> template
Returns reg value only if type is compatible, avoiding bitcast.
This commit is contained in:
parent
dd9bd1338b
commit
8754bbd444
@ -361,6 +361,24 @@ struct is_llvm_expr_of<T, Of, std::void_t<typename is_llvm_expr<T>::type, typena
|
||||
template <typename T, typename... Types>
|
||||
using llvm_common_t = std::enable_if_t<(is_llvm_expr_of<T, Types>::ok && ...), typename is_llvm_expr<T>::type>;
|
||||
|
||||
template <typename T, typename U = llvm_common_t<llvm_value_t<T>>>
|
||||
struct llvm_match_t
|
||||
{
|
||||
using type = T;
|
||||
|
||||
llvm::Value* value = nullptr;
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return value != nullptr;
|
||||
}
|
||||
|
||||
llvm::Value* eval(llvm::IRBuilder<>* ir) const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool ForceSigned = false>
|
||||
struct llvm_const_int
|
||||
{
|
||||
|
@ -2686,6 +2686,31 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
|
||||
return {get_vr<T>(args)...};
|
||||
}
|
||||
|
||||
template <typename T = u32[4], uint I>
|
||||
llvm_match_t<T> match_vr(const bf_t<u32, I, 7>& index)
|
||||
{
|
||||
llvm_match_t<T> r;
|
||||
|
||||
if (m_block)
|
||||
{
|
||||
auto v = m_block->reg.at(index);
|
||||
|
||||
if (v && v->getType() == get_type<T>())
|
||||
{
|
||||
r.value = v;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename T = u32[4], typename... Args>
|
||||
std::tuple<std::conditional_t<false, Args, llvm_match_t<T>>...> match_vrs(const Args&... args)
|
||||
{
|
||||
return {match_vr<T>(args)...};
|
||||
}
|
||||
|
||||
void set_reg_fixed(u32 index, llvm::Value* value, bool fixup = true)
|
||||
{
|
||||
llvm::StoreInst* dummy{};
|
||||
@ -4962,6 +4987,18 @@ public:
|
||||
|
||||
void AND(spu_opcode_t op)
|
||||
{
|
||||
if (const auto [a, b] = match_vrs<u8[16]>(op.ra, op.rb); a && b)
|
||||
{
|
||||
set_vr(op.rt, a & b);
|
||||
return;
|
||||
}
|
||||
|
||||
if (const auto [a, b] = match_vrs<u16[8]>(op.ra, op.rb); a && b)
|
||||
{
|
||||
set_vr(op.rt, a & b);
|
||||
return;
|
||||
}
|
||||
|
||||
set_vr(op.rt, get_vr(op.ra) & get_vr(op.rb));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user