1 | /* Cpu detection code, extracted from mmx.h ((c)1997-99 by H. Dietz
|
---|
2 | and R. Fisher). Converted to C and improved by Fabrice Bellard */
|
---|
3 |
|
---|
4 | #include <stdlib.h>
|
---|
5 | #include "../dsputil.h"
|
---|
6 |
|
---|
7 | #ifdef ARCH_X86_64
|
---|
8 | # define REG_b "rbx"
|
---|
9 | # define REG_S "rsi"
|
---|
10 | #else
|
---|
11 | # define REG_b "ebx"
|
---|
12 | # define REG_S "esi"
|
---|
13 | #endif
|
---|
14 |
|
---|
15 | /* ebx saving is necessary for PIC. gcc seems unable to see it alone */
|
---|
16 | #define cpuid(index,eax,ebx,ecx,edx)\
|
---|
17 | __asm __volatile\
|
---|
18 | ("mov %%"REG_b", %%"REG_S"\n\t"\
|
---|
19 | "cpuid\n\t"\
|
---|
20 | "xchg %%"REG_b", %%"REG_S\
|
---|
21 | : "=a" (eax), "=S" (ebx),\
|
---|
22 | "=c" (ecx), "=d" (edx)\
|
---|
23 | : "0" (index));
|
---|
24 |
|
---|
25 | /* Function to test if multimedia instructions are supported... */
|
---|
26 | int mm_support(void)
|
---|
27 | {
|
---|
28 | int rval = 0;
|
---|
29 | int eax, ebx, ecx, edx;
|
---|
30 | int max_std_level, max_ext_level, std_caps=0, ext_caps=0;
|
---|
31 | long a, c;
|
---|
32 |
|
---|
33 | __asm__ __volatile__ (
|
---|
34 | /* See if CPUID instruction is supported ... */
|
---|
35 | /* ... Get copies of EFLAGS into eax and ecx */
|
---|
36 | "pushf\n\t"
|
---|
37 | "pop %0\n\t"
|
---|
38 | "mov %0, %1\n\t"
|
---|
39 |
|
---|
40 | /* ... Toggle the ID bit in one copy and store */
|
---|
41 | /* to the EFLAGS reg */
|
---|
42 | "xor $0x200000, %0\n\t"
|
---|
43 | "push %0\n\t"
|
---|
44 | "popf\n\t"
|
---|
45 |
|
---|
46 | /* ... Get the (hopefully modified) EFLAGS */
|
---|
47 | "pushf\n\t"
|
---|
48 | "pop %0\n\t"
|
---|
49 | : "=a" (a), "=c" (c)
|
---|
50 | :
|
---|
51 | : "cc"
|
---|
52 | );
|
---|
53 |
|
---|
54 | if (a == c)
|
---|
55 | return 0; /* CPUID not supported */
|
---|
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 | if (ecx & 1)
|
---|
68 | rval |= MM_SSE3;
|
---|
69 | }
|
---|
70 |
|
---|
71 | cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
|
---|
72 |
|
---|
73 | if(max_ext_level >= 0x80000001){
|
---|
74 | cpuid(0x80000001, eax, ebx, ecx, ext_caps);
|
---|
75 | if (ext_caps & (1<<31))
|
---|
76 | rval |= MM_3DNOW;
|
---|
77 | if (ext_caps & (1<<30))
|
---|
78 | rval |= MM_3DNOWEXT;
|
---|
79 | if (ext_caps & (1<<23))
|
---|
80 | rval |= MM_MMX;
|
---|
81 | if (ext_caps & (1<<22))
|
---|
82 | rval |= MM_MMXEXT;
|
---|
83 | }
|
---|
84 |
|
---|
85 | #if 0
|
---|
86 | av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s\n",
|
---|
87 | (rval&MM_MMX) ? "MMX ":"",
|
---|
88 | (rval&MM_MMXEXT) ? "MMX2 ":"",
|
---|
89 | (rval&MM_SSE) ? "SSE ":"",
|
---|
90 | (rval&MM_SSE2) ? "SSE2 ":"",
|
---|
91 | (rval&MM_3DNOW) ? "3DNow ":"",
|
---|
92 | (rval&MM_3DNOWEXT) ? "3DNowExt ":"");
|
---|
93 | #endif
|
---|
94 | return rval;
|
---|
95 | }
|
---|
96 |
|
---|
97 | #ifdef __TEST__
|
---|
98 | int main ( void )
|
---|
99 | {
|
---|
100 | int mm_flags;
|
---|
101 | mm_flags = mm_support();
|
---|
102 | printf("mm_support = 0x%08X\n",mm_flags);
|
---|
103 | return 0;
|
---|
104 | }
|
---|
105 | #endif
|
---|