AK/SIMD: Add a generic implementation of expand

This commit is contained in:
Lucas CHOLLET
2025-10-06 10:44:29 +02:00
committed by Nico Weber
parent 0974ac8fd4
commit 63cd81ddf6
2 changed files with 40 additions and 3 deletions

View File

@@ -14,19 +14,37 @@ namespace AK::SIMD {
// SIMD Vector Expansion
namespace Detail {
template<SIMDVector V, typename T, size_t... Is>
requires(SameAs<T, ElementOf<V>>)
ALWAYS_INLINE static constexpr V expand_to_impl(T t, IndexSequence<Is...> const&)
{
return V { ((void)Is, t)... };
}
}
template<SIMDVector V, typename T>
requires(SameAs<T, ElementOf<V>>)
ALWAYS_INLINE static constexpr V expand_to(T t)
{
return Detail::expand_to_impl<V>(t, MakeIndexSequence<vector_length<V>>());
}
ALWAYS_INLINE static constexpr f32x4 expand4(float f)
{
return f32x4 { f, f, f, f };
return expand_to<f32x4>(f);
}
ALWAYS_INLINE static constexpr i32x4 expand4(i32 i)
{
return i32x4 { i, i, i, i };
return expand_to<i32x4>(i);
}
ALWAYS_INLINE static constexpr u32x4 expand4(u32 u)
{
return u32x4 { u, u, u, u };
return expand_to<u32x4>(u);
}
// Masking

View File

@@ -13,6 +13,25 @@
// See the comment in <AK/SIMDMath.h>
#pragma GCC diagnostic ignored "-Wpsabi"
TEST_CASE(expand_to)
{
auto v1 = AK::SIMD::expand_to<AK::SIMD::u8x2>(static_cast<u8>(1));
static_assert(AK::SIMD::vector_length<decltype(v1)> == 2);
EXPECT(v1[0] == 1 && v1[0] == v1[1]);
auto v2 = AK::SIMD::expand_to<AK::SIMD::u8x32>(static_cast<u8>(2));
static_assert(AK::SIMD::vector_length<decltype(v2)> == 32);
EXPECT(v2[0] == 2);
for (u8 i = 1; i < AK::SIMD::vector_length<decltype(v2)>; ++i)
EXPECT(v2[i - 1] == v2[i]);
auto v3 = AK::SIMD::expand_to<AK::SIMD::i32x8>(-1);
static_assert(AK::SIMD::vector_length<decltype(v3)> == 8);
EXPECT(v3[0] == -1);
for (u8 i = 1; i < AK::SIMD::vector_length<decltype(v3)>; ++i)
EXPECT(v3[i - 1] == v3[i]);
}
TEST_CASE(exp)
{
AK::SIMD::f32x4 v = { .2f, .4f, .6f, .8f };