1 /********************************************************************
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. *
8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2008 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 CPU capability detection for x86 processors.
14 Originally written by Rudolf Marek.
17 last mod: $Id: cpu.c 14718 2008-04-12 08:36:58Z conrad $
19 ********************************************************************/
25 ogg_uint32_t
oc_cpu_flags_get(void){
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
){
48 # define cpuid(_op,_eax,_ebx,_ecx,_edx) \
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__( \
71 # else /* x86_32, GCC */
73 # define cpuid(_op,_eax,_ebx,_ecx,_edx) \
74 __asm__ __volatile__( \
87 # endif /* arch switch */
89 ogg_uint32_t
oc_cpu_flags_get(void){
90 ogg_uint32_t flags
= 0;
96 # if !defined(_MSC_VER) && !defined(__amd64__) && !defined(__x86_64__)
103 "xorl $0x200000,%0\n\t"
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){
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){
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
;
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");