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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 * Copyright © 2000 SuSE, Inc.
michael@0 3 * Copyright © 2007 Red Hat, Inc.
michael@0 4 *
michael@0 5 * Permission to use, copy, modify, distribute, and sell this software and its
michael@0 6 * documentation for any purpose is hereby granted without fee, provided that
michael@0 7 * the above copyright notice appear in all copies and that both that
michael@0 8 * copyright notice and this permission notice appear in supporting
michael@0 9 * documentation, and that the name of SuSE not be used in advertising or
michael@0 10 * publicity pertaining to distribution of the software without specific,
michael@0 11 * written prior permission. SuSE makes no representations about the
michael@0 12 * suitability of this software for any purpose. It is provided "as is"
michael@0 13 * without express or implied warranty.
michael@0 14 *
michael@0 15 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
michael@0 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
michael@0 17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
michael@0 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
michael@0 19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
michael@0 20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
michael@0 21 */
michael@0 22 #ifdef HAVE_CONFIG_H
michael@0 23 #include <config.h>
michael@0 24 #endif
michael@0 25
michael@0 26 #include "pixman-private.h"
michael@0 27
michael@0 28 #ifdef USE_VMX
michael@0 29
michael@0 30 /* The CPU detection code needs to be in a file not compiled with
michael@0 31 * "-maltivec -mabi=altivec", as gcc would try to save vector register
michael@0 32 * across function calls causing SIGILL on cpus without Altivec/vmx.
michael@0 33 */
michael@0 34 #ifdef __APPLE__
michael@0 35 #include <sys/sysctl.h>
michael@0 36
michael@0 37 static pixman_bool_t
michael@0 38 pixman_have_vmx (void)
michael@0 39 {
michael@0 40 int error, have_vmx;
michael@0 41 size_t length = sizeof(have_vmx);
michael@0 42
michael@0 43 error = sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
michael@0 44
michael@0 45 if (error)
michael@0 46 return FALSE;
michael@0 47
michael@0 48 return have_vmx;
michael@0 49 }
michael@0 50
michael@0 51 #elif defined (__OpenBSD__)
michael@0 52 #include <sys/param.h>
michael@0 53 #include <sys/sysctl.h>
michael@0 54 #include <machine/cpu.h>
michael@0 55
michael@0 56 static pixman_bool_t
michael@0 57 pixman_have_vmx (void)
michael@0 58 {
michael@0 59 int error, have_vmx;
michael@0 60 int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
michael@0 61 size_t length = sizeof(have_vmx);
michael@0 62
michael@0 63 error = sysctl (mib, 2, &have_vmx, &length, NULL, 0);
michael@0 64
michael@0 65 if (error != 0)
michael@0 66 return FALSE;
michael@0 67
michael@0 68 return have_vmx;
michael@0 69 }
michael@0 70
michael@0 71 #elif defined (__linux__)
michael@0 72
michael@0 73 #include <sys/types.h>
michael@0 74 #include <sys/stat.h>
michael@0 75 #include <fcntl.h>
michael@0 76 #include <unistd.h>
michael@0 77 #include <stdio.h>
michael@0 78 #include <linux/auxvec.h>
michael@0 79 #include <asm/cputable.h>
michael@0 80
michael@0 81 static pixman_bool_t
michael@0 82 pixman_have_vmx (void)
michael@0 83 {
michael@0 84 int have_vmx = FALSE;
michael@0 85 int fd;
michael@0 86 struct
michael@0 87 {
michael@0 88 unsigned long type;
michael@0 89 unsigned long value;
michael@0 90 } aux;
michael@0 91
michael@0 92 fd = open ("/proc/self/auxv", O_RDONLY);
michael@0 93 if (fd >= 0)
michael@0 94 {
michael@0 95 while (read (fd, &aux, sizeof (aux)) == sizeof (aux))
michael@0 96 {
michael@0 97 if (aux.type == AT_HWCAP && (aux.value & PPC_FEATURE_HAS_ALTIVEC))
michael@0 98 {
michael@0 99 have_vmx = TRUE;
michael@0 100 break;
michael@0 101 }
michael@0 102 }
michael@0 103
michael@0 104 close (fd);
michael@0 105 }
michael@0 106
michael@0 107 return have_vmx;
michael@0 108 }
michael@0 109
michael@0 110 #else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
michael@0 111 #include <signal.h>
michael@0 112 #include <setjmp.h>
michael@0 113
michael@0 114 static jmp_buf jump_env;
michael@0 115
michael@0 116 static void
michael@0 117 vmx_test (int sig,
michael@0 118 siginfo_t *si,
michael@0 119 void * unused)
michael@0 120 {
michael@0 121 longjmp (jump_env, 1);
michael@0 122 }
michael@0 123
michael@0 124 static pixman_bool_t
michael@0 125 pixman_have_vmx (void)
michael@0 126 {
michael@0 127 struct sigaction sa, osa;
michael@0 128 int jmp_result;
michael@0 129
michael@0 130 sa.sa_flags = SA_SIGINFO;
michael@0 131 sigemptyset (&sa.sa_mask);
michael@0 132 sa.sa_sigaction = vmx_test;
michael@0 133 sigaction (SIGILL, &sa, &osa);
michael@0 134 jmp_result = setjmp (jump_env);
michael@0 135 if (jmp_result == 0)
michael@0 136 {
michael@0 137 asm volatile ( "vor 0, 0, 0" );
michael@0 138 }
michael@0 139 sigaction (SIGILL, &osa, NULL);
michael@0 140 return (jmp_result == 0);
michael@0 141 }
michael@0 142
michael@0 143 #endif /* __APPLE__ */
michael@0 144 #endif /* USE_VMX */
michael@0 145
michael@0 146 pixman_implementation_t *
michael@0 147 _pixman_ppc_get_implementations (pixman_implementation_t *imp)
michael@0 148 {
michael@0 149 #ifdef USE_VMX
michael@0 150 if (!_pixman_disabled ("vmx") && pixman_have_vmx ())
michael@0 151 imp = _pixman_implementation_create_vmx (imp);
michael@0 152 #endif
michael@0 153
michael@0 154 return imp;
michael@0 155 }

mercurial