Skip to content

Latest commit

 

History

History
634 lines (581 loc) · 18.3 KB

SDL_cpuinfo.c

File metadata and controls

634 lines (581 loc) · 18.3 KB
 
1
2
/*
SDL - Simple DirectMedia Layer
Dec 31, 2011
Dec 31, 2011
3
Copyright (C) 1997-2012 Sam Lantinga
4
5
This library is free software; you can redistribute it and/or
Feb 1, 2006
Feb 1, 2006
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
Feb 1, 2006
Feb 1, 2006
8
version 2.1 of the License, or (at your option) any later version.
9
10
11
12
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Feb 1, 2006
Feb 1, 2006
13
Lesser General Public License for more details.
Feb 1, 2006
Feb 1, 2006
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
20
21
Sam Lantinga
slouken@libsdl.org
*/
Feb 21, 2006
Feb 21, 2006
22
#include "SDL_config.h"
23
24
25
/* CPU feature detection for SDL */
Feb 16, 2006
Feb 16, 2006
26
27
28
#include "SDL.h"
#include "SDL_cpuinfo.h"
Dec 2, 2009
Dec 2, 2009
29
#if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))
Jan 6, 2004
Jan 6, 2004
30
#include <sys/sysctl.h> /* For AltiVec check */
Jul 18, 2012
Jul 18, 2012
31
32
33
34
#elif defined(__OpenBSD__) && defined(__powerpc__)
#include <sys/param.h>
#include <sys/sysctl.h> /* For AltiVec check */
#include <machine/cpu.h>
Mar 9, 2006
Mar 9, 2006
35
36
37
#elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
#include <signal.h>
#include <setjmp.h>
Jan 6, 2004
Jan 6, 2004
38
39
#endif
Nov 24, 2003
Nov 24, 2003
40
41
#define CPU_HAS_RDTSC 0x00000001
#define CPU_HAS_MMX 0x00000002
Jan 24, 2004
Jan 24, 2004
42
43
44
45
46
47
#define CPU_HAS_MMXEXT 0x00000004
#define CPU_HAS_3DNOW 0x00000010
#define CPU_HAS_3DNOWEXT 0x00000020
#define CPU_HAS_SSE 0x00000040
#define CPU_HAS_SSE2 0x00000080
#define CPU_HAS_ALTIVEC 0x00000100
Oct 31, 2019
Oct 31, 2019
48
#define CPU_HAS_ARM_SIMD 0x00000200
Oct 31, 2019
Oct 31, 2019
49
#define CPU_HAS_ARM_NEON 0x00000400
Jul 18, 2012
Jul 18, 2012
51
#if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
Jan 29, 2004
Jan 29, 2004
52
53
54
55
56
57
58
59
/* This is the brute force way of detecting instruction sets...
the idea is borrowed from the libmpeg2 library - thanks!
*/
static jmp_buf jmpbuf;
static void illegal_instruction(int sig)
{
longjmp(jmpbuf, 1);
}
Feb 16, 2006
Feb 16, 2006
60
#endif /* HAVE_SETJMP */
Jan 29, 2004
Jan 29, 2004
61
Feb 24, 2006
Feb 24, 2006
62
static __inline__ int CPU_haveCPUID(void)
Nov 24, 2003
Nov 24, 2003
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{
int has_CPUID = 0;
#if defined(__GNUC__) && defined(i386)
__asm__ (
" pushfl # Get original EFLAGS \n"
" popl %%eax \n"
" movl %%eax,%%ecx \n"
" xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
" pushl %%eax # Save new EFLAGS value on stack \n"
" popfl # Replace current EFLAGS value \n"
" pushfl # Get new EFLAGS \n"
" popl %%eax # Store new EFLAGS in EAX \n"
" xorl %%ecx,%%eax # Can not toggle ID bit, \n"
" jz 1f # Processor=80486 \n"
" movl $1,%0 # We have CPUID support \n"
"1: \n"
Jan 17, 2004
Jan 17, 2004
79
: "=m" (has_CPUID)
Nov 24, 2003
Nov 24, 2003
80
81
82
:
: "%eax", "%ecx"
);
Apr 11, 2004
Apr 11, 2004
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#elif defined(__GNUC__) && defined(__x86_64__)
/* Technically, if this is being compiled under __x86_64__ then it has
CPUid by definition. But it's nice to be able to prove it. :) */
__asm__ (
" pushfq # Get original EFLAGS \n"
" popq %%rax \n"
" movq %%rax,%%rcx \n"
" xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
" pushq %%rax # Save new EFLAGS value on stack \n"
" popfq # Replace current EFLAGS value \n"
" pushfq # Get new EFLAGS \n"
" popq %%rax # Store new EFLAGS in EAX \n"
" xorl %%ecx,%%eax # Can not toggle ID bit, \n"
" jz 1f # Processor=80486 \n"
" movl $1,%0 # We have CPUID support \n"
"1: \n"
: "=m" (has_CPUID)
:
: "%rax", "%rcx"
);
Feb 26, 2006
Feb 26, 2006
103
#elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
Nov 24, 2003
Nov 24, 2003
104
__asm {
Nov 24, 2003
Nov 24, 2003
105
106
107
108
109
110
111
112
113
114
115
116
117
pushfd ; Get original EFLAGS
pop eax
mov ecx, eax
xor eax, 200000h ; Flip ID bit in EFLAGS
push eax ; Save new EFLAGS value on stack
popfd ; Replace current EFLAGS value
pushfd ; Get new EFLAGS
pop eax ; Store new EFLAGS in EAX
xor eax, ecx ; Can not toggle ID bit,
jz done ; Processor=80486
mov has_CPUID,1 ; We have CPUID support
done:
}
Jun 20, 2006
Jun 20, 2006
118
#elif defined(__sun) && defined(__i386)
Feb 16, 2006
Feb 16, 2006
119
__asm (
Jan 5, 2006
Jan 5, 2006
120
" pushfl \n"
Feb 16, 2006
Feb 16, 2006
121
122
123
124
125
126
127
128
129
130
" popl %eax \n"
" movl %eax,%ecx \n"
" xorl $0x200000,%eax \n"
" pushl %eax \n"
" popfl \n"
" pushfl \n"
" popl %eax \n"
" xorl %ecx,%eax \n"
" jz 1f \n"
" movl $1,-8(%ebp) \n"
Jan 5, 2006
Jan 5, 2006
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"1: \n"
);
#elif defined(__sun) && defined(__amd64)
__asm (
" pushfq \n"
" popq %rax \n"
" movq %rax,%rcx \n"
" xorl $0x200000,%eax \n"
" pushq %rax \n"
" popfq \n"
" pushfq \n"
" popq %rax \n"
" xorl %ecx,%eax \n"
" jz 1f \n"
" movl $1,-8(%rbp) \n"
"1: \n"
);
Nov 24, 2003
Nov 24, 2003
148
149
150
151
#endif
return has_CPUID;
}
Feb 24, 2006
Feb 24, 2006
152
static __inline__ int CPU_getCPUIDFeatures(void)
Nov 24, 2003
Nov 24, 2003
153
154
{
int features = 0;
Jul 1, 2009
Jul 1, 2009
155
#if defined(__GNUC__) && defined(i386)
Nov 24, 2003
Nov 24, 2003
156
157
__asm__ (
" xorl %%eax,%%eax # Set up for CPUID instruction \n"
Dec 2, 2009
Dec 2, 2009
158
" pushl %%ebx \n"
Nov 24, 2003
Nov 24, 2003
159
" cpuid # Get and save vendor ID \n"
Dec 3, 2009
Dec 3, 2009
160
" popl %%ebx \n"
Nov 24, 2003
Nov 24, 2003
161
162
163
164
" cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n"
" jl 1f # We dont have the CPUID instruction\n"
" xorl %%eax,%%eax \n"
" incl %%eax \n"
Dec 3, 2009
Dec 3, 2009
165
" pushl %%ebx \n"
Nov 24, 2003
Nov 24, 2003
166
" cpuid # Get family/model/stepping/features\n"
Dec 2, 2009
Dec 2, 2009
167
" popl %%ebx \n"
Nov 24, 2003
Nov 24, 2003
168
169
" movl %%edx,%0 \n"
"1: \n"
Jan 17, 2004
Jan 17, 2004
170
: "=m" (features)
Nov 24, 2003
Nov 24, 2003
171
:
Nov 1, 2009
Nov 1, 2009
172
: "%eax", "%ecx", "%edx"
Nov 24, 2003
Nov 24, 2003
173
);
Jul 1, 2009
Jul 1, 2009
174
175
176
#elif defined(__GNUC__) && defined(__x86_64__)
__asm__ (
" xorl %%eax,%%eax # Set up for CPUID instruction \n"
Dec 3, 2009
Dec 3, 2009
177
" pushq %%rbx \n"
Jul 1, 2009
Jul 1, 2009
178
" cpuid # Get and save vendor ID \n"
Dec 3, 2009
Dec 3, 2009
179
" popq %%rbx \n"
Jul 1, 2009
Jul 1, 2009
180
181
182
183
" cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n"
" jl 1f # We dont have the CPUID instruction\n"
" xorl %%eax,%%eax \n"
" incl %%eax \n"
Dec 3, 2009
Dec 3, 2009
184
" pushq %%rbx \n"
Jul 1, 2009
Jul 1, 2009
185
" cpuid # Get family/model/stepping/features\n"
Dec 3, 2009
Dec 3, 2009
186
" popq %%rbx \n"
Jul 1, 2009
Jul 1, 2009
187
188
189
190
" movl %%edx,%0 \n"
"1: \n"
: "=m" (features)
:
Nov 1, 2009
Nov 1, 2009
191
: "%rax", "%rcx", "%rdx"
Jul 1, 2009
Jul 1, 2009
192
);
Feb 26, 2006
Feb 26, 2006
193
#elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
Nov 24, 2003
Nov 24, 2003
194
__asm {
Nov 24, 2003
Nov 24, 2003
195
xor eax, eax ; Set up for CPUID instruction
Dec 2, 2009
Dec 2, 2009
196
push ebx
Nov 24, 2003
Nov 24, 2003
197
cpuid ; Get and save vendor ID
Dec 3, 2009
Dec 3, 2009
198
pop ebx
Nov 24, 2003
Nov 24, 2003
199
200
201
202
cmp eax, 1 ; Make sure 1 is valid input for CPUID
jl done ; We dont have the CPUID instruction
xor eax, eax
inc eax
Dec 3, 2009
Dec 3, 2009
203
push ebx
Nov 24, 2003
Nov 24, 2003
204
cpuid ; Get family/model/stepping/features
Dec 2, 2009
Dec 2, 2009
205
pop ebx
Nov 24, 2003
Nov 24, 2003
206
207
208
mov features, edx
done:
}
Jun 20, 2006
Jun 20, 2006
209
#elif defined(__sun) && (defined(__i386) || defined(__amd64))
Jan 5, 2006
Jan 5, 2006
210
211
__asm(
" xorl %eax,%eax \n"
Dec 2, 2009
Dec 2, 2009
212
" pushl %ebx \n"
Jan 5, 2006
Jan 5, 2006
213
" cpuid \n"
Dec 3, 2009
Dec 3, 2009
214
" popl %ebx \n"
Jan 5, 2006
Jan 5, 2006
215
216
217
218
" cmpl $1,%eax \n"
" jl 1f \n"
" xorl %eax,%eax \n"
" incl %eax \n"
Dec 3, 2009
Dec 3, 2009
219
" pushl %ebx \n"
Jan 5, 2006
Jan 5, 2006
220
" cpuid \n"
Dec 2, 2009
Dec 2, 2009
221
" popl %ebx \n"
Jan 5, 2006
Jan 5, 2006
222
223
224
225
226
227
#ifdef __i386
" movl %edx,-8(%ebp) \n"
#else
" movl %edx,-8(%rbp) \n"
#endif
"1: \n"
Feb 19, 2013
Feb 19, 2013
228
);
Nov 24, 2003
Nov 24, 2003
229
230
231
232
#endif
return features;
}
Feb 24, 2006
Feb 24, 2006
233
static __inline__ int CPU_getCPUIDFeaturesExt(void)
Nov 24, 2003
Nov 24, 2003
234
{
Jan 24, 2004
Jan 24, 2004
235
int features = 0;
Jul 1, 2009
Jul 1, 2009
236
#if defined(__GNUC__) && defined(i386)
Nov 24, 2003
Nov 24, 2003
237
238
__asm__ (
" movl $0x80000000,%%eax # Query for extended functions \n"
Dec 2, 2009
Dec 2, 2009
239
" pushl %%ebx \n"
Nov 24, 2003
Nov 24, 2003
240
" cpuid # Get extended function limit \n"
Dec 3, 2009
Dec 3, 2009
241
" popl %%ebx \n"
Nov 24, 2003
Nov 24, 2003
242
" cmpl $0x80000001,%%eax \n"
Jan 24, 2004
Jan 24, 2004
243
" jl 1f # Nope, we dont have function 800000001h\n"
Nov 24, 2003
Nov 24, 2003
244
" movl $0x80000001,%%eax # Setup extended function 800000001h\n"
Dec 3, 2009
Dec 3, 2009
245
" pushl %%ebx \n"
Nov 24, 2003
Nov 24, 2003
246
" cpuid # and get the information \n"
Dec 2, 2009
Dec 2, 2009
247
" popl %%ebx \n"
Jan 24, 2004
Jan 24, 2004
248
" movl %%edx,%0 \n"
Nov 24, 2003
Nov 24, 2003
249
"1: \n"
Jan 24, 2004
Jan 24, 2004
250
: "=m" (features)
Nov 24, 2003
Nov 24, 2003
251
:
Nov 1, 2009
Nov 1, 2009
252
: "%eax", "%ecx", "%edx"
Nov 24, 2003
Nov 24, 2003
253
);
Jul 1, 2009
Jul 1, 2009
254
255
256
#elif defined(__GNUC__) && defined (__x86_64__)
__asm__ (
" movl $0x80000000,%%eax # Query for extended functions \n"
Dec 2, 2009
Dec 2, 2009
257
" pushq %%rbx \n"
Jul 1, 2009
Jul 1, 2009
258
" cpuid # Get extended function limit \n"
Dec 3, 2009
Dec 3, 2009
259
" popq %%rbx \n"
Jul 1, 2009
Jul 1, 2009
260
261
262
" cmpl $0x80000001,%%eax \n"
" jl 1f # Nope, we dont have function 800000001h\n"
" movl $0x80000001,%%eax # Setup extended function 800000001h\n"
Dec 3, 2009
Dec 3, 2009
263
" pushq %%rbx \n"
Jul 1, 2009
Jul 1, 2009
264
" cpuid # and get the information \n"
Dec 2, 2009
Dec 2, 2009
265
" popq %%rbx \n"
Jul 1, 2009
Jul 1, 2009
266
267
268
269
" movl %%edx,%0 \n"
"1: \n"
: "=m" (features)
:
Nov 1, 2009
Nov 1, 2009
270
: "%rax", "%rcx", "%rdx"
Jul 1, 2009
Jul 1, 2009
271
);
Feb 26, 2006
Feb 26, 2006
272
#elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
Nov 24, 2003
Nov 24, 2003
273
__asm {
Nov 24, 2003
Nov 24, 2003
274
mov eax,80000000h ; Query for extended functions
Dec 2, 2009
Dec 2, 2009
275
push ebx
Nov 24, 2003
Nov 24, 2003
276
cpuid ; Get extended function limit
Dec 3, 2009
Dec 3, 2009
277
pop ebx
Nov 24, 2003
Nov 24, 2003
278
cmp eax,80000001h
Jan 24, 2004
Jan 24, 2004
279
jl done ; Nope, we dont have function 800000001h
Nov 24, 2003
Nov 24, 2003
280
mov eax,80000001h ; Setup extended function 800000001h
Dec 3, 2009
Dec 3, 2009
281
push ebx
Nov 24, 2003
Nov 24, 2003
282
cpuid ; and get the information
Dec 2, 2009
Dec 2, 2009
283
pop ebx
Jan 24, 2004
Jan 24, 2004
284
mov features,edx
Nov 24, 2003
Nov 24, 2003
285
286
done:
}
Jan 5, 2006
Jan 5, 2006
287
288
289
#elif defined(__sun) && ( defined(__i386) || defined(__amd64) )
__asm (
" movl $0x80000000,%eax \n"
Dec 2, 2009
Dec 2, 2009
290
" pushl %ebx \n"
Jan 5, 2006
Jan 5, 2006
291
" cpuid \n"
Dec 3, 2009
Dec 3, 2009
292
" popl %ebx \n"
Jan 5, 2006
Jan 5, 2006
293
294
295
" cmpl $0x80000001,%eax \n"
" jl 1f \n"
" movl $0x80000001,%eax \n"
Dec 3, 2009
Dec 3, 2009
296
" pushl %ebx \n"
Jan 5, 2006
Jan 5, 2006
297
" cpuid \n"
Dec 2, 2009
Dec 2, 2009
298
" popl %ebx \n"
Jan 5, 2006
Jan 5, 2006
299
300
301
302
303
304
305
#ifdef __i386
" movl %edx,-8(%ebp) \n"
#else
" movl %edx,-8(%rbp) \n"
#endif
"1: \n"
);
Nov 24, 2003
Nov 24, 2003
306
#endif
Jan 24, 2004
Jan 24, 2004
307
308
309
return features;
}
Feb 24, 2006
Feb 24, 2006
310
static __inline__ int CPU_haveRDTSC(void)
Jan 24, 2004
Jan 24, 2004
311
312
313
314
315
316
317
{
if ( CPU_haveCPUID() ) {
return (CPU_getCPUIDFeatures() & 0x00000010);
}
return 0;
}
Feb 24, 2006
Feb 24, 2006
318
static __inline__ int CPU_haveMMX(void)
Jan 24, 2004
Jan 24, 2004
319
320
321
322
323
324
325
{
if ( CPU_haveCPUID() ) {
return (CPU_getCPUIDFeatures() & 0x00800000);
}
return 0;
}
Feb 24, 2006
Feb 24, 2006
326
static __inline__ int CPU_haveMMXExt(void)
Jan 24, 2004
Jan 24, 2004
327
328
329
330
331
332
333
{
if ( CPU_haveCPUID() ) {
return (CPU_getCPUIDFeaturesExt() & 0x00400000);
}
return 0;
}
Feb 24, 2006
Feb 24, 2006
334
static __inline__ int CPU_have3DNow(void)
Jan 24, 2004
Jan 24, 2004
335
336
337
338
339
340
341
{
if ( CPU_haveCPUID() ) {
return (CPU_getCPUIDFeaturesExt() & 0x80000000);
}
return 0;
}
Feb 24, 2006
Feb 24, 2006
342
static __inline__ int CPU_have3DNowExt(void)
Jan 24, 2004
Jan 24, 2004
343
344
345
346
347
{
if ( CPU_haveCPUID() ) {
return (CPU_getCPUIDFeaturesExt() & 0x40000000);
}
return 0;
Nov 24, 2003
Nov 24, 2003
348
349
}
Feb 24, 2006
Feb 24, 2006
350
static __inline__ int CPU_haveSSE(void)
Nov 24, 2003
Nov 24, 2003
351
352
353
354
355
356
{
if ( CPU_haveCPUID() ) {
return (CPU_getCPUIDFeatures() & 0x02000000);
}
return 0;
}
Feb 24, 2006
Feb 24, 2006
358
static __inline__ int CPU_haveSSE2(void)
Jan 24, 2004
Jan 24, 2004
359
360
361
362
363
364
365
{
if ( CPU_haveCPUID() ) {
return (CPU_getCPUIDFeatures() & 0x04000000);
}
return 0;
}
Feb 24, 2006
Feb 24, 2006
366
static __inline__ int CPU_haveAltiVec(void)
Jan 6, 2004
Jan 6, 2004
367
{
Jan 31, 2004
Jan 31, 2004
368
volatile int altivec = 0;
Jul 18, 2012
Jul 18, 2012
369
370
371
372
373
374
#if (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__))
# ifdef __OpenBSD__
int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
# else
int selectors[2] = { CTL_HW, HW_VECTORUNIT };
# endif
Jan 6, 2004
Jan 6, 2004
375
376
377
378
int hasVectorUnit = 0;
size_t length = sizeof(hasVectorUnit);
int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0);
if( 0 == error )
Jan 29, 2004
Jan 29, 2004
379
altivec = (hasVectorUnit != 0);
Feb 16, 2006
Feb 16, 2006
380
#elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
Jan 29, 2004
Jan 29, 2004
381
382
383
384
385
386
387
388
389
390
void (*handler)(int sig);
handler = signal(SIGILL, illegal_instruction);
if ( setjmp(jmpbuf) == 0 ) {
asm volatile ("mtspr 256, %0\n\t"
"vand %%v0, %%v0, %%v0"
:
: "r" (-1));
altivec = 1;
}
signal(SIGILL, handler);
Jan 6, 2004
Jan 6, 2004
391
#endif
Jan 29, 2004
Jan 29, 2004
392
return altivec;
Jan 6, 2004
Jan 6, 2004
393
394
}
Oct 31, 2019
Oct 31, 2019
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
#ifdef __linux__
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <elf.h>
static __inline__ int CPU_haveARMSIMD(void)
{
int arm_simd = 0;
int fd;
fd = open("/proc/self/auxv", O_RDONLY);
if (fd >= 0)
{
Elf32_auxv_t aux;
while (read(fd, &aux, sizeof aux) == sizeof aux)
{
if (aux.a_type == AT_PLATFORM)
{
const char *plat = (const char *) aux.a_un.a_val;
arm_simd = strncmp(plat, "v6l", 3) == 0 ||
strncmp(plat, "v7l", 3) == 0;
}
}
close(fd);
}
return arm_simd;
}
Oct 31, 2019
Oct 31, 2019
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
static __inline__ int CPU_haveARMNEON(void)
{
int arm_neon = 0;
int fd;
fd = open("/proc/self/auxv", O_RDONLY);
if (fd >= 0)
{
Elf32_auxv_t aux;
while (read(fd, &aux, sizeof aux) == sizeof aux)
{
if (aux.a_type == AT_HWCAP)
arm_neon = (aux.a_un.a_val & 4096) != 0;
}
close(fd);
}
return arm_neon;
}
Jan 6, 2020
Jan 6, 2020
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
#elif defined(__RISCOS__)
#include <kernel.h>
#include <swis.h>
static __inline__ int CPU_haveARMSIMD(void)
{
_kernel_swi_regs regs;
regs.r[0] = 0;
if (_kernel_swi(OS_PlatformFeatures, &regs, &regs) != NULL)
return 0;
if (!(regs.r[0] & (1<<31)))
return 0;
regs.r[0] = 34;
regs.r[1] = 29;
if (_kernel_swi(OS_PlatformFeatures, &regs, &regs) != NULL)
return 0;
return regs.r[0];
}
static __inline__ int CPU_haveARMNEON(void)
{
/* Use the VFPSupport_Features SWI to access the MVFR registers */
_kernel_swi_regs regs;
regs.r[0] = 0;
if (_kernel_swi(VFPSupport_Features, &regs, &regs) == NULL) {
if ((regs.r[2] & 0xFFF000) == 0x111000) {
return 1;
}
}
return 0;
}
Oct 31, 2019
Oct 31, 2019
481
482
483
484
485
486
487
#else
static __inline__ int CPU_haveARMSIMD(void)
{
return 0;
}
Oct 31, 2019
Oct 31, 2019
488
489
490
491
492
static __inline__ int CPU_haveARMNEON(void)
{
return 0;
}
Oct 31, 2019
Oct 31, 2019
493
494
#endif
495
496
static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
Feb 24, 2006
Feb 24, 2006
497
static Uint32 SDL_GetCPUFeatures(void)
498
499
500
{
if ( SDL_CPUFeatures == 0xFFFFFFFF ) {
SDL_CPUFeatures = 0;
Nov 24, 2003
Nov 24, 2003
501
502
503
if ( CPU_haveRDTSC() ) {
SDL_CPUFeatures |= CPU_HAS_RDTSC;
}
504
505
506
if ( CPU_haveMMX() ) {
SDL_CPUFeatures |= CPU_HAS_MMX;
}
Jan 24, 2004
Jan 24, 2004
507
508
509
if ( CPU_haveMMXExt() ) {
SDL_CPUFeatures |= CPU_HAS_MMXEXT;
}
510
511
512
if ( CPU_have3DNow() ) {
SDL_CPUFeatures |= CPU_HAS_3DNOW;
}
Jan 24, 2004
Jan 24, 2004
513
514
515
if ( CPU_have3DNowExt() ) {
SDL_CPUFeatures |= CPU_HAS_3DNOWEXT;
}
516
517
518
if ( CPU_haveSSE() ) {
SDL_CPUFeatures |= CPU_HAS_SSE;
}
Jan 24, 2004
Jan 24, 2004
519
520
521
if ( CPU_haveSSE2() ) {
SDL_CPUFeatures |= CPU_HAS_SSE2;
}
Jan 6, 2004
Jan 6, 2004
522
523
524
if ( CPU_haveAltiVec() ) {
SDL_CPUFeatures |= CPU_HAS_ALTIVEC;
}
Oct 31, 2019
Oct 31, 2019
525
526
527
if ( CPU_haveARMSIMD() ) {
SDL_CPUFeatures |= CPU_HAS_ARM_SIMD;
}
Oct 31, 2019
Oct 31, 2019
528
529
530
if ( CPU_haveARMNEON() ) {
SDL_CPUFeatures |= CPU_HAS_ARM_NEON;
}
531
532
533
534
}
return SDL_CPUFeatures;
}
Feb 24, 2006
Feb 24, 2006
535
SDL_bool SDL_HasRDTSC(void)
Nov 24, 2003
Nov 24, 2003
536
537
538
539
540
541
542
{
if ( SDL_GetCPUFeatures() & CPU_HAS_RDTSC ) {
return SDL_TRUE;
}
return SDL_FALSE;
}
Feb 24, 2006
Feb 24, 2006
543
SDL_bool SDL_HasMMX(void)
544
545
546
547
548
549
550
{
if ( SDL_GetCPUFeatures() & CPU_HAS_MMX ) {
return SDL_TRUE;
}
return SDL_FALSE;
}
Feb 24, 2006
Feb 24, 2006
551
SDL_bool SDL_HasMMXExt(void)
Feb 10, 2004
Feb 10, 2004
553
if ( SDL_GetCPUFeatures() & CPU_HAS_MMXEXT ) {
554
555
556
557
558
return SDL_TRUE;
}
return SDL_FALSE;
}
Feb 24, 2006
Feb 24, 2006
559
SDL_bool SDL_Has3DNow(void)
Feb 10, 2004
Feb 10, 2004
561
if ( SDL_GetCPUFeatures() & CPU_HAS_3DNOW ) {
562
563
564
565
566
return SDL_TRUE;
}
return SDL_FALSE;
}
Feb 24, 2006
Feb 24, 2006
567
SDL_bool SDL_Has3DNowExt(void)
Jan 6, 2004
Jan 6, 2004
568
{
Feb 10, 2004
Feb 10, 2004
569
if ( SDL_GetCPUFeatures() & CPU_HAS_3DNOWEXT ) {
Jan 6, 2004
Jan 6, 2004
570
571
572
573
574
return SDL_TRUE;
}
return SDL_FALSE;
}
Feb 24, 2006
Feb 24, 2006
575
SDL_bool SDL_HasSSE(void)
Jan 24, 2004
Jan 24, 2004
576
{
Feb 10, 2004
Feb 10, 2004
577
578
579
580
if ( SDL_GetCPUFeatures() & CPU_HAS_SSE ) {
return SDL_TRUE;
}
return SDL_FALSE;
Jan 24, 2004
Jan 24, 2004
581
582
}
Feb 24, 2006
Feb 24, 2006
583
SDL_bool SDL_HasSSE2(void)
Jan 24, 2004
Jan 24, 2004
584
{
Feb 10, 2004
Feb 10, 2004
585
586
587
588
if ( SDL_GetCPUFeatures() & CPU_HAS_SSE2 ) {
return SDL_TRUE;
}
return SDL_FALSE;
Jan 24, 2004
Jan 24, 2004
589
590
}
Feb 24, 2006
Feb 24, 2006
591
SDL_bool SDL_HasAltiVec(void)
Jan 24, 2004
Jan 24, 2004
592
{
Feb 10, 2004
Feb 10, 2004
593
594
595
596
if ( SDL_GetCPUFeatures() & CPU_HAS_ALTIVEC ) {
return SDL_TRUE;
}
return SDL_FALSE;
Jan 24, 2004
Jan 24, 2004
597
598
}
Oct 31, 2019
Oct 31, 2019
599
600
601
602
603
604
605
606
SDL_bool SDL_HasARMSIMD(void)
{
if ( SDL_GetCPUFeatures() & CPU_HAS_ARM_SIMD ) {
return SDL_TRUE;
}
return SDL_FALSE;
}
Oct 31, 2019
Oct 31, 2019
607
608
609
610
611
612
613
614
SDL_bool SDL_HasARMNEON(void)
{
if ( SDL_GetCPUFeatures() & CPU_HAS_ARM_NEON ) {
return SDL_TRUE;
}
return SDL_FALSE;
}
615
616
617
618
619
620
#ifdef TEST_MAIN
#include <stdio.h>
int main()
{
Jan 6, 2004
Jan 6, 2004
621
printf("RDTSC: %d\n", SDL_HasRDTSC());
622
printf("MMX: %d\n", SDL_HasMMX());
Jan 24, 2004
Jan 24, 2004
623
printf("MMXExt: %d\n", SDL_HasMMXExt());
624
printf("3DNow: %d\n", SDL_Has3DNow());
Jan 24, 2004
Jan 24, 2004
625
printf("3DNowExt: %d\n", SDL_Has3DNowExt());
626
printf("SSE: %d\n", SDL_HasSSE());
Jan 24, 2004
Jan 24, 2004
627
printf("SSE2: %d\n", SDL_HasSSE2());
Jan 6, 2004
Jan 6, 2004
628
printf("AltiVec: %d\n", SDL_HasAltiVec());
Oct 31, 2019
Oct 31, 2019
629
printf("ARM SIMD: %d\n", SDL_HasARMSIMD());
Oct 31, 2019
Oct 31, 2019
630
printf("ARM NEON: %d\n", SDL_HasARMNEON());
Nov 24, 2003
Nov 24, 2003
631
return 0;
632
633
634
}
#endif /* TEST_MAIN */