diff options
-rw-r--r-- | configure.ac | 15 | ||||
-rw-r--r-- | pixman/pixman-mmx.c | 64 |
2 files changed, 71 insertions, 8 deletions
diff --git a/configure.ac b/configure.ac index 8370844..2178126 100644 --- a/configure.ac +++ b/configure.ac @@ -347,14 +347,21 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ #error "Need GCC >= 3.4 for MMX intrinsics" #endif #include <mmintrin.h> -#include <xmmintrin.h> int main () { __m64 v = _mm_cvtsi32_si64 (1); __m64 w; - /* Test some intrinsics from xmmintrin.h */ - w = _mm_shuffle_pi16(v, 5); - w = _mm_mulhi_pu16(w, w); + /* Some versions of clang will choke on K */ + asm ("pshufw %2, %1, %0\n\t" + : "=y" (w) + : "y" (v), "K" (5) + ); + + /* Some versions of clang will choke on this */ + asm ("pmulhuw %1, %0\n\t" + : "+y" (w) + : "y" (v) + ); return _mm_cvtsi64_si32 (v); }]])], have_mmx_intrinsics=yes) diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c index 88c3a39..05c48a4 100644 --- a/pixman/pixman-mmx.c +++ b/pixman/pixman-mmx.c @@ -40,9 +40,6 @@ #else #include <mmintrin.h> #endif -#ifdef USE_X86_MMX -#include <xmmintrin.h> -#endif #include "pixman-private.h" #include "pixman-combine32.h" #include "pixman-inlines.h" @@ -62,7 +59,66 @@ _mm_empty (void) } #endif -#ifndef _MM_SHUFFLE +#ifdef USE_X86_MMX +# if (defined(__SUNPRO_C) || defined(_MSC_VER) || defined(_WIN64)) +# include <xmmintrin.h> +# else +/* We have to compile with -msse to use xmmintrin.h, but that causes SSE + * instructions to be generated that we don't want. Just duplicate the + * functions we want to use. */ +extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_movemask_pi8 (__m64 __A) +{ + int ret; + + asm ("pmovmskb %1, %0\n\t" + : "=r" (ret) + : "y" (__A) + ); + + return ret; +} + +extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mulhi_pu16 (__m64 __A, __m64 __B) +{ + asm ("pmulhuw %1, %0\n\t" + : "+y" (__A) + : "y" (__B) + ); + return __A; +} + +# ifdef __OPTIMIZE__ +extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_shuffle_pi16 (__m64 __A, int8_t const __N) +{ + __m64 ret; + + asm ("pshufw %2, %1, %0\n\t" + : "=y" (ret) + : "y" (__A), "K" (__N) + ); + + return ret; +} +# else +# define _mm_shuffle_pi16(A, N) \ + ({ \ + __m64 ret; \ + \ + asm ("pshufw %2, %1, %0\n\t" \ + : "=y" (ret) \ + : "y" (A), "K" ((const int8_t)N) \ + ); \ + \ + ret; \ + }) +# endif +# endif +#endif + +#ifndef _MSC_VER #define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \ (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | (fp0)) #endif |