Mercurial > vec
changeset 32:0de48dc864ea
Backed out changeset d00b95f95dd1
author | Paper <paper@tflc.us> |
---|---|
date | Fri, 25 Apr 2025 17:40:38 -0400 |
parents | bf6ad516f1e6 |
children | 4655b49eaf9f |
files | CMakeLists.txt src/impl/arm/neon.c |
diffstat | 2 files changed, 122 insertions(+), 64 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Fri Apr 25 17:40:33 2025 -0400 +++ b/CMakeLists.txt Fri Apr 25 17:40:38 2025 -0400 @@ -37,10 +37,10 @@ if(COMPILER_HAS_ALTIVEC) set(COMPILER_ALTIVEC_FLAGS "-maltivec") endif() - check_c_compiler_flag("-mfpu=neon" COMPILER_HAS_NEON) - if(COMPILER_HAS_NEON) - set(COMPILER_NEON_FLAGS "-mfpu=neon") - endif() + #check_c_compiler_flag("-mfpu=neon" COMPILER_HAS_NEON) + #if(COMPILER_HAS_NEON) + # set(COMPILER_NEON_FLAGS "-mfpu=neon") + #endif() check_c_compiler_flag("-mmmx" COMPILER_HAS_MMX) if(COMPILER_HAS_MMX) set(COMPILER_MMX_FLAGS "-mmmx")
--- a/src/impl/arm/neon.c Fri Apr 25 17:40:33 2025 -0400 +++ b/src/impl/arm/neon.c Fri Apr 25 17:40:38 2025 -0400 @@ -23,7 +23,6 @@ **/ #include "vec/impl/arm/neon.h" -#include "vec/impl/generic.h" #include <arm_neon.h> @@ -31,91 +30,69 @@ // weren't bad enough... lol) #define VEC_DEFINE_OPERATIONS_SIGN(sign, csign, bits, size) \ - union v##sign##int##bits##x##size##_impl_data { \ - v##sign##int##bits##x##size vec; \ - sign##int##bits##x##size##_t neon; \ - }; \ - \ - VEC_STATIC_ASSERT(VEC_ALIGNOF(sign##int##bits##x##size##_t) <= VEC_ALIGNOF(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " alignment needs to be expanded to fit intrinsic type size"); \ - VEC_STATIC_ASSERT(sizeof(sign##int##bits##x##size##_t) <= sizeof(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " needs to be expanded to fit intrinsic type size"); \ - \ static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_load_aligned(const vec_##sign##int##bits in[size]) \ { \ - union v##sign##int##bits##x##size##_impl_data vec; \ + v##sign##int##bits##x##size vec; \ vec.neon = vld1_##sign##bits(in); \ - return vec.vec; \ + return vec; \ } \ \ static void v##sign##int##bits##x##size##_neon_store_aligned(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ { \ - vstore_lane_##bits(sign, ((union v##sign##int##bits##x##size##_impl_data *)&vec)->neon, out); \ + vstore_lane_##bits(sign, vec.neon, out); \ } \ \ static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_add(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ - union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ - union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ - \ - vec1d->neon = vadd_##sign##bits(vec1d->neon, vec2d->neon); \ - return vec1d->vec; \ + v##sign##int##bits##x##size vec; \ + vec.neon = vadd_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ } \ \ static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_sub(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ - union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ - union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ - \ - vec1d->neon = vsub_##sign##bits(vec1d->neon, vec2d->neon); \ - return vec1d->vec; \ + v##sign##int##bits##x##size vec; \ + vec.neon = vsub_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ } \ \ static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_mul(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ - union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ - union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ - \ - vec1d->neon = vmul_##sign##bits(vec1d->neon, vec2d->neon); \ - return vec1d->vec; \ + v##sign##int##bits##x##size vec; \ + vec.neon = vmul_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ } \ \ static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_lshift(v##sign##int##bits##x##size vec1, vuint##bits##x##size vec2) \ { \ - union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ - union vuint##bits##x##size##_impl_data *vec2d = (union vuint##bits##x##size##_impl_data *)&vec2; \ - \ - vec1d->neon = vshl_##sign##bits(vec1d->neon, (vreinterpret_##bits##_u##bits)vec2d->neon); \ - return vec1d->vec; \ + v##sign##int##bits##x##size vec; \ + vec.neon = vshl_##sign##bits(vec1.neon, vreinterpret_##bits##_u##bits(vec2.neon)); \ + return vec; \ } \ \ static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_and(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ - union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ - union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ - \ - vec1d->neon = vand_##sign##bits(vec1d->neon, vec2d->neon); \ - return vec1d->vec; \ + v##sign##int##bits##x##size vec; \ + vec.neon = vand_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ } \ \ static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_or(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ - union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ - union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ - \ - vec1d->neon = vorr_##sign##bits(vec1d->neon, vec2d->neon); \ - return vec1d->vec; \ + v##sign##int##bits##x##size vec; \ + vec.neon = vorr_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ } \ \ static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_xor(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ { \ - union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ - union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ - \ - vec1d->neon = veor_##sign##bits(vec1d->neon, vec2d->neon); \ - return vec1d->vec; \ + v##sign##int##bits##x##size vec; \ + vec.neon = veor_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ } \ \ static v##sign##int##bits##x##size##_impl v##sign##int##bits##x##size##_impl_neon = { \ - v##sign##int##bits##x##size##_fallback_splat, \ + /* .splat = */ NULL, \ v##sign##int##bits##x##size##_neon_load_aligned, \ v##sign##int##bits##x##size##_neon_load_aligned, \ v##sign##int##bits##x##size##_neon_store_aligned, \ @@ -123,25 +100,20 @@ v##sign##int##bits##x##size##_neon_add, \ v##sign##int##bits##x##size##_neon_sub, \ v##sign##int##bits##x##size##_neon_mul, \ - v##sign##int##bits##x##size##_fallback_div, \ - v##sign##int##bits##x##size##_fallback_avg, \ + /* .div = */ NULL, \ + /* .avg = */ NULL, \ v##sign##int##bits##x##size##_neon_and, \ v##sign##int##bits##x##size##_neon_or, \ v##sign##int##bits##x##size##_neon_xor, \ - v##sign##int##bits##x##size##_fallback_not, \ + /* .not = */ NULL, \ v##sign##int##bits##x##size##_neon_lshift, \ - v##sign##int##bits##x##size##_fallback_rshift, \ - v##sign##int##bits##x##size##_fallback_lrshift, \ - v##sign##int##bits##x##size##_fallback_cmplt, \ - v##sign##int##bits##x##size##_fallback_cmple, \ - v##sign##int##bits##x##size##_fallback_cmpeq, \ - v##sign##int##bits##x##size##_fallback_cmpge, \ - v##sign##int##bits##x##size##_fallback_cmpgt, \ + /* .rshift = */ NULL, \ + /* .lrshift = */ NULL, \ }; #define VEC_DEFINE_OPERATIONS(bits, size) \ - VEC_DEFINE_OPERATIONS_SIGN(u, U, bits, size) \ - VEC_DEFINE_OPERATIONS_SIGN( , , bits, size) + VEC_DEFINE_OPERATIONS_SIGN( , , bits, size) \ + VEC_DEFINE_OPERATIONS_SIGN(u, U, bits, size) // Ok, we'll start out with the 64-bit types. @@ -383,6 +355,92 @@ #define vreinterpret_32_u32(x) vreinterpretq_s32_u32(x) #define vreinterpret_64_u64(x) vreinterpretq_s64_u64(x) +#define VEC_DEFINE_OPERATIONS_SIGN(sign, csign, bits, size) \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_load_aligned(const vec_##sign##int##bits in[size]) \ + { \ + v##sign##int##bits##x##size vec; \ + vec.neon = vld1_##sign##bits(in); \ + return vec; \ + } \ + \ + static void v##sign##int##bits##x##size##_neon_store_aligned(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ + { \ + vstore_lane_##bits(sign, vec.neon, out); \ + } \ + \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_add(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + { \ + v##sign##int##bits##x##size vec; \ + vec.neon = vadd_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ + } \ + \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_sub(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + { \ + v##sign##int##bits##x##size vec; \ + vec.neon = vsub_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ + } \ + \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_mul(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + { \ + v##sign##int##bits##x##size vec; \ + vec.neon = vmul_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ + } \ + \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_lshift(v##sign##int##bits##x##size vec1, vuint##bits##x##size vec2) \ + { \ + v##sign##int##bits##x##size vec; \ + vec.neon = vshl_##sign##bits(vec1.neon, vreinterpret_##bits##_u##bits(vec2.neon)); \ + return vec; \ + } \ + \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_and(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + { \ + v##sign##int##bits##x##size vec; \ + vec.neon = vand_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ + } \ + \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_or(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + { \ + v##sign##int##bits##x##size vec; \ + vec.neon = vorr_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ + } \ + \ + static v##sign##int##bits##x##size v##sign##int##bits##x##size##_neon_xor(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ + { \ + v##sign##int##bits##x##size vec; \ + vec.neon = veor_##sign##bits(vec1.neon, vec2.neon); \ + return vec; \ + } \ + \ + static v##sign##int##bits##x##size##_impl v##sign##int##bits##x##size##_impl_neon = { \ + /* .splat = */ NULL, \ + v##sign##int##bits##x##size##_neon_load_aligned, \ + v##sign##int##bits##x##size##_neon_load_aligned, \ + v##sign##int##bits##x##size##_neon_store_aligned, \ + v##sign##int##bits##x##size##_neon_store_aligned, \ + v##sign##int##bits##x##size##_neon_add, \ + v##sign##int##bits##x##size##_neon_sub, \ + v##sign##int##bits##x##size##_neon_mul, \ + /* .div = */ NULL, \ + /* .avg = */ NULL, \ + v##sign##int##bits##x##size##_neon_and, \ + v##sign##int##bits##x##size##_neon_or, \ + v##sign##int##bits##x##size##_neon_xor, \ + /* .not = */ NULL, \ + v##sign##int##bits##x##size##_neon_lshift, \ + /* .rshift = */ NULL, \ + /* .lrshift = */ NULL, \ + }; + +#define VEC_DEFINE_OPERATIONS(bits, size) \ + VEC_DEFINE_OPERATIONS_SIGN( , , bits, size) \ + VEC_DEFINE_OPERATIONS_SIGN(u, U, bits, size) + VEC_DEFINE_OPERATIONS(8, 16) VEC_DEFINE_OPERATIONS(16, 8) VEC_DEFINE_OPERATIONS(32, 4)