mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-07-10 01:54:46 -06:00
SPU LLVM: Idiomatic FSM implementation
- Compiles down to just 2 instructions on Neon, instead of falling back to scalar instructions - Remove this workaround when LLVM fixes this issue upstream: https://github.com/llvm/llvm-project/issues/200325
This commit is contained in:
parent
4a92d96cf4
commit
2f2ac69d60
@ -5657,22 +5657,44 @@ public:
|
||||
}
|
||||
|
||||
const auto v = extract(get_vr(op.ra), 3);
|
||||
#ifdef ARCH_ARM64
|
||||
// Workaround for bad codegen via LLVM
|
||||
// More idiomatic version that compiles to 2 neon instructions
|
||||
// Remove me when addressed by upstream llvm: https://github.com/llvm/llvm-project/issues/200325 - Whatcookie
|
||||
const auto masks = build<u32[4]>(1, 2, 4, 8);
|
||||
const auto bits = vsplat<u32[4]>(zext<u32>(trunc<i4>(v)));
|
||||
set_vr(op.rt, sext<s32[4]>((bits & masks) == masks));
|
||||
#else
|
||||
const auto m = bitcast<bool[4]>(trunc<i4>(v));
|
||||
set_vr(op.rt, sext<s32[4]>(m));
|
||||
#endif
|
||||
}
|
||||
|
||||
void FSMH(spu_opcode_t op)
|
||||
{
|
||||
const auto v = extract(get_vr(op.ra), 3);
|
||||
#ifdef ARCH_ARM64
|
||||
const auto masks = build<u16[8]>(1, 2, 4, 8, 16, 32, 64, 128);
|
||||
const auto bits = vsplat<u16[8]>(zext<u16>(trunc<u8>(v)));
|
||||
set_vr(op.rt, sext<s16[8]>((bits & masks) == masks));
|
||||
#else
|
||||
const auto m = bitcast<bool[8]>(trunc<u8>(v));
|
||||
set_vr(op.rt, sext<s16[8]>(m));
|
||||
#endif
|
||||
}
|
||||
|
||||
void FSMB(spu_opcode_t op)
|
||||
{
|
||||
const auto v = extract(get_vr(op.ra), 3);
|
||||
#ifdef ARCH_ARM64
|
||||
const auto masks = build<u8[16]>(1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128);
|
||||
const auto bytes = bitcast<u8[16]>(vsplat<u16[8]>(trunc<u16>(v)));
|
||||
const auto bits = zshuffle(bytes, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1);
|
||||
set_vr(op.rt, sext<s8[16]>((bits & masks) == masks));
|
||||
#else
|
||||
const auto m = bitcast<bool[16]>(trunc<u16>(v));
|
||||
set_vr(op.rt, sext<s8[16]>(m));
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename TA>
|
||||
@ -6333,8 +6355,15 @@ public:
|
||||
|
||||
void FSMBI(spu_opcode_t op)
|
||||
{
|
||||
#ifdef ARCH_ARM64
|
||||
const auto masks = build<u8[16]>(1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128);
|
||||
const auto bytes = bitcast<u8[16]>(vsplat<u16[8]>(get_imm<u16>(op.i16)));
|
||||
const auto bits = zshuffle(bytes, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1);
|
||||
set_vr(op.rt, sext<s8[16]>((bits & masks) == masks));
|
||||
#else
|
||||
const auto m = bitcast<bool[16]>(get_imm<u16>(op.i16));
|
||||
set_vr(op.rt, sext<s8[16]>(m));
|
||||
#endif
|
||||
}
|
||||
|
||||
void IL(spu_opcode_t op)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user