Mercurial > vec
diff src/impl/arm/neon.c @ 28:c6c99ab1088a
*: add min/max functions and a big big refactor (again)
agh, this time I added a few more implementations (and generally
made the code just a little faster...)
author | Paper <paper@tflc.us> |
---|---|
date | Thu, 24 Apr 2025 00:54:02 -0400 |
parents | d00b95f95dd1 |
children | bf6ad516f1e6 |
line wrap: on
line diff
--- a/src/impl/arm/neon.c Mon Nov 25 00:33:02 2024 -0500 +++ b/src/impl/arm/neon.c Thu Apr 24 00:54:02 2025 -0400 @@ -39,19 +39,19 @@ 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]) \ + VEC_FUNC_IMPL 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; \ vec.neon = vld1_##sign##bits(in); \ 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]) \ + VEC_FUNC_IMPL 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); \ } \ \ - 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) \ + VEC_FUNC_IMPL 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; \ @@ -60,7 +60,7 @@ 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) \ + VEC_FUNC_IMPL 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; \ @@ -69,7 +69,7 @@ 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) \ + VEC_FUNC_IMPL 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; \ @@ -78,7 +78,7 @@ 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) \ + VEC_FUNC_IMPL 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; \ @@ -87,7 +87,7 @@ 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) \ + VEC_FUNC_IMPL 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; \ @@ -96,7 +96,7 @@ 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) \ + VEC_FUNC_IMPL 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; \ @@ -105,7 +105,7 @@ 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) \ + VEC_FUNC_IMPL 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; \ @@ -114,29 +114,18 @@ return vec1d->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, \ - 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, \ - 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, \ - v##sign##int##bits##x##size##_fallback_not, \ - 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, \ + const v##sign##int##bits##x##size##_impl v##sign##int##bits##x##size##_impl_neon = { \ + .load = v##sign##int##bits##x##size##_neon_load_aligned, \ + .load_aligned = v##sign##int##bits##x##size##_neon_load_aligned, \ + .store = v##sign##int##bits##x##size##_neon_store_aligned, \ + .store_aligned = v##sign##int##bits##x##size##_neon_store_aligned, \ + .add = v##sign##int##bits##x##size##_neon_add, \ + .sub = v##sign##int##bits##x##size##_neon_sub, \ + .mul = v##sign##int##bits##x##size##_neon_mul, \ + .band = v##sign##int##bits##x##size##_neon_and, \ + .bor = v##sign##int##bits##x##size##_neon_or, \ + .bxor = v##sign##int##bits##x##size##_neon_xor, \ + .lshift = v##sign##int##bits##x##size##_neon_lshift, \ }; #define VEC_DEFINE_OPERATIONS(bits, size) \ @@ -244,7 +233,7 @@ // NEON doesn't have native 64-bit multiplication, so we have // to do it ourselves -static inline int64x2_t vmulq_s64(const int64x2_t a, const int64x2_t b) +VEC_FUNC_IMPL int64x2_t vmulq_s64(const int64x2_t a, const int64x2_t b) { const uint32x2_t ac = vreinterpret_u32_s32(vmovn_s64(a)); const uint32x2_t pr = vreinterpret_u32_s32(vmovn_s64(b)); @@ -254,7 +243,7 @@ return vreinterpretq_s64_u64(vmlal_u32(vreinterpretq_u64_s64(vshlq_n_s64(vreinterpretq_s64_u64(vpaddlq_u32(vreinterpretq_u32_s32(hi))), 32)), ac, pr)); } -static inline uint64x2_t vmulq_u64(const uint64x2_t a, const uint64x2_t b) +VEC_FUNC_IMPL uint64x2_t vmulq_u64(const uint64x2_t a, const uint64x2_t b) { const uint32x2_t ac = vmovn_u64(a); const uint32x2_t pr = vmovn_u64(b);