diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2017-02-09 22:41:30 +0200 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2017-07-17 19:00:42 +0300 |
commit | 326d8953b4742228c6a82fab36dd0718601da9c1 (patch) | |
tree | d5381862ce15e36c0c114af109a98a1e0f12b49b | |
parent | fd91749e5a4feb45eafa91a0fd76685a104ad5e0 (diff) | |
download | meson-326d8953b4742228c6a82fab36dd0718601da9c1.zip meson-326d8953b4742228c6a82fab36dd0718601da9c1.tar.gz meson-326d8953b4742228c6a82fab36dd0718601da9c1.tar.bz2 |
Add support for MMX checking.
-rw-r--r-- | test cases/common/139 simd/fallback.c | 3 | ||||
-rw-r--r-- | test cases/common/139 simd/meson.build | 24 | ||||
-rw-r--r-- | test cases/common/139 simd/simd_mmx.c | 22 | ||||
-rw-r--r-- | test cases/common/139 simd/simdchecker.c | 20 | ||||
-rw-r--r-- | test cases/common/139 simd/simdfuncs.h | 12 |
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. */ |