[Pixman] [PATCH 03/10] Move ARM specific CPU detection to a new file pixman-arm.c

Søren Sandmann Pedersen sandmann at cs.au.dk
Fri Jun 29 13:44:48 PDT 2012


From: Søren Sandmann Pedersen <ssp at redhat.com>

Similar to the x86 commit, this moves the ARM specific CPU detection
to its own file which exports a pixman_arm_get_implementations()
function that is supposed to be a noop on non-ARM.
---
 pixman/Makefile.sources |    1 +
 pixman/pixman-arm.c     |  295 +++++++++++++++++++++++++++++++++++++++++++++++
 pixman/pixman-cpu.c     |  254 +---------------------------------------
 pixman/pixman-private.h |    3 +
 4 files changed, 300 insertions(+), 253 deletions(-)
 create mode 100644 pixman/pixman-arm.c

diff --git a/pixman/Makefile.sources b/pixman/Makefile.sources
index 4e0137a..7f2b75f 100644
--- a/pixman/Makefile.sources
+++ b/pixman/Makefile.sources
@@ -8,6 +8,7 @@ libpixman_sources =			\
 	pixman-conical-gradient.c	\
 	pixman-cpu.c			\
 	pixman-x86.c			\
+	pixman-arm.c			\
 	pixman-edge.c			\
 	pixman-edge-accessors.c		\
 	pixman-fast-path.c		\
diff --git a/pixman/pixman-arm.c b/pixman/pixman-arm.c
new file mode 100644
index 0000000..6625d7f
--- /dev/null
+++ b/pixman/pixman-arm.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pixman-private.h"
+
+#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
+
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(USE_ARM_SIMD) && defined(_MSC_VER)
+/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
+#include <windows.h>
+#endif
+
+#if defined(__APPLE__)
+#include "TargetConditionals.h"
+#endif
+
+#if defined(_MSC_VER)
+
+#if defined(USE_ARM_SIMD)
+extern int pixman_msvc_try_arm_simd_op ();
+
+pixman_bool_t
+pixman_have_arm_simd (void)
+{
+    static pixman_bool_t initialized = FALSE;
+    static pixman_bool_t have_arm_simd = FALSE;
+
+    if (!initialized)
+    {
+	__try {
+	    pixman_msvc_try_arm_simd_op ();
+	    have_arm_simd = TRUE;
+	} __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION) {
+	    have_arm_simd = FALSE;
+	}
+	initialized = TRUE;
+    }
+
+    return have_arm_simd;
+}
+
+#endif /* USE_ARM_SIMD */
+
+#if defined(USE_ARM_NEON)
+extern int pixman_msvc_try_arm_neon_op ();
+
+pixman_bool_t
+pixman_have_arm_neon (void)
+{
+    static pixman_bool_t initialized = FALSE;
+    static pixman_bool_t have_arm_neon = FALSE;
+
+    if (!initialized)
+    {
+	__try
+	{
+	    pixman_msvc_try_arm_neon_op ();
+	    have_arm_neon = TRUE;
+	}
+	__except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
+	{
+	    have_arm_neon = FALSE;
+	}
+	initialized = TRUE;
+    }
+
+    return have_arm_neon;
+}
+
+#endif /* USE_ARM_NEON */
+
+#elif (defined (__APPLE__) && defined(TARGET_OS_IPHONE)) /* iOS (iPhone/iPad/iPod touch) */
+
+/* Detection of ARM NEON on iOS is fairly simple because iOS binaries
+ * contain separate executable images for each processor architecture.
+ * So all we have to do is detect the armv7 architecture build. The
+ * operating system automatically runs the armv7 binary for armv7 devices
+ * and the armv6 binary for armv6 devices.
+ */
+
+pixman_bool_t
+pixman_have_arm_simd (void)
+{
+#if defined(USE_ARM_SIMD)
+    return TRUE;
+#else
+    return FALSE;
+#endif
+}
+
+pixman_bool_t
+pixman_have_arm_neon (void)
+{
+#if defined(USE_ARM_NEON) && defined(__ARM_NEON__)
+    /* This is an armv7 cpu build */
+    return TRUE;
+#else
+    /* This is an armv6 cpu build */
+    return FALSE;
+#endif
+}
+
+pixman_bool_t
+pixman_have_arm_iwmmxt (void)
+{
+#if defined(USE_ARM_IWMMXT)
+    return FALSE;
+#else
+    return FALSE;
+#endif
+}
+
+#elif defined (__linux__) || defined(__ANDROID__) || defined(ANDROID) /* linux ELF or ANDROID */
+
+static pixman_bool_t arm_has_v7 = FALSE;
+static pixman_bool_t arm_has_v6 = FALSE;
+static pixman_bool_t arm_has_vfp = FALSE;
+static pixman_bool_t arm_has_neon = FALSE;
+static pixman_bool_t arm_has_iwmmxt = FALSE;
+static pixman_bool_t arm_tests_initialized = FALSE;
+
+#if defined(__ANDROID__) || defined(ANDROID) /* Android device support */
+
+#include <cpu-features.h>
+
+static void
+pixman_arm_read_auxv_or_cpu_features ()
+{
+    AndroidCpuFamily cpu_family;
+    uint64_t cpu_features;
+
+    cpu_family = android_getCpuFamily();
+    cpu_features = android_getCpuFeatures();
+
+    if (cpu_family == ANDROID_CPU_FAMILY_ARM)
+    {
+	if (cpu_features & ANDROID_CPU_ARM_FEATURE_ARMv7)
+	    arm_has_v7 = TRUE;
+	
+	if (cpu_features & ANDROID_CPU_ARM_FEATURE_VFPv3)
+	    arm_has_vfp = TRUE;
+	
+	if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON)
+	    arm_has_neon = TRUE;
+    }
+
+    arm_tests_initialized = TRUE;
+}
+
+#elif defined (__linux__) /* linux ELF */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <elf.h>
+
+static void
+pixman_arm_read_auxv_or_cpu_features ()
+{
+    int fd;
+    Elf32_auxv_t aux;
+
+    fd = open ("/proc/self/auxv", O_RDONLY);
+    if (fd >= 0)
+    {
+	while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t))
+	{
+	    if (aux.a_type == AT_HWCAP)
+	    {
+		uint32_t hwcap = aux.a_un.a_val;
+		/* hardcode these values to avoid depending on specific
+		 * versions of the hwcap header, e.g. HWCAP_NEON
+		 */
+		arm_has_vfp = (hwcap & 64) != 0;
+		arm_has_iwmmxt = (hwcap & 512) != 0;
+		/* this flag is only present on kernel 2.6.29 */
+		arm_has_neon = (hwcap & 4096) != 0;
+	    }
+	    else if (aux.a_type == AT_PLATFORM)
+	    {
+		const char *plat = (const char*) aux.a_un.a_val;
+		if (strncmp (plat, "v7l", 3) == 0)
+		{
+		    arm_has_v7 = TRUE;
+		    arm_has_v6 = TRUE;
+		}
+		else if (strncmp (plat, "v6l", 3) == 0)
+		{
+		    arm_has_v6 = TRUE;
+		}
+	    }
+	}
+	close (fd);
+    }
+
+    arm_tests_initialized = TRUE;
+}
+
+#endif /* Linux elf */
+
+#if defined(USE_ARM_SIMD)
+pixman_bool_t
+pixman_have_arm_simd (void)
+{
+    if (!arm_tests_initialized)
+	pixman_arm_read_auxv_or_cpu_features ();
+
+    return arm_has_v6;
+}
+
+#endif /* USE_ARM_SIMD */
+
+#if defined(USE_ARM_NEON)
+pixman_bool_t
+pixman_have_arm_neon (void)
+{
+    if (!arm_tests_initialized)
+	pixman_arm_read_auxv_or_cpu_features ();
+
+    return arm_has_neon;
+}
+
+#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_or_cpu_features ();
+
+    return arm_has_iwmmxt;
+}
+
+#endif /* USE_ARM_IWMMXT */
+
+#else /* !_MSC_VER && !Linux elf && !Android */
+
+#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 || USE_ARM_IWMMXT */
+
+pixman_implementation_t *
+_pixman_arm_get_implementations (pixman_implementation_t *imp)
+{
+#ifdef USE_ARM_SIMD
+    if (!_pixman_disabled ("arm-simd") && pixman_have_arm_simd ())
+	imp = _pixman_implementation_create_arm_simd (imp);
+#endif
+
+#ifdef USE_ARM_IWMMXT
+    if (!_pixman_disabled ("arm-iwmmxt") && pixman_have_arm_iwmmxt ())
+	imp = _pixman_implementation_create_mmx (imp);
+#endif
+
+#ifdef USE_ARM_NEON
+    if (!_pixman_disabled ("arm-neon") && pixman_have_arm_neon ())
+	imp = _pixman_implementation_create_arm_neon (imp);
+#endif
+
+    return imp;
+}
+
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index 0bfc90f..319d71f 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -26,11 +26,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-#if defined(USE_ARM_SIMD) && defined(_MSC_VER)
-/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
-#include <windows.h>
-#endif
-
 #if defined(__APPLE__)
 #include "TargetConditionals.h"
 #endif
@@ -192,241 +187,6 @@ pixman_have_vmx (void)
 #endif /* __APPLE__ */
 #endif /* USE_VMX */
 
-#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
-
-#if defined(_MSC_VER)
-
-#if defined(USE_ARM_SIMD)
-extern int pixman_msvc_try_arm_simd_op ();
-
-pixman_bool_t
-pixman_have_arm_simd (void)
-{
-    static pixman_bool_t initialized = FALSE;
-    static pixman_bool_t have_arm_simd = FALSE;
-
-    if (!initialized)
-    {
-	__try {
-	    pixman_msvc_try_arm_simd_op ();
-	    have_arm_simd = TRUE;
-	} __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION) {
-	    have_arm_simd = FALSE;
-	}
-	initialized = TRUE;
-    }
-
-    return have_arm_simd;
-}
-
-#endif /* USE_ARM_SIMD */
-
-#if defined(USE_ARM_NEON)
-extern int pixman_msvc_try_arm_neon_op ();
-
-pixman_bool_t
-pixman_have_arm_neon (void)
-{
-    static pixman_bool_t initialized = FALSE;
-    static pixman_bool_t have_arm_neon = FALSE;
-
-    if (!initialized)
-    {
-	__try
-	{
-	    pixman_msvc_try_arm_neon_op ();
-	    have_arm_neon = TRUE;
-	}
-	__except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
-	{
-	    have_arm_neon = FALSE;
-	}
-	initialized = TRUE;
-    }
-
-    return have_arm_neon;
-}
-
-#endif /* USE_ARM_NEON */
-
-#elif (defined (__APPLE__) && defined(TARGET_OS_IPHONE)) /* iOS (iPhone/iPad/iPod touch) */
-
-/* Detection of ARM NEON on iOS is fairly simple because iOS binaries
- * contain separate executable images for each processor architecture.
- * So all we have to do is detect the armv7 architecture build. The
- * operating system automatically runs the armv7 binary for armv7 devices
- * and the armv6 binary for armv6 devices.
- */
-
-pixman_bool_t
-pixman_have_arm_simd (void)
-{
-#if defined(USE_ARM_SIMD)
-    return TRUE;
-#else
-    return FALSE;
-#endif
-}
-
-pixman_bool_t
-pixman_have_arm_neon (void)
-{
-#if defined(USE_ARM_NEON) && defined(__ARM_NEON__)
-    /* This is an armv7 cpu build */
-    return TRUE;
-#else
-    /* This is an armv6 cpu build */
-    return FALSE;
-#endif
-}
-
-pixman_bool_t
-pixman_have_arm_iwmmxt (void)
-{
-#if defined(USE_ARM_IWMMXT)
-    return FALSE;
-#else
-    return FALSE;
-#endif
-}
-
-#elif defined (__linux__) || defined(__ANDROID__) || defined(ANDROID) /* linux ELF or ANDROID */
-
-static pixman_bool_t arm_has_v7 = FALSE;
-static pixman_bool_t arm_has_v6 = FALSE;
-static pixman_bool_t arm_has_vfp = FALSE;
-static pixman_bool_t arm_has_neon = FALSE;
-static pixman_bool_t arm_has_iwmmxt = FALSE;
-static pixman_bool_t arm_tests_initialized = FALSE;
-
-#if defined(__ANDROID__) || defined(ANDROID) /* Android device support */
-
-#include <cpu-features.h>
-
-static void
-pixman_arm_read_auxv_or_cpu_features ()
-{
-    AndroidCpuFamily cpu_family;
-    uint64_t cpu_features;
-
-    cpu_family = android_getCpuFamily();
-    cpu_features = android_getCpuFeatures();
-
-    if (cpu_family == ANDROID_CPU_FAMILY_ARM)
-    {
-	if (cpu_features & ANDROID_CPU_ARM_FEATURE_ARMv7)
-	    arm_has_v7 = TRUE;
-	
-	if (cpu_features & ANDROID_CPU_ARM_FEATURE_VFPv3)
-	    arm_has_vfp = TRUE;
-	
-	if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON)
-	    arm_has_neon = TRUE;
-    }
-
-    arm_tests_initialized = TRUE;
-}
-
-#elif defined (__linux__) /* linux ELF */
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <string.h>
-#include <elf.h>
-
-static void
-pixman_arm_read_auxv_or_cpu_features ()
-{
-    int fd;
-    Elf32_auxv_t aux;
-
-    fd = open ("/proc/self/auxv", O_RDONLY);
-    if (fd >= 0)
-    {
-	while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t))
-	{
-	    if (aux.a_type == AT_HWCAP)
-	    {
-		uint32_t hwcap = aux.a_un.a_val;
-		/* hardcode these values to avoid depending on specific
-		 * versions of the hwcap header, e.g. HWCAP_NEON
-		 */
-		arm_has_vfp = (hwcap & 64) != 0;
-		arm_has_iwmmxt = (hwcap & 512) != 0;
-		/* this flag is only present on kernel 2.6.29 */
-		arm_has_neon = (hwcap & 4096) != 0;
-	    }
-	    else if (aux.a_type == AT_PLATFORM)
-	    {
-		const char *plat = (const char*) aux.a_un.a_val;
-		if (strncmp (plat, "v7l", 3) == 0)
-		{
-		    arm_has_v7 = TRUE;
-		    arm_has_v6 = TRUE;
-		}
-		else if (strncmp (plat, "v6l", 3) == 0)
-		{
-		    arm_has_v6 = TRUE;
-		}
-	    }
-	}
-	close (fd);
-    }
-
-    arm_tests_initialized = TRUE;
-}
-
-#endif /* Linux elf */
-
-#if defined(USE_ARM_SIMD)
-pixman_bool_t
-pixman_have_arm_simd (void)
-{
-    if (!arm_tests_initialized)
-	pixman_arm_read_auxv_or_cpu_features ();
-
-    return arm_has_v6;
-}
-
-#endif /* USE_ARM_SIMD */
-
-#if defined(USE_ARM_NEON)
-pixman_bool_t
-pixman_have_arm_neon (void)
-{
-    if (!arm_tests_initialized)
-	pixman_arm_read_auxv_or_cpu_features ();
-
-    return arm_has_neon;
-}
-
-#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_or_cpu_features ();
-
-    return arm_has_iwmmxt;
-}
-
-#endif /* USE_ARM_IWMMXT */
-
-#else /* !_MSC_VER && !Linux elf && !Android */
-
-#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 || USE_ARM_IWMMXT */
-
 #if defined(USE_MIPS_DSPR2) || defined(USE_LOONGSON_MMI)
 
 #if defined (__linux__) /* linux ELF */
@@ -533,24 +293,12 @@ _pixman_choose_implementation (void)
 	imp = _pixman_implementation_create_fast_path (imp);
 
     imp = _pixman_x86_get_implementations (imp);
+    imp = _pixman_arm_get_implementations (imp);
     
-#ifdef USE_ARM_SIMD
-    if (!_pixman_disabled ("arm-simd") && pixman_have_arm_simd ())
-	imp = _pixman_implementation_create_arm_simd (imp);
-#endif
-
-#ifdef USE_ARM_IWMMXT
-    if (!_pixman_disabled ("arm-iwmmxt") && pixman_have_arm_iwmmxt ())
-	imp = _pixman_implementation_create_mmx (imp);
-#endif
 #ifdef USE_LOONGSON_MMI
     if (!_pixman_disabled ("loongson-mmi") && pixman_have_loongson_mmi ())
 	imp = _pixman_implementation_create_mmx (imp);
 #endif
-#ifdef USE_ARM_NEON
-    if (!_pixman_disabled ("arm-neon") && pixman_have_arm_neon ())
-	imp = _pixman_implementation_create_arm_neon (imp);
-#endif
 
 #ifdef USE_MIPS_DSPR2
     if (!_pixman_disabled ("mips-dspr2") && pixman_have_mips_dspr2 ())
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9d411d4..301b748 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -578,6 +578,9 @@ pixman_implementation_t *
 _pixman_x86_get_implementations (pixman_implementation_t *imp);
 
 pixman_implementation_t *
+_pixman_arm_get_implementations (pixman_implementation_t *imp);
+
+pixman_implementation_t *
 _pixman_choose_implementation (void);
 
 pixman_bool_t
-- 
1.7.10.4



More information about the Pixman mailing list