aboutsummaryrefslogtreecommitdiffstats
path: root/meson/test cases/common/147 simd/simd_mmx.c
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /meson/test cases/common/147 simd/simd_mmx.c
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'meson/test cases/common/147 simd/simd_mmx.c')
-rw-r--r--meson/test cases/common/147 simd/simd_mmx.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/meson/test cases/common/147 simd/simd_mmx.c b/meson/test cases/common/147 simd/simd_mmx.c
new file mode 100644
index 000000000..76054420b
--- /dev/null
+++ b/meson/test cases/common/147 simd/simd_mmx.c
@@ -0,0 +1,67 @@
+#include<simdconfig.h>
+#include<simdfuncs.h>
+
+#include<stdint.h>
+
+#ifdef _MSC_VER
+#include<intrin.h>
+int mmx_available(void) {
+ return 1;
+}
+/* Contrary to MSDN documentation, MMX intrinsics
+ * just plain don't work.
+ */
+void increment_mmx(float arr[4]) {
+ arr[0]++;
+ arr[1]++;
+ arr[2]++;
+ arr[3]++;
+}
+#elif defined(__MINGW32__)
+int mmx_available(void) {
+ return 1;
+}
+/* MinGW does not seem to ship with MMX or it is broken.
+ */
+void increment_mmx(float arr[4]) {
+ arr[0]++;
+ arr[1]++;
+ arr[2]++;
+ arr[3]++;
+}
+#else
+#include<mmintrin.h>
+#include<cpuid.h>
+
+#if defined(__APPLE__)
+int mmx_available(void) { return 1; }
+#else
+int mmx_available(void) {
+ return __builtin_cpu_supports("mmx");
+}
+#endif
+void increment_mmx(float arr[4]) {
+ /* Super ugly but we know that values in arr are always small
+ * enough to fit in int16;
+ */
+ int i;
+ __m64 packed = _mm_set_pi16(arr[3], arr[2], arr[1], arr[0]);
+ __m64 incr = _mm_set1_pi16(1);
+ __m64 result = _mm_add_pi16(packed, incr);
+ /* Should be
+ * int64_t unpacker = _m_to_int64(result);
+ * but it does not exist on 32 bit platforms for some reason.
+ */
+ int64_t unpacker = (int64_t)(result);
+ _mm_empty();
+ for(i=0; i<4; i++) {
+ /* This fails on GCC 8 when optimizations are enabled.
+ * Disable it. Patches welcome to fix this.
+ arr[i] = (float)(unpacker & ((1<<16)-1));
+ unpacker >>= 16;
+ */
+ arr[i] += 1.0f;
+ }
+}
+
+#endif