src/cpuinfo/SDL_cpuinfo.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 27 Jan 2011 20:46:45 -0800
changeset 5120 b3f075368b1f
parent 5115 427998ff3bcf
child 5259 6a65c1fc07af
permissions -rw-r--r--
Added API function to get CPU cache line size.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* CPU feature detection for SDL */
    25 
    26 #include "SDL_cpuinfo.h"
    27 
    28 #ifdef HAVE_SYSCONF
    29 #include <unistd.h>
    30 #endif
    31 #ifdef HAVE_SYSCTLBYNAME
    32 #include <sys/types.h>
    33 #include <sys/sysctl.h>
    34 #endif
    35 #if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))
    36 #include <sys/sysctl.h>         /* For AltiVec check */
    37 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
    38 #include <signal.h>
    39 #include <setjmp.h>
    40 #endif
    41 #ifdef __WIN32__
    42 #include "../core/windows/SDL_windows.h"
    43 #endif
    44 
    45 #define CPU_HAS_RDTSC   0x00000001
    46 #define CPU_HAS_MMX     0x00000002
    47 #define CPU_HAS_MMXEXT  0x00000004
    48 #define CPU_HAS_3DNOW   0x00000010
    49 #define CPU_HAS_3DNOWEXT 0x00000020
    50 #define CPU_HAS_SSE     0x00000040
    51 #define CPU_HAS_SSE2    0x00000080
    52 #define CPU_HAS_ALTIVEC 0x00000100
    53 
    54 #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__
    55 /* This is the brute force way of detecting instruction sets...
    56    the idea is borrowed from the libmpeg2 library - thanks!
    57  */
    58 static jmp_buf jmpbuf;
    59 static void
    60 illegal_instruction(int sig)
    61 {
    62     longjmp(jmpbuf, 1);
    63 }
    64 #endif /* HAVE_SETJMP */
    65 
    66 static __inline__ int
    67 CPU_haveCPUID(void)
    68 {
    69     int has_CPUID = 0;
    70 /* *INDENT-OFF* */
    71 #if defined(__GNUC__) && defined(i386)
    72     __asm__ (
    73 "        pushfl                      # Get original EFLAGS             \n"
    74 "        popl    %%eax                                                 \n"
    75 "        movl    %%eax,%%ecx                                           \n"
    76 "        xorl    $0x200000,%%eax     # Flip ID bit in EFLAGS           \n"
    77 "        pushl   %%eax               # Save new EFLAGS value on stack  \n"
    78 "        popfl                       # Replace current EFLAGS value    \n"
    79 "        pushfl                      # Get new EFLAGS                  \n"
    80 "        popl    %%eax               # Store new EFLAGS in EAX         \n"
    81 "        xorl    %%ecx,%%eax         # Can not toggle ID bit,          \n"
    82 "        jz      1f                  # Processor=80486                 \n"
    83 "        movl    $1,%0               # We have CPUID support           \n"
    84 "1:                                                                    \n"
    85     : "=m" (has_CPUID)
    86     :
    87     : "%eax", "%ecx"
    88     );
    89 #elif defined(__GNUC__) && defined(__x86_64__)
    90 /* Technically, if this is being compiled under __x86_64__ then it has 
    91 CPUid by definition.  But it's nice to be able to prove it.  :)      */
    92     __asm__ (
    93 "        pushfq                      # Get original EFLAGS             \n"
    94 "        popq    %%rax                                                 \n"
    95 "        movq    %%rax,%%rcx                                           \n"
    96 "        xorl    $0x200000,%%eax     # Flip ID bit in EFLAGS           \n"
    97 "        pushq   %%rax               # Save new EFLAGS value on stack  \n"
    98 "        popfq                       # Replace current EFLAGS value    \n"
    99 "        pushfq                      # Get new EFLAGS                  \n"
   100 "        popq    %%rax               # Store new EFLAGS in EAX         \n"
   101 "        xorl    %%ecx,%%eax         # Can not toggle ID bit,          \n"
   102 "        jz      1f                  # Processor=80486                 \n"
   103 "        movl    $1,%0               # We have CPUID support           \n"
   104 "1:                                                                    \n"
   105     : "=m" (has_CPUID)
   106     :
   107     : "%rax", "%rcx"
   108     );
   109 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
   110     __asm {
   111         pushfd                      ; Get original EFLAGS
   112         pop     eax
   113         mov     ecx, eax
   114         xor     eax, 200000h        ; Flip ID bit in EFLAGS
   115         push    eax                 ; Save new EFLAGS value on stack
   116         popfd                       ; Replace current EFLAGS value
   117         pushfd                      ; Get new EFLAGS
   118         pop     eax                 ; Store new EFLAGS in EAX
   119         xor     eax, ecx            ; Can not toggle ID bit,
   120         jz      done                ; Processor=80486
   121         mov     has_CPUID,1         ; We have CPUID support
   122 done:
   123     }
   124 #elif defined(__sun) && defined(__i386)
   125     __asm (
   126 "       pushfl                 \n"
   127 "       popl    %eax           \n"
   128 "       movl    %eax,%ecx      \n"
   129 "       xorl    $0x200000,%eax \n"
   130 "       pushl   %eax           \n"
   131 "       popfl                  \n"
   132 "       pushfl                 \n"
   133 "       popl    %eax           \n"
   134 "       xorl    %ecx,%eax      \n"
   135 "       jz      1f             \n"
   136 "       movl    $1,-8(%ebp)    \n"
   137 "1:                            \n"
   138     );
   139 #elif defined(__sun) && defined(__amd64)
   140     __asm (
   141 "       pushfq                 \n"
   142 "       popq    %rax           \n"
   143 "       movq    %rax,%rcx      \n"
   144 "       xorl    $0x200000,%eax \n"
   145 "       pushq   %rax           \n"
   146 "       popfq                  \n"
   147 "       pushfq                 \n"
   148 "       popq    %rax           \n"
   149 "       xorl    %ecx,%eax      \n"
   150 "       jz      1f             \n"
   151 "       movl    $1,-8(%rbp)    \n"
   152 "1:                            \n"
   153     );
   154 #endif
   155 /* *INDENT-ON* */
   156     return has_CPUID;
   157 }
   158 
   159 #if defined(__GNUC__) && defined(i386)
   160 #define cpuid(func, a, b, c, d) \
   161     __asm__ __volatile__ ( \
   162 "        pushl %%ebx        \n" \
   163 "        cpuid              \n" \
   164 "        movl %%ebx, %%esi  \n" \
   165 "        popl %%ebx         \n" : \
   166             "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (func))
   167 #elif defined(__GNUC__) && defined(__x86_64__)
   168 #define cpuid(func, a, b, c, d) \
   169     __asm__ __volatile__ ( \
   170 "        pushq %%rbx        \n" \
   171 "        cpuid              \n" \
   172 "        movq %%rbx, %%rsi  \n" \
   173 "        popq %%rbx         \n" : \
   174             "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (func))
   175 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
   176 #define cpuid(func, a, b, c, d) \
   177     __asm { \
   178         __asm mov eax, func \
   179         __asm cpuid \
   180         __asm mov a, eax \
   181         __asm mov b, ebx \
   182         __asm mov c, ecx \
   183         __asm mov d, edx \
   184     }
   185 #else
   186 #define cpuid(func, a, b, c, d) \
   187     a = b = c = d = 0
   188 #endif
   189 
   190 static __inline__ int
   191 CPU_getCPUIDFeatures(void)
   192 {
   193     int features = 0;
   194     int a, b, c, d;
   195 
   196     cpuid(0, a, b, c, d);
   197     if (a >= 1) {
   198         cpuid(1, a, b, c, d);
   199         features = d;
   200     }
   201     return features;
   202 }
   203 
   204 static __inline__ int
   205 CPU_getCPUIDFeaturesExt(void)
   206 {
   207     int features = 0;
   208     int a, b, c, d;
   209 
   210     cpuid(0x80000000, a, b, c, d);
   211     if (a >= 0x80000001) {
   212         cpuid(0x80000001, a, b, c, d);
   213         features = d;
   214     }
   215     return features;
   216 }
   217 
   218 static __inline__ int
   219 CPU_haveRDTSC(void)
   220 {
   221     if (CPU_haveCPUID()) {
   222         return (CPU_getCPUIDFeatures() & 0x00000010);
   223     }
   224     return 0;
   225 }
   226 
   227 static __inline__ int
   228 CPU_haveMMX(void)
   229 {
   230     if (CPU_haveCPUID()) {
   231         return (CPU_getCPUIDFeatures() & 0x00800000);
   232     }
   233     return 0;
   234 }
   235 
   236 static __inline__ int
   237 CPU_haveMMXExt(void)
   238 {
   239     if (CPU_haveCPUID()) {
   240         return (CPU_getCPUIDFeaturesExt() & 0x00400000);
   241     }
   242     return 0;
   243 }
   244 
   245 static __inline__ int
   246 CPU_have3DNow(void)
   247 {
   248     if (CPU_haveCPUID()) {
   249         return (CPU_getCPUIDFeaturesExt() & 0x80000000);
   250     }
   251     return 0;
   252 }
   253 
   254 static __inline__ int
   255 CPU_have3DNowExt(void)
   256 {
   257     if (CPU_haveCPUID()) {
   258         return (CPU_getCPUIDFeaturesExt() & 0x40000000);
   259     }
   260     return 0;
   261 }
   262 
   263 static __inline__ int
   264 CPU_haveSSE(void)
   265 {
   266     if (CPU_haveCPUID()) {
   267         return (CPU_getCPUIDFeatures() & 0x02000000);
   268     }
   269     return 0;
   270 }
   271 
   272 static __inline__ int
   273 CPU_haveSSE2(void)
   274 {
   275     if (CPU_haveCPUID()) {
   276         return (CPU_getCPUIDFeatures() & 0x04000000);
   277     }
   278     return 0;
   279 }
   280 
   281 static __inline__ int
   282 CPU_haveAltiVec(void)
   283 {
   284     volatile int altivec = 0;
   285 #if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))
   286     int selectors[2] = { CTL_HW, HW_VECTORUNIT };
   287     int hasVectorUnit = 0;
   288     size_t length = sizeof(hasVectorUnit);
   289     int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0);
   290     if (0 == error)
   291         altivec = (hasVectorUnit != 0);
   292 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
   293     void (*handler) (int sig);
   294     handler = signal(SIGILL, illegal_instruction);
   295     if (setjmp(jmpbuf) == 0) {
   296         asm volatile ("mtspr 256, %0\n\t" "vand %%v0, %%v0, %%v0"::"r" (-1));
   297         altivec = 1;
   298     }
   299     signal(SIGILL, handler);
   300 #endif
   301     return altivec;
   302 }
   303 
   304 static int SDL_CPUCount = 0;
   305 
   306 int
   307 SDL_GetCPUCount(void)
   308 {
   309     if (!SDL_CPUCount) {
   310 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
   311         if (SDL_CPUCount <= 0) {
   312             SDL_CPUCount = (int)sysconf(_SC_NPROCESSORS_ONLN);
   313         }
   314 #endif
   315 #ifdef HAVE_SYSCTLBYNAME
   316         if (SDL_CPUCount <= 0) {
   317             size_t size = sizeof(SDL_CPUCount);
   318             sysctlbyname("hw.ncpu", &SDL_CPUCount, &size, NULL, 0);
   319         }
   320 #endif
   321 #ifdef __WIN32__
   322         if (SDL_CPUCount <= 0) {
   323             SYSTEM_INFO info;
   324             GetSystemInfo(&info);
   325             SDL_CPUCount = info.dwNumberOfProcessors;
   326         }
   327 #endif
   328         /* There has to be at least 1, right? :) */
   329         if (SDL_CPUCount <= 0) {
   330             SDL_CPUCount = 1;
   331         }
   332     }
   333     return SDL_CPUCount;
   334 }
   335 
   336 /* Oh, such a sweet sweet trick, just not very useful. :) */
   337 static const char *
   338 SDL_GetCPUType(void)
   339 {
   340     static char SDL_CPUType[13];
   341 
   342     if (!SDL_CPUType[0]) {
   343         int i = 0;
   344         int a, b, c, d;
   345 
   346         if (CPU_haveCPUID()) {
   347             cpuid(0x00000000, a, b, c, d);
   348             SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
   349             SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
   350             SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
   351             SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
   352             SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
   353             SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
   354             SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
   355             SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
   356             SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
   357             SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
   358             SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
   359             SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
   360         }
   361         if (!SDL_CPUType[0]) {
   362             SDL_strlcpy(SDL_CPUType, "Unknown", sizeof(SDL_CPUType));
   363         }
   364     }
   365     return SDL_CPUType;
   366 }
   367 
   368 static const char *
   369 SDL_GetCPUName(void)
   370 {
   371     static char SDL_CPUName[48];
   372 
   373     if (!SDL_CPUName[0]) {
   374         int i = 0;
   375         int a, b, c, d;
   376 
   377         if (CPU_haveCPUID()) {
   378             cpuid(0x80000000, a, b, c, d);
   379             if (a >= 0x80000004) {
   380                 cpuid(0x80000002, a, b, c, d);
   381                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   382                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   383                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   384                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   385                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   386                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   387                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   388                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   389                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   390                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   391                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   392                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   393                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   394                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   395                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   396                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   397                 cpuid(0x80000003, a, b, c, d);
   398                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   399                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   400                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   401                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   402                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   403                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   404                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   405                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   406                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   407                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   408                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   409                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   410                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   411                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   412                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   413                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   414                 cpuid(0x80000004, a, b, c, d);
   415                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   416                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   417                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   418                 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
   419                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   420                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   421                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   422                 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
   423                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   424                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   425                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   426                 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
   427                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   428                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   429                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   430                 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
   431             }
   432         }
   433         if (!SDL_CPUName[0]) {
   434             SDL_strlcpy(SDL_CPUName, "Unknown", sizeof(SDL_CPUName));
   435         }
   436     }
   437     return SDL_CPUName;
   438 }
   439 
   440 int
   441 SDL_GetCPUCacheLineSize(void)
   442 {
   443     const char *cpuType = SDL_GetCPUType();
   444 
   445     if (SDL_strcmp(cpuType, "GenuineIntel") == 0) {
   446         int a, b, c, d;
   447 
   448         cpuid(0x00000001, a, b, c, d);
   449         return (((b >> 8) & 0xff) * 8);
   450     } else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0) {
   451         int a, b, c, d;
   452 
   453         cpuid(0x80000005, a, b, c, d);
   454         return (c & 0xff);
   455     } else {
   456         /* Just make a guess here... */
   457         return SDL_CACHELINE_SIZE;
   458     }
   459 }
   460 
   461 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
   462 
   463 static Uint32
   464 SDL_GetCPUFeatures(void)
   465 {
   466     if (SDL_CPUFeatures == 0xFFFFFFFF) {
   467         SDL_CPUFeatures = 0;
   468         if (CPU_haveRDTSC()) {
   469             SDL_CPUFeatures |= CPU_HAS_RDTSC;
   470         }
   471         if (CPU_haveMMX()) {
   472             SDL_CPUFeatures |= CPU_HAS_MMX;
   473         }
   474         if (CPU_haveMMXExt()) {
   475             SDL_CPUFeatures |= CPU_HAS_MMXEXT;
   476         }
   477         if (CPU_have3DNow()) {
   478             SDL_CPUFeatures |= CPU_HAS_3DNOW;
   479         }
   480         if (CPU_have3DNowExt()) {
   481             SDL_CPUFeatures |= CPU_HAS_3DNOWEXT;
   482         }
   483         if (CPU_haveSSE()) {
   484             SDL_CPUFeatures |= CPU_HAS_SSE;
   485         }
   486         if (CPU_haveSSE2()) {
   487             SDL_CPUFeatures |= CPU_HAS_SSE2;
   488         }
   489         if (CPU_haveAltiVec()) {
   490             SDL_CPUFeatures |= CPU_HAS_ALTIVEC;
   491         }
   492     }
   493     return SDL_CPUFeatures;
   494 }
   495 
   496 SDL_bool
   497 SDL_HasRDTSC(void)
   498 {
   499     if (SDL_GetCPUFeatures() & CPU_HAS_RDTSC) {
   500         return SDL_TRUE;
   501     }
   502     return SDL_FALSE;
   503 }
   504 
   505 SDL_bool
   506 SDL_HasMMX(void)
   507 {
   508     if (SDL_GetCPUFeatures() & CPU_HAS_MMX) {
   509         return SDL_TRUE;
   510     }
   511     return SDL_FALSE;
   512 }
   513 
   514 SDL_bool
   515 SDL_HasMMXExt(void)
   516 {
   517     if (SDL_GetCPUFeatures() & CPU_HAS_MMXEXT) {
   518         return SDL_TRUE;
   519     }
   520     return SDL_FALSE;
   521 }
   522 
   523 SDL_bool
   524 SDL_Has3DNow(void)
   525 {
   526     if (SDL_GetCPUFeatures() & CPU_HAS_3DNOW) {
   527         return SDL_TRUE;
   528     }
   529     return SDL_FALSE;
   530 }
   531 
   532 SDL_bool
   533 SDL_Has3DNowExt(void)
   534 {
   535     if (SDL_GetCPUFeatures() & CPU_HAS_3DNOWEXT) {
   536         return SDL_TRUE;
   537     }
   538     return SDL_FALSE;
   539 }
   540 
   541 SDL_bool
   542 SDL_HasSSE(void)
   543 {
   544     if (SDL_GetCPUFeatures() & CPU_HAS_SSE) {
   545         return SDL_TRUE;
   546     }
   547     return SDL_FALSE;
   548 }
   549 
   550 SDL_bool
   551 SDL_HasSSE2(void)
   552 {
   553     if (SDL_GetCPUFeatures() & CPU_HAS_SSE2) {
   554         return SDL_TRUE;
   555     }
   556     return SDL_FALSE;
   557 }
   558 
   559 SDL_bool
   560 SDL_HasAltiVec(void)
   561 {
   562     if (SDL_GetCPUFeatures() & CPU_HAS_ALTIVEC) {
   563         return SDL_TRUE;
   564     }
   565     return SDL_FALSE;
   566 }
   567 
   568 #ifdef TEST_MAIN
   569 
   570 #include <stdio.h>
   571 
   572 int
   573 main()
   574 {
   575     printf("CPU count: %d\n", SDL_GetCPUCount());
   576     printf("CPU type: %s\n", SDL_GetCPUType());
   577     printf("CPU name: %s\n", SDL_GetCPUName());
   578     printf("CacheLine size: %d\n", SDL_GetCPUCacheLineSize());
   579     printf("RDTSC: %d\n", SDL_HasRDTSC());
   580     printf("MMX: %d\n", SDL_HasMMX());
   581     printf("MMXExt: %d\n", SDL_HasMMXExt());
   582     printf("3DNow: %d\n", SDL_Has3DNow());
   583     printf("3DNowExt: %d\n", SDL_Has3DNowExt());
   584     printf("SSE: %d\n", SDL_HasSSE());
   585     printf("SSE2: %d\n", SDL_HasSSE2());
   586     printf("AltiVec: %d\n", SDL_HasAltiVec());
   587     return 0;
   588 }
   589 
   590 #endif /* TEST_MAIN */
   591 
   592 /* vi: set ts=4 sw=4 expandtab: */