summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac15
-rw-r--r--pixman/pixman-mmx.c64
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