aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-02-09 22:41:30 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2017-07-17 19:00:42 +0300
commit326d8953b4742228c6a82fab36dd0718601da9c1 (patch)
treed5381862ce15e36c0c114af109a98a1e0f12b49b
parentfd91749e5a4feb45eafa91a0fd76685a104ad5e0 (diff)
downloadmeson-326d8953b4742228c6a82fab36dd0718601da9c1.zip
meson-326d8953b4742228c6a82fab36dd0718601da9c1.tar.gz
meson-326d8953b4742228c6a82fab36dd0718601da9c1.tar.bz2
Add support for MMX checking.
-rw-r--r--test cases/common/139 simd/fallback.c3
-rw-r--r--test cases/common/139 simd/meson.build24
-rw-r--r--test cases/common/139 simd/simd_mmx.c22
-rw-r--r--test cases/common/139 simd/simdchecker.c20
-rw-r--r--test cases/common/139 simd/simdfuncs.h12
5 files changed, 70 insertions, 11 deletions
diff --git a/test cases/common/139 simd/fallback.c b/test cases/common/139 simd/fallback.c
index 2b98304..ab435f4 100644
--- a/test cases/common/139 simd/fallback.c
+++ b/test cases/common/139 simd/fallback.c
@@ -1,7 +1,8 @@
#include<simdfuncs.h>
void increment_fallback(float arr[4]) {
- for(int i=0; i<4; i++) {
+ int i;
+ for(i=0; i<4; i++) {
arr[i]++;
}
}
diff --git a/test cases/common/139 simd/meson.build b/test cases/common/139 simd/meson.build
index b26d007..153b458 100644
--- a/test cases/common/139 simd/meson.build
+++ b/test cases/common/139 simd/meson.build
@@ -1,13 +1,33 @@
project('simd', 'c')
+cc = meson.get_compiler('c')
+
cdata = configuration_data()
-#cdata.set('HAVE_MMX', 1)
+# The idea is to have a simd module and then do something like:
+#
+# static_libs = simd.check('mysimdstuff',
+# mmx : 'mmx_funcs.c',
+# sse : 'sse_funcs.c',
+# sse2 : 'sse2_funcs.c',
+# <etc>
+# configuration : cdata, # adds HAVE_XXX
+# compiler : cc)
+#
+# and then have a target that uses the result in links_with.
+
+simdlibs = []
+
+if cc.has_argument('-mmmx')
+ cdata.set('HAVE_MMX', 1)
+ simdlibs += static_library('simd_mmx', 'simd_mmx.c', c_args : '-mmmx')
+endif
configure_file(output : 'simdconfig.h',
configuration : cdata)
-p = executable('simdtest', 'simdchecker.c', 'fallback.c')
+p = executable('simdtest', 'simdchecker.c', 'fallback.c',
+ link_with : simdlibs)
test('simdtest', p)
diff --git a/test cases/common/139 simd/simd_mmx.c b/test cases/common/139 simd/simd_mmx.c
new file mode 100644
index 0000000..dc1d51c
--- /dev/null
+++ b/test cases/common/139 simd/simd_mmx.c
@@ -0,0 +1,22 @@
+#include<mmintrin.h>
+#include<cpuid.h>
+#include<stdint.h>
+
+int mmx_available() {
+ return __builtin_cpu_supports("mmx");
+}
+
+void increment_mmx(float arr[4]) {
+ /* Super ugly but we know that values in arr are always small
+ * enough to fit in int16;
+ */
+ __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);
+ int64_t unpacker = _m_to_int64(result);
+ _mm_empty();
+ for(int i=0; i<4; i++) {
+ arr[i] = unpacker & ((1<<16)-1);
+ unpacker >>= 16;
+ }
+}
diff --git a/test cases/common/139 simd/simdchecker.c b/test cases/common/139 simd/simdchecker.c
index bcc6cef..d75af25 100644
--- a/test cases/common/139 simd/simdchecker.c
+++ b/test cases/common/139 simd/simdchecker.c
@@ -2,28 +2,36 @@
#include<stdio.h>
/*
- * A function that checks at runtime if simd acceleration is
- * available and calls the respective function if it is. Falls
- * back to plain C implementation if not.
+ * A function that checks at runtime which simd accelerations are
+ * available and calls the best one. Falls
+ * back to plain C implementation if SIMD is not available.
*/
int main(int argc, char **argv) {
float four[4] = {2.0, 3.0, 4.0, 5.0};
const float expected[4] = {3.0, 4.0, 5.0, 6.0};
void (*fptr)(float[4]) = NULL;
+ const char *type;
-#if HAVE_MMX
- if(mmx_available()) {
+#if HAVE_SSE
+ /* Add here. The first matched one is used so put "better" instruction
+ * sets at the top.
+ */
+#elif HAVE_MMX
+ if(fptr == NULL && mmx_available()) {
fptr = increment_mmx;
+ type = "MMX";
}
#endif
if(fptr == NULL) {
fptr = increment_fallback;
+ type = "fallback";
}
+ printf("Using %s.\n", type);
fptr(four);
for(int i=0; i<4; i++) {
if(four[i] != expected[i]) {
- printf("Increment function failed.\n");
+ printf("Increment function failed, got %f expected %f.\n", four[i], expected[i]);
return 1;
}
}
diff --git a/test cases/common/139 simd/simdfuncs.h b/test cases/common/139 simd/simdfuncs.h
index 17c627e..4b452fc 100644
--- a/test cases/common/139 simd/simdfuncs.h
+++ b/test cases/common/139 simd/simdfuncs.h
@@ -3,13 +3,21 @@
#include<simdconfig.h>
/* Yes, I do know that arr[4] decays into a pointer
- * here. Don't do this in real code but for test code
- * it is ok.
+ * as a function argument. Don't do this in real code
+ * but for this test it is ok.
*/
void increment_fallback(float arr[4]);
#if HAVE_MMX
+int mmx_available();
void increment_mmx(float arr[4]);
#endif
+#if HAVE_SSE
+#endif
+
+#if HAVE_SSE2
+#endif
+
+/* And so on. */