pixman: Branch 'master' - 9 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Fri Jul 6 22:12:00 PDT 2012


 pixman/Makefile.sources        |    5 
 pixman/pixman-arm.c            |  225 +++++++++++
 pixman/pixman-cpu.c            |  815 -----------------------------------------
 pixman/pixman-implementation.c |   51 ++
 pixman/pixman-mips.c           |   84 ++++
 pixman/pixman-ppc.c            |  155 +++++++
 pixman/pixman-private.h        |   17 
 pixman/pixman-x86.c            |  282 ++++++++++++++
 8 files changed, 818 insertions(+), 816 deletions(-)

New commits:
commit 6aac8e85701be418e1ce13debc1bc8a30687f66b
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Jun 27 22:11:29 2012 -0400

    Simplify CPU detection on PPC.
    
    Get rid of the initialized and have_vmx static variables in
    pixman-ppc.c There is no point to them since CPU detection only
    happens once per process.
    
    On Linux, just read /proc/self/auxv instead of generating the filename
    with getpid() and don't bother with the stack buffer. Instead just
    read the aux entries one by one.

diff --git a/pixman/pixman-ppc.c b/pixman/pixman-ppc.c
index 786f204..f1bea1e 100644
--- a/pixman/pixman-ppc.c
+++ b/pixman/pixman-ppc.c
@@ -31,26 +31,20 @@
  * "-maltivec -mabi=altivec", as gcc would try to save vector register
  * across function calls causing SIGILL on cpus without Altivec/vmx.
  */
-static pixman_bool_t initialized = FALSE;
-static volatile pixman_bool_t have_vmx = TRUE;
-
 #ifdef __APPLE__
 #include <sys/sysctl.h>
 
 static pixman_bool_t
 pixman_have_vmx (void)
 {
-    if (!initialized)
-    {
-	size_t length = sizeof(have_vmx);
-	int error =
-	    sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
+    size_t length = sizeof(have_vmx);
+    int error, have_mmx;
 
-	if (error)
-	    have_vmx = FALSE;
+    sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
+
+    if (error)
+	return FALSE;
 
-	initialized = TRUE;
-    }
     return have_vmx;
 }
 
@@ -62,22 +56,20 @@ pixman_have_vmx (void)
 static pixman_bool_t
 pixman_have_vmx (void)
 {
-    if (!initialized)
-    {
-	int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
-	size_t length = sizeof(have_vmx);
-	int error =
-	    sysctl (mib, 2, &have_vmx, &length, NULL, 0);
+    int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
+    size_t length = sizeof(have_vmx);
+    int error, have_vmx;
 
-	if (error != 0)
-	    have_vmx = FALSE;
+    error = sysctl (mib, 2, &have_vmx, &length, NULL, 0);
+
+    if (error != 0)
+	return FALSE;
 
-	initialized = TRUE;
-    }
     return have_vmx;
 }
 
 #elif defined (__linux__)
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -89,51 +81,27 @@ pixman_have_vmx (void)
 static pixman_bool_t
 pixman_have_vmx (void)
 {
-    if (!initialized)
+    int have_vmx = FALSE;
+    int fd;
+    struct
     {
-	char fname[64];
-	unsigned long buf[64];
-	ssize_t count = 0;
-	pid_t pid;
-	int fd, i;
+	unsigned long type;
+	unsigned long value;
+    } aux;
 
-	pid = getpid ();
-	snprintf (fname, sizeof(fname) - 1, "/proc/%d/auxv", pid);
-
-	fd = open (fname, O_RDONLY);
-	if (fd >= 0)
+    fd = open ("/proc/self/auxv", O_RDONLY);
+    if (fd >= 0)
+    {
+	while (read (fd, &aux, sizeof (aux)) == sizeof (aux))
 	{
-	    for (i = 0; i <= (count / sizeof(unsigned long)); i += 2)
+	    if (aux.type == AT_HWCAP && (aux.value & PPC_FEATURE_HAS_ALTIVEC))
 	    {
-		/* Read more if buf is empty... */
-		if (i == (count / sizeof(unsigned long)))
-		{
-		    count = read (fd, buf, sizeof(buf));
-		    if (count <= 0)
-			break;
-		    i = 0;
-		}
-
-		if (buf[i] == AT_HWCAP)
-		{
-		    have_vmx = !!(buf[i + 1] & PPC_FEATURE_HAS_ALTIVEC);
-		    initialized = TRUE;
-		    break;
-		}
-		else if (buf[i] == AT_NULL)
-		{
-		    break;
-		}
+		have_vmx = TRUE;
+		break;
 	    }
-	    close (fd);
 	}
-    }
-    if (!initialized)
-    {
-	/* Something went wrong. Assume 'no' rather than playing
-	   fragile tricks with catching SIGILL. */
-	have_vmx = FALSE;
-	initialized = TRUE;
+
+	close (fd);
     }
 
     return have_vmx;
@@ -159,22 +127,17 @@ pixman_have_vmx (void)
     struct sigaction sa, osa;
     int jmp_result;
 
-    if (!initialized)
+    sa.sa_flags = SA_SIGINFO;
+    sigemptyset (&sa.sa_mask);
+    sa.sa_sigaction = vmx_test;
+    sigaction (SIGILL, &sa, &osa);
+    jmp_result = setjmp (jump_env);
+    if (jmp_result == 0)
     {
-	sa.sa_flags = SA_SIGINFO;
-	sigemptyset (&sa.sa_mask);
-	sa.sa_sigaction = vmx_test;
-	sigaction (SIGILL, &sa, &osa);
-	jmp_result = setjmp (jump_env);
-	if (jmp_result == 0)
-	{
-	    asm volatile ( "vor 0, 0, 0" );
-	}
-	sigaction (SIGILL, &osa, NULL);
-	have_vmx = (jmp_result == 0);
-	initialized = TRUE;
+	asm volatile ( "vor 0, 0, 0" );
     }
-    return have_vmx;
+    sigaction (SIGILL, &osa, NULL);
+    return (jmp_result == 0);
 }
 
 #endif /* __APPLE__ */
commit 4b78d785373c1d02abe695267379674776b3da3d
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Jun 27 22:05:18 2012 -0400

    Simplifications to ARM CPU detection
    
    Organize pixman-arm.c such that each operating system/compiler exports
    a detect_cpu_features() function that returns a bitmask with the
    various features that we are interested in. A new function
    have_feature() then calls this function, caches the result, and return
    whether the given feature is available.
    
    The result is that all the pixman_have_arm_<feature> functions become
    redundant and can be deleted.

diff --git a/pixman/pixman-arm.c b/pixman/pixman-arm.c
index 6625d7f..23374e4 100644
--- a/pixman/pixman-arm.c
+++ b/pixman/pixman-arm.c
@@ -25,132 +25,83 @@
 
 #include "pixman-private.h"
 
+typedef enum
+{
+    ARM_V7		= (1 << 0),
+    ARM_V6		= (1 << 1),
+    ARM_VFP		= (1 << 2),
+    ARM_NEON		= (1 << 3),
+    ARM_IWMMXT		= (1 << 4)
+} arm_cpu_features_t;
+
 #if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
 
-#include <string.h>
-#include <stdlib.h>
+#if defined(_MSC_VER)
 
-#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_neon_op ();
 extern int pixman_msvc_try_arm_simd_op ();
 
-pixman_bool_t
-pixman_have_arm_simd (void)
+static arm_cpu_features_t
+detect_cpu_features (void)
 {
-    static pixman_bool_t initialized = FALSE;
-    static pixman_bool_t have_arm_simd = FALSE;
+    arm_cpu_features_t features = 0;
 
-    if (!initialized)
+    __try
+    {
+	pixman_msvc_try_arm_simd_op ();
+	features |= ARM_V6;
+    }
+    __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
     {
-	__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 ();
+	features |= ARM_NEON;
+    }
+    __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
     {
-	__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;
+    return features;
 }
 
-#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.
- */
+#elif defined(__APPLE__) && defined(TARGET_OS_IPHONE) /* iOS */
 
-pixman_bool_t
-pixman_have_arm_simd (void)
-{
-#if defined(USE_ARM_SIMD)
-    return TRUE;
-#else
-    return FALSE;
-#endif
-}
+#include "TargetConditionals.h"
 
-pixman_bool_t
-pixman_have_arm_neon (void)
+static arm_cpu_features_t
+detect_cpu_features (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;
+    arm_cpu_features_t features = 0;
+
+    features |= ARM_V6;
+
+    /* 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.
+     */
+#if defined(__ARM_NEON__)
+    features |= ARM_NEON;
 #endif
-}
 
-pixman_bool_t
-pixman_have_arm_iwmmxt (void)
-{
-#if defined(USE_ARM_IWMMXT)
-    return FALSE;
-#else
-    return FALSE;
-#endif
+    return features;
 }
 
-#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 */
+#elif defined(__ANDROID__) || defined(ANDROID) /* Android */
 
 #include <cpu-features.h>
 
-static void
-pixman_arm_read_auxv_or_cpu_features ()
+static arm_cpu_features_t
+detect_cpu_features (void)
 {
+    arm_cpu_features_t features = 0;
     AndroidCpuFamily cpu_family;
     uint64_t cpu_features;
 
@@ -160,16 +111,16 @@ pixman_arm_read_auxv_or_cpu_features ()
     if (cpu_family == ANDROID_CPU_FAMILY_ARM)
     {
 	if (cpu_features & ANDROID_CPU_ARM_FEATURE_ARMv7)
-	    arm_has_v7 = TRUE;
-	
+	    features |= ARM_V7;
+
 	if (cpu_features & ANDROID_CPU_ARM_FEATURE_VFPv3)
-	    arm_has_vfp = TRUE;
-	
+	    features |= ARM_VFP;
+
 	if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON)
-	    arm_has_neon = TRUE;
+	    features |= ARM_NEON;
     }
 
-    arm_tests_initialized = TRUE;
+    return features;
 }
 
 #elif defined (__linux__) /* linux ELF */
@@ -182,11 +133,12 @@ pixman_arm_read_auxv_or_cpu_features ()
 #include <string.h>
 #include <elf.h>
 
-static void
-pixman_arm_read_auxv_or_cpu_features ()
+static arm_cpu_features_t
+detect_cpu_features (void)
 {
-    int fd;
+    arm_cpu_features_t features = 0;
     Elf32_auxv_t aux;
+    int fd;
 
     fd = open ("/proc/self/auxv", O_RDONLY);
     if (fd >= 0)
@@ -196,100 +148,78 @@ pixman_arm_read_auxv_or_cpu_features ()
 	    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;
+		if ((hwcap & 64) != 0)
+		    features |= ARM_VFP;
+		if ((hwcap & 512) != 0)
+		    features |= ARM_IWMMXT;
 		/* this flag is only present on kernel 2.6.29 */
-		arm_has_neon = (hwcap & 4096) != 0;
+		if ((hwcap & 4096) != 0)
+		    features |= ARM_NEON;
 	    }
 	    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;
-		}
+		    features |= (ARM_V7 | ARM_V6);
 		else if (strncmp (plat, "v6l", 3) == 0)
-		{
-		    arm_has_v6 = TRUE;
-		}
+		    features |= ARM_V6;
 	    }
 	}
 	close (fd);
     }
 
-    arm_tests_initialized = TRUE;
+    return features;
 }
 
-#endif /* Linux elf */
+#else /* Unknown */
 
-#if defined(USE_ARM_SIMD)
-pixman_bool_t
-pixman_have_arm_simd (void)
+static arm_cpu_features_t
+detect_cpu_features (void)
 {
-    if (!arm_tests_initialized)
-	pixman_arm_read_auxv_or_cpu_features ();
-
-    return arm_has_v6;
+    return 0;
 }
 
-#endif /* USE_ARM_SIMD */
+#endif /* Linux elf */
 
-#if defined(USE_ARM_NEON)
-pixman_bool_t
-pixman_have_arm_neon (void)
+static pixman_bool_t
+have_feature (arm_cpu_features_t feature)
 {
-    if (!arm_tests_initialized)
-	pixman_arm_read_auxv_or_cpu_features ();
-
-    return arm_has_neon;
-}
+    static pixman_bool_t initialized;
+    static arm_cpu_features_t features;
 
-#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 ();
+    if (!initialized)
+    {
+	features = detect_cpu_features();
+	initialized = TRUE;
+    }
 
-    return arm_has_iwmmxt;
+    return (features & feature) == feature;
 }
 
-#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 ())
+    if (!_pixman_disabled ("arm-simd") && have_feature (ARM_V6))
 	imp = _pixman_implementation_create_arm_simd (imp);
 #endif
 
 #ifdef USE_ARM_IWMMXT
-    if (!_pixman_disabled ("arm-iwmmxt") && pixman_have_arm_iwmmxt ())
+    if (!_pixman_disabled ("arm-iwmmxt") && have_feature (ARM_IWMMXT))
 	imp = _pixman_implementation_create_mmx (imp);
 #endif
 
 #ifdef USE_ARM_NEON
-    if (!_pixman_disabled ("arm-neon") && pixman_have_arm_neon ())
+    if (!_pixman_disabled ("arm-neon") && have_feature (ARM_NEON))
 	imp = _pixman_implementation_create_arm_neon (imp);
 #endif
 
     return imp;
 }
-
commit 8b795a9c17aa25328b9c76b949d319bb578d5f1e
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Jun 27 14:14:54 2012 -0400

    Simplify MIPS CPU detection
    
    There is no reason to have pixman_have_<feature> functions when all
    they do is call pixman_have_mips_feature().
    
    Instead rename pixman_have_mips_feature() to have_feature() and call
    it directly from _pixman_mips_get_implementations(). Also on
    non-Linux, just make have_feature() return FALSE.

diff --git a/pixman/pixman-mips.c b/pixman/pixman-mips.c
index 9d3ee59..2b280c6 100644
--- a/pixman/pixman-mips.c
+++ b/pixman/pixman-mips.c
@@ -30,21 +30,18 @@
 #include <string.h>
 #include <stdlib.h>
 
-#if defined (__linux__) /* linux ELF */
-
 static pixman_bool_t
-pixman_have_mips_feature (const char *search_string)
+have_feature (const char *search_string)
 {
-    const char *file_name = "/proc/cpuinfo";
+#if defined (__linux__) /* linux ELF */
     /* Simple detection of MIPS features at runtime for Linux.
      * It is based on /proc/cpuinfo, which reveals hardware configuration
      * to user-space applications.  According to MIPS (early 2010), no similar
      * facility is universally available on the MIPS architectures, so it's up
      * to individual OSes to provide such.
      */
-
+    const char *file_name = "/proc/cpuinfo";
     char cpuinfo_line[256];
-
     FILE *f = NULL;
 
     if ((f = fopen (file_name, "r")) == NULL)
@@ -60,51 +57,28 @@ pixman_have_mips_feature (const char *search_string)
     }
 
     fclose (f);
+#endif
 
-    /* Did not find string in the proc file. */
+    /* Did not find string in the proc file, or not Linux ELF. */
     return FALSE;
 }
 
-#if defined(USE_MIPS_DSPR2)
-pixman_bool_t
-pixman_have_mips_dspr2 (void)
-{
-     /* Only currently available MIPS core that supports DSPr2 is 74K. */
-    return pixman_have_mips_feature ("MIPS 74K");
-}
 #endif
 
-#if defined(USE_LOONGSON_MMI)
-pixman_bool_t
-pixman_have_loongson_mmi (void)
-{
-    /* I really don't know if some Loongson CPUs don't have MMI. */
-    return pixman_have_mips_feature ("Loongson");
-}
-#endif
-
-#else /* linux ELF */
-
-#define pixman_have_mips_dspr2() FALSE
-#define pixman_have_loongson_mmi() FALSE
-
-#endif /* linux ELF */
-
-#endif /* USE_MIPS_DSPR2 || USE_LOONGSON_MMI */
-
 pixman_implementation_t *
 _pixman_mips_get_implementations (pixman_implementation_t *imp)
 {
 #ifdef USE_LOONGSON_MMI
-    if (!_pixman_disabled ("loongson-mmi") && pixman_have_loongson_mmi ())
+    /* I really don't know if some Loongson CPUs don't have MMI. */
+    if (!_pixman_disabled ("loongson-mmi") && have_feature ("Loongson"))
 	imp = _pixman_implementation_create_mmx (imp);
 #endif
 
 #ifdef USE_MIPS_DSPR2
-    if (!_pixman_disabled ("mips-dspr2") && pixman_have_mips_dspr2 ())
+    /* Only currently available MIPS core that supports DSPr2 is 74K. */
+    if (!_pixman_disabled ("mips-dspr2") && have_feature ("MIPS 74K"))
 	imp = _pixman_implementation_create_mips_dspr2 (imp);
 #endif
 
     return imp;
 }
-
commit 16502dd3ae3bf1d49faf1de533bd58013e168e64
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Jun 27 23:04:24 2012 -0400

    Move the remaining bits of pixman-cpu into pixman-implementation.c

diff --git a/pixman/Makefile.sources b/pixman/Makefile.sources
index 73758ff..6472994 100644
--- a/pixman/Makefile.sources
+++ b/pixman/Makefile.sources
@@ -6,7 +6,6 @@ libpixman_sources =			\
 	pixman-combine32.c		\
 	pixman-combine64.c		\
 	pixman-conical-gradient.c	\
-	pixman-cpu.c			\
 	pixman-x86.c			\
 	pixman-mips.c			\
 	pixman-arm.c			\
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
deleted file mode 100644
index 5cef480..0000000
--- a/pixman/pixman-cpu.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 <stdlib.h>
-
-#include "pixman-private.h"
-
-pixman_bool_t
-_pixman_disabled (const char *name)
-{
-    const char *env;
-
-    if ((env = getenv ("PIXMAN_DISABLE")))
-    {
-	do
-	{
-	    const char *end;
-	    int len;
-
-	    if ((end = strchr (env, ' ')))
-		len = end - env;
-	    else
-		len = strlen (env);
-
-	    if (strlen (name) == len && strncmp (name, env, len) == 0)
-	    {
-		printf ("pixman: Disabled %s implementation\n", name);
-		return TRUE;
-	    }
-
-	    env += len;
-	}
-	while (*env++);
-    }
-
-    return FALSE;
-}
-
-pixman_implementation_t *
-_pixman_choose_implementation (void)
-{
-    pixman_implementation_t *imp;
-
-    imp = _pixman_implementation_create_general();
-
-    if (!_pixman_disabled ("fast"))
-	imp = _pixman_implementation_create_fast_path (imp);
-
-    imp = _pixman_x86_get_implementations (imp);
-    imp = _pixman_arm_get_implementations (imp);
-    imp = _pixman_ppc_get_implementations (imp);
-    imp = _pixman_mips_get_implementations (imp);
-
-    imp = _pixman_implementation_create_noop (imp);
-
-    return imp;
-}
-
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index c769ab8..77d0906 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -223,3 +223,54 @@ _pixman_implementation_dest_iter_init (pixman_implementation_t	*imp,
 
     (*imp->dest_iter_init) (imp, iter);
 }
+
+pixman_bool_t
+_pixman_disabled (const char *name)
+{
+    const char *env;
+
+    if ((env = getenv ("PIXMAN_DISABLE")))
+    {
+	do
+	{
+	    const char *end;
+	    int len;
+
+	    if ((end = strchr (env, ' ')))
+		len = end - env;
+	    else
+		len = strlen (env);
+
+	    if (strlen (name) == len && strncmp (name, env, len) == 0)
+	    {
+		printf ("pixman: Disabled %s implementation\n", name);
+		return TRUE;
+	    }
+
+	    env += len;
+	}
+	while (*env++);
+    }
+
+    return FALSE;
+}
+
+pixman_implementation_t *
+_pixman_choose_implementation (void)
+{
+    pixman_implementation_t *imp;
+
+    imp = _pixman_implementation_create_general();
+
+    if (!_pixman_disabled ("fast"))
+	imp = _pixman_implementation_create_fast_path (imp);
+
+    imp = _pixman_x86_get_implementations (imp);
+    imp = _pixman_arm_get_implementations (imp);
+    imp = _pixman_ppc_get_implementations (imp);
+    imp = _pixman_mips_get_implementations (imp);
+
+    imp = _pixman_implementation_create_noop (imp);
+
+    return imp;
+}
commit 5813bb96aec1c48636db621558534561fef67b68
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Jun 26 17:26:34 2012 -0400

    Move MIPS specific CPU detection to its own file, pixman-mips.c

diff --git a/pixman/Makefile.sources b/pixman/Makefile.sources
index 414ac02..73758ff 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-mips.c			\
 	pixman-arm.c			\
 	pixman-ppc.c			\
 	pixman-edge.c			\
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index 914f116..5cef480 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -22,76 +22,10 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-
-#include <string.h>
 #include <stdlib.h>
 
 #include "pixman-private.h"
 
-#if defined(USE_MIPS_DSPR2) || defined(USE_LOONGSON_MMI)
-
-#if defined (__linux__) /* linux ELF */
-
-static pixman_bool_t
-pixman_have_mips_feature (const char *search_string)
-{
-    const char *file_name = "/proc/cpuinfo";
-    /* Simple detection of MIPS features at runtime for Linux.
-     * It is based on /proc/cpuinfo, which reveals hardware configuration
-     * to user-space applications.  According to MIPS (early 2010), no similar
-     * facility is universally available on the MIPS architectures, so it's up
-     * to individual OSes to provide such.
-     */
-
-    char cpuinfo_line[256];
-
-    FILE *f = NULL;
-
-    if ((f = fopen (file_name, "r")) == NULL)
-        return FALSE;
-
-    while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL)
-    {
-        if (strstr (cpuinfo_line, search_string) != NULL)
-        {
-            fclose (f);
-            return TRUE;
-        }
-    }
-
-    fclose (f);
-
-    /* Did not find string in the proc file. */
-    return FALSE;
-}
-
-#if defined(USE_MIPS_DSPR2)
-pixman_bool_t
-pixman_have_mips_dspr2 (void)
-{
-     /* Only currently available MIPS core that supports DSPr2 is 74K. */
-    return pixman_have_mips_feature ("MIPS 74K");
-}
-#endif
-
-#if defined(USE_LOONGSON_MMI)
-pixman_bool_t
-pixman_have_loongson_mmi (void)
-{
-    /* I really don't know if some Loongson CPUs don't have MMI. */
-    return pixman_have_mips_feature ("Loongson");
-}
-#endif
-
-#else /* linux ELF */
-
-#define pixman_have_mips_dspr2() FALSE
-#define pixman_have_loongson_mmi() FALSE
-
-#endif /* linux ELF */
-
-#endif /* USE_MIPS_DSPR2 || USE_LOONGSON_MMI */
-
 pixman_bool_t
 _pixman_disabled (const char *name)
 {
@@ -136,16 +70,7 @@ _pixman_choose_implementation (void)
     imp = _pixman_x86_get_implementations (imp);
     imp = _pixman_arm_get_implementations (imp);
     imp = _pixman_ppc_get_implementations (imp);
-    
-#ifdef USE_LOONGSON_MMI
-    if (!_pixman_disabled ("loongson-mmi") && pixman_have_loongson_mmi ())
-	imp = _pixman_implementation_create_mmx (imp);
-#endif
-
-#ifdef USE_MIPS_DSPR2
-    if (!_pixman_disabled ("mips-dspr2") && pixman_have_mips_dspr2 ())
-	imp = _pixman_implementation_create_mips_dspr2 (imp);
-#endif
+    imp = _pixman_mips_get_implementations (imp);
 
     imp = _pixman_implementation_create_noop (imp);
 
diff --git a/pixman/pixman-mips.c b/pixman/pixman-mips.c
new file mode 100644
index 0000000..9d3ee59
--- /dev/null
+++ b/pixman/pixman-mips.c
@@ -0,0 +1,110 @@
+/*
+ * 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_MIPS_DSPR2) || defined(USE_LOONGSON_MMI)
+
+#include <string.h>
+#include <stdlib.h>
+
+#if defined (__linux__) /* linux ELF */
+
+static pixman_bool_t
+pixman_have_mips_feature (const char *search_string)
+{
+    const char *file_name = "/proc/cpuinfo";
+    /* Simple detection of MIPS features at runtime for Linux.
+     * It is based on /proc/cpuinfo, which reveals hardware configuration
+     * to user-space applications.  According to MIPS (early 2010), no similar
+     * facility is universally available on the MIPS architectures, so it's up
+     * to individual OSes to provide such.
+     */
+
+    char cpuinfo_line[256];
+
+    FILE *f = NULL;
+
+    if ((f = fopen (file_name, "r")) == NULL)
+        return FALSE;
+
+    while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL)
+    {
+        if (strstr (cpuinfo_line, search_string) != NULL)
+        {
+            fclose (f);
+            return TRUE;
+        }
+    }
+
+    fclose (f);
+
+    /* Did not find string in the proc file. */
+    return FALSE;
+}
+
+#if defined(USE_MIPS_DSPR2)
+pixman_bool_t
+pixman_have_mips_dspr2 (void)
+{
+     /* Only currently available MIPS core that supports DSPr2 is 74K. */
+    return pixman_have_mips_feature ("MIPS 74K");
+}
+#endif
+
+#if defined(USE_LOONGSON_MMI)
+pixman_bool_t
+pixman_have_loongson_mmi (void)
+{
+    /* I really don't know if some Loongson CPUs don't have MMI. */
+    return pixman_have_mips_feature ("Loongson");
+}
+#endif
+
+#else /* linux ELF */
+
+#define pixman_have_mips_dspr2() FALSE
+#define pixman_have_loongson_mmi() FALSE
+
+#endif /* linux ELF */
+
+#endif /* USE_MIPS_DSPR2 || USE_LOONGSON_MMI */
+
+pixman_implementation_t *
+_pixman_mips_get_implementations (pixman_implementation_t *imp)
+{
+#ifdef USE_LOONGSON_MMI
+    if (!_pixman_disabled ("loongson-mmi") && pixman_have_loongson_mmi ())
+	imp = _pixman_implementation_create_mmx (imp);
+#endif
+
+#ifdef USE_MIPS_DSPR2
+    if (!_pixman_disabled ("mips-dspr2") && pixman_have_mips_dspr2 ())
+	imp = _pixman_implementation_create_mips_dspr2 (imp);
+#endif
+
+    return imp;
+}
+
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 5e5b883..4d8f64d 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -598,6 +598,9 @@ pixman_implementation_t *
 _pixman_ppc_get_implementations (pixman_implementation_t *imp);
 
 pixman_implementation_t *
+_pixman_mips_get_implementations (pixman_implementation_t *imp);
+
+pixman_implementation_t *
 _pixman_choose_implementation (void);
 
 pixman_bool_t
commit 4ac0a1d60fccf4f9a782747ce61fd15825eddb5a
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Jun 26 17:30:22 2012 -0400

    Move PowerPC specific CPU detection to its own file pixman-ppc.c

diff --git a/pixman/Makefile.sources b/pixman/Makefile.sources
index 7f2b75f..414ac02 100644
--- a/pixman/Makefile.sources
+++ b/pixman/Makefile.sources
@@ -9,6 +9,7 @@ libpixman_sources =			\
 	pixman-cpu.c			\
 	pixman-x86.c			\
 	pixman-arm.c			\
+	pixman-ppc.c			\
 	pixman-edge.c			\
 	pixman-edge-accessors.c		\
 	pixman-fast-path.c		\
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index 319d71f..914f116 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -26,167 +26,8 @@
 #include <string.h>
 #include <stdlib.h>
 
-#if defined(__APPLE__)
-#include "TargetConditionals.h"
-#endif
-
 #include "pixman-private.h"
 
-#ifdef USE_VMX
-
-/* The CPU detection code needs to be in a file not compiled with
- * "-maltivec -mabi=altivec", as gcc would try to save vector register
- * across function calls causing SIGILL on cpus without Altivec/vmx.
- */
-static pixman_bool_t initialized = FALSE;
-static volatile pixman_bool_t have_vmx = TRUE;
-
-#ifdef __APPLE__
-#include <sys/sysctl.h>
-
-static pixman_bool_t
-pixman_have_vmx (void)
-{
-    if (!initialized)
-    {
-	size_t length = sizeof(have_vmx);
-	int error =
-	    sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
-
-	if (error)
-	    have_vmx = FALSE;
-
-	initialized = TRUE;
-    }
-    return have_vmx;
-}
-
-#elif defined (__OpenBSD__)
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <machine/cpu.h>
-
-static pixman_bool_t
-pixman_have_vmx (void)
-{
-    if (!initialized)
-    {
-	int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
-	size_t length = sizeof(have_vmx);
-	int error =
-	    sysctl (mib, 2, &have_vmx, &length, NULL, 0);
-
-	if (error != 0)
-	    have_vmx = FALSE;
-
-	initialized = TRUE;
-    }
-    return have_vmx;
-}
-
-#elif defined (__linux__)
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <linux/auxvec.h>
-#include <asm/cputable.h>
-
-static pixman_bool_t
-pixman_have_vmx (void)
-{
-    if (!initialized)
-    {
-	char fname[64];
-	unsigned long buf[64];
-	ssize_t count = 0;
-	pid_t pid;
-	int fd, i;
-
-	pid = getpid ();
-	snprintf (fname, sizeof(fname) - 1, "/proc/%d/auxv", pid);
-
-	fd = open (fname, O_RDONLY);
-	if (fd >= 0)
-	{
-	    for (i = 0; i <= (count / sizeof(unsigned long)); i += 2)
-	    {
-		/* Read more if buf is empty... */
-		if (i == (count / sizeof(unsigned long)))
-		{
-		    count = read (fd, buf, sizeof(buf));
-		    if (count <= 0)
-			break;
-		    i = 0;
-		}
-
-		if (buf[i] == AT_HWCAP)
-		{
-		    have_vmx = !!(buf[i + 1] & PPC_FEATURE_HAS_ALTIVEC);
-		    initialized = TRUE;
-		    break;
-		}
-		else if (buf[i] == AT_NULL)
-		{
-		    break;
-		}
-	    }
-	    close (fd);
-	}
-    }
-    if (!initialized)
-    {
-	/* Something went wrong. Assume 'no' rather than playing
-	   fragile tricks with catching SIGILL. */
-	have_vmx = FALSE;
-	initialized = TRUE;
-    }
-
-    return have_vmx;
-}
-
-#else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
-#include <signal.h>
-#include <setjmp.h>
-
-static jmp_buf jump_env;
-
-static void
-vmx_test (int        sig,
-	  siginfo_t *si,
-	  void *     unused)
-{
-    longjmp (jump_env, 1);
-}
-
-static pixman_bool_t
-pixman_have_vmx (void)
-{
-    struct sigaction sa, osa;
-    int jmp_result;
-
-    if (!initialized)
-    {
-	sa.sa_flags = SA_SIGINFO;
-	sigemptyset (&sa.sa_mask);
-	sa.sa_sigaction = vmx_test;
-	sigaction (SIGILL, &sa, &osa);
-	jmp_result = setjmp (jump_env);
-	if (jmp_result == 0)
-	{
-	    asm volatile ( "vor 0, 0, 0" );
-	}
-	sigaction (SIGILL, &osa, NULL);
-	have_vmx = (jmp_result == 0);
-	initialized = TRUE;
-    }
-    return have_vmx;
-}
-
-#endif /* __APPLE__ */
-#endif /* USE_VMX */
-
 #if defined(USE_MIPS_DSPR2) || defined(USE_LOONGSON_MMI)
 
 #if defined (__linux__) /* linux ELF */
@@ -294,6 +135,7 @@ _pixman_choose_implementation (void)
 
     imp = _pixman_x86_get_implementations (imp);
     imp = _pixman_arm_get_implementations (imp);
+    imp = _pixman_ppc_get_implementations (imp);
     
 #ifdef USE_LOONGSON_MMI
     if (!_pixman_disabled ("loongson-mmi") && pixman_have_loongson_mmi ())
@@ -305,11 +147,6 @@ _pixman_choose_implementation (void)
 	imp = _pixman_implementation_create_mips_dspr2 (imp);
 #endif
 
-#ifdef USE_VMX
-    if (!_pixman_disabled ("vmx") && pixman_have_vmx ())
-	imp = _pixman_implementation_create_vmx (imp);
-#endif
-
     imp = _pixman_implementation_create_noop (imp);
 
     return imp;
diff --git a/pixman/pixman-ppc.c b/pixman/pixman-ppc.c
new file mode 100644
index 0000000..786f204
--- /dev/null
+++ b/pixman/pixman-ppc.c
@@ -0,0 +1,192 @@
+/*
+ * 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"
+
+#ifdef USE_VMX
+
+/* The CPU detection code needs to be in a file not compiled with
+ * "-maltivec -mabi=altivec", as gcc would try to save vector register
+ * across function calls causing SIGILL on cpus without Altivec/vmx.
+ */
+static pixman_bool_t initialized = FALSE;
+static volatile pixman_bool_t have_vmx = TRUE;
+
+#ifdef __APPLE__
+#include <sys/sysctl.h>
+
+static pixman_bool_t
+pixman_have_vmx (void)
+{
+    if (!initialized)
+    {
+	size_t length = sizeof(have_vmx);
+	int error =
+	    sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
+
+	if (error)
+	    have_vmx = FALSE;
+
+	initialized = TRUE;
+    }
+    return have_vmx;
+}
+
+#elif defined (__OpenBSD__)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <machine/cpu.h>
+
+static pixman_bool_t
+pixman_have_vmx (void)
+{
+    if (!initialized)
+    {
+	int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
+	size_t length = sizeof(have_vmx);
+	int error =
+	    sysctl (mib, 2, &have_vmx, &length, NULL, 0);
+
+	if (error != 0)
+	    have_vmx = FALSE;
+
+	initialized = TRUE;
+    }
+    return have_vmx;
+}
+
+#elif defined (__linux__)
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <linux/auxvec.h>
+#include <asm/cputable.h>
+
+static pixman_bool_t
+pixman_have_vmx (void)
+{
+    if (!initialized)
+    {
+	char fname[64];
+	unsigned long buf[64];
+	ssize_t count = 0;
+	pid_t pid;
+	int fd, i;
+
+	pid = getpid ();
+	snprintf (fname, sizeof(fname) - 1, "/proc/%d/auxv", pid);
+
+	fd = open (fname, O_RDONLY);
+	if (fd >= 0)
+	{
+	    for (i = 0; i <= (count / sizeof(unsigned long)); i += 2)
+	    {
+		/* Read more if buf is empty... */
+		if (i == (count / sizeof(unsigned long)))
+		{
+		    count = read (fd, buf, sizeof(buf));
+		    if (count <= 0)
+			break;
+		    i = 0;
+		}
+
+		if (buf[i] == AT_HWCAP)
+		{
+		    have_vmx = !!(buf[i + 1] & PPC_FEATURE_HAS_ALTIVEC);
+		    initialized = TRUE;
+		    break;
+		}
+		else if (buf[i] == AT_NULL)
+		{
+		    break;
+		}
+	    }
+	    close (fd);
+	}
+    }
+    if (!initialized)
+    {
+	/* Something went wrong. Assume 'no' rather than playing
+	   fragile tricks with catching SIGILL. */
+	have_vmx = FALSE;
+	initialized = TRUE;
+    }
+
+    return have_vmx;
+}
+
+#else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
+#include <signal.h>
+#include <setjmp.h>
+
+static jmp_buf jump_env;
+
+static void
+vmx_test (int        sig,
+	  siginfo_t *si,
+	  void *     unused)
+{
+    longjmp (jump_env, 1);
+}
+
+static pixman_bool_t
+pixman_have_vmx (void)
+{
+    struct sigaction sa, osa;
+    int jmp_result;
+
+    if (!initialized)
+    {
+	sa.sa_flags = SA_SIGINFO;
+	sigemptyset (&sa.sa_mask);
+	sa.sa_sigaction = vmx_test;
+	sigaction (SIGILL, &sa, &osa);
+	jmp_result = setjmp (jump_env);
+	if (jmp_result == 0)
+	{
+	    asm volatile ( "vor 0, 0, 0" );
+	}
+	sigaction (SIGILL, &osa, NULL);
+	have_vmx = (jmp_result == 0);
+	initialized = TRUE;
+    }
+    return have_vmx;
+}
+
+#endif /* __APPLE__ */
+#endif /* USE_VMX */
+
+pixman_implementation_t *
+_pixman_ppc_get_implementations (pixman_implementation_t *imp)
+{
+#ifdef USE_VMX
+    if (!_pixman_disabled ("vmx") && pixman_have_vmx ())
+	imp = _pixman_implementation_create_vmx (imp);
+#endif
+
+    return imp;
+}
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0a1c69f..5e5b883 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -595,6 +595,9 @@ pixman_implementation_t *
 _pixman_arm_get_implementations (pixman_implementation_t *imp);
 
 pixman_implementation_t *
+_pixman_ppc_get_implementations (pixman_implementation_t *imp);
+
+pixman_implementation_t *
 _pixman_choose_implementation (void);
 
 pixman_bool_t
commit 8590415f0e54520a176ff0fb53deb82be16873dd
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Jun 26 17:02:24 2012 -0400

    Move ARM specific CPU detection to a new file pixman-arm.c
    
    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.

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 67536c0..0a1c69f 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -592,6 +592,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
commit 39ac18570a70674897aa7085406d9a4f6069feb4
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Jun 26 12:44:32 2012 -0400

    Move x86 specific CPU detection to a new file pixman-x86.c
    
    Extract the x86 specific parts of pixman-cpu.c and put them in their
    own file called pixman-x86.c which exports one function
    pixman_x86_get_implementations() that creates the MMX and SSE2
    implementations. This file is supposed to be compiled on all
    architectures, but pixman_x86_get_implementations() should be a noop
    on non-x86.

diff --git a/pixman/Makefile.sources b/pixman/Makefile.sources
index 11f959d..4e0137a 100644
--- a/pixman/Makefile.sources
+++ b/pixman/Makefile.sources
@@ -7,6 +7,7 @@ libpixman_sources =			\
 	pixman-combine64.c		\
 	pixman-conical-gradient.c	\
 	pixman-cpu.c			\
+	pixman-x86.c			\
 	pixman-edge.c			\
 	pixman-edge-accessors.c		\
 	pixman-fast-path.c		\
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index a0d2f8c..0bfc90f 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -491,244 +491,6 @@ pixman_have_loongson_mmi (void)
 
 #endif /* USE_MIPS_DSPR2 || USE_LOONGSON_MMI */
 
-#if defined(USE_X86_MMX) || defined(USE_SSE2)
-/* The CPU detection code needs to be in a file not compiled with
- * "-mmmx -msse", as gcc would generate CMOV instructions otherwise
- * that would lead to SIGILL instructions on old CPUs that don't have
- * it.
- */
-#if !defined(__amd64__) && !defined(__x86_64__) && !defined(_M_AMD64)
-
-#ifdef HAVE_GETISAX
-#include <sys/auxv.h>
-#endif
-
-typedef enum
-{
-    NO_FEATURES = 0,
-    MMX = 0x1,
-    MMX_EXTENSIONS = 0x2,
-    SSE = 0x6,
-    SSE2 = 0x8,
-    CMOV = 0x10
-} cpu_features_t;
-
-
-static unsigned int
-detect_cpu_features (void)
-{
-    unsigned int features = 0;
-    unsigned int result = 0;
-
-#ifdef HAVE_GETISAX
-    if (getisax (&result, 1))
-    {
-	if (result & AV_386_CMOV)
-	    features |= CMOV;
-	if (result & AV_386_MMX)
-	    features |= MMX;
-	if (result & AV_386_AMD_MMX)
-	    features |= MMX_EXTENSIONS;
-	if (result & AV_386_SSE)
-	    features |= SSE;
-	if (result & AV_386_SSE2)
-	    features |= SSE2;
-    }
-#else
-    char vendor[13];
-#ifdef _MSC_VER
-    int vendor0 = 0, vendor1, vendor2;
-#endif
-    vendor[0] = 0;
-    vendor[12] = 0;
-
-#ifdef __GNUC__
-    /* see p. 118 of amd64 instruction set manual Vol3 */
-    /* We need to be careful about the handling of %ebx and
-     * %esp here. We can't declare either one as clobbered
-     * since they are special registers (%ebx is the "PIC
-     * register" holding an offset to global data, %esp the
-     * stack pointer), so we need to make sure they have their
-     * original values when we access the output operands.
-     */
-    __asm__ (
-        "pushf\n"
-        "pop %%eax\n"
-        "mov %%eax, %%ecx\n"
-        "xor $0x00200000, %%eax\n"
-        "push %%eax\n"
-        "popf\n"
-        "pushf\n"
-        "pop %%eax\n"
-        "mov $0x0, %%edx\n"
-        "xor %%ecx, %%eax\n"
-        "jz 1f\n"
-
-        "mov $0x00000000, %%eax\n"
-        "push %%ebx\n"
-        "cpuid\n"
-        "mov %%ebx, %%eax\n"
-        "pop %%ebx\n"
-        "mov %%eax, %1\n"
-        "mov %%edx, %2\n"
-        "mov %%ecx, %3\n"
-        "mov $0x00000001, %%eax\n"
-        "push %%ebx\n"
-        "cpuid\n"
-        "pop %%ebx\n"
-        "1:\n"
-        "mov %%edx, %0\n"
-	: "=r" (result),
-        "=m" (vendor[0]),
-        "=m" (vendor[4]),
-        "=m" (vendor[8])
-	:
-	: "%eax", "%ecx", "%edx"
-        );
-
-#elif defined (_MSC_VER)
-
-    _asm {
-	pushfd
-	pop eax
-	mov ecx, eax
-	xor eax, 00200000h
-	push eax
-	popfd
-	pushfd
-	pop eax
-	mov edx, 0
-	xor eax, ecx
-	jz nocpuid
-
-	mov eax, 0
-	push ebx
-	cpuid
-	mov eax, ebx
-	pop ebx
-	mov vendor0, eax
-	mov vendor1, edx
-	mov vendor2, ecx
-	mov eax, 1
-	push ebx
-	cpuid
-	pop ebx
-    nocpuid:
-	mov result, edx
-    }
-    memmove (vendor + 0, &vendor0, 4);
-    memmove (vendor + 4, &vendor1, 4);
-    memmove (vendor + 8, &vendor2, 4);
-
-#else
-#   error unsupported compiler
-#endif
-
-    features = 0;
-    if (result)
-    {
-	/* result now contains the standard feature bits */
-	if (result & (1 << 15))
-	    features |= CMOV;
-	if (result & (1 << 23))
-	    features |= MMX;
-	if (result & (1 << 25))
-	    features |= SSE;
-	if (result & (1 << 26))
-	    features |= SSE2;
-	if ((features & MMX) && !(features & SSE) &&
-	    (strcmp (vendor, "AuthenticAMD") == 0 ||
-	     strcmp (vendor, "Geode by NSC") == 0))
-	{
-	    /* check for AMD MMX extensions */
-#ifdef __GNUC__
-	    __asm__ (
-	        "	push %%ebx\n"
-	        "	mov $0x80000000, %%eax\n"
-	        "	cpuid\n"
-	        "	xor %%edx, %%edx\n"
-	        "	cmp $0x1, %%eax\n"
-	        "	jge 2f\n"
-	        "	mov $0x80000001, %%eax\n"
-	        "	cpuid\n"
-	        "2:\n"
-	        "	pop %%ebx\n"
-	        "	mov %%edx, %0\n"
-		: "=r" (result)
-		:
-		: "%eax", "%ecx", "%edx"
-	        );
-#elif defined _MSC_VER
-	    _asm {
-		push ebx
-		mov eax, 80000000h
-		cpuid
-		xor edx, edx
-		cmp eax, 1
-		jge notamd
-		mov eax, 80000001h
-		cpuid
-	    notamd:
-		pop ebx
-		mov result, edx
-	    }
-#endif
-	    if (result & (1 << 22))
-		features |= MMX_EXTENSIONS;
-	}
-    }
-#endif /* HAVE_GETISAX */
-
-    return features;
-}
-
-#ifdef USE_X86_MMX
-static pixman_bool_t
-pixman_have_mmx (void)
-{
-    static pixman_bool_t initialized = FALSE;
-    static pixman_bool_t mmx_present;
-
-    if (!initialized)
-    {
-	unsigned int features = detect_cpu_features ();
-	mmx_present = (features & (MMX | MMX_EXTENSIONS)) == (MMX | MMX_EXTENSIONS);
-	initialized = TRUE;
-    }
-
-    return mmx_present;
-}
-#endif
-
-#ifdef USE_SSE2
-static pixman_bool_t
-pixman_have_sse2 (void)
-{
-    static pixman_bool_t initialized = FALSE;
-    static pixman_bool_t sse2_present;
-
-    if (!initialized)
-    {
-	unsigned int features = detect_cpu_features ();
-	sse2_present = (features & (MMX | MMX_EXTENSIONS | SSE | SSE2)) == (MMX | MMX_EXTENSIONS | SSE | SSE2);
-	initialized = TRUE;
-    }
-
-    return sse2_present;
-}
-
-#endif
-
-#else /* __amd64__ */
-#ifdef USE_X86_MMX
-#define pixman_have_mmx() TRUE
-#endif
-#ifdef USE_SSE2
-#define pixman_have_sse2() TRUE
-#endif
-#endif /* __amd64__ */
-#endif
-
 pixman_bool_t
 _pixman_disabled (const char *name)
 {
@@ -770,16 +532,8 @@ _pixman_choose_implementation (void)
     if (!_pixman_disabled ("fast"))
 	imp = _pixman_implementation_create_fast_path (imp);
 
-#ifdef USE_X86_MMX
-    if (!_pixman_disabled ("mmx") && pixman_have_mmx ())
-	imp = _pixman_implementation_create_mmx (imp);
-#endif
-
-#ifdef USE_SSE2
-    if (!_pixman_disabled ("sse2") && pixman_have_sse2 ())
-	imp = _pixman_implementation_create_sse2 (imp);
-#endif
-
+    imp = _pixman_x86_get_implementations (imp);
+    
 #ifdef USE_ARM_SIMD
     if (!_pixman_disabled ("arm-simd") && pixman_have_arm_simd ())
 	imp = _pixman_implementation_create_arm_simd (imp);
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 75b7c54..67536c0 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -585,6 +585,12 @@ pixman_implementation_t *
 _pixman_implementation_create_vmx (pixman_implementation_t *fallback);
 #endif
 
+pixman_bool_t
+_pixman_implementation_disabled (const char *name);
+
+pixman_implementation_t *
+_pixman_x86_get_implementations (pixman_implementation_t *imp);
+
 pixman_implementation_t *
 _pixman_choose_implementation (void);
 
diff --git a/pixman/pixman-x86.c b/pixman/pixman-x86.c
new file mode 100644
index 0000000..52ad3df
--- /dev/null
+++ b/pixman/pixman-x86.c
@@ -0,0 +1,282 @@
+/*
+ * 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_X86_MMX) || defined (USE_SSE2)
+
+/* The CPU detection code needs to be in a file not compiled with
+ * "-mmmx -msse", as gcc would generate CMOV instructions otherwise
+ * that would lead to SIGILL instructions on old CPUs that don't have
+ * it.
+ */
+#if !defined(__amd64__) && !defined(__x86_64__) && !defined(_M_AMD64)
+
+#ifdef HAVE_GETISAX
+#include <sys/auxv.h>
+#endif
+
+typedef enum
+{
+    NO_FEATURES = 0,
+    MMX = 0x1,
+    MMX_EXTENSIONS = 0x2,
+    SSE = 0x6,
+    SSE2 = 0x8,
+    CMOV = 0x10
+} cpu_features_t;
+
+
+static unsigned int
+detect_cpu_features (void)
+{
+    unsigned int features = 0;
+    unsigned int result = 0;
+    
+#ifdef HAVE_GETISAX
+    if (getisax (&result, 1))
+    {
+	if (result & AV_386_CMOV)
+	    features |= CMOV;
+	if (result & AV_386_MMX)
+	    features |= MMX;
+	if (result & AV_386_AMD_MMX)
+	    features |= MMX_EXTENSIONS;
+	if (result & AV_386_SSE)
+	    features |= SSE;
+	if (result & AV_386_SSE2)
+	    features |= SSE2;
+    }
+#else
+    char vendor[13];
+#ifdef _MSC_VER
+    int vendor0 = 0, vendor1, vendor2;
+#endif
+    vendor[0] = 0;
+    vendor[12] = 0;
+    
+#ifdef __GNUC__
+    /* see p. 118 of amd64 instruction set manual Vol3 */
+    /* We need to be careful about the handling of %ebx and
+     * %esp here. We can't declare either one as clobbered
+     * since they are special registers (%ebx is the "PIC
+     * register" holding an offset to global data, %esp the
+     * stack pointer), so we need to make sure they have their
+     * original values when we access the output operands.
+     */
+    __asm__ (
+        "pushf\n"
+        "pop %%eax\n"
+        "mov %%eax, %%ecx\n"
+        "xor $0x00200000, %%eax\n"
+        "push %%eax\n"
+        "popf\n"
+        "pushf\n"
+        "pop %%eax\n"
+        "mov $0x0, %%edx\n"
+        "xor %%ecx, %%eax\n"
+        "jz 1f\n"
+	
+        "mov $0x00000000, %%eax\n"
+        "push %%ebx\n"
+        "cpuid\n"
+        "mov %%ebx, %%eax\n"
+        "pop %%ebx\n"
+        "mov %%eax, %1\n"
+        "mov %%edx, %2\n"
+        "mov %%ecx, %3\n"
+        "mov $0x00000001, %%eax\n"
+        "push %%ebx\n"
+        "cpuid\n"
+        "pop %%ebx\n"
+        "1:\n"
+        "mov %%edx, %0\n"
+	: "=r" (result),
+	  "=m" (vendor[0]),
+	  "=m" (vendor[4]),
+	  "=m" (vendor[8])
+	:
+	: "%eax", "%ecx", "%edx"
+        );
+    
+#elif defined (_MSC_VER)
+    
+    _asm {
+	pushfd
+	    pop eax
+	    mov ecx, eax
+	    xor eax, 00200000h
+	    push eax
+	    popfd
+	    pushfd
+	    pop eax
+	    mov edx, 0
+	    xor eax, ecx
+	    jz nocpuid
+	    
+	    mov eax, 0
+	    push ebx
+	    cpuid
+	    mov eax, ebx
+	    pop ebx
+	    mov vendor0, eax
+	    mov vendor1, edx
+	    mov vendor2, ecx
+	    mov eax, 1
+	    push ebx
+	    cpuid
+	    pop ebx
+	    nocpuid:
+	    mov result, edx
+	    }
+    memmove (vendor + 0, &vendor0, 4);
+    memmove (vendor + 4, &vendor1, 4);
+    memmove (vendor + 8, &vendor2, 4);
+    
+#else
+#   error unsupported compiler
+#endif
+    
+    features = 0;
+    if (result)
+    {
+	/* result now contains the standard feature bits */
+	if (result & (1 << 15))
+	    features |= CMOV;
+	if (result & (1 << 23))
+	    features |= MMX;
+	if (result & (1 << 25))
+	    features |= SSE;
+	if (result & (1 << 26))
+	    features |= SSE2;
+	if ((features & MMX) && !(features & SSE) &&
+	    (strcmp (vendor, "AuthenticAMD") == 0 ||
+	     strcmp (vendor, "Geode by NSC") == 0))
+	{
+	    /* check for AMD MMX extensions */
+#ifdef __GNUC__
+	    __asm__ (
+	        "	push %%ebx\n"
+	        "	mov $0x80000000, %%eax\n"
+	        "	cpuid\n"
+	        "	xor %%edx, %%edx\n"
+	        "	cmp $0x1, %%eax\n"
+	        "	jge 2f\n"
+	        "	mov $0x80000001, %%eax\n"
+	        "	cpuid\n"
+	        "2:\n"
+	        "	pop %%ebx\n"
+	        "	mov %%edx, %0\n"
+		: "=r" (result)
+		:
+		: "%eax", "%ecx", "%edx"
+	        );
+#elif defined _MSC_VER
+	    _asm {
+		push ebx
+		    mov eax, 80000000h
+		    cpuid
+		    xor edx, edx
+		    cmp eax, 1
+		    jge notamd
+		    mov eax, 80000001h
+		    cpuid
+		    notamd:
+		    pop ebx
+		    mov result, edx
+		    }
+#endif
+	    if (result & (1 << 22))
+		features |= MMX_EXTENSIONS;
+	}
+    }
+#endif /* HAVE_GETISAX */
+    
+    return features;
+}
+
+#ifdef USE_X86_MMX
+static pixman_bool_t
+pixman_have_mmx (void)
+{
+    static pixman_bool_t initialized = FALSE;
+    static pixman_bool_t mmx_present;
+    
+    if (!initialized)
+    {
+	unsigned int features = detect_cpu_features ();
+	mmx_present = (features & (MMX | MMX_EXTENSIONS)) == (MMX | MMX_EXTENSIONS);
+	initialized = TRUE;
+    }
+    
+    return mmx_present;
+}
+#endif
+
+#ifdef USE_SSE2
+static pixman_bool_t
+pixman_have_sse2 (void)
+{
+    static pixman_bool_t initialized = FALSE;
+    static pixman_bool_t sse2_present;
+    
+    if (!initialized)
+    {
+	unsigned int features = detect_cpu_features ();
+	sse2_present = (features & (MMX | MMX_EXTENSIONS | SSE | SSE2)) == (MMX | MMX_EXTENSIONS | SSE | SSE2);
+	initialized = TRUE;
+    }
+    
+    return sse2_present;
+}
+
+#endif
+
+#else /* __amd64__ */
+#ifdef USE_X86_MMX
+#define pixman_have_mmx() TRUE
+#endif
+#ifdef USE_SSE2
+#define pixman_have_sse2() TRUE
+#endif
+#endif /* __amd64__ */
+
+#endif
+
+pixman_implementation_t *
+_pixman_x86_get_implementations (pixman_implementation_t *imp)
+{
+#ifdef USE_X86_MMX
+    if (!_pixman_disabled ("mmx") && pixman_have_mmx())
+	imp = _pixman_implementation_create_mmx (imp);
+#endif
+
+#ifdef USE_SSE2
+    if (!_pixman_disabled ("sse2") && pixman_have_sse2())
+	imp = _pixman_implementation_create_sse2 (imp);
+#endif
+
+    return imp;
+}
commit 1a3b7614a9808f8af15204d0751a6820bf67059c
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Jun 26 18:07:39 2012 -0400

    pixman-cpu.c: Rename disabled to _pixman_disabled() and export it

diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index aa9036f..a0d2f8c 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -729,8 +729,8 @@ pixman_have_sse2 (void)
 #endif /* __amd64__ */
 #endif
 
-static pixman_bool_t
-disabled (const char *name)
+pixman_bool_t
+_pixman_disabled (const char *name)
 {
     const char *env;
 
@@ -767,44 +767,44 @@ _pixman_choose_implementation (void)
 
     imp = _pixman_implementation_create_general();
 
-    if (!disabled ("fast"))
+    if (!_pixman_disabled ("fast"))
 	imp = _pixman_implementation_create_fast_path (imp);
 
 #ifdef USE_X86_MMX
-    if (!disabled ("mmx") && pixman_have_mmx ())
+    if (!_pixman_disabled ("mmx") && pixman_have_mmx ())
 	imp = _pixman_implementation_create_mmx (imp);
 #endif
 
 #ifdef USE_SSE2
-    if (!disabled ("sse2") && pixman_have_sse2 ())
+    if (!_pixman_disabled ("sse2") && pixman_have_sse2 ())
 	imp = _pixman_implementation_create_sse2 (imp);
 #endif
 
 #ifdef USE_ARM_SIMD
-    if (!disabled ("arm-simd") && pixman_have_arm_simd ())
+    if (!_pixman_disabled ("arm-simd") && pixman_have_arm_simd ())
 	imp = _pixman_implementation_create_arm_simd (imp);
 #endif
 
 #ifdef USE_ARM_IWMMXT
-    if (!disabled ("arm-iwmmxt") && pixman_have_arm_iwmmxt ())
+    if (!_pixman_disabled ("arm-iwmmxt") && pixman_have_arm_iwmmxt ())
 	imp = _pixman_implementation_create_mmx (imp);
 #endif
 #ifdef USE_LOONGSON_MMI
-    if (!disabled ("loongson-mmi") && pixman_have_loongson_mmi ())
+    if (!_pixman_disabled ("loongson-mmi") && pixman_have_loongson_mmi ())
 	imp = _pixman_implementation_create_mmx (imp);
 #endif
 #ifdef USE_ARM_NEON
-    if (!disabled ("arm-neon") && pixman_have_arm_neon ())
+    if (!_pixman_disabled ("arm-neon") && pixman_have_arm_neon ())
 	imp = _pixman_implementation_create_arm_neon (imp);
 #endif
 
 #ifdef USE_MIPS_DSPR2
-    if (!disabled ("mips-dspr2") && pixman_have_mips_dspr2 ())
+    if (!_pixman_disabled ("mips-dspr2") && pixman_have_mips_dspr2 ())
 	imp = _pixman_implementation_create_mips_dspr2 (imp);
 #endif
 
 #ifdef USE_VMX
-    if (!disabled ("vmx") && pixman_have_vmx ())
+    if (!_pixman_disabled ("vmx") && pixman_have_vmx ())
 	imp = _pixman_implementation_create_vmx (imp);
 #endif
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0c27798..75b7c54 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -588,6 +588,8 @@ _pixman_implementation_create_vmx (pixman_implementation_t *fallback);
 pixman_implementation_t *
 _pixman_choose_implementation (void);
 
+pixman_bool_t
+_pixman_disabled (const char *name);
 
 
 /*


More information about the xorg-commit mailing list