From: Søren Sandmann Pedersen <s...@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

_______________________________________________
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman

Reply via email to