• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/x86/cpuid.c

Go to the documentation of this file.
00001 /*
00002  * CPU detection code, extracted from mmx.h
00003  * (c)1997-99 by H. Dietz and R. Fisher
00004  * Converted to C and improved by Fabrice Bellard.
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 #include <stdlib.h>
00024 #include "libavutil/x86_cpu.h"
00025 #include "libavcodec/dsputil.h"
00026 
00027 #undef printf
00028 
00029 /* ebx saving is necessary for PIC. gcc seems unable to see it alone */
00030 #define cpuid(index,eax,ebx,ecx,edx)\
00031     __asm__ volatile\
00032         ("mov %%"REG_b", %%"REG_S"\n\t"\
00033          "cpuid\n\t"\
00034          "xchg %%"REG_b", %%"REG_S\
00035          : "=a" (eax), "=S" (ebx),\
00036            "=c" (ecx), "=d" (edx)\
00037          : "0" (index));
00038 
00039 /* Function to test if multimedia instructions are supported...  */
00040 int mm_support(void)
00041 {
00042     int rval = 0;
00043     int eax, ebx, ecx, edx;
00044     int max_std_level, max_ext_level, std_caps=0, ext_caps=0;
00045 
00046 #if ARCH_X86_32
00047     x86_reg a, c;
00048     __asm__ volatile (
00049         /* See if CPUID instruction is supported ... */
00050         /* ... Get copies of EFLAGS into eax and ecx */
00051         "pushfl\n\t"
00052         "pop %0\n\t"
00053         "mov %0, %1\n\t"
00054 
00055         /* ... Toggle the ID bit in one copy and store */
00056         /*     to the EFLAGS reg */
00057         "xor $0x200000, %0\n\t"
00058         "push %0\n\t"
00059         "popfl\n\t"
00060 
00061         /* ... Get the (hopefully modified) EFLAGS */
00062         "pushfl\n\t"
00063         "pop %0\n\t"
00064         : "=a" (a), "=c" (c)
00065         :
00066         : "cc"
00067         );
00068 
00069     if (a == c)
00070         return 0; /* CPUID not supported */
00071 #endif
00072 
00073     cpuid(0, max_std_level, ebx, ecx, edx);
00074 
00075     if(max_std_level >= 1){
00076         cpuid(1, eax, ebx, ecx, std_caps);
00077         if (std_caps & (1<<23))
00078             rval |= FF_MM_MMX;
00079         if (std_caps & (1<<25))
00080             rval |= FF_MM_MMX2
00081 #if HAVE_SSE
00082                   | FF_MM_SSE;
00083         if (std_caps & (1<<26))
00084             rval |= FF_MM_SSE2;
00085         if (ecx & 1)
00086             rval |= FF_MM_SSE3;
00087         if (ecx & 0x00000200 )
00088             rval |= FF_MM_SSSE3;
00089         if (ecx & 0x00080000 )
00090             rval |= FF_MM_SSE4;
00091         if (ecx & 0x00100000 )
00092             rval |= FF_MM_SSE42;
00093 #endif
00094                   ;
00095     }
00096 
00097     cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
00098 
00099     if(max_ext_level >= 0x80000001){
00100         cpuid(0x80000001, eax, ebx, ecx, ext_caps);
00101         if (ext_caps & (1<<31))
00102             rval |= FF_MM_3DNOW;
00103         if (ext_caps & (1<<30))
00104             rval |= FF_MM_3DNOWEXT;
00105         if (ext_caps & (1<<23))
00106             rval |= FF_MM_MMX;
00107         if (ext_caps & (1<<22))
00108             rval |= FF_MM_MMX2;
00109     }
00110 
00111 #if 0
00112     av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s%s%s%s%s\n",
00113         (rval&FF_MM_MMX) ? "MMX ":"",
00114         (rval&FF_MM_MMX2) ? "MMX2 ":"",
00115         (rval&FF_MM_SSE) ? "SSE ":"",
00116         (rval&FF_MM_SSE2) ? "SSE2 ":"",
00117         (rval&FF_MM_SSE3) ? "SSE3 ":"",
00118         (rval&FF_MM_SSSE3) ? "SSSE3 ":"",
00119         (rval&FF_MM_SSE4) ? "SSE4.1 ":"",
00120         (rval&FF_MM_SSE42) ? "SSE4.2 ":"",
00121         (rval&FF_MM_3DNOW) ? "3DNow ":"",
00122         (rval&FF_MM_3DNOWEXT) ? "3DNowExt ":"");
00123 #endif
00124     return rval;
00125 }
00126 
00127 #ifdef TEST
00128 int main ( void )
00129 {
00130     int mm_flags;
00131     mm_flags = mm_support();
00132     printf("mm_support = 0x%08X\n",mm_flags);
00133     return 0;
00134 }
00135 #endif

Generated on Fri Sep 16 2011 17:17:46 for FFmpeg by  doxygen 1.7.1