Mercurial > libavutil.hg
comparison x86/cpu.h @ 1009:40b8596460af libavutil
Move mm_support() from libavcodec to libavutil, make it a public
function and rename it to av_get_cpu_flags().
author | stefano |
---|---|
date | Wed, 08 Sep 2010 15:07:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1008:8280cce54f50 | 1009:40b8596460af |
---|---|
1 /* | |
2 * CPU detection code, extracted from mmx.h | |
3 * (c)1997-99 by H. Dietz and R. Fisher | |
4 * Converted to C and improved by Fabrice Bellard. | |
5 * | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
23 #ifndef AVUTIL_X86_CPU_H2 | |
24 #define AVUTIL_X86_CPU_H2 | |
25 | |
26 #include <stdlib.h> | |
27 #include "libavutil/x86_cpu.h" | |
28 #include "libavutil/cpu.h" | |
29 | |
30 /* ebx saving is necessary for PIC. gcc seems unable to see it alone */ | |
31 #define cpuid(index,eax,ebx,ecx,edx)\ | |
32 __asm__ volatile\ | |
33 ("mov %%"REG_b", %%"REG_S"\n\t"\ | |
34 "cpuid\n\t"\ | |
35 "xchg %%"REG_b", %%"REG_S\ | |
36 : "=a" (eax), "=S" (ebx),\ | |
37 "=c" (ecx), "=d" (edx)\ | |
38 : "0" (index)); | |
39 | |
40 /* Function to test if multimedia instructions are supported... */ | |
41 int av_get_cpu_flags(void) | |
42 { | |
43 int rval = 0; | |
44 int eax, ebx, ecx, edx; | |
45 int max_std_level, max_ext_level, std_caps=0, ext_caps=0; | |
46 int family=0, model=0; | |
47 union { int i[3]; char c[12]; } vendor; | |
48 | |
49 #if ARCH_X86_32 | |
50 x86_reg a, c; | |
51 __asm__ volatile ( | |
52 /* See if CPUID instruction is supported ... */ | |
53 /* ... Get copies of EFLAGS into eax and ecx */ | |
54 "pushfl\n\t" | |
55 "pop %0\n\t" | |
56 "mov %0, %1\n\t" | |
57 | |
58 /* ... Toggle the ID bit in one copy and store */ | |
59 /* to the EFLAGS reg */ | |
60 "xor $0x200000, %0\n\t" | |
61 "push %0\n\t" | |
62 "popfl\n\t" | |
63 | |
64 /* ... Get the (hopefully modified) EFLAGS */ | |
65 "pushfl\n\t" | |
66 "pop %0\n\t" | |
67 : "=a" (a), "=c" (c) | |
68 : | |
69 : "cc" | |
70 ); | |
71 | |
72 if (a == c) | |
73 return 0; /* CPUID not supported */ | |
74 #endif | |
75 | |
76 cpuid(0, max_std_level, vendor.i[0], vendor.i[2], vendor.i[1]); | |
77 | |
78 if(max_std_level >= 1){ | |
79 cpuid(1, eax, ebx, ecx, std_caps); | |
80 family = ((eax>>8)&0xf) + ((eax>>20)&0xff); | |
81 model = ((eax>>4)&0xf) + ((eax>>12)&0xf0); | |
82 if (std_caps & (1<<23)) | |
83 rval |= AV_CPU_FLAG_MMX; | |
84 if (std_caps & (1<<25)) | |
85 rval |= AV_CPU_FLAG_MMX2 | |
86 #if HAVE_SSE | |
87 | AV_CPU_FLAG_SSE; | |
88 if (std_caps & (1<<26)) | |
89 rval |= AV_CPU_FLAG_SSE2; | |
90 if (ecx & 1) | |
91 rval |= AV_CPU_FLAG_SSE3; | |
92 if (ecx & 0x00000200 ) | |
93 rval |= AV_CPU_FLAG_SSSE3; | |
94 if (ecx & 0x00080000 ) | |
95 rval |= AV_CPU_FLAG_SSE4; | |
96 if (ecx & 0x00100000 ) | |
97 rval |= AV_CPU_FLAG_SSE42; | |
98 #endif | |
99 ; | |
100 } | |
101 | |
102 cpuid(0x80000000, max_ext_level, ebx, ecx, edx); | |
103 | |
104 if(max_ext_level >= 0x80000001){ | |
105 cpuid(0x80000001, eax, ebx, ecx, ext_caps); | |
106 if (ext_caps & (1<<31)) | |
107 rval |= AV_CPU_FLAG_3DNOW; | |
108 if (ext_caps & (1<<30)) | |
109 rval |= AV_CPU_FLAG_3DNOWEXT; | |
110 if (ext_caps & (1<<23)) | |
111 rval |= AV_CPU_FLAG_MMX; | |
112 if (ext_caps & (1<<22)) | |
113 rval |= AV_CPU_FLAG_MMX2; | |
114 } | |
115 | |
116 if (!strncmp(vendor.c, "GenuineIntel", 12) && | |
117 family == 6 && (model == 9 || model == 13 || model == 14)) { | |
118 /* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and 6/14 (core1 "yonah") | |
119 * theoretically support sse2, but it's usually slower than mmx, | |
120 * so let's just pretend they don't. */ | |
121 if (rval & AV_CPU_FLAG_SSE2) rval ^= AV_CPU_FLAG_SSE2SLOW|AV_CPU_FLAG_SSE2; | |
122 if (rval & AV_CPU_FLAG_SSE3) rval ^= AV_CPU_FLAG_SSE3SLOW|AV_CPU_FLAG_SSE3; | |
123 } | |
124 | |
125 return rval; | |
126 } | |
127 | |
128 #endif /* AVUTIL_X86_CPU_H2 */ |