Change the translation of the "Help" menu item to "?", so that the menu can be displa...
[reactos.git] / rosapps / smartpdf / fitz / base / base_cpudep.c
1 /*
2 run-time cpu feature detection code
3 mm, alphabet soup...
4
5 Glenn Kennard <d98gk@efd.lth.se>
6 */
7
8 #include "fitz-base.h"
9
10 /* global run-time constant */
11 unsigned fz_cpuflags = 0;
12
13 #ifndef HAVE_CPUDEP
14
15 void fz_accelerate(void)
16 {
17 }
18
19 void fz_cpudetect(void)
20 {
21 }
22
23 #else
24
25 #include <signal.h> /* signal/sigaction */
26 #include <setjmp.h> /* sigsetjmp/siglongjmp */
27
28 #ifdef WIN32
29 #define sigjmp_buf jmp_buf
30 #define sigsetjmp(a,b) setjmp(a)
31 #define siglongjmp longjmp
32 #endif
33
34 typedef struct {
35 void (*test)(void);
36 const unsigned flag;
37 const char *name;
38 } featuretest;
39
40
41 #if defined(ARCH_X86) || defined(ARCH_X86_64)
42
43 /* need emms?? */
44 static void mmx(void)
45 { __asm__ ("pand %mm0, %mm0\n\t"); }
46
47 static void m3dnow(void)
48 { __asm__ ("pavgusb %mm0, %mm0\n\t"); }
49
50 static void mmxext(void) /* aka Extended 3DNow! */
51 { __asm__ ("pmaxsw %mm0, %mm0\n\t"); }
52
53 static void sse(void)
54 { __asm__ ("andps %xmm0, %xmm0\n\t"); }
55
56 static void sse2(void)
57 { __asm__ ("andpd %xmm0, %xmm0\n\t"); }
58
59 /* static void sse3(void) */
60 /* { __asm__ ("haddps %%xmm0, %%xmm0\n\t" : : : "%xmm0"); } */
61
62 #ifdef ARCH_X86_64
63 static void amd64(void)
64 { __asm__ ("and %rax, %rax\n\t"); }
65 #endif
66
67
68 static const featuretest features[] = {
69 { mmx, HAVE_MMX, "mmx" },
70 { m3dnow, HAVE_3DNOW, "3dnow" },
71 { mmxext, HAVE_MMXEXT, "mmxext" },
72 { sse, HAVE_SSE, "sse" },
73 { sse2, HAVE_SSE2, "sse2" },
74 /* { sse3, HAVE_SSE3, "sse3" }, */
75 #ifdef ARCH_X86_64
76 { amd64, HAVE_AMD64, "amd64" }
77 #endif
78 };
79
80 #endif
81
82
83 #if defined(ARCH_SPARC)
84 /* assembler must have -xarch=v8plusa passed to it (v9a for 64 bit binaries) */
85 static void vis(void)
86 { __asm__ ("fand %f8, %f8, %f8\n\t"); }
87
88 static const featuretest features[] = {
89 { vis, HAVE_VIS, "vis" }
90 };
91
92 #endif
93
94
95 #if defined(ARCH_PPC)
96
97 static void altivec(void)
98 { __asm__ ("vand v0, v0, v0\n\t"); }
99
100
101 static const featuretest features[] = {
102 { altivec, HAVE_ALTIVEC, "altivec" },
103 };
104
105 #endif
106
107 static sigjmp_buf jmpbuf;
108 static volatile sig_atomic_t canjump;
109
110 static void
111 sigillhandler(int sig)
112 {
113 if (!canjump) {
114 signal(sig, SIG_DFL);
115 raise(sig);
116 }
117
118 canjump = 0;
119 siglongjmp(jmpbuf, 1);
120 }
121
122 static int
123 enabled(char *env, const char *ext)
124 {
125 int len;
126 char *s;
127 if (!env)
128 return 1;
129 len = strlen(ext);
130 while ((s = strstr(env, ext)))
131 {
132 s += len;
133 if (*s == ' ' || *s == ',' || *s == '\0')
134 return 1;
135 }
136 return 0;
137 }
138
139 static void
140 dumpflags(void)
141 {
142 unsigned f = fz_cpuflags;
143 int i, n;
144
145 fputs("detected cpu features:", stdout);
146 n = 0;
147 for (i = 0; i < sizeof(features) / sizeof(featuretest); i++)
148 {
149 if (f & features[i].flag)
150 {
151 fputc(' ', stdout);
152 fputs(features[i].name, stdout);
153 n ++;
154 }
155 }
156 if (!n)
157 fputs(" none", stdout);
158 fputc('\n', stdout);
159 }
160
161 void fz_cpudetect(void)
162 {
163 static int hasrun = 0;
164
165 unsigned flags = 0;
166 int i;
167 void (*oldhandler)(int) = NULL;
168 void (*tmphandler)(int);
169 char *env;
170
171 if (hasrun)
172 return;
173 hasrun = 1;
174
175 env = getenv("CPUACCEL");
176
177 for (i = 0; i < sizeof(features) / sizeof(featuretest); i++)
178 {
179 canjump = 0;
180
181 tmphandler = signal(SIGILL, sigillhandler);
182 if (!oldhandler)
183 oldhandler = tmphandler;
184
185 if (sigsetjmp(jmpbuf, 1))
186 {
187 /* test failed - disable feature */
188 flags &= ~features[i].flag;
189 continue;
190 }
191
192 canjump = 1;
193
194 features[i].test();
195
196 /* if we got here the test succeeded */
197 if (enabled(env, features[i].name))
198 flags |= features[i].flag;
199 else
200 flags &= ~features[i].flag;
201 }
202
203 /* restore previous signal handler */
204 signal(SIGILL, oldhandler);
205
206 fz_cpuflags = flags;
207
208 #if defined(ARCH_X86) || defined(ARCH_X86_64)
209 __asm__ __volatile__ ("emms\n\t");
210 #endif
211
212 dumpflags();
213 }
214
215 static __attribute__((constructor, used)) void fzcpudetect(void)
216 {
217 fz_cpudetect();
218 }
219
220 #endif
221