From 9ee334e9700d48a3471e7eab3e02d42e2c383bc0 Mon Sep 17 00:00:00 2001 From: Hendiadyoin1 Date: Mon, 15 Apr 2024 20:28:22 +0200 Subject: [PATCH] AK: Add introspection helpers to SIMD.h (cherry picked from commit 8d6028d366c918b3656c0a4c6808a570dcecf8f4) --- AK/SIMD.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/AK/SIMD.h b/AK/SIMD.h index b923f7a1110..f109899d02a 100644 --- a/AK/SIMD.h +++ b/AK/SIMD.h @@ -6,6 +6,7 @@ #pragma once +#include #include namespace AK::SIMD { @@ -61,4 +62,55 @@ using f32x8 = float __attribute__((vector_size(32))); using f64x2 = double __attribute__((vector_size(16))); using f64x4 = double __attribute__((vector_size(32))); +// FIXME: Is this really the best/simplest way? +// Ideally we should look for the presence of the vector_size attribute instead +// FIXME: This cannot just be vector as that would somehow clash with AK::Vector, even without being exported +template +concept SIMDVector = requires { __builtin_convertvector(declval(), T); }; + +template +using ElementOf = RemoveReference()[0])>; + +static_assert(IsSame, i8>); +static_assert(IsSame, float>); + +template +constexpr static size_t vector_length = sizeof(V) / sizeof(ElementOf); + +static_assert(vector_length == 4); +static_assert(vector_length == 4); + +namespace Detail { +template +struct IndexVectorFor; + +template +requires(IsIntegral>) +struct IndexVectorFor { + using Type = T; +}; + +template +requires(IsFloatingPoint>) +struct IndexVectorFor { + using Type = Conditional< + IsSame, float>, + u32 __attribute__((vector_size(sizeof(T)))), + u64 __attribute__((vector_size(sizeof(T))))>; +}; + +} + +template +using IndexVectorFor = typename Detail::IndexVectorFor::Type; + +static_assert(IsSame, i8x16>); +static_assert(IsSame, u32x4>); +static_assert(IsSame, u64x4>); +#if defined(AK_COMPILER_CLANG) +// FIXME: GCC silently ignores the dependent vector_size attribute, this seems to be a bug +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68703 +static_assert(IsSame, u32x4>); +static_assert(IsSame, u64x4>); +#endif }