changeset 10:d1d5d767004c

chore: merge diverging branches
author Paper <paper@tflc.us>
date Mon, 18 Nov 2024 15:44:09 -0500
parents 6ff0b7a44bb6 (current diff) 6e0eb3aa12ab (diff)
children 13575ba795d3
files include/vec/vec.h test/main.c test/test_arith.h test/test_compare.h
diffstat 10 files changed, 115 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Mon Nov 18 15:44:09 2024 -0500
@@ -0,0 +1,42 @@
+syntax: glob
+
+# stupid OS X things
+.DS_Store
+._*
+
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+
+syntax: regexp
+
+# Build dir
+^build/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CMakeLists.txt	Mon Nov 18 15:44:09 2024 -0500
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(vec VERSION 1.0.0 DESCRIPTION "a tiny C99 SIMD vector library")
+
+add_library(vec SHARED src/vec.c)
+
+set_target_properties(vec PROPERTIES PUBLIC_HEADER include/vec/vec.h)
+
+target_include_directories(vec PRIVATE include)
+
+# Installing
+
+include(GNUInstallDirs)
+
+install(TARGETS vec
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+
+# pkg-config
+configure_file(vec.pc.in vec.pc @ONLY)
+install(FILES ${CMAKE_BINARY_DIR}/vec.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
\ No newline at end of file
--- a/include/vec/impl/gcc.h	Mon Nov 18 13:52:09 2024 -0500
+++ b/include/vec/impl/gcc.h	Mon Nov 18 15:44:09 2024 -0500
@@ -30,8 +30,9 @@
 #define VEC_DEFINE_OPERATIONS(sign, csign, bits, size) \
 	VEC_DECL_LOAD_ALIGNED(sign, bits, size) \
 	{ \
-		/* no real known alignment here */ \
-		return *(v##sign##int##bits##x##size *)in; \
+		v##sign##int##bits##x##size vec; \
+		memcpy(&vec, in, sizeof(*in) * size); \
+		return vec; \
 	} \
 	\
 	VEC_DECL_LOAD(sign, bits, size) \
@@ -41,7 +42,7 @@
 	\
 	VEC_DECL_STORE_ALIGNED(sign, bits, size) \
 	{ \
-		*(v##sign##int##bits##x##size *)out = vec; \
+		memcpy(out, &vec, sizeof(vec)); \
 	} \
 	\
 	VEC_DECL_STORE(sign, bits, size) \
--- a/include/vec/impl/sse2.h	Mon Nov 18 13:52:09 2024 -0500
+++ b/include/vec/impl/sse2.h	Mon Nov 18 15:44:09 2024 -0500
@@ -174,7 +174,7 @@
 #ifndef VEC_VUINT64X2
 # define VEC_VUINT64X2
 typedef __m128i vuint64x2;
-static inline VEC_ALWAYS_INLINE vuint64x2 VUINT64x2_CONSTANT(uint64_t a, uint64_t b)
+VEC_FUNC_KEYWORDS vuint64x2 VUINT64x2_CONSTANT(uint64_t a, uint64_t b)
 {
 	return _mm_setr_epi32(b, b >> 32, a, a >> 32);
 }
@@ -216,11 +216,11 @@
 #ifndef VEC_VINT64X2
 # define VEC_VINT64X2
 typedef __m128i vint64x2;
-static inline VEC_ALWAYS_INLINE vint64x2 VINT64x2_CONSTANT(int64_t a, int64_t b)
+# define VINT64x2_ALIGNMENT VEC_SSE2_ALIGNMENT
+VEC_FUNC_KEYWORDS vint64x2 VINT64x2_CONSTANT(int64_t a, int64_t b)
 {
 	return _mm_setr_epi32(b, vec_rshift(b, 32), a, vec_rshift(a, 32));
 }
-# define VINT64x2_ALIGNMENT VEC_SSE2_ALIGNMENT
 VEC_DEFINE_OPERATIONS(, , 64, 2)
 VEC_GENERIC_COMPARISONS(, , 64, 2)
 #endif
--- a/include/vec/vec.h	Mon Nov 18 13:52:09 2024 -0500
+++ b/include/vec/vec.h	Mon Nov 18 15:44:09 2024 -0500
@@ -63,6 +63,18 @@
 # define VEC_ALWAYS_INLINE
 #endif
 
+/* Allow users to define all of the symbols externally in
+ * one translation unit, or as a shared library. */
+#ifdef VEC_EXTERN
+# ifdef VEC_EXTERN_DEFINE
+#  define VEC_FUNC_KEYWORDS extern inline
+# else
+#  define VEC_FUNC_KEYWORDS inline
+# endif
+#else
+# define VEC_FUNC_KEYWORDS static inline VEC_ALWAYS_INLINE
+#endif
+
 #ifdef VEC_ALIGNED
 # define VEC_ALIGNED_ARRAY(type, var, length, align) \
 	VEC_ALIGNED(align) type var[length]
@@ -83,32 +95,32 @@
 /* --------------------------------------------------------------- */
 /* bit shift */
 
-static inline VEC_ALWAYS_INLINE uintmax_t vec_ulrshift(uintmax_t x, unsigned int y)
+VEC_FUNC_KEYWORDS uintmax_t vec_ulrshift(uintmax_t x, unsigned int y)
 {
 	return x >> y;
 }
 
-static inline VEC_ALWAYS_INLINE uintmax_t vec_ullshift(uintmax_t x, unsigned int y)
+VEC_FUNC_KEYWORDS uintmax_t vec_ullshift(uintmax_t x, unsigned int y)
 {
 	return x << y;
 }
 
-static inline VEC_ALWAYS_INLINE intmax_t vec_lrshift(intmax_t x, unsigned int y)
+VEC_FUNC_KEYWORDS intmax_t vec_lrshift(intmax_t x, unsigned int y)
 {
 	return (intmax_t)(((uintmax_t)x) >> y);
 }
 
-static inline VEC_ALWAYS_INLINE intmax_t vec_llshift(intmax_t x, unsigned int y)
+VEC_FUNC_KEYWORDS intmax_t vec_llshift(intmax_t x, unsigned int y)
 {
 	return (intmax_t)(((uintmax_t)x) << y);
 }
 
-static inline VEC_ALWAYS_INLINE uintmax_t vec_urshift(uintmax_t x, unsigned int y)
+VEC_FUNC_KEYWORDS uintmax_t vec_urshift(uintmax_t x, unsigned int y)
 {
 	return x >> y;
 }
 
-static inline VEC_ALWAYS_INLINE uintmax_t vec_ulshift(uintmax_t x, unsigned int y)
+VEC_FUNC_KEYWORDS uintmax_t vec_ulshift(uintmax_t x, unsigned int y)
 {
 	return x << y;
 }
@@ -139,7 +151,7 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
 **/
-static inline VEC_ALWAYS_INLINE intmax_t vec_rshift(intmax_t x, unsigned int y)
+VEC_FUNC_KEYWORDS intmax_t vec_rshift(intmax_t x, unsigned int y)
 {
 	static const uintmax_t roffset = UINTMAX_C(1) << ((sizeof(intmax_t) * CHAR_BIT) - 1);
 
@@ -151,7 +163,7 @@
 	return (intmax_t)urx;
 }
 
-static inline VEC_ALWAYS_INLINE intmax_t vec_lshift(intmax_t x, unsigned int y)
+VEC_FUNC_KEYWORDS intmax_t vec_lshift(intmax_t x, unsigned int y)
 {
 	static const uintmax_t roffset = UINTMAX_C(1) << ((sizeof(intmax_t) * CHAR_BIT) - 1);
 
@@ -290,7 +302,7 @@
 /* Implementation defines to keep everything relatively consistent */
 
 #define VEC_OPERATION_DECL(sign, bits, size, ret, op, params) \
-	static inline VEC_ALWAYS_INLINE ret v##sign##int##bits##x##size##_##op params
+	VEC_FUNC_KEYWORDS ret v##sign##int##bits##x##size##_##op params
 
 #define VEC_OPERATION_THIS_DECL(sign, bits, size, op, params) \
 	VEC_OPERATION_DECL(sign, bits, size, v##sign##int##bits##x##size, op, params)
@@ -389,7 +401,7 @@
 #define VEC_GENERIC_AVG(sign, bits, size) \
 	VEC_DECL_AVG(sign, bits, size) \
 	{ \
-		return v##sign##int##bits##x##size##_div(v##sign##int##bits##x##size##_mul(vec1, vec2), v##sign##int##bits##x##size##_splat(2)); \
+		return v##sign##int##bits##x##size##_div(v##sign##int##bits##x##size##_add(vec1, vec2), v##sign##int##bits##x##size##_splat(2)); \
 	}
 
 #define VEC_GENERIC_THAN_OR_EQUAL(sign, bits, size) \
@@ -413,7 +425,7 @@
 		v##sign##int##bits##x##size##_store_aligned(vec1, vec1a); \
 		v##sign##int##bits##x##size##_store_aligned(vec2, vec2a); \
 	\
-		for (int i = 0; i < size; i++) vec1a[i] = (vec1a[i] op vec2a[i]) ? UINT##bits##_MAX : 0; \
+		for (int i = 0; i < size; i++) vec1a[i] = (vec1a[i] op vec2a[i]) ? (sign##int##bits##_t)(UINT##bits##_MAX) : 0; \
 	\
 		return v##sign##int##bits##x##size##_load_aligned(vec1a); \
 	}
@@ -450,7 +462,7 @@
 #define DEFINE_NOT_OPERATION(sign, bits, size) \
 	VEC_DECL_NOT(sign, bits, size) \
 	{ \
-		return v##sign##int##bits##x##size##_xor(vec, v##sign##int##bits##x##size##_splat(UINT##bits##_MAX)); \
+		return v##sign##int##bits##x##size##_xor(vec, v##sign##int##bits##x##size##_splat((sign##int##bits##_t)UINT##bits##_MAX)); \
 	}
 
 DEFINE_NOT_OPERATION(, 8, 16)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vec.c	Mon Nov 18 15:44:09 2024 -0500
@@ -0,0 +1,3 @@
+#define VEC_EXTERN
+#define VEC_EXTERN_DEFINE
+#include "vec/vec.h"
--- a/test/main.c	Mon Nov 18 13:52:09 2024 -0500
+++ b/test/main.c	Mon Nov 18 15:44:09 2024 -0500
@@ -1,3 +1,5 @@
+#define VEC_EXTERN
+#define VEC_EXTERN_DEFINE
 #include "vec/vec.h"
 
 #include <stdio.h>
--- a/test/test_arith.h	Mon Nov 18 13:52:09 2024 -0500
+++ b/test/test_arith.h	Mon Nov 18 15:44:09 2024 -0500
@@ -40,7 +40,7 @@
 	\
 		for (int i = 0; i < size; i++) { \
 			if ((sign##int##bits##_t)(equiv) != orig_c[i]) { \
-				fprintf(stderr, "v" #sign "int" #bits "x" #size "_" #op " test FAILED at index %d: (" #equiv ") [%" PRI ## psign ## bits "] does not equal result [%" PRI ## psign ## bits "]!\n", i, equiv, orig_c[i]); \
+				fprintf(stderr, "v" #sign "int" #bits "x" #size "_" #op " test FAILED at index %d: (" #equiv ") [%" PRI ## psign ## bits "] does not equal result [%" PRI ## psign ## bits "]!\n", i, (sign##int##bits##_t)(equiv), orig_c[i]); \
 				print_v##sign##int##bits##x##size(stderr,a); \
 				print_vuint##bits##x##size(stderr,b); \
 				print_v##sign##int##bits##x##size(stderr,c); \
@@ -60,7 +60,7 @@
 	CREATE_TEST(sign, psign, csign, bits, size, and, orig_a[i] & orig_b[i]) \
 	CREATE_TEST(sign, psign, csign, bits, size, or,  orig_a[i] | orig_b[i]) \
 	CREATE_TEST(sign, psign, csign, bits, size, xor, orig_a[i] ^ orig_b[i]) \
-	CREATE_TEST(sign, psign, csign, bits, size, avg, (orig_a[i] * orig_b[i]) / 2) \
+	CREATE_TEST(sign, psign, csign, bits, size, avg, (sign##int##bits##_t)(orig_a[i] + orig_b[i]) / 2) \
 	CREATE_TEST_SHIFT(sign, psign, csign, bits, size, rshift, vec_##sign##rshift(orig_a[i], orig_b[i])) \
 	CREATE_TEST_SHIFT(sign, psign, csign, bits, size, lshift, vec_##sign##lshift(orig_a[i], orig_b[i])) \
 	CREATE_TEST_SHIFT(sign, psign, csign, bits, size, lrshift, vec_##sign##lrshift(orig_a[i], orig_b[i]))
@@ -104,6 +104,7 @@
 			ret |= test_arith_v##sign##int##bits##x##size##_and(a, b); \
 			ret |= test_arith_v##sign##int##bits##x##size##_or(a, b); \
 			ret |= test_arith_v##sign##int##bits##x##size##_xor(a, b); \
+			ret |= test_arith_v##sign##int##bits##x##size##_avg(a, b); \
 		} \
 	} \
 	\
--- a/test/test_compare.h	Mon Nov 18 13:52:09 2024 -0500
+++ b/test/test_compare.h	Mon Nov 18 15:44:09 2024 -0500
@@ -11,7 +11,7 @@
 	\
 		for (int i = 0; i < size; i++) { \
 			if ((sign##int##bits##_t)(((equiv) ? UINT##bits##_MAX : 0)) != orig_c[i]) { \
-				fprintf(stderr, "v" #sign "int" #bits "x" #size "_" #op " test FAILED at index %d: (" #equiv ") [%" PRI ## psign ## bits "] does not equal result [%" PRI ## psign ## bits "]!\n", i, equiv, orig_c[i]); \
+				fprintf(stderr, "v" #sign "int" #bits "x" #size "_" #op " test FAILED at index %d: (" #equiv ") [%d] does not equal result [%" PRI ## psign ## bits "]!\n", i, equiv, orig_c[i]); \
 				print_v##sign##int##bits##x##size(stderr,a); \
 				print_v##sign##int##bits##x##size(stderr,b); \
 				print_v##sign##int##bits##x##size(stderr,c); \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vec.pc.in	Mon Nov 18 15:44:09 2024 -0500
@@ -0,0 +1,12 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+
+Name: @PROJECT_NAME@
+Description: @PROJECT_DESCRIPTION@
+Version: @PROJECT_VERSION@
+
+Requires:
+Libs: -L${libdir} -lvec
+Cflags: -I${includedir} -DVEC_EXTERN