mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-12-27 06:21:02 +00:00
SPU LLVM: emulate PSHUFB
For targets without SSSE3 support
This commit is contained in:
parent
759370ea1b
commit
37577714fa
@ -500,6 +500,25 @@ jit_compiler::~jit_compiler()
|
||||
{
|
||||
}
|
||||
|
||||
bool jit_compiler::has_ssse3() const
|
||||
{
|
||||
if (m_cpu == "generic" ||
|
||||
m_cpu == "k8" ||
|
||||
m_cpu == "opteron" ||
|
||||
m_cpu == "athlon64" ||
|
||||
m_cpu == "athlon-fx" ||
|
||||
m_cpu == "k8-sse3" ||
|
||||
m_cpu == "opteron-sse3" ||
|
||||
m_cpu == "athlon64-sse3" ||
|
||||
m_cpu == "amdfam10" ||
|
||||
m_cpu == "barcelona")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void jit_compiler::add(std::unique_ptr<llvm::Module> module, const std::string& path)
|
||||
{
|
||||
ObjectCache cache{path};
|
||||
|
@ -111,6 +111,9 @@ public:
|
||||
return *m_engine;
|
||||
}
|
||||
|
||||
// Test SSSE3 feature
|
||||
bool has_ssse3() const;
|
||||
|
||||
// Add module (path to obj cache dir)
|
||||
void add(std::unique_ptr<llvm::Module> module, const std::string& path);
|
||||
|
||||
|
@ -1089,7 +1089,29 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
|
||||
value_t<u8[16]> pshufb(T1 a, T2 b)
|
||||
{
|
||||
value_t<u8[16]> result;
|
||||
result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_ssse3_pshuf_b_128), {a.eval(m_ir), b.eval(m_ir)});
|
||||
|
||||
if (m_spurt->m_jit.has_ssse3())
|
||||
{
|
||||
result.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_ssse3_pshuf_b_128), {a.eval(m_ir), b.eval(m_ir)});
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto data0 = a.eval(m_ir);
|
||||
const auto index = b.eval(m_ir);
|
||||
const auto mask = m_ir->CreateAnd(index, 0xf);
|
||||
const auto zero = llvm::ConstantInt::get(get_type<u8[16]>(), 0u);
|
||||
|
||||
result.value = zero;
|
||||
|
||||
for (u32 i = 0; i < 16; i++)
|
||||
{
|
||||
const auto x = m_ir->CreateExtractElement(data0, m_ir->CreateExtractElement(mask, i));
|
||||
result.value = m_ir->CreateInsertElement(result.value, x, i);
|
||||
}
|
||||
|
||||
result.value = m_ir->CreateSelect(m_ir->CreateICmpSLT(index, zero), zero, result.value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user