cputest.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:4k
源码类别:

Windows CE

开发平台:

C/C++

  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. #include <stdlib.h>
  4. #include "../dsputil.h"
  5. #ifdef ARCH_X86_64
  6. #  define REG_b "rbx"
  7. #  define REG_S "rsi"
  8. #else
  9. #  define REG_b "ebx"
  10. #  define REG_S "esi"
  11. #endif
  12. /* ebx saving is necessary for PIC. gcc seems unable to see it alone */
  13. #define cpuid(index,eax,ebx,ecx,edx)
  14.     __asm __volatile
  15. ("mov %%"REG_b", %%"REG_S"nt"
  16.          "cpuidnt"
  17.          "xchg %%"REG_b", %%"REG_S
  18.          : "=a" (eax), "=S" (ebx),
  19.            "=c" (ecx), "=d" (edx)
  20.          : "0" (index));
  21. /* Function to test if multimedia instructions are supported...  */
  22. int mm_support(void)
  23. {
  24.     int rval = 0;
  25.     int eax, ebx, ecx, edx;
  26.     int max_std_level, max_ext_level, std_caps=0, ext_caps=0;
  27.     long a, c;
  28.     
  29.     __asm__ __volatile__ (
  30.                           /* See if CPUID instruction is supported ... */
  31.                           /* ... Get copies of EFLAGS into eax and ecx */
  32.                           "pushfnt"
  33.                           "pop %0nt"
  34.                           "mov %0, %1nt"
  35.                           
  36.                           /* ... Toggle the ID bit in one copy and store */
  37.                           /*     to the EFLAGS reg */
  38.                           "xor $0x200000, %0nt"
  39.                           "push %0nt"
  40.                           "popfnt"
  41.                           
  42.                           /* ... Get the (hopefully modified) EFLAGS */
  43.                           "pushfnt"
  44.                           "pop %0nt"
  45.                           : "=a" (a), "=c" (c)
  46.                           :
  47.                           : "cc" 
  48.                           );
  49.     
  50.     if (a == c)
  51.         return 0; /* CPUID not supported */
  52.     cpuid(0, max_std_level, ebx, ecx, edx);
  53.     if(max_std_level >= 1){
  54.         cpuid(1, eax, ebx, ecx, std_caps);
  55.         if (std_caps & (1<<23))
  56.             rval |= MM_MMX;
  57.         if (std_caps & (1<<25)) 
  58.             rval |= MM_MMXEXT | MM_SSE;
  59.         if (std_caps & (1<<26)) 
  60.             rval |= MM_SSE2;
  61.     }
  62.     cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
  63.     if(max_ext_level >= 0x80000001){
  64.         cpuid(0x80000001, eax, ebx, ecx, ext_caps);
  65.         if (ext_caps & (1<<31))
  66.             rval |= MM_3DNOW;
  67.         if (ext_caps & (1<<30))
  68.             rval |= MM_3DNOWEXT;
  69.         if (ext_caps & (1<<23))
  70.             rval |= MM_MMX;
  71.     }
  72.     cpuid(0, eax, ebx, ecx, edx);
  73.     if (       ebx == 0x68747541 &&
  74.                edx == 0x69746e65 &&
  75.                ecx == 0x444d4163) {
  76.         /* AMD */
  77.         if(ext_caps & (1<<22))
  78.             rval |= MM_MMXEXT;
  79.     } else if (ebx == 0x746e6543 &&
  80.                edx == 0x48727561 &&
  81.                ecx == 0x736c7561) {  /*  "CentaurHauls" */
  82.         /* VIA C3 */
  83. if(ext_caps & (1<<24))
  84.   rval |= MM_MMXEXT;
  85.     } else if (ebx == 0x69727943 &&
  86.                edx == 0x736e4978 &&
  87.                ecx == 0x64616574) {
  88.         /* Cyrix Section */
  89.         /* See if extended CPUID level 80000001 is supported */
  90.         /* The value of CPUID/80000001 for the 6x86MX is undefined
  91.            according to the Cyrix CPU Detection Guide (Preliminary
  92.            Rev. 1.01 table 1), so we'll check the value of eax for
  93.            CPUID/0 to see if standard CPUID level 2 is supported.
  94.            According to the table, the only CPU which supports level
  95.            2 is also the only one which supports extended CPUID levels.
  96.         */
  97.         if (eax < 2) 
  98.             return rval;
  99.         if (ext_caps & (1<<24))
  100.             rval |= MM_MMXEXT;
  101.     }
  102. #if 0
  103.     av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%sn", 
  104.         (rval&MM_MMX) ? "MMX ":"", 
  105.         (rval&MM_MMXEXT) ? "MMX2 ":"", 
  106.         (rval&MM_SSE) ? "SSE ":"", 
  107.         (rval&MM_SSE2) ? "SSE2 ":"", 
  108.         (rval&MM_3DNOW) ? "3DNow ":"", 
  109.         (rval&MM_3DNOWEXT) ? "3DNowExt ":"");
  110. #endif
  111.     return rval;
  112. }
  113. #ifdef __TEST__
  114. int main ( void )
  115. {
  116.   int mm_flags;
  117.   mm_flags = mm_support();
  118.   printf("mm_support = 0x%08Xn",mm_flags);
  119.   return 0;
  120. }
  121. #endif