diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2004-12-13 16:11:38 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2004-12-13 16:11:38 +0000 |
commit | e42a152bbc0cc5e3486ab94f03e40d04eae13a67 (patch) | |
tree | d5309b7e9a364dd844054da4afa4d382f0b57d1c | |
parent | 74679f5c1ced93085602d1974f25fb8dfe7d760c (diff) | |
download | ffmpeg-e42a152bbc0cc5e3486ab94f03e40d04eae13a67.tar.gz |
x86 cpu capabilities detection rewrite / cleanup
Originally committed as revision 3750 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/avcodec.h | 1 | ||||
-rw-r--r-- | libavcodec/dsputil.h | 1 | ||||
-rw-r--r-- | libavcodec/i386/cputest.c | 101 |
3 files changed, 42 insertions, 61 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 6a00248336..8d1ecfa8b9 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1169,6 +1169,7 @@ typedef struct AVCodecContext { #define FF_MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */ #define FF_MM_SSE 0x0008 /* SSE functions */ #define FF_MM_SSE2 0x0010 /* PIV SSE2 functions */ +#define FF_MM_3DNOWEXT 0x0020 /* AMD 3DNowExt */ #endif /* HAVE_MMX */ /** diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index 2eb1ed404b..83b10baf81 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -408,6 +408,7 @@ int mm_support(void); #define MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */ #define MM_SSE 0x0008 /* SSE functions */ #define MM_SSE2 0x0010 /* PIV SSE2 functions */ +#define MM_3DNOWEXT 0x0020 /* AMD 3DNowExt */ extern int mm_flags; diff --git a/libavcodec/i386/cputest.c b/libavcodec/i386/cputest.c index d2694993e4..593e0550db 100644 --- a/libavcodec/i386/cputest.c +++ b/libavcodec/i386/cputest.c @@ -27,6 +27,7 @@ int mm_support(void) { int rval = 0; int eax, ebx, ecx, edx; + int max_std_level, max_ext_level, std_caps=0, ext_caps=0; long a, c; __asm__ __volatile__ ( @@ -52,58 +53,44 @@ int mm_support(void) if (a == c) return 0; /* CPUID not supported */ - - cpuid(0, eax, ebx, ecx, edx); - if (ebx == 0x756e6547 && - edx == 0x49656e69 && - ecx == 0x6c65746e) { - - /* intel */ - inteltest: - cpuid(1, eax, ebx, ecx, edx); - if ((edx & 0x00800000) == 0) - return 0; - rval |= MM_MMX; - if (edx & 0x02000000) + cpuid(0, max_std_level, ebx, ecx, edx); + + if(max_std_level >= 1){ + cpuid(1, eax, ebx, ecx, std_caps); + if (std_caps & (1<<23)) + rval |= MM_MMX; + if (std_caps & (1<<25)) rval |= MM_MMXEXT | MM_SSE; - if (edx & 0x04000000) + if (std_caps & (1<<26)) rval |= MM_SSE2; - return rval; - } else if (ebx == 0x68747541 && + } + + cpuid(0x80000000, max_ext_level, ebx, ecx, edx); + + if(max_ext_level >= 0x80000001){ + cpuid(0x80000001, eax, ebx, ecx, ext_caps); + if (ext_caps & (1<<31)) + rval |= MM_3DNOW; + if (ext_caps & (1<<30)) + rval |= MM_3DNOWEXT; + if (ext_caps & (1<<23)) + rval |= MM_MMX; + } + + cpuid(0, eax, ebx, ecx, edx); + if ( ebx == 0x68747541 && edx == 0x69746e65 && ecx == 0x444d4163) { /* AMD */ - cpuid(0x80000000, eax, ebx, ecx, edx); - if ((unsigned)eax < 0x80000001) - goto inteltest; - cpuid(0x80000001, eax, ebx, ecx, edx); - if ((edx & 0x00800000) == 0) - return 0; - rval = MM_MMX; - if (edx & 0x80000000) - rval |= MM_3DNOW; - if (edx & 0x00400000) + if(ext_caps & (1<<22)) rval |= MM_MMXEXT; - goto inteltest; } else if (ebx == 0x746e6543 && edx == 0x48727561 && ecx == 0x736c7561) { /* "CentaurHauls" */ /* VIA C3 */ - cpuid(0x80000000, eax, ebx, ecx, edx); - if ((unsigned)eax < 0x80000001) - goto inteltest; - cpuid(0x80000001, eax, ebx, ecx, edx); - rval = 0; - if( edx & ( 1 << 31) ) - rval |= MM_3DNOW; - if( edx & ( 1 << 23) ) - rval |= MM_MMX; - if( edx & ( 1 << 24) ) + if(ext_caps & (1<<24)) rval |= MM_MMXEXT; - if(rval==0) - goto inteltest; - return rval; } else if (ebx == 0x69727943 && edx == 0x736e4978 && ecx == 0x64616574) { @@ -116,29 +103,21 @@ int mm_support(void) According to the table, the only CPU which supports level 2 is also the only one which supports extended CPUID levels. */ - if (eax != 2) - goto inteltest; - cpuid(0x80000001, eax, ebx, ecx, edx); - if ((eax & 0x00800000) == 0) - return 0; - rval = MM_MMX; - if (eax & 0x01000000) + if (eax < 2) + return rval; + if (ext_caps & (1<<24)) rval |= MM_MMXEXT; - return rval; - } else if (ebx == 0x756e6547 && - edx == 0x54656e69 && - ecx == 0x3638784d) { - /* Tranmeta Crusoe */ - cpuid(0x80000000, eax, ebx, ecx, edx); - if ((unsigned)eax < 0x80000001) - return 0; - cpuid(0x80000001, eax, ebx, ecx, edx); - if ((edx & 0x00800000) == 0) - return 0; - return MM_MMX; - } else { - return 0; } +#if 0 + av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s\n", + (rval&MM_MMX) ? "MMX ":"", + (rval&MM_MMXEXT) ? "MMX2 ":"", + (rval&MM_SSE) ? "SSE ":"", + (rval&MM_SSE2) ? "SSE2 ":"", + (rval&MM_3DNOW) ? "3DNow ":"", + (rval&MM_3DNOWEXT) ? "3DNowExt ":""); +#endif + return rval; } #ifdef __TEST__ |