# HG changeset patch # User Paper # Date 1732512782 18000 # Node ID d00b95f95dd1887d64c6bec921ab69cb8f7c8a13 # Parent 6c91cd9a2f2dd52a3ccfd66f019a4b160840cb9c impl/arm/neon: it compiles again, but is untested diff -r 6c91cd9a2f2d -r d00b95f95dd1 CMakeLists.txt --- a/CMakeLists.txt Mon Nov 25 04:43:22 2024 +0000 +++ b/CMakeLists.txt Mon Nov 25 00:33:02 2024 -0500 @@ -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") diff -r 6c91cd9a2f2d -r d00b95f95dd1 src/impl/arm/neon.c --- a/src/impl/arm/neon.c Mon Nov 25 04:43:22 2024 +0000 +++ b/src/impl/arm/neon.c Mon Nov 25 00:33:02 2024 -0500 @@ -23,6 +23,7 @@ **/ #include "vec/impl/arm/neon.h" +#include "vec/impl/generic.h" #include @@ -30,69 +31,91 @@ // 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]) \ { \ - v##sign##int##bits##x##size vec; \ + union v##sign##int##bits##x##size##_impl_data vec; \ vec.neon = vld1_##sign##bits(in); \ - return vec; \ + return vec.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); \ + vstore_lane_##bits(sign, ((union v##sign##int##bits##x##size##_impl_data *)&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; \ + 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; \ } \ \ 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; \ + 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; \ } \ \ 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; \ + 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; \ } \ \ 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; \ + 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; \ } \ \ 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; \ + 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; \ } \ \ 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; \ + 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; \ } \ \ 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; \ + 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; \ } \ \ static v##sign##int##bits##x##size##_impl v##sign##int##bits##x##size##_impl_neon = { \ - /* .splat = */ NULL, \ + v##sign##int##bits##x##size##_fallback_splat, \ 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, \ @@ -100,20 +123,25 @@ 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##_fallback_div, \ + v##sign##int##bits##x##size##_fallback_avg, \ 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##_fallback_not, \ v##sign##int##bits##x##size##_neon_lshift, \ - /* .rshift = */ NULL, \ - /* .lrshift = */ NULL, \ + 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, \ }; #define VEC_DEFINE_OPERATIONS(bits, size) \ - VEC_DEFINE_OPERATIONS_SIGN( , , bits, size) \ - VEC_DEFINE_OPERATIONS_SIGN(u, U, bits, size) + VEC_DEFINE_OPERATIONS_SIGN(u, U, bits, size) \ + VEC_DEFINE_OPERATIONS_SIGN( , , bits, size) // Ok, we'll start out with the 64-bit types. @@ -355,92 +383,6 @@ #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)