home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wvis0626.zip / warpvision_20020626.zip / libavcodec / i386 / cputest.c next >
C/C++ Source or Header  |  2002-06-19  |  4KB  |  115 lines

  1. /* Cpu detection code, extracted from mmx.h ((c)1997-99 by H. Dietz
  2.    and R. Fisher). Converted to C and improved by Fabrice Bellard */
  3.  
  4. #include <stdlib.h>
  5. #include "../dsputil.h"
  6.  
  7. /* ebx saving is necessary for PIC. gcc seems unable to see it alone */
  8. #define cpuid(index,eax,ebx,ecx,edx)\
  9.     __asm __volatile\
  10.     ("movl %%ebx, %%esi\n\t"\
  11.          "cpuid\n\t"\
  12.          "xchgl %%ebx, %%esi"\
  13.          : "=a" (eax), "=S" (ebx),\
  14.            "=c" (ecx), "=d" (edx)\
  15.          : "0" (index));
  16.  
  17. /* Function to test if multimedia instructions are supported...  */
  18. int mm_support(void)
  19. {
  20.     int rval;
  21.     int eax, ebx, ecx, edx;
  22.     
  23.     __asm__ __volatile__ (
  24.                           /* See if CPUID instruction is supported ... */
  25.                           /* ... Get copies of EFLAGS into eax and ecx */
  26.                           "pushf\n\t"
  27.                           "popl %0\n\t"
  28.                           "movl %0, %1\n\t"
  29.                           
  30.                           /* ... Toggle the ID bit in one copy and store */
  31.                           /*     to the EFLAGS reg */
  32.                           "xorl $0x200000, %0\n\t"
  33.                           "push %0\n\t"
  34.                           "popf\n\t"
  35.                           
  36.                           /* ... Get the (hopefully modified) EFLAGS */
  37.                           "pushf\n\t"
  38.                           "popl %0\n\t"
  39.                           : "=a" (eax), "=c" (ecx)
  40.                           :
  41.                           : "cc" 
  42.                           );
  43.     
  44.     if (eax == ecx)
  45.         return 0; /* CPUID not supported */
  46.     
  47.     cpuid(0, eax, ebx, ecx, edx);
  48.  
  49.     if (ebx == 0x756e6547 &&
  50.         edx == 0x49656e69 &&
  51.         ecx == 0x6c65746e) {
  52.         
  53.         /* intel */
  54.     inteltest:
  55.         cpuid(1, eax, ebx, ecx, edx);
  56.         if ((edx & 0x00800000) == 0)
  57.             return 0;
  58.         rval = MM_MMX;
  59.         if (edx & 0x02000000) 
  60.             rval |= MM_MMXEXT | MM_SSE;
  61.         if (edx & 0x04000000) 
  62.             rval |= MM_SSE2;
  63.         return rval;
  64.     } else if (ebx == 0x68747541 &&
  65.                edx == 0x69746e65 &&
  66.                ecx == 0x444d4163) {
  67.         /* AMD */
  68.         cpuid(0x80000000, eax, ebx, ecx, edx);
  69.         if ((unsigned)eax < 0x80000001)
  70.             goto inteltest;
  71.         cpuid(0x80000001, eax, ebx, ecx, edx);
  72.         if ((edx & 0x00800000) == 0)
  73.             return 0;
  74.         rval = MM_MMX;
  75.         if (edx & 0x80000000)
  76.             rval |= MM_3DNOW;
  77.         if (edx & 0x00400000)
  78.             rval |= MM_MMXEXT;
  79.         return rval;
  80.     } else if (ebx == 0x69727943 &&
  81.                edx == 0x736e4978 &&
  82.                ecx == 0x64616574) {
  83.         /* Cyrix Section */
  84.         /* See if extended CPUID level 80000001 is supported */
  85.         /* The value of CPUID/80000001 for the 6x86MX is undefined
  86.            according to the Cyrix CPU Detection Guide (Preliminary
  87.            Rev. 1.01 table 1), so we'll check the value of eax for
  88.            CPUID/0 to see if standard CPUID level 2 is supported.
  89.            According to the table, the only CPU which supports level
  90.            2 is also the only one which supports extended CPUID levels.
  91.         */
  92.         if (eax != 2) 
  93.             goto inteltest;
  94.         cpuid(0x80000001, eax, ebx, ecx, edx);
  95.         if ((eax & 0x00800000) == 0)
  96.             return 0;
  97.         rval = MM_MMX;
  98.         if (eax & 0x01000000)
  99.             rval |= MM_MMXEXT;
  100.         return rval;
  101.     } else {
  102.         return 0;
  103.     }
  104. }
  105.  
  106. #ifdef __TEST__
  107. int main ( void )
  108. {
  109.   int mm_flags;
  110.   mm_flags = mm_support();
  111.   printf("mm_support = 0x%08u\n",mm_flags);
  112.   return 0;
  113. }
  114. #endif
  115.