mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-07-10 01:44:41 -06:00
SPU LLVM: Calculate FREST fraction LUT using vperm2dlculate FREST fraction using vperm2d for AVX512 (#18931)
The `FREST` instruction uses a scalar lookup-table loop to calculate the mantissa. Given that it's only 32 elements, we can load it into two 512-bit vectors and treat them as the sources to the `vperm2d` shuffle instruction. This allows it to be calculated in parallel, improving its performance.
This commit is contained in:
parent
c7478d6dcc
commit
927e2492ef
@ -3670,6 +3670,23 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T1, typename T2, typename T3>
|
||||||
|
value_t<u32[4]> vperm2d128From512(T1 a, T2 b, T3 c)
|
||||||
|
{
|
||||||
|
value_t<u32[4]> result;
|
||||||
|
value_t<u32[16]> perm512;
|
||||||
|
|
||||||
|
const auto data0 = a.eval(m_ir);
|
||||||
|
const auto index128 = b.eval(m_ir);
|
||||||
|
const auto data1 = c.eval(m_ir);
|
||||||
|
|
||||||
|
const auto index512 = m_ir->CreateInsertVector(get_type<u32[16]>(), llvm::UndefValue::get(get_type<u32[16]>()), index128, m_ir->getInt64(0));
|
||||||
|
perm512.value = m_ir->CreateCall(get_intrinsic(llvm::Intrinsic::x86_avx512_vpermi2var_d_512), {data0, index512, data1});
|
||||||
|
|
||||||
|
result.value = m_ir->CreateExtractVector(get_type<u32[4]>(), perm512.value, m_ir->getInt64(0));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
value_t<u8[16]> gf2p8affineqb(T1 a, T2 b, u8 c)
|
value_t<u8[16]> gf2p8affineqb(T1 a, T2 b, u8 c)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -7498,13 +7498,23 @@ public:
|
|||||||
const auto a_sign = (a & splat<u32[4]>(0x80000000));
|
const auto a_sign = (a & splat<u32[4]>(0x80000000));
|
||||||
value_t<u32[4]> final_result = eval(splat<u32[4]>(0));
|
value_t<u32[4]> final_result = eval(splat<u32[4]>(0));
|
||||||
|
|
||||||
for (u32 i = 0; i < 4; i++)
|
if (m_use_avx512)
|
||||||
{
|
{
|
||||||
const auto eval_fraction = eval(extract(a_fraction, i));
|
value_t<u32[16]> lo_lut;
|
||||||
|
value_t<u32[16]> hi_lut;
|
||||||
|
lo_lut.value = llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(spu_frest_fraction_lut, 16));
|
||||||
|
hi_lut.value = llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(spu_frest_fraction_lut + 16, 16));
|
||||||
|
|
||||||
value_t<u32> r_fraction = load_const<u32>(m_spu_frest_fraction_lut, eval_fraction);
|
final_result = vperm2d128From512(lo_lut, a_fraction, hi_lut);
|
||||||
|
}
|
||||||
final_result = eval(insert(final_result, i, r_fraction));
|
else
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
const auto eval_fraction = eval(extract(a_fraction, i));
|
||||||
|
value_t<u32> r_fraction = load_const<u32>(m_spu_frest_fraction_lut, eval_fraction);
|
||||||
|
final_result = eval(insert(final_result, i, r_fraction));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//final_result = eval(select(final_result != (0), final_result, bitcast<u32[4]>(pshufb(splat<u8[16]>(0), bitcast<u8[16]>(final_result)))));
|
//final_result = eval(select(final_result != (0), final_result, bitcast<u32[4]>(pshufb(splat<u8[16]>(0), bitcast<u8[16]>(final_result)))));
|
||||||
@ -8551,13 +8561,23 @@ public:
|
|||||||
const auto a_sign = (a & splat<u32[4]>(0x80000000));
|
const auto a_sign = (a & splat<u32[4]>(0x80000000));
|
||||||
value_t<u32[4]> b = eval(splat<u32[4]>(0));
|
value_t<u32[4]> b = eval(splat<u32[4]>(0));
|
||||||
|
|
||||||
for (u32 i = 0; i < 4; i++)
|
if (m_use_avx512)
|
||||||
{
|
{
|
||||||
const auto eval_fraction = eval(extract(a_fraction, i));
|
value_t<u32[16]> lo_lut;
|
||||||
|
value_t<u32[16]> hi_lut;
|
||||||
|
lo_lut.value = llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(spu_frest_fraction_lut, 16));
|
||||||
|
hi_lut.value = llvm::ConstantDataVector::get(m_context, llvm::ArrayRef(spu_frest_fraction_lut + 16, 16));
|
||||||
|
|
||||||
value_t<u32> r_fraction = load_const<u32>(m_spu_frest_fraction_lut, eval_fraction);
|
b = vperm2d128From512(lo_lut, a_fraction, hi_lut);
|
||||||
|
}
|
||||||
b = eval(insert(b, i, r_fraction));
|
else
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
const auto eval_fraction = eval(extract(a_fraction, i));
|
||||||
|
value_t<u32> r_fraction = load_const<u32>(m_spu_frest_fraction_lut, eval_fraction);
|
||||||
|
b = eval(insert(b, i, r_fraction));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b = eval(b | fix_exponent | a_sign);
|
b = eval(b | fix_exponent | a_sign);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user