[Pixman] [PATCH 4/4] mmx: compile on ARM for iwmmxt optimizations
Matt Turner
mattst88 at gmail.com
Thu Aug 25 14:22:30 PDT 2011
Signed-off-by: Matt Turner <mattst88 at gmail.com>
---
I left the gcc check at 4.6 in the hopes that my gcc patch will be
accepted for some gcc-4.6 release. If it doesn't, the check for 4.6
shouldn't be harmful, because the intrinsic I chose to test is known
to cause an unpatched gcc-4.6 to assert.
configure.ac | 48 +++++++++++++++++++++++++++++++++++++++++++++++
pixman/Makefile.am | 12 +++++++++++
pixman/pixman-cpu.c | 24 ++++++++++++++++++++--
pixman/pixman-private.h | 2 +-
4 files changed, 82 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac
index 6828ecf..eb5b298 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__ < 4 || (__GNUC__ == 3 && __GNUC_MINOR__ < 6))
+error "Need GCC >= 4.6 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_xor_si64 (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 b8ce196..0b4577a 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 78d3033..dff27d1 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_X86_MMX) || defined(USE_SSE2)
/* The CPU detection code needs to be in a file not compiled with
@@ -596,11 +609,16 @@ _pixman_choose_implementation (void)
imp = _pixman_implementation_create_arm_simd (imp);
#endif
+#ifdef USE_ARM_IWMMXT
+ if (pixman_have_arm_iwmmxt ())
+ imp = _pixman_implementation_create_mmx (imp);
+#endif
+
#ifdef USE_ARM_NEON
if (pixman_have_arm_neon ())
imp = _pixman_implementation_create_arm_neon (imp);
#endif
-
+
#ifdef USE_VMX
if (pixman_have_vmx ())
imp = _pixman_implementation_create_vmx (imp);
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 71e52cc..ec93861 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_X86_MMX
+#if defined USE_X86_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