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