Coverage Report

Created: 2025-07-07 10:01

/work/workdir/UnpackedTarball/pixman/pixman/pixman-ppc.c
Line
Count
Source
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
25
26
#include "pixman-private.h"
27
28
#ifdef USE_VMX
29
30
/* The CPU detection code needs to be in a file not compiled with
31
 * "-maltivec -mabi=altivec", as gcc would try to save vector register
32
 * across function calls causing SIGILL on cpus without Altivec/vmx.
33
 */
34
#ifdef __APPLE__
35
#include <sys/sysctl.h>
36
37
static pixman_bool_t
38
pixman_have_vmx (void)
39
{
40
    int error, have_vmx;
41
    size_t length = sizeof(have_vmx);
42
43
    error = sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
44
45
    if (error)
46
  return FALSE;
47
48
    return have_vmx;
49
}
50
51
#elif defined (__OpenBSD__)
52
#include <sys/param.h>
53
#include <sys/sysctl.h>
54
#include <machine/cpu.h>
55
56
static pixman_bool_t
57
pixman_have_vmx (void)
58
{
59
    int error, have_vmx;
60
    int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
61
    size_t length = sizeof(have_vmx);
62
63
    error = sysctl (mib, 2, &have_vmx, &length, NULL, 0);
64
65
    if (error != 0)
66
  return FALSE;
67
68
    return have_vmx;
69
}
70
71
#elif defined (__FreeBSD__)
72
#include <machine/cpu.h>
73
#include <sys/auxv.h>
74
75
static pixman_bool_t
76
pixman_have_vmx (void)
77
{
78
79
    unsigned long cpufeatures;
80
    int have_vmx;
81
82
    if (elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)))
83
    return FALSE;
84
85
    have_vmx = cpufeatures & PPC_FEATURE_HAS_ALTIVEC;
86
    return have_vmx;
87
}
88
89
#elif defined (__linux__)
90
91
#include <sys/types.h>
92
#include <sys/stat.h>
93
#include <fcntl.h>
94
#include <unistd.h>
95
#include <stdio.h>
96
#include <linux/auxvec.h>
97
#include <asm/cputable.h>
98
99
static pixman_bool_t
100
pixman_have_vmx (void)
101
{
102
    int have_vmx = FALSE;
103
    int fd;
104
    struct
105
    {
106
  unsigned long type;
107
  unsigned long value;
108
    } aux;
109
110
    fd = open ("/proc/self/auxv", O_RDONLY);
111
    if (fd >= 0)
112
    {
113
  while (read (fd, &aux, sizeof (aux)) == sizeof (aux))
114
  {
115
      if (aux.type == AT_HWCAP && (aux.value & PPC_FEATURE_HAS_ALTIVEC))
116
      {
117
    have_vmx = TRUE;
118
    break;
119
      }
120
  }
121
122
  close (fd);
123
    }
124
125
    return have_vmx;
126
}
127
128
#else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
129
#include <signal.h>
130
#include <setjmp.h>
131
132
static jmp_buf jump_env;
133
134
static void
135
vmx_test (int        sig,
136
    siginfo_t *si,
137
    void *     unused)
138
{
139
    longjmp (jump_env, 1);
140
}
141
142
static pixman_bool_t
143
pixman_have_vmx (void)
144
{
145
    struct sigaction sa, osa;
146
    int jmp_result;
147
148
    sa.sa_flags = SA_SIGINFO;
149
    sigemptyset (&sa.sa_mask);
150
    sa.sa_sigaction = vmx_test;
151
    sigaction (SIGILL, &sa, &osa);
152
    jmp_result = setjmp (jump_env);
153
    if (jmp_result == 0)
154
    {
155
  asm volatile ( "vor 0, 0, 0" );
156
    }
157
    sigaction (SIGILL, &osa, NULL);
158
    return (jmp_result == 0);
159
}
160
161
#endif /* __APPLE__ */
162
#endif /* USE_VMX */
163
164
pixman_implementation_t *
165
_pixman_ppc_get_implementations (pixman_implementation_t *imp)
166
108
{
167
#ifdef USE_VMX
168
    if (!_pixman_disabled ("vmx") && pixman_have_vmx ())
169
  imp = _pixman_implementation_create_vmx (imp);
170
#endif
171
172
108
    return imp;
173
108
}