mmx: Improve detection of support for "K" constraint
authorAndrea Canciani <ranma42@gmail.com>
Sun, 11 Oct 2015 07:45:57 +0000 (09:45 +0200)
committerMatt Turner <mattst88@gmail.com>
Wed, 18 Nov 2015 22:19:58 +0000 (14:19 -0800)
Older versions of clang emitted an error on the "K" constraint, but at
least since version 3.7 it is supported. Just like gcc, this
constraint is only allowed for constants, but apparently clang
requires them to be known before inlining.

Using the macro definition _mm_shuffle_pi16(A, N) ensures that the "K"
constraint is always applied to a literal constant, independently from
the compiler optimizations and allows building pixman-mmx on modern
clang.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Andrea Canciani <ranma42@gmail.com>
configure.ac
pixman/pixman-mmx.c

index 2178126df40e912a9948ba43fb297a22ea9d7e9a..3a669092df59b03098b5d95e9dbed4c131f0675f 100644 (file)
@@ -347,15 +347,27 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
 #error "Need GCC >= 3.4 for MMX intrinsics"
 #endif
 #include <mmintrin.h>
+#include <stdint.h>
+
+/* Check support for block expressions */
+#define _mm_shuffle_pi16(A, N)                                         \
+    ({                                                                 \
+       __m64 ret;                                                      \
+                                                                       \
+       /* Some versions of clang will choke on K */                    \
+       asm ("pshufw %2, %1, %0\n\t"                                    \
+            : "=y" (ret)                                               \
+            : "y" (A), "K" ((const int8_t)N)                           \
+       );                                                              \
+                                                                       \
+       ret;                                                            \
+    })
+
 int main () {
     __m64 v = _mm_cvtsi32_si64 (1);
     __m64 w;
 
-    /* Some versions of clang will choke on K */
-    asm ("pshufw %2, %1, %0\n\t"
-        : "=y" (w)
-        : "y" (v), "K" (5)
-    );
+    w = _mm_shuffle_pi16(v, 5);
 
     /* Some versions of clang will choke on this */
     asm ("pmulhuw %1, %0\n\t"
index 05c48a4fe46345bfa2b98737d220792fc7753f7d..dec3974324259f2c5d669870d144fda839adf7ec 100644 (file)
@@ -89,21 +89,7 @@ _mm_mulhi_pu16 (__m64 __A, __m64 __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)                                      \
+# define _mm_shuffle_pi16(A, N)                                                \
     ({                                                                 \
        __m64 ret;                                                      \
                                                                        \
@@ -114,7 +100,6 @@ _mm_shuffle_pi16 (__m64 __A, int8_t const __N)
                                                                        \
        ret;                                                            \
     })
-#  endif
 # endif
 #endif