mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 21:41:26 +12:00
SPU LLVM: emulate PSHUFB
For targets without SSSE3 support
This commit is contained in:
parent
759370ea1b
commit
37577714fa
3 changed files with 45 additions and 1 deletions
|
@ -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)
|
void jit_compiler::add(std::unique_ptr<llvm::Module> module, const std::string& path)
|
||||||
{
|
{
|
||||||
ObjectCache cache{path};
|
ObjectCache cache{path};
|
||||||
|
|
|
@ -111,6 +111,9 @@ public:
|
||||||
return *m_engine;
|
return *m_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test SSSE3 feature
|
||||||
|
bool has_ssse3() const;
|
||||||
|
|
||||||
// Add module (path to obj cache dir)
|
// Add module (path to obj cache dir)
|
||||||
void add(std::unique_ptr<llvm::Module> module, const std::string& path);
|
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]> pshufb(T1 a, T2 b)
|
||||||
{
|
{
|
||||||
value_t<u8[16]> result;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue