gfx/cairo/libpixman/src/pixman-cpu.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2  * Copyright © 2000 SuSE, Inc.
     3  * Copyright © 2007 Red Hat, Inc.
     4  *
     5  * Permission to use, copy, modify, distribute, and sell this software and its
     6  * documentation for any purpose is hereby granted without fee, provided that
     7  * the above copyright notice appear in all copies and that both that
     8  * copyright notice and this permission notice appear in supporting
     9  * documentation, and that the name of SuSE not be used in advertising or
    10  * publicity pertaining to distribution of the software without specific,
    11  * written prior permission.  SuSE makes no representations about the
    12  * suitability of this software for any purpose.  It is provided "as is"
    13  * without express or implied warranty.
    14  *
    15  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
    16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
    17  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
    19  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
    20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    21  */
    22 #ifdef HAVE_CONFIG_H
    23 #include <config.h>
    24 #endif
    26 #include <string.h>
    27 #include <stdlib.h>
    29 #if defined(USE_ARM_SIMD) && defined(_MSC_VER)
    30 /* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
    31 #include <windows.h>
    32 #endif
    34 #if defined(__APPLE__)
    35 #include "TargetConditionals.h"
    36 #endif
    38 #include "pixman-private.h"
    40 #ifdef USE_VMX
    42 /* The CPU detection code needs to be in a file not compiled with
    43  * "-maltivec -mabi=altivec", as gcc would try to save vector register
    44  * across function calls causing SIGILL on cpus without Altivec/vmx.
    45  */
    46 static pixman_bool_t initialized = FALSE;
    47 static volatile pixman_bool_t have_vmx = TRUE;
    49 #ifdef __APPLE__
    50 #include <sys/sysctl.h>
    52 static pixman_bool_t
    53 pixman_have_vmx (void)
    54 {
    55     if (!initialized)
    56     {
    57 	size_t length = sizeof(have_vmx);
    58 	int error =
    59 	    sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
    61 	if (error)
    62 	    have_vmx = FALSE;
    64 	initialized = TRUE;
    65     }
    66     return have_vmx;
    67 }
    69 #elif defined (__OpenBSD__)
    70 #include <sys/param.h>
    71 #include <sys/sysctl.h>
    72 #include <machine/cpu.h>
    74 static pixman_bool_t
    75 pixman_have_vmx (void)
    76 {
    77     if (!initialized)
    78     {
    79 	int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
    80 	size_t length = sizeof(have_vmx);
    81 	int error =
    82 	    sysctl (mib, 2, &have_vmx, &length, NULL, 0);
    84 	if (error != 0)
    85 	    have_vmx = FALSE;
    87 	initialized = TRUE;
    88     }
    89     return have_vmx;
    90 }
    92 #elif defined (__linux__)
    93 #include <sys/types.h>
    94 #include <sys/stat.h>
    95 #include <fcntl.h>
    96 #include <unistd.h>
    97 #include <stdio.h>
    98 #include <linux/auxvec.h>
    99 #include <asm/cputable.h>
   101 static pixman_bool_t
   102 pixman_have_vmx (void)
   103 {
   104     if (!initialized)
   105     {
   106 	char fname[64];
   107 	unsigned long buf[64];
   108 	ssize_t count = 0;
   109 	pid_t pid;
   110 	int fd, i;
   112 	pid = getpid ();
   113 	snprintf (fname, sizeof(fname) - 1, "/proc/%d/auxv", pid);
   115 	fd = open (fname, O_RDONLY);
   116 	if (fd >= 0)
   117 	{
   118 	    for (i = 0; i <= (count / sizeof(unsigned long)); i += 2)
   119 	    {
   120 		/* Read more if buf is empty... */
   121 		if (i == (count / sizeof(unsigned long)))
   122 		{
   123 		    count = read (fd, buf, sizeof(buf));
   124 		    if (count <= 0)
   125 			break;
   126 		    i = 0;
   127 		}
   129 		if (buf[i] == AT_HWCAP)
   130 		{
   131 		    have_vmx = !!(buf[i + 1] & PPC_FEATURE_HAS_ALTIVEC);
   132 		    initialized = TRUE;
   133 		    break;
   134 		}
   135 		else if (buf[i] == AT_NULL)
   136 		{
   137 		    break;
   138 		}
   139 	    }
   140 	    close (fd);
   141 	}
   142     }
   143     if (!initialized)
   144     {
   145 	/* Something went wrong. Assume 'no' rather than playing
   146 	   fragile tricks with catching SIGILL. */
   147 	have_vmx = FALSE;
   148 	initialized = TRUE;
   149     }
   151     return have_vmx;
   152 }
   154 #else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
   155 #include <signal.h>
   156 #include <setjmp.h>
   158 static jmp_buf jump_env;
   160 static void
   161 vmx_test (int        sig,
   162 	  siginfo_t *si,
   163 	  void *     unused)
   164 {
   165     longjmp (jump_env, 1);
   166 }
   168 static pixman_bool_t
   169 pixman_have_vmx (void)
   170 {
   171     struct sigaction sa, osa;
   172     int jmp_result;
   174     if (!initialized)
   175     {
   176 	sa.sa_flags = SA_SIGINFO;
   177 	sigemptyset (&sa.sa_mask);
   178 	sa.sa_sigaction = vmx_test;
   179 	sigaction (SIGILL, &sa, &osa);
   180 	jmp_result = setjmp (jump_env);
   181 	if (jmp_result == 0)
   182 	{
   183 	    asm volatile ( "vor 0, 0, 0" );
   184 	}
   185 	sigaction (SIGILL, &osa, NULL);
   186 	have_vmx = (jmp_result == 0);
   187 	initialized = TRUE;
   188     }
   189     return have_vmx;
   190 }
   192 #endif /* __APPLE__ */
   193 #endif /* USE_VMX */
   195 #if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
   197 #if defined(_MSC_VER)
   199 #if defined(USE_ARM_SIMD)
   200 extern int pixman_msvc_try_arm_simd_op ();
   202 pixman_bool_t
   203 pixman_have_arm_simd (void)
   204 {
   205     static pixman_bool_t initialized = FALSE;
   206     static pixman_bool_t have_arm_simd = FALSE;
   208     if (!initialized)
   209     {
   210 	__try {
   211 	    pixman_msvc_try_arm_simd_op ();
   212 	    have_arm_simd = TRUE;
   213 	} __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION) {
   214 	    have_arm_simd = FALSE;
   215 	}
   216 	initialized = TRUE;
   217     }
   219     return have_arm_simd;
   220 }
   222 #endif /* USE_ARM_SIMD */
   224 #if defined(USE_ARM_NEON)
   225 extern int pixman_msvc_try_arm_neon_op ();
   227 pixman_bool_t
   228 pixman_have_arm_neon (void)
   229 {
   230     static pixman_bool_t initialized = FALSE;
   231     static pixman_bool_t have_arm_neon = FALSE;
   233     if (!initialized)
   234     {
   235 	__try
   236 	{
   237 	    pixman_msvc_try_arm_neon_op ();
   238 	    have_arm_neon = TRUE;
   239 	}
   240 	__except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
   241 	{
   242 	    have_arm_neon = FALSE;
   243 	}
   244 	initialized = TRUE;
   245     }
   247     return have_arm_neon;
   248 }
   250 #endif /* USE_ARM_NEON */
   252 #elif (defined (__APPLE__) && defined(TARGET_OS_IPHONE)) /* iOS (iPhone/iPad/iPod touch) */
   254 /* Detection of ARM NEON on iOS is fairly simple because iOS binaries
   255  * contain separate executable images for each processor architecture.
   256  * So all we have to do is detect the armv7 architecture build. The
   257  * operating system automatically runs the armv7 binary for armv7 devices
   258  * and the armv6 binary for armv6 devices.
   259  */
   261 pixman_bool_t
   262 pixman_have_arm_simd (void)
   263 {
   264 #if defined(USE_ARM_SIMD)
   265     return TRUE;
   266 #else
   267     return FALSE;
   268 #endif
   269 }
   271 pixman_bool_t
   272 pixman_have_arm_neon (void)
   273 {
   274 #if defined(USE_ARM_NEON) && defined(__ARM_NEON__)
   275     /* This is an armv7 cpu build */
   276     return TRUE;
   277 #else
   278     /* This is an armv6 cpu build */
   279     return FALSE;
   280 #endif
   281 }
   283 pixman_bool_t
   284 pixman_have_arm_iwmmxt (void)
   285 {
   286 #if defined(USE_ARM_IWMMXT)
   287     return FALSE;
   288 #else
   289     return FALSE;
   290 #endif
   291 }
   293 #elif defined (__linux__) || defined(__ANDROID__) || defined(ANDROID) /* linux ELF or ANDROID */
   295 static pixman_bool_t arm_has_v7 = FALSE;
   296 static pixman_bool_t arm_has_v6 = FALSE;
   297 static pixman_bool_t arm_has_vfp = FALSE;
   298 static pixman_bool_t arm_has_neon = FALSE;
   299 static pixman_bool_t arm_has_iwmmxt = FALSE;
   300 static pixman_bool_t arm_tests_initialized = FALSE;
   302 #if defined(__ANDROID__) || defined(ANDROID) /* Android device support */
   304 static void
   305 pixman_arm_read_auxv_or_cpu_features ()
   306 {
   307     char buf[1024];
   308     char* pos;
   309     const char* ver_token = "CPU architecture: ";
   310     FILE* f = fopen("/proc/cpuinfo", "r");
   311     if (!f) {
   312 	arm_tests_initialized = TRUE;
   313 	return;
   314     }
   316     fread(buf, sizeof(char), sizeof(buf), f);
   317     fclose(f);
   318     pos = strstr(buf, ver_token);
   319     if (pos) {
   320 	char vchar = *(pos + strlen(ver_token));
   321 	if (vchar >= '0' && vchar <= '9') {
   322 	    int ver = vchar - '0';
   323 	    arm_has_v7 = ver >= 7;
   324 	    arm_has_v6 = ver >= 6;
   325 	}
   326     }
   327     arm_has_neon = strstr(buf, "neon") != NULL;
   328     arm_has_vfp = strstr(buf, "vfp") != NULL;
   329     arm_has_iwmmxt = strstr(buf, "iwmmxt") != NULL;
   330     arm_tests_initialized = TRUE;
   331 }
   333 #elif defined (__linux__) /* linux ELF */
   335 #include <unistd.h>
   336 #include <sys/types.h>
   337 #include <sys/stat.h>
   338 #include <sys/mman.h>
   339 #include <fcntl.h>
   340 #include <string.h>
   341 #include <elf.h>
   343 static void
   344 pixman_arm_read_auxv_or_cpu_features ()
   345 {
   346     int fd;
   347     Elf32_auxv_t aux;
   349     fd = open ("/proc/self/auxv", O_RDONLY);
   350     if (fd >= 0)
   351     {
   352 	while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t))
   353 	{
   354 	    if (aux.a_type == AT_HWCAP)
   355 	    {
   356 		uint32_t hwcap = aux.a_un.a_val;
   357 		/* hardcode these values to avoid depending on specific
   358 		 * versions of the hwcap header, e.g. HWCAP_NEON
   359 		 */
   360 		arm_has_vfp = (hwcap & 64) != 0;
   361 		arm_has_iwmmxt = (hwcap & 512) != 0;
   362 		/* this flag is only present on kernel 2.6.29 */
   363 		arm_has_neon = (hwcap & 4096) != 0;
   364 	    }
   365 	    else if (aux.a_type == AT_PLATFORM)
   366 	    {
   367 		const char *plat = (const char*) aux.a_un.a_val;
   368 		if (strncmp (plat, "v7l", 3) == 0)
   369 		{
   370 		    arm_has_v7 = TRUE;
   371 		    arm_has_v6 = TRUE;
   372 		}
   373 		else if (strncmp (plat, "v6l", 3) == 0)
   374 		{
   375 		    arm_has_v6 = TRUE;
   376 		}
   377 	    }
   378 	}
   379 	close (fd);
   380     }
   382     arm_tests_initialized = TRUE;
   383 }
   385 #endif /* Linux elf */
   387 #if defined(USE_ARM_SIMD)
   388 pixman_bool_t
   389 pixman_have_arm_simd (void)
   390 {
   391     if (!arm_tests_initialized)
   392 	pixman_arm_read_auxv_or_cpu_features ();
   394     return arm_has_v6;
   395 }
   397 #endif /* USE_ARM_SIMD */
   399 #if defined(USE_ARM_NEON)
   400 pixman_bool_t
   401 pixman_have_arm_neon (void)
   402 {
   403     if (!arm_tests_initialized)
   404 	pixman_arm_read_auxv_or_cpu_features ();
   406     return arm_has_neon;
   407 }
   409 #endif /* USE_ARM_NEON */
   411 #if defined(USE_ARM_IWMMXT)
   412 pixman_bool_t
   413 pixman_have_arm_iwmmxt (void)
   414 {
   415     if (!arm_tests_initialized)
   416 	pixman_arm_read_auxv_or_cpu_features ();
   418     return arm_has_iwmmxt;
   419 }
   421 #endif /* USE_ARM_IWMMXT */
   423 #else /* !_MSC_VER && !Linux elf && !Android */
   425 #define pixman_have_arm_simd() FALSE
   426 #define pixman_have_arm_neon() FALSE
   427 #define pixman_have_arm_iwmmxt() FALSE
   429 #endif
   431 #endif /* USE_ARM_SIMD || USE_ARM_NEON || USE_ARM_IWMMXT */
   433 #if defined(USE_MIPS_DSPR2)
   435 #if defined (__linux__) /* linux ELF */
   437 pixman_bool_t
   438 pixman_have_mips_dspr2 (void)
   439 {
   440     const char *search_string = "MIPS 74K";
   441     const char *file_name = "/proc/cpuinfo";
   442     /* Simple detection of MIPS DSP ASE (revision 2) at runtime for Linux.
   443      * It is based on /proc/cpuinfo, which reveals hardware configuration
   444      * to user-space applications.  According to MIPS (early 2010), no similar
   445      * facility is universally available on the MIPS architectures, so it's up
   446      * to individual OSes to provide such.
   447      *
   448      * Only currently available MIPS core that supports DSPr2 is 74K.
   449      */
   451     char cpuinfo_line[256];
   453     FILE *f = NULL;
   455     if ((f = fopen (file_name, "r")) == NULL)
   456         return FALSE;
   458     while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL)
   459     {
   460         if (strstr (cpuinfo_line, search_string) != NULL)
   461         {
   462             fclose (f);
   463             return TRUE;
   464         }
   465     }
   467     fclose (f);
   469     /* Did not find string in the proc file. */
   470     return FALSE;
   471 }
   473 #else /* linux ELF */
   475 #define pixman_have_mips_dspr2() FALSE
   477 #endif /* linux ELF */
   479 #endif /* USE_MIPS_DSPR2 */
   481 #if defined(USE_X86_MMX) || defined(USE_SSE2)
   482 /* The CPU detection code needs to be in a file not compiled with
   483  * "-mmmx -msse", as gcc would generate CMOV instructions otherwise
   484  * that would lead to SIGILL instructions on old CPUs that don't have
   485  * it.
   486  */
   487 #if !defined(__amd64__) && !defined(__x86_64__) && !defined(_M_AMD64)
   489 #ifdef HAVE_GETISAX
   490 #include <sys/auxv.h>
   491 #endif
   493 typedef enum
   494 {
   495     NO_FEATURES = 0,
   496     MMX = 0x1,
   497     MMX_EXTENSIONS = 0x2,
   498     SSE = 0x6,
   499     SSE2 = 0x8,
   500     CMOV = 0x10
   501 } cpu_features_t;
   504 static unsigned int
   505 detect_cpu_features (void)
   506 {
   507     unsigned int features = 0;
   508     unsigned int result = 0;
   510 #ifdef HAVE_GETISAX
   511     if (getisax (&result, 1))
   512     {
   513 	if (result & AV_386_CMOV)
   514 	    features |= CMOV;
   515 	if (result & AV_386_MMX)
   516 	    features |= MMX;
   517 	if (result & AV_386_AMD_MMX)
   518 	    features |= MMX_EXTENSIONS;
   519 	if (result & AV_386_SSE)
   520 	    features |= SSE;
   521 	if (result & AV_386_SSE2)
   522 	    features |= SSE2;
   523     }
   524 #else
   525     char vendor[13];
   526 #ifdef _MSC_VER
   527     int vendor0 = 0, vendor1, vendor2;
   528 #endif
   529     vendor[0] = 0;
   530     vendor[12] = 0;
   532 #ifdef __GNUC__
   533     /* see p. 118 of amd64 instruction set manual Vol3 */
   534     /* We need to be careful about the handling of %ebx and
   535      * %esp here. We can't declare either one as clobbered
   536      * since they are special registers (%ebx is the "PIC
   537      * register" holding an offset to global data, %esp the
   538      * stack pointer), so we need to make sure they have their
   539      * original values when we access the output operands.
   540      */
   541     __asm__ (
   542         "pushf\n"
   543         "pop %%eax\n"
   544         "mov %%eax, %%ecx\n"
   545         "xor $0x00200000, %%eax\n"
   546         "push %%eax\n"
   547         "popf\n"
   548         "pushf\n"
   549         "pop %%eax\n"
   550         "mov $0x0, %%edx\n"
   551         "xor %%ecx, %%eax\n"
   552         "jz 1f\n"
   554         "mov $0x00000000, %%eax\n"
   555         "push %%ebx\n"
   556         "cpuid\n"
   557         "mov %%ebx, %%eax\n"
   558         "pop %%ebx\n"
   559         "mov %%eax, %1\n"
   560         "mov %%edx, %2\n"
   561         "mov %%ecx, %3\n"
   562         "mov $0x00000001, %%eax\n"
   563         "push %%ebx\n"
   564         "cpuid\n"
   565         "pop %%ebx\n"
   566         "1:\n"
   567         "mov %%edx, %0\n"
   568 	: "=r" (result),
   569         "=m" (vendor[0]),
   570         "=m" (vendor[4]),
   571         "=m" (vendor[8])
   572 	:
   573 	: "%eax", "%ecx", "%edx"
   574         );
   576 #elif defined (_MSC_VER)
   578     _asm {
   579 	pushfd
   580 	pop eax
   581 	mov ecx, eax
   582 	xor eax, 00200000h
   583 	push eax
   584 	popfd
   585 	pushfd
   586 	pop eax
   587 	mov edx, 0
   588 	xor eax, ecx
   589 	jz nocpuid
   591 	mov eax, 0
   592 	push ebx
   593 	cpuid
   594 	mov eax, ebx
   595 	pop ebx
   596 	mov vendor0, eax
   597 	mov vendor1, edx
   598 	mov vendor2, ecx
   599 	mov eax, 1
   600 	push ebx
   601 	cpuid
   602 	pop ebx
   603     nocpuid:
   604 	mov result, edx
   605     }
   606     memmove (vendor + 0, &vendor0, 4);
   607     memmove (vendor + 4, &vendor1, 4);
   608     memmove (vendor + 8, &vendor2, 4);
   610 #else
   611 #   error unsupported compiler
   612 #endif
   614     features = 0;
   615     if (result)
   616     {
   617 	/* result now contains the standard feature bits */
   618 	if (result & (1 << 15))
   619 	    features |= CMOV;
   620 	if (result & (1 << 23))
   621 	    features |= MMX;
   622 	if (result & (1 << 25))
   623 	    features |= SSE;
   624 	if (result & (1 << 26))
   625 	    features |= SSE2;
   626 	if ((features & MMX) && !(features & SSE) &&
   627 	    (strcmp (vendor, "AuthenticAMD") == 0 ||
   628 	     strcmp (vendor, "Geode by NSC") == 0))
   629 	{
   630 	    /* check for AMD MMX extensions */
   631 #ifdef __GNUC__
   632 	    __asm__ (
   633 	        "	push %%ebx\n"
   634 	        "	mov $0x80000000, %%eax\n"
   635 	        "	cpuid\n"
   636 	        "	xor %%edx, %%edx\n"
   637 	        "	cmp $0x1, %%eax\n"
   638 	        "	jge 2f\n"
   639 	        "	mov $0x80000001, %%eax\n"
   640 	        "	cpuid\n"
   641 	        "2:\n"
   642 	        "	pop %%ebx\n"
   643 	        "	mov %%edx, %0\n"
   644 		: "=r" (result)
   645 		:
   646 		: "%eax", "%ecx", "%edx"
   647 	        );
   648 #elif defined _MSC_VER
   649 	    _asm {
   650 		push ebx
   651 		mov eax, 80000000h
   652 		cpuid
   653 		xor edx, edx
   654 		cmp eax, 1
   655 		jge notamd
   656 		mov eax, 80000001h
   657 		cpuid
   658 	    notamd:
   659 		pop ebx
   660 		mov result, edx
   661 	    }
   662 #endif
   663 	    if (result & (1 << 22))
   664 		features |= MMX_EXTENSIONS;
   665 	}
   666     }
   667 #endif /* HAVE_GETISAX */
   669     return features;
   670 }
   672 #ifdef USE_X86_MMX
   673 static pixman_bool_t
   674 pixman_have_mmx (void)
   675 {
   676     static pixman_bool_t initialized = FALSE;
   677     static pixman_bool_t mmx_present;
   679     if (!initialized)
   680     {
   681 	unsigned int features = detect_cpu_features ();
   682 	mmx_present = (features & (MMX | MMX_EXTENSIONS)) == (MMX | MMX_EXTENSIONS);
   683 	initialized = TRUE;
   684     }
   686     return mmx_present;
   687 }
   688 #endif
   690 #ifdef USE_SSE2
   691 static pixman_bool_t
   692 pixman_have_sse2 (void)
   693 {
   694     static pixman_bool_t initialized = FALSE;
   695     static pixman_bool_t sse2_present;
   697     if (!initialized)
   698     {
   699 	unsigned int features = detect_cpu_features ();
   700 	sse2_present = (features & (MMX | MMX_EXTENSIONS | SSE | SSE2)) == (MMX | MMX_EXTENSIONS | SSE | SSE2);
   701 	initialized = TRUE;
   702     }
   704     return sse2_present;
   705 }
   707 #endif
   709 #else /* __amd64__ */
   710 #ifdef USE_X86_MMX
   711 #define pixman_have_mmx() TRUE
   712 #endif
   713 #ifdef USE_SSE2
   714 #define pixman_have_sse2() TRUE
   715 #endif
   716 #endif /* __amd64__ */
   717 #endif
   719 static pixman_bool_t
   720 disabled (const char *name)
   721 {
   722     const char *env;
   724     if ((env = getenv ("PIXMAN_DISABLE")))
   725     {
   726 	do
   727 	{
   728 	    const char *end;
   729 	    int len;
   731 	    if ((end = strchr (env, ' ')))
   732 		len = end - env;
   733 	    else
   734 		len = strlen (env);
   736 	    if (strlen (name) == len && strncmp (name, env, len) == 0)
   737 	    {
   738 		printf ("pixman: Disabled %s implementation\n", name);
   739 		return TRUE;
   740 	    }
   742 	    env += len;
   743 	}
   744 	while (*env++);
   745     }
   747     return FALSE;
   748 }
   750 pixman_implementation_t *
   751 _pixman_choose_implementation (void)
   752 {
   753     pixman_implementation_t *imp;
   755     imp = _pixman_implementation_create_general();
   757     if (!disabled ("fast"))
   758 	imp = _pixman_implementation_create_fast_path (imp);
   760 #ifdef USE_X86_MMX
   761     if (!disabled ("mmx") && pixman_have_mmx ())
   762 	imp = _pixman_implementation_create_mmx (imp);
   763 #endif
   765 #ifdef USE_SSE2
   766     if (!disabled ("sse2") && pixman_have_sse2 ())
   767 	imp = _pixman_implementation_create_sse2 (imp);
   768 #endif
   770 #ifdef USE_ARM_SIMD
   771     if (!disabled ("arm-simd") && pixman_have_arm_simd ())
   772 	imp = _pixman_implementation_create_arm_simd (imp);
   773 #endif
   775 #ifdef USE_ARM_IWMMXT
   776     if (!disabled ("arm-iwmmxt") && pixman_have_arm_iwmmxt ())
   777 	imp = _pixman_implementation_create_mmx (imp);
   778 #endif
   780 #ifdef USE_ARM_NEON
   781     if (!disabled ("arm-neon") && pixman_have_arm_neon ())
   782 	imp = _pixman_implementation_create_arm_neon (imp);
   783 #endif
   785 #ifdef USE_MIPS_DSPR2
   786     if (!disabled ("mips-dspr2") && pixman_have_mips_dspr2 ())
   787 	imp = _pixman_implementation_create_mips_dspr2 (imp);
   788 #endif
   790 #ifdef USE_VMX
   791     if (!disabled ("vmx") && pixman_have_vmx ())
   792 	imp = _pixman_implementation_create_vmx (imp);
   793 #endif
   795     imp = _pixman_implementation_create_noop (imp);
   797     return imp;
   798 }

mercurial