Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / media / libtheora / lib / cpu.c
blobc1b19d8071f051b4e65f9a1fb6fd4bff6bd3c887
1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2008 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 CPU capability detection for x86 processors.
14 Originally written by Rudolf Marek.
16 function:
17 last mod: $Id: cpu.c 14718 2008-04-12 08:36:58Z conrad $
19 ********************************************************************/
21 #include "cpu.h"
23 #if !defined(USE_ASM)
25 ogg_uint32_t oc_cpu_flags_get(void){
26 return 0;
29 #else /* USE_ASM */
31 # if defined(_MSC_VER)
32 /* Visual C cpuid helper function. For VS2005 we could
33 as well use the _cpuid builtin, but that wouldn't work
34 for VS2003 users, so we do it in inline assembler */
36 static void oc_cpuid_helper (ogg_uint32_t * CpuInfo, ogg_uint32_t op){
37 _asm {
38 mov eax, [op]
39 mov esi, CpuInfo
40 cpuid
41 mov [esi + 0], eax
42 mov [esi + 4], ebx
43 mov [esi + 8], ecx
44 mov [esi +12], edx
48 # define cpuid(_op,_eax,_ebx,_ecx,_edx) \
49 { \
50 ogg_uint32_t nfo[4]; \
51 oc_cpuid_helper (nfo, (_op)); \
52 (_eax) = nfo[0],(_ebx) = nfo[1]; \
53 (_ecx) = nfo[2],(_edx) = nfo[3]; \
56 # elif (defined(__amd64__) || defined(__x86_64__))
58 # define cpuid(_op,_eax,_ebx,_ecx,_edx) \
59 __asm__ __volatile__( \
60 "push %%rbx\n\t" \
61 "cpuid\n\t" \
62 "movl %%ebx,%1\n\t" \
63 "pop %%rbx\n\t" \
64 :"=a" (_eax), \
65 "=r" (_ebx), \
66 "=c" (_ecx), \
67 "=d" (_edx) \
68 :"a" (_op) \
69 :"cc" \
71 # else /* x86_32, GCC */
73 # define cpuid(_op,_eax,_ebx,_ecx,_edx) \
74 __asm__ __volatile__( \
75 "pushl %%ebx\n\t" \
76 "cpuid\n\t" \
77 "movl %%ebx,%1\n\t" \
78 "popl %%ebx\n\t" \
79 :"=a" (_eax), \
80 "=r" (_ebx), \
81 "=c" (_ecx), \
82 "=d" (_edx) \
83 :"a" (_op) \
84 :"cc" \
87 # endif /* arch switch */
89 ogg_uint32_t oc_cpu_flags_get(void){
90 ogg_uint32_t flags = 0;
91 ogg_uint32_t eax;
92 ogg_uint32_t ebx;
93 ogg_uint32_t ecx;
94 ogg_uint32_t edx;
96 # if !defined(_MSC_VER) && !defined(__amd64__) && !defined(__x86_64__)
97 /* check for cpuid */
98 __asm__ __volatile__(
99 "pushfl\n\t"
100 "pushfl\n\t"
101 "popl %0\n\t"
102 "movl %0,%1\n\t"
103 "xorl $0x200000,%0\n\t"
104 "pushl %0\n\t"
105 "popfl\n\t"
106 "pushfl\n\t"
107 "popl %0\n\t"
108 "popfl\n\t"
109 :"=r" (eax),
110 "=r" (ebx)
112 :"cc"
114 /*No cpuid.*/
115 if(eax==ebx)return 0;
116 # endif /* GCC, x86_32 */
118 cpuid(0,eax,ebx,ecx,edx);
119 if(ebx==0x756e6547&&edx==0x49656e69&&ecx==0x6c65746e){
120 /*Intel:*/
121 inteltest:
122 cpuid(1,eax,ebx,ecx,edx);
123 if((edx&0x00800000)==0)return 0;
124 flags=OC_CPU_X86_MMX;
125 if(edx&0x02000000)flags|=OC_CPU_X86_MMXEXT|OC_CPU_X86_SSE;
126 if(edx&0x04000000)flags|=OC_CPU_X86_SSE2;
128 else if(ebx==0x68747541&&edx==0x69746e65&&ecx==0x444d4163 ||
129 ebx==0x646f6547&&edx==0x79622065&&ecx==0x43534e20){
130 /*AMD:*/
131 /*Geode:*/
132 cpuid(0x80000000,eax,ebx,ecx,edx);
133 if(eax<0x80000001)goto inteltest;
134 cpuid(0x80000001,eax,ebx,ecx,edx);
135 if((edx&0x00800000)==0)return 0;
136 flags=OC_CPU_X86_MMX;
137 if(edx&0x80000000)flags|=OC_CPU_X86_3DNOW;
138 if(edx&0x40000000)flags|=OC_CPU_X86_3DNOWEXT;
139 if(edx&0x00400000)flags|=OC_CPU_X86_MMXEXT;
141 else{
142 /*Implement me.*/
143 flags=0;
146 # ifdef DEBUG
147 if (flags) {
148 TH_DEBUG("vectorized instruction sets supported:");
149 if (flags & OC_CPU_X86_MMX) TH_DEBUG(" mmx");
150 if (flags & OC_CPU_X86_MMXEXT) TH_DEBUG(" mmxext");
151 if (flags & OC_CPU_X86_SSE) TH_DEBUG(" sse");
152 if (flags & OC_CPU_X86_SSE2) TH_DEBUG(" sse2");
153 if (flags & OC_CPU_X86_3DNOW) TH_DEBUG(" 3dnow");
154 if (flags & OC_CPU_X86_3DNOWEXT) TH_DEBUG(" 3dnowext");
155 TH_DEBUG("\n");
157 # endif
159 return flags;
162 #endif /* USE_ASM */