Mercurial > libavcodec.hg
comparison i386/cputest.c @ 2388:55a72627a2c5 libavcodec
x86 cpu capabilities detection rewrite / cleanup
author | michael |
---|---|
date | Mon, 13 Dec 2004 16:11:38 +0000 |
parents | 9214c91cdfb7 |
children | ef2149182f1c |
comparison
equal
deleted
inserted
replaced
2387:f45248df9796 | 2388:55a72627a2c5 |
---|---|
25 /* Function to test if multimedia instructions are supported... */ | 25 /* Function to test if multimedia instructions are supported... */ |
26 int mm_support(void) | 26 int mm_support(void) |
27 { | 27 { |
28 int rval = 0; | 28 int rval = 0; |
29 int eax, ebx, ecx, edx; | 29 int eax, ebx, ecx, edx; |
30 int max_std_level, max_ext_level, std_caps=0, ext_caps=0; | |
30 long a, c; | 31 long a, c; |
31 | 32 |
32 __asm__ __volatile__ ( | 33 __asm__ __volatile__ ( |
33 /* See if CPUID instruction is supported ... */ | 34 /* See if CPUID instruction is supported ... */ |
34 /* ... Get copies of EFLAGS into eax and ecx */ | 35 /* ... Get copies of EFLAGS into eax and ecx */ |
50 : "cc" | 51 : "cc" |
51 ); | 52 ); |
52 | 53 |
53 if (a == c) | 54 if (a == c) |
54 return 0; /* CPUID not supported */ | 55 return 0; /* CPUID not supported */ |
55 | 56 |
57 cpuid(0, max_std_level, ebx, ecx, edx); | |
58 | |
59 if(max_std_level >= 1){ | |
60 cpuid(1, eax, ebx, ecx, std_caps); | |
61 if (std_caps & (1<<23)) | |
62 rval |= MM_MMX; | |
63 if (std_caps & (1<<25)) | |
64 rval |= MM_MMXEXT | MM_SSE; | |
65 if (std_caps & (1<<26)) | |
66 rval |= MM_SSE2; | |
67 } | |
68 | |
69 cpuid(0x80000000, max_ext_level, ebx, ecx, edx); | |
70 | |
71 if(max_ext_level >= 0x80000001){ | |
72 cpuid(0x80000001, eax, ebx, ecx, ext_caps); | |
73 if (ext_caps & (1<<31)) | |
74 rval |= MM_3DNOW; | |
75 if (ext_caps & (1<<30)) | |
76 rval |= MM_3DNOWEXT; | |
77 if (ext_caps & (1<<23)) | |
78 rval |= MM_MMX; | |
79 } | |
80 | |
56 cpuid(0, eax, ebx, ecx, edx); | 81 cpuid(0, eax, ebx, ecx, edx); |
57 | 82 if ( ebx == 0x68747541 && |
58 if (ebx == 0x756e6547 && | |
59 edx == 0x49656e69 && | |
60 ecx == 0x6c65746e) { | |
61 | |
62 /* intel */ | |
63 inteltest: | |
64 cpuid(1, eax, ebx, ecx, edx); | |
65 if ((edx & 0x00800000) == 0) | |
66 return 0; | |
67 rval |= MM_MMX; | |
68 if (edx & 0x02000000) | |
69 rval |= MM_MMXEXT | MM_SSE; | |
70 if (edx & 0x04000000) | |
71 rval |= MM_SSE2; | |
72 return rval; | |
73 } else if (ebx == 0x68747541 && | |
74 edx == 0x69746e65 && | 83 edx == 0x69746e65 && |
75 ecx == 0x444d4163) { | 84 ecx == 0x444d4163) { |
76 /* AMD */ | 85 /* AMD */ |
77 cpuid(0x80000000, eax, ebx, ecx, edx); | 86 if(ext_caps & (1<<22)) |
78 if ((unsigned)eax < 0x80000001) | |
79 goto inteltest; | |
80 cpuid(0x80000001, eax, ebx, ecx, edx); | |
81 if ((edx & 0x00800000) == 0) | |
82 return 0; | |
83 rval = MM_MMX; | |
84 if (edx & 0x80000000) | |
85 rval |= MM_3DNOW; | |
86 if (edx & 0x00400000) | |
87 rval |= MM_MMXEXT; | 87 rval |= MM_MMXEXT; |
88 goto inteltest; | |
89 } else if (ebx == 0x746e6543 && | 88 } else if (ebx == 0x746e6543 && |
90 edx == 0x48727561 && | 89 edx == 0x48727561 && |
91 ecx == 0x736c7561) { /* "CentaurHauls" */ | 90 ecx == 0x736c7561) { /* "CentaurHauls" */ |
92 /* VIA C3 */ | 91 /* VIA C3 */ |
93 cpuid(0x80000000, eax, ebx, ecx, edx); | 92 if(ext_caps & (1<<24)) |
94 if ((unsigned)eax < 0x80000001) | |
95 goto inteltest; | |
96 cpuid(0x80000001, eax, ebx, ecx, edx); | |
97 rval = 0; | |
98 if( edx & ( 1 << 31) ) | |
99 rval |= MM_3DNOW; | |
100 if( edx & ( 1 << 23) ) | |
101 rval |= MM_MMX; | |
102 if( edx & ( 1 << 24) ) | |
103 rval |= MM_MMXEXT; | 93 rval |= MM_MMXEXT; |
104 if(rval==0) | |
105 goto inteltest; | |
106 return rval; | |
107 } else if (ebx == 0x69727943 && | 94 } else if (ebx == 0x69727943 && |
108 edx == 0x736e4978 && | 95 edx == 0x736e4978 && |
109 ecx == 0x64616574) { | 96 ecx == 0x64616574) { |
110 /* Cyrix Section */ | 97 /* Cyrix Section */ |
111 /* See if extended CPUID level 80000001 is supported */ | 98 /* See if extended CPUID level 80000001 is supported */ |
114 Rev. 1.01 table 1), so we'll check the value of eax for | 101 Rev. 1.01 table 1), so we'll check the value of eax for |
115 CPUID/0 to see if standard CPUID level 2 is supported. | 102 CPUID/0 to see if standard CPUID level 2 is supported. |
116 According to the table, the only CPU which supports level | 103 According to the table, the only CPU which supports level |
117 2 is also the only one which supports extended CPUID levels. | 104 2 is also the only one which supports extended CPUID levels. |
118 */ | 105 */ |
119 if (eax != 2) | 106 if (eax < 2) |
120 goto inteltest; | 107 return rval; |
121 cpuid(0x80000001, eax, ebx, ecx, edx); | 108 if (ext_caps & (1<<24)) |
122 if ((eax & 0x00800000) == 0) | |
123 return 0; | |
124 rval = MM_MMX; | |
125 if (eax & 0x01000000) | |
126 rval |= MM_MMXEXT; | 109 rval |= MM_MMXEXT; |
127 return rval; | |
128 } else if (ebx == 0x756e6547 && | |
129 edx == 0x54656e69 && | |
130 ecx == 0x3638784d) { | |
131 /* Tranmeta Crusoe */ | |
132 cpuid(0x80000000, eax, ebx, ecx, edx); | |
133 if ((unsigned)eax < 0x80000001) | |
134 return 0; | |
135 cpuid(0x80000001, eax, ebx, ecx, edx); | |
136 if ((edx & 0x00800000) == 0) | |
137 return 0; | |
138 return MM_MMX; | |
139 } else { | |
140 return 0; | |
141 } | 110 } |
111 #if 0 | |
112 av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s\n", | |
113 (rval&MM_MMX) ? "MMX ":"", | |
114 (rval&MM_MMXEXT) ? "MMX2 ":"", | |
115 (rval&MM_SSE) ? "SSE ":"", | |
116 (rval&MM_SSE2) ? "SSE2 ":"", | |
117 (rval&MM_3DNOW) ? "3DNow ":"", | |
118 (rval&MM_3DNOWEXT) ? "3DNowExt ":""); | |
119 #endif | |
120 return rval; | |
142 } | 121 } |
143 | 122 |
144 #ifdef __TEST__ | 123 #ifdef __TEST__ |
145 int main ( void ) | 124 int main ( void ) |
146 { | 125 { |