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)