[Pixman] [PATCH 3/3] mmx: compile on ARM for iwmmxt optimizations
mattst88 at gmail.com
mattst88 at gmail.com
Wed Jul 20 12:29:14 PDT 2011
From: Matt Turner <mattst88 at gmail.com>
Signed-off-by: Matt Turner <mattst88 at gmail.com>
---
configure.ac | 48 +++++++++++++++++++++++++++++++++++++++++++++++
pixman/Makefile.am | 12 +++++++++++
pixman/pixman-cpu.c | 22 +++++++++++++++++++-
pixman/pixman-mmx.c | 11 +++++++++-
pixman/pixman-private.h | 2 +-
5 files changed, 91 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac
index 4c62102..3123ad9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -540,6 +540,54 @@ if test $enable_arm_neon = yes && test $have_arm_neon = no ; then
AC_MSG_ERROR([ARM NEON intrinsics not detected])
fi
+dnl ===========================================================================
+dnl Check for IWMMXT
+
+if test "x$IWMMXT_CFLAGS" = "x" ; then
+ IWMMXT_CFLAGS="-march=iwmmxt -flax-vector-conversions -Winline"
+fi
+
+have_iwmmxt_intrinsics=no
+AC_MSG_CHECKING(whether to use ARM IWMMXT intrinsics)
+xserver_save_CFLAGS=$CFLAGS
+CFLAGS="$IWMMXT_CFLAGS $CFLAGS"
+AC_COMPILE_IFELSE([
+#if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
+error "Need GCC >= 3.4 for IWMMXT intrinsics"
+#endif
+#include <mmintrin.h>
+int main () {
+ union {
+ __m64 v;
+ [char c[8];]
+ } a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} },
+ b = { .c = {1, 2, 3, 4, 5, 6, 7, 8} };
+ __m64 c = _mm_adds_pi8 (a.v, b.v);
+}], have_iwmmxt_intrinsics=yes)
+CFLAGS=$xserver_save_CFLAGS
+
+AC_ARG_ENABLE(arm-iwmmxt,
+ [AC_HELP_STRING([--disable-arm-iwmmxt],
+ [disable ARM IWMMXT fast paths])],
+ [enable_iwmmxt=$enableval], [enable_iwmmxt=auto])
+
+if test $enable_iwmmxt = no ; then
+ have_iwmmxt_intrinsics=disabled
+fi
+
+if test $have_iwmmxt_intrinsics = yes ; then
+ AC_DEFINE(USE_ARM_IWMMXT, 1, [use ARM IWMMXT compiler intrinsics])
+else
+ IWMMXT_CFLAGS=
+fi
+
+AC_MSG_RESULT($have_iwmmxt_intrinsics)
+if test $enable_iwmmxt = yes && test $have_iwmmxt_intrinsics = no ; then
+ AC_MSG_ERROR([IWMMXT intrinsics not detected])
+fi
+
+AM_CONDITIONAL(USE_ARM_IWMMXT, test $have_iwmmxt_intrinsics = yes)
+
dnl =========================================================================================
dnl Check for GNU-style inline assembly support
diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 1e20bb0..83c744c 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -125,5 +125,17 @@ libpixman_1_la_LIBADD += libpixman-arm-neon.la
ASM_CFLAGS_arm_neon=
endif
+# iwmmxt code
+if USE_ARM_IWMMXT
+noinst_LTLIBRARIES += libpixman-iwmmxt.la
+libpixman_iwmmxt_la_SOURCES = pixman-mmx.c
+libpixman_iwmmxt_la_CFLAGS = $(DEP_CFLAGS) $(IWMMXT_CFLAGS)
+libpixman_iwmmxt_la_LIBADD = $(DEP_LIBS)
+libpixman_1_la_LDFLAGS += $(IWMMXT_LDFLAGS)
+libpixman_1_la_LIBADD += libpixman-iwmmxt.la
+
+ASM_CFLAGS_IWMMXT=$(IWMMXT_CFLAGS)
+endif
+
.c.s : $(libpixmaninclude_HEADERS) $(BUILT_SOURCES)
$(CC) $(CFLAGS) $(ASM_CFLAGS_$(@:pixman-%.s=%)) $(ASM_CFLAGS_$(@:pixman-arm-%.s=arm_%)) -DHAVE_CONFIG_H -I$(srcdir) -I$(builddir) -I$(top_builddir) -S -o $@ $<
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index 973ed54..68dc924 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -187,7 +187,7 @@ pixman_have_vmx (void)
#endif /* __APPLE__ */
#endif /* USE_VMX */
-#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON)
+#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
#if defined(_MSC_VER)
@@ -328,14 +328,27 @@ pixman_have_arm_neon (void)
#endif /* USE_ARM_NEON */
+#if defined(USE_ARM_IWMMXT)
+pixman_bool_t
+pixman_have_arm_iwmmxt (void)
+{
+ if (!arm_tests_initialized)
+ pixman_arm_read_auxv ();
+
+ return arm_has_iwmmxt;
+}
+
+#endif /* USE_ARM_IWMMXT */
+
#else /* linux ELF */
#define pixman_have_arm_simd() FALSE
#define pixman_have_arm_neon() FALSE
+#define pixman_have_arm_iwmmxt() FALSE
#endif
-#endif /* USE_ARM_SIMD || USE_ARM_NEON */
+#endif /* USE_ARM_SIMD || USE_ARM_NEON || USE_ARM_IWMMXT */
#if defined(USE_MMX) || defined(USE_SSE2)
/* The CPU detection code needs to be in a file not compiled with
@@ -600,6 +613,11 @@ _pixman_choose_implementation (void)
if (pixman_have_arm_neon ())
imp = _pixman_implementation_create_arm_neon (imp);
#endif
+
+#ifdef USE_ARM_IWMMXT
+ if (pixman_have_arm_iwmmxt ())
+ imp = _pixman_implementation_create_mmx (imp);
+#endif
#ifdef USE_VMX
if (pixman_have_vmx ())
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index b9b09b6..e5b2d25 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -33,7 +33,7 @@
#include <config.h>
#endif
-#ifdef USE_MMX
+#if defined USE_MMX || defined USE_ARM_IWMMXT
#include <mmintrin.h>
#include "pixman-private.h"
@@ -47,6 +47,15 @@
#define CHECKPOINT()
#endif
+#ifdef USE_ARM_IWMMXT
+/* Empty the multimedia state. For some reason, ARM's mmintrin.h doesn't provide this. */
+extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_empty (void)
+{
+
+}
+#endif
+
/* Notes about writing mmx code
*
* give memory operands as the second operand. If you give it as the
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 65494c9..8d8b913 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -545,7 +545,7 @@ _pixman_implementation_create_fast_path (pixman_implementation_t *fallback);
pixman_implementation_t *
_pixman_implementation_create_noop (pixman_implementation_t *fallback);
-#ifdef USE_MMX
+#if defined USE_MMX || defined USE_ARM_IWMMXT
pixman_implementation_t *
_pixman_implementation_create_mmx (pixman_implementation_t *fallback);
#endif
--
1.7.3.4
More information about the Pixman
mailing list