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 {