Mercurial > libavcodec.hg
annotate i386/cputest.c @ 16:89bc3bf1a031 libavcodec
added external cpuid code to solve -fPIC and gcc unclear constraints problems
author | glantau |
---|---|
date | Mon, 30 Jul 2001 23:51:20 +0000 |
parents | b8374040680d |
children | c31fb57d17a6 |
rev | line source |
---|---|
0 | 1 /* Cpu detection code, extracted from mmx.h ((c)1997-99 by H. Dietz |
2 and R. Fisher). Converted to C and improved by Gerard Lantau */ | |
3 | |
4 #include <stdlib.h> | |
5 #include "../dsputil.h" | |
6 | |
16
89bc3bf1a031
added external cpuid code to solve -fPIC and gcc unclear constraints problems
glantau
parents:
4
diff
changeset
|
7 /* need this external function to solve -fPIC ebx issues ! */ |
89bc3bf1a031
added external cpuid code to solve -fPIC and gcc unclear constraints problems
glantau
parents:
4
diff
changeset
|
8 extern void cpuid(int index, int *eax, int *ebx, int *ecx, int *edx); |
0 | 9 |
10 /* Function to test if multimedia instructions are supported... */ | |
11 int mm_support(void) | |
12 { | |
13 int rval; | |
14 int eax, ebx, ecx, edx; | |
15 | |
16 __asm__ __volatile__ ( | |
17 /* See if CPUID instruction is supported ... */ | |
18 /* ... Get copies of EFLAGS into eax and ecx */ | |
19 "pushf\n\t" | |
20 "popl %0\n\t" | |
21 "movl %0, %1\n\t" | |
22 | |
23 /* ... Toggle the ID bit in one copy and store */ | |
24 /* to the EFLAGS reg */ | |
25 "xorl $0x200000, %0\n\t" | |
26 "push %0\n\t" | |
27 "popf\n\t" | |
28 | |
29 /* ... Get the (hopefully modified) EFLAGS */ | |
30 "pushf\n\t" | |
31 "popl %0\n\t" | |
32 : "=a" (eax), "=c" (ecx) | |
33 : | |
34 : "cc" | |
35 ); | |
36 | |
37 if (eax == ecx) | |
38 return 0; /* CPUID not supported */ | |
39 | |
4 | 40 cpuid(0, &eax, &ebx, &ecx, &edx); |
0 | 41 |
42 if (ebx == 0x756e6547 && | |
43 edx == 0x49656e69 && | |
44 ecx == 0x6c65746e) { | |
45 | |
46 /* intel */ | |
47 inteltest: | |
4 | 48 cpuid(1, &eax, &ebx, &ecx, &edx); |
0 | 49 if ((edx & 0x00800000) == 0) |
50 return 0; | |
51 rval = MM_MMX; | |
52 if (edx & 0x02000000) | |
53 rval |= MM_MMXEXT | MM_SSE; | |
54 if (edx & 0x04000000) | |
55 rval |= MM_SSE2; | |
56 return rval; | |
57 } else if (ebx == 0x68747541 && | |
58 edx == 0x69746e65 && | |
59 ecx == 0x444d4163) { | |
60 /* AMD */ | |
4 | 61 cpuid(0x80000000, &eax, &ebx, &ecx, &edx); |
0 | 62 if ((unsigned)eax < 0x80000001) |
63 goto inteltest; | |
4 | 64 cpuid(0x80000001, &eax, &ebx, &ecx, &edx); |
0 | 65 if ((edx & 0x00800000) == 0) |
66 return 0; | |
67 rval = MM_MMX; | |
68 if (edx & 0x80000000) | |
69 rval |= MM_3DNOW; | |
70 if (edx & 0x00400000) | |
71 rval |= MM_MMXEXT; | |
72 return rval; | |
73 } else if (ebx == 0x69727943 && | |
74 edx == 0x736e4978 && | |
75 ecx == 0x64616574) { | |
76 /* Cyrix Section */ | |
77 /* See if extended CPUID level 80000001 is supported */ | |
78 /* The value of CPUID/80000001 for the 6x86MX is undefined | |
79 according to the Cyrix CPU Detection Guide (Preliminary | |
80 Rev. 1.01 table 1), so we'll check the value of eax for | |
81 CPUID/0 to see if standard CPUID level 2 is supported. | |
82 According to the table, the only CPU which supports level | |
83 2 is also the only one which supports extended CPUID levels. | |
84 */ | |
85 if (eax != 2) | |
86 goto inteltest; | |
4 | 87 cpuid(0x80000001, &eax, &ebx, &ecx, &edx); |
0 | 88 if ((eax & 0x00800000) == 0) |
89 return 0; | |
90 rval = MM_MMX; | |
91 if (eax & 0x01000000) | |
92 rval |= MM_MMXEXT; | |
93 return rval; | |
94 } else { | |
95 return 0; | |
96 } | |
97 } |