SDL  2.0
SDL_cpuinfo.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #ifdef TEST_MAIN
22 #include "SDL_config.h"
23 #else
24 #include "../SDL_internal.h"
25 #endif
26 
27 #if defined(__WIN32__)
28 #include "../core/windows/SDL_windows.h"
29 #endif
30 
31 /* CPU feature detection for SDL */
32 
33 #include "SDL_cpuinfo.h"
34 
35 #ifdef HAVE_SYSCONF
36 #include <unistd.h>
37 #endif
38 #ifdef HAVE_SYSCTLBYNAME
39 #include <sys/types.h>
40 #include <sys/sysctl.h>
41 #endif
42 #if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))
43 #include <sys/sysctl.h> /* For AltiVec check */
44 #elif defined(__OpenBSD__) && defined(__powerpc__)
45 #include <sys/param.h>
46 #include <sys/sysctl.h> /* For AltiVec check */
47 #include <machine/cpu.h>
48 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
49 #include <signal.h>
50 #include <setjmp.h>
51 #endif
52 
53 #define CPU_HAS_RDTSC 0x00000001
54 #define CPU_HAS_ALTIVEC 0x00000002
55 #define CPU_HAS_MMX 0x00000004
56 #define CPU_HAS_3DNOW 0x00000008
57 #define CPU_HAS_SSE 0x00000010
58 #define CPU_HAS_SSE2 0x00000020
59 #define CPU_HAS_SSE3 0x00000040
60 #define CPU_HAS_SSE41 0x00000100
61 #define CPU_HAS_SSE42 0x00000200
62 #define CPU_HAS_AVX 0x00000400
63 #define CPU_HAS_AVX2 0x00000800
64 
65 #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
66 /* This is the brute force way of detecting instruction sets...
67  the idea is borrowed from the libmpeg2 library - thanks!
68  */
69 static jmp_buf jmpbuf;
70 static void
71 illegal_instruction(int sig)
72 {
73  longjmp(jmpbuf, 1);
74 }
75 #endif /* HAVE_SETJMP */
76 
77 static int
79 {
80  int has_CPUID = 0;
81 /* *INDENT-OFF* */
82 #ifndef SDL_CPUINFO_DISABLED
83 #if defined(__GNUC__) && defined(i386)
84  __asm__ (
85 " pushfl # Get original EFLAGS \n"
86 " popl %%eax \n"
87 " movl %%eax,%%ecx \n"
88 " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
89 " pushl %%eax # Save new EFLAGS value on stack \n"
90 " popfl # Replace current EFLAGS value \n"
91 " pushfl # Get new EFLAGS \n"
92 " popl %%eax # Store new EFLAGS in EAX \n"
93 " xorl %%ecx,%%eax # Can not toggle ID bit, \n"
94 " jz 1f # Processor=80486 \n"
95 " movl $1,%0 # We have CPUID support \n"
96 "1: \n"
97  : "=m" (has_CPUID)
98  :
99  : "%eax", "%ecx"
100  );
101 #elif defined(__GNUC__) && defined(__x86_64__)
102 /* Technically, if this is being compiled under __x86_64__ then it has
103  CPUid by definition. But it's nice to be able to prove it. :) */
104  __asm__ (
105 " pushfq # Get original EFLAGS \n"
106 " popq %%rax \n"
107 " movq %%rax,%%rcx \n"
108 " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
109 " pushq %%rax # Save new EFLAGS value on stack \n"
110 " popfq # Replace current EFLAGS value \n"
111 " pushfq # Get new EFLAGS \n"
112 " popq %%rax # Store new EFLAGS in EAX \n"
113 " xorl %%ecx,%%eax # Can not toggle ID bit, \n"
114 " jz 1f # Processor=80486 \n"
115 " movl $1,%0 # We have CPUID support \n"
116 "1: \n"
117  : "=m" (has_CPUID)
118  :
119  : "%rax", "%rcx"
120  );
121 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
122  __asm {
123  pushfd ; Get original EFLAGS
124  pop eax
125  mov ecx, eax
126  xor eax, 200000h ; Flip ID bit in EFLAGS
127  push eax ; Save new EFLAGS value on stack
128  popfd ; Replace current EFLAGS value
129  pushfd ; Get new EFLAGS
130  pop eax ; Store new EFLAGS in EAX
131  xor eax, ecx ; Can not toggle ID bit,
132  jz done ; Processor=80486
133  mov has_CPUID,1 ; We have CPUID support
134 done:
135  }
136 #elif defined(_MSC_VER) && defined(_M_X64)
137  has_CPUID = 1;
138 #elif defined(__sun) && defined(__i386)
139  __asm (
140 " pushfl \n"
141 " popl %eax \n"
142 " movl %eax,%ecx \n"
143 " xorl $0x200000,%eax \n"
144 " pushl %eax \n"
145 " popfl \n"
146 " pushfl \n"
147 " popl %eax \n"
148 " xorl %ecx,%eax \n"
149 " jz 1f \n"
150 " movl $1,-8(%ebp) \n"
151 "1: \n"
152  );
153 #elif defined(__sun) && defined(__amd64)
154  __asm (
155 " pushfq \n"
156 " popq %rax \n"
157 " movq %rax,%rcx \n"
158 " xorl $0x200000,%eax \n"
159 " pushq %rax \n"
160 " popfq \n"
161 " pushfq \n"
162 " popq %rax \n"
163 " xorl %ecx,%eax \n"
164 " jz 1f \n"
165 " movl $1,-8(%rbp) \n"
166 "1: \n"
167  );
168 #endif
169 #endif
170 /* *INDENT-ON* */
171  return has_CPUID;
172 }
173 
174 #if defined(__GNUC__) && defined(i386)
175 #define cpuid(func, a, b, c, d) \
176  __asm__ __volatile__ ( \
177 " pushl %%ebx \n" \
178 " xorl %%ecx,%%ecx \n" \
179 " cpuid \n" \
180 " movl %%ebx, %%esi \n" \
181 " popl %%ebx \n" : \
182  "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (func))
183 #elif defined(__GNUC__) && defined(__x86_64__)
184 #define cpuid(func, a, b, c, d) \
185  __asm__ __volatile__ ( \
186 " pushq %%rbx \n" \
187 " xorq %%rcx,%%rcx \n" \
188 " cpuid \n" \
189 " movq %%rbx, %%rsi \n" \
190 " popq %%rbx \n" : \
191  "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (func))
192 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
193 #define cpuid(func, a, b, c, d) \
194  __asm { \
195  __asm mov eax, func \
196  __asm xor ecx, ecx \
197  __asm cpuid \
198  __asm mov a, eax \
199  __asm mov b, ebx \
200  __asm mov c, ecx \
201  __asm mov d, edx \
202 }
203 #elif defined(_MSC_VER) && defined(_M_X64)
204 #define cpuid(func, a, b, c, d) \
205 { \
206  int CPUInfo[4]; \
207  __cpuid(CPUInfo, func); \
208  a = CPUInfo[0]; \
209  b = CPUInfo[1]; \
210  c = CPUInfo[2]; \
211  d = CPUInfo[3]; \
212 }
213 #else
214 #define cpuid(func, a, b, c, d) \
215  a = b = c = d = 0
216 #endif
217 
218 static int
220 {
221  int features = 0;
222  int a, b, c, d;
223 
224  cpuid(0, a, b, c, d);
225  if (a >= 1) {
226  cpuid(1, a, b, c, d);
227  features = d;
228  }
229  return features;
230 }
231 
232 static SDL_bool
234 {
235  int a, b, c, d;
236 
237  /* Check to make sure we can call xgetbv */
238  cpuid(0, a, b, c, d);
239  if (a < 1) {
240  return SDL_FALSE;
241  }
242  cpuid(1, a, b, c, d);
243  if (!(c & 0x08000000)) {
244  return SDL_FALSE;
245  }
246 
247  /* Call xgetbv to see if YMM register state is saved */
248  a = 0;
249 #if defined(__GNUC__) && (defined(i386) || defined(__x86_64__))
250  asm(".byte 0x0f, 0x01, 0xd0" : "=a" (a) : "c" (0) : "%edx");
251 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) /* VS2010 SP1 */
252  a = (int)_xgetbv(0);
253 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
254  __asm
255  {
256  xor ecx, ecx
257  _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0
258  mov a, eax
259  }
260 #endif
261  return ((a & 6) == 6) ? SDL_TRUE : SDL_FALSE;
262 }
263 
264 static int
266 {
267  if (CPU_haveCPUID()) {
268  return (CPU_getCPUIDFeatures() & 0x00000010);
269  }
270  return 0;
271 }
272 
273 static int
275 {
276  volatile int altivec = 0;
277 #ifndef SDL_CPUINFO_DISABLED
278 #if (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__))
279 #ifdef __OpenBSD__
280  int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
281 #else
282  int selectors[2] = { CTL_HW, HW_VECTORUNIT };
283 #endif
284  int hasVectorUnit = 0;
285  size_t length = sizeof(hasVectorUnit);
286  int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0);
287  if (0 == error)
288  altivec = (hasVectorUnit != 0);
289 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
290  void (*handler) (int sig);
291  handler = signal(SIGILL, illegal_instruction);
292  if (setjmp(jmpbuf) == 0) {
293  asm volatile ("mtspr 256, %0\n\t" "vand %%v0, %%v0, %%v0"::"r" (-1));
294  altivec = 1;
295  }
296  signal(SIGILL, handler);
297 #endif
298 #endif
299  return altivec;
300 }
301 
302 static int
304 {
305  if (CPU_haveCPUID()) {
306  return (CPU_getCPUIDFeatures() & 0x00800000);
307  }
308  return 0;
309 }
310 
311 static int
313 {
314  if (CPU_haveCPUID()) {
315  int a, b, c, d;
316 
317  cpuid(0x80000000, a, b, c, d);
318  if (a >= 0x80000001) {
319  cpuid(0x80000001, a, b, c, d);
320  return (d & 0x80000000);
321  }
322  }
323  return 0;
324 }
325 
326 static int
328 {
329  if (CPU_haveCPUID()) {
330  return (CPU_getCPUIDFeatures() & 0x02000000);
331  }
332  return 0;
333 }
334 
335 static int
337 {
338  if (CPU_haveCPUID()) {
339  return (CPU_getCPUIDFeatures() & 0x04000000);
340  }
341  return 0;
342 }
343 
344 static int
346 {
347  if (CPU_haveCPUID()) {
348  int a, b, c, d;
349 
350  cpuid(0, a, b, c, d);
351  if (a >= 1) {
352  cpuid(1, a, b, c, d);
353  return (c & 0x00000001);
354  }
355  }
356  return 0;
357 }
358 
359 static int
361 {
362  if (CPU_haveCPUID()) {
363  int a, b, c, d;
364 
365  cpuid(0, a, b, c, d);
366  if (a >= 1) {
367  cpuid(1, a, b, c, d);
368  return (c & 0x00080000);
369  }
370  }
371  return 0;
372 }
373 
374 static int
376 {
377  if (CPU_haveCPUID()) {
378  int a, b, c, d;
379 
380  cpuid(0, a, b, c, d);
381  if (a >= 1) {
382  cpuid(1, a, b, c, d);
383  return (c & 0x00100000);
384  }
385  }
386  return 0;
387 }
388 
389 static int
391 {
392  if (CPU_haveCPUID() && CPU_OSSavesYMM()) {
393  int a, b, c, d;
394 
395  cpuid(0, a, b, c, d);
396  if (a >= 1) {
397  cpuid(1, a, b, c, d);
398  return (c & 0x10000000);
399  }
400  }
401  return 0;
402 }
403 
404 static int
406 {
407  if (CPU_haveCPUID() && CPU_OSSavesYMM()) {
408  int a, b, c, d;
409 
410  cpuid(0, a, b, c, d);
411  if (a >= 7) {
412  cpuid(7, a, b, c, d);
413  return (b & 0x00000020);
414  }
415  }
416  return 0;
417 }
418 
419 static int SDL_CPUCount = 0;
420 
421 int
423 {
424  if (!SDL_CPUCount) {
425 #ifndef SDL_CPUINFO_DISABLED
426 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
427  if (SDL_CPUCount <= 0) {
428  SDL_CPUCount = (int)sysconf(_SC_NPROCESSORS_ONLN);
429  }
430 #endif
431 #ifdef HAVE_SYSCTLBYNAME
432  if (SDL_CPUCount <= 0) {
433  size_t size = sizeof(SDL_CPUCount);
434  sysctlbyname("hw.ncpu", &SDL_CPUCount, &size, NULL, 0);
435  }
436 #endif
437 #ifdef __WIN32__
438  if (SDL_CPUCount <= 0) {
439  SYSTEM_INFO info;
440  GetSystemInfo(&info);
441  SDL_CPUCount = info.dwNumberOfProcessors;
442  }
443 #endif
444 #endif
445  /* There has to be at least 1, right? :) */
446  if (SDL_CPUCount <= 0) {
447  SDL_CPUCount = 1;
448  }
449  }
450  return SDL_CPUCount;
451 }
452 
453 /* Oh, such a sweet sweet trick, just not very useful. :) */
454 static const char *
456 {
457  static char SDL_CPUType[13];
458 
459  if (!SDL_CPUType[0]) {
460  int i = 0;
461 
462  if (CPU_haveCPUID()) {
463  int a, b, c, d;
464  cpuid(0x00000000, a, b, c, d);
465  (void) a;
466  SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
467  SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
468  SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
469  SDL_CPUType[i++] = (char)(b & 0xff);
470 
471  SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
472  SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
473  SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
474  SDL_CPUType[i++] = (char)(d & 0xff);
475 
476  SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
477  SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
478  SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
479  SDL_CPUType[i++] = (char)(c & 0xff);
480  }
481  if (!SDL_CPUType[0]) {
482  SDL_strlcpy(SDL_CPUType, "Unknown", sizeof(SDL_CPUType));
483  }
484  }
485  return SDL_CPUType;
486 }
487 
488 
489 #ifdef TEST_MAIN /* !!! FIXME: only used for test at the moment. */
490 static const char *
491 SDL_GetCPUName(void)
492 {
493  static char SDL_CPUName[48];
494 
495  if (!SDL_CPUName[0]) {
496  int i = 0;
497  int a, b, c, d;
498 
499  if (CPU_haveCPUID()) {
500  cpuid(0x80000000, a, b, c, d);
501  if (a >= 0x80000004) {
502  cpuid(0x80000002, a, b, c, d);
503  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
504  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
505  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
506  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
507  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
508  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
509  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
510  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
511  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
512  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
513  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
514  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
515  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
516  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
517  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
518  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
519  cpuid(0x80000003, a, b, c, d);
520  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
521  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
522  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
523  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
524  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
525  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
526  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
527  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
528  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
529  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
530  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
531  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
532  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
533  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
534  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
535  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
536  cpuid(0x80000004, a, b, c, d);
537  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
538  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
539  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
540  SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
541  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
542  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
543  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
544  SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
545  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
546  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
547  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
548  SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
549  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
550  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
551  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
552  SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
553  }
554  }
555  if (!SDL_CPUName[0]) {
556  SDL_strlcpy(SDL_CPUName, "Unknown", sizeof(SDL_CPUName));
557  }
558  }
559  return SDL_CPUName;
560 }
561 #endif
562 
563 int
565 {
566  const char *cpuType = SDL_GetCPUType();
567  int a, b, c, d;
568  (void) a; (void) b; (void) c; (void) d;
569  if (SDL_strcmp(cpuType, "GenuineIntel") == 0) {
570  cpuid(0x00000001, a, b, c, d);
571  return (((b >> 8) & 0xff) * 8);
572  } else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0) {
573  cpuid(0x80000005, a, b, c, d);
574  return (c & 0xff);
575  } else {
576  /* Just make a guess here... */
577  return SDL_CACHELINE_SIZE;
578  }
579 }
580 
581 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
582 
583 static Uint32
585 {
586  if (SDL_CPUFeatures == 0xFFFFFFFF) {
587  SDL_CPUFeatures = 0;
588  if (CPU_haveRDTSC()) {
590  }
591  if (CPU_haveAltiVec()) {
593  }
594  if (CPU_haveMMX()) {
596  }
597  if (CPU_have3DNow()) {
599  }
600  if (CPU_haveSSE()) {
602  }
603  if (CPU_haveSSE2()) {
605  }
606  if (CPU_haveSSE3()) {
608  }
609  if (CPU_haveSSE41()) {
611  }
612  if (CPU_haveSSE42()) {
614  }
615  if (CPU_haveAVX()) {
617  }
618  if (CPU_haveAVX2()) {
620  }
621  }
622  return SDL_CPUFeatures;
623 }
624 
625 SDL_bool
627 {
629  return SDL_TRUE;
630  }
631  return SDL_FALSE;
632 }
633 
634 SDL_bool
636 {
638  return SDL_TRUE;
639  }
640  return SDL_FALSE;
641 }
642 
643 SDL_bool
645 {
647  return SDL_TRUE;
648  }
649  return SDL_FALSE;
650 }
651 
652 SDL_bool
654 {
656  return SDL_TRUE;
657  }
658  return SDL_FALSE;
659 }
660 
661 SDL_bool
663 {
665  return SDL_TRUE;
666  }
667  return SDL_FALSE;
668 }
669 
670 SDL_bool
672 {
674  return SDL_TRUE;
675  }
676  return SDL_FALSE;
677 }
678 
679 SDL_bool
681 {
683  return SDL_TRUE;
684  }
685  return SDL_FALSE;
686 }
687 
688 SDL_bool
690 {
692  return SDL_TRUE;
693  }
694  return SDL_FALSE;
695 }
696 
697 SDL_bool
699 {
701  return SDL_TRUE;
702  }
703  return SDL_FALSE;
704 }
705 
706 SDL_bool
708 {
710  return SDL_TRUE;
711  }
712  return SDL_FALSE;
713 }
714 
715 SDL_bool
717 {
719  return SDL_TRUE;
720  }
721  return SDL_FALSE;
722 }
723 
724 static int SDL_SystemRAM = 0;
725 
726 int
728 {
729  if (!SDL_SystemRAM) {
730 #ifndef SDL_CPUINFO_DISABLED
731 #if defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
732  if (SDL_SystemRAM <= 0) {
733  SDL_SystemRAM = (int)((Sint64)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / (1024*1024));
734  }
735 #endif
736 #ifdef HAVE_SYSCTLBYNAME
737  if (SDL_SystemRAM <= 0) {
738 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
739 #ifdef HW_REALMEM
740  int mib[2] = {CTL_HW, HW_REALMEM};
741 #else
742  /* might only report up to 2 GiB */
743  int mib[2] = {CTL_HW, HW_PHYSMEM};
744 #endif /* HW_REALMEM */
745 #else
746  int mib[2] = {CTL_HW, HW_MEMSIZE};
747 #endif /* __FreeBSD__ || __FreeBSD_kernel__ */
748  Uint64 memsize = 0;
749  size_t len = sizeof(memsize);
750 
751  if (sysctl(mib, 2, &memsize, &len, NULL, 0) == 0) {
752  SDL_SystemRAM = (int)(memsize / (1024*1024));
753  }
754  }
755 #endif
756 #ifdef __WIN32__
757  if (SDL_SystemRAM <= 0) {
758  MEMORYSTATUSEX stat;
759  stat.dwLength = sizeof(stat);
760  if (GlobalMemoryStatusEx(&stat)) {
761  SDL_SystemRAM = (int)(stat.ullTotalPhys / (1024 * 1024));
762  }
763  }
764 #endif
765 #endif
766  }
767  return SDL_SystemRAM;
768 }
769 
770 
771 #ifdef TEST_MAIN
772 
773 #include <stdio.h>
774 
775 int
776 main()
777 {
778  printf("CPU count: %d\n", SDL_GetCPUCount());
779  printf("CPU type: %s\n", SDL_GetCPUType());
780  printf("CPU name: %s\n", SDL_GetCPUName());
781  printf("CacheLine size: %d\n", SDL_GetCPUCacheLineSize());
782  printf("RDTSC: %d\n", SDL_HasRDTSC());
783  printf("Altivec: %d\n", SDL_HasAltiVec());
784  printf("MMX: %d\n", SDL_HasMMX());
785  printf("3DNow: %d\n", SDL_Has3DNow());
786  printf("SSE: %d\n", SDL_HasSSE());
787  printf("SSE2: %d\n", SDL_HasSSE2());
788  printf("SSE3: %d\n", SDL_HasSSE3());
789  printf("SSE4.1: %d\n", SDL_HasSSE41());
790  printf("SSE4.2: %d\n", SDL_HasSSE42());
791  printf("AVX: %d\n", SDL_HasAVX());
792  printf("AVX2: %d\n", SDL_HasAVX2());
793  printf("RAM: %d MB\n", SDL_GetSystemRAM());
794  return 0;
795 }
796 
797 #endif /* TEST_MAIN */
798 
799 /* vi: set ts=4 sw=4 expandtab: */
#define CPU_HAS_SSE41
Definition: SDL_cpuinfo.c:60
#define SDL_strlcpy
#define CPU_HAS_RDTSC
Definition: SDL_cpuinfo.c:53
#define CPU_HAS_SSE3
Definition: SDL_cpuinfo.c:59
static int CPU_haveSSE42(void)
Definition: SDL_cpuinfo.c:375
SDL_bool SDL_HasSSE41(void)
Definition: SDL_cpuinfo.c:689
int SDL_GetCPUCount(void)
Definition: SDL_cpuinfo.c:422
static int CPU_haveAVX(void)
Definition: SDL_cpuinfo.c:390
static const char * SDL_GetCPUType(void)
Definition: SDL_cpuinfo.c:455
static int CPU_haveRDTSC(void)
Definition: SDL_cpuinfo.c:265
#define CPU_HAS_SSE2
Definition: SDL_cpuinfo.c:58
static SDL_bool CPU_OSSavesYMM(void)
Definition: SDL_cpuinfo.c:233
SDL_bool SDL_HasSSE(void)
Definition: SDL_cpuinfo.c:662
SDL_bool SDL_HasSSE3(void)
Definition: SDL_cpuinfo.c:680
static int CPU_have3DNow(void)
Definition: SDL_cpuinfo.c:312
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:159
SDL_bool SDL_HasAltiVec(void)
Definition: SDL_cpuinfo.c:635
#define CPU_HAS_ALTIVEC
Definition: SDL_cpuinfo.c:54
static int SDL_SystemRAM
Definition: SDL_cpuinfo.c:724
static int CPU_haveCPUID(void)
Definition: SDL_cpuinfo.c:78
GLsizeiptr size
uint64_t Uint64
An unsigned 64-bit integer type.
Definition: SDL_stdinc.h:168
SDL_bool SDL_HasSSE42(void)
Definition: SDL_cpuinfo.c:698
GLenum GLsizei len
SDL_bool SDL_HasMMX(void)
Definition: SDL_cpuinfo.c:644
SDL_bool SDL_HasAVX2(void)
Definition: SDL_cpuinfo.c:716
static int CPU_haveAltiVec(void)
Definition: SDL_cpuinfo.c:274
#define CPU_HAS_AVX
Definition: SDL_cpuinfo.c:62
static int CPU_haveSSE3(void)
Definition: SDL_cpuinfo.c:345
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
GLsizei const GLfloat * value
#define pop
Definition: SDL_qsort.c:192
int done
Definition: checkkeys.c:28
#define SDL_CACHELINE_SIZE
Definition: SDL_cpuinfo.h:77
const GLubyte * c
#define cpuid(func, a, b, c, d)
Definition: SDL_cpuinfo.c:214
SDL_bool SDL_HasAVX(void)
Definition: SDL_cpuinfo.c:707
static Uint32 SDL_CPUFeatures
Definition: SDL_cpuinfo.c:581
static int CPU_haveSSE(void)
Definition: SDL_cpuinfo.c:327
static Uint32 SDL_GetCPUFeatures(void)
Definition: SDL_cpuinfo.c:584
#define CPU_HAS_SSE
Definition: SDL_cpuinfo.c:57
static int CPU_haveAVX2(void)
Definition: SDL_cpuinfo.c:405
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define CPU_HAS_AVX2
Definition: SDL_cpuinfo.c:63
#define NULL
Definition: begin_code.h:143
SDL_bool
Definition: SDL_stdinc.h:130
SDL_bool SDL_HasRDTSC(void)
Definition: SDL_cpuinfo.c:626
#define CPU_HAS_MMX
Definition: SDL_cpuinfo.c:55
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
static int CPU_getCPUIDFeatures(void)
Definition: SDL_cpuinfo.c:219
int SDL_GetSystemRAM(void)
Definition: SDL_cpuinfo.c:727
static int SDL_CPUCount
Definition: SDL_cpuinfo.c:419
#define main
Definition: SDL_main.h:104
#define CPU_HAS_SSE42
Definition: SDL_cpuinfo.c:61
#define SDL_strcmp
int64_t Sint64
A signed 64-bit integer type.
Definition: SDL_stdinc.h:164
GLuint GLsizei GLsizei * length
GLboolean GLboolean GLboolean GLboolean a
SDL_bool SDL_HasSSE2(void)
Definition: SDL_cpuinfo.c:671
GLuint in
#define CPU_HAS_3DNOW
Definition: SDL_cpuinfo.c:56
static int CPU_haveSSE41(void)
Definition: SDL_cpuinfo.c:360
static int CPU_haveMMX(void)
Definition: SDL_cpuinfo.c:303
GLboolean GLboolean GLboolean b
static int CPU_haveSSE2(void)
Definition: SDL_cpuinfo.c:336
SDL_bool SDL_Has3DNow(void)
Definition: SDL_cpuinfo.c:653
GLfloat GLfloat GLfloat GLfloat h
int SDL_GetCPUCacheLineSize(void)
Definition: SDL_cpuinfo.c:564