Add Russian translation provided by Валерий Крувялис <valkru@mail.ru>
[xiph-mirror.git] / theora-old / lib / cpu.c
blob68fc367e5ea935fb8fcbb03539bc7d00af249761
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-2003 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function:
14 last mod: $Id$
16 ********************************************************************/
18 #include "cpu.h"
20 void
21 cpuid(ogg_int32_t op, ogg_uint32_t *out_eax, ogg_uint32_t *out_ebx, ogg_uint32_t *out_ecx, ogg_uint32_t *out_edx)
23 #ifdef USE_ASM
24 # if defined(__x86_64__)
25 asm volatile ("pushq %%rbx \n\t"
26 "cpuid \n\t"
27 "movl %%ebx,%1 \n\t"
28 "popq %%rbx"
29 : "=a" (*out_eax),
30 "=r" (*out_ebx),
31 "=c" (*out_ecx),
32 "=d" (*out_edx)
33 : "a" (op)
34 : "cc");
35 # elif defined(__i386__)
36 asm volatile ("pushl %%ebx \n\t"
37 "cpuid \n\t"
38 "movl %%ebx,%1 \n\t"
39 "popl %%ebx"
40 : "=a" (*out_eax),
41 "=r" (*out_ebx),
42 "=c" (*out_ecx),
43 "=d" (*out_edx)
44 : "a" (op)
45 : "cc");
46 # elif defined(WIN32)
47 ogg_uint32_t my_eax, my_ebx, my_ecx, my_edx;
48 __asm {
49 //push ebx
50 mov eax, op
51 cpuid
52 mov my_eax, eax
53 mov my_ebx, ebx
54 mov my_ecx, ecx
55 mov my_edx, edx
61 *out_eax = my_eax;
62 *out_ebx = my_ebx;
63 *out_ecx = my_ecx;
64 *out_edx = my_edx;
65 # endif
67 #endif
70 #if defined(USE_ASM)
72 static ogg_uint32_t cpu_get_flags (void)
74 ogg_uint32_t eax, ebx, ecx, edx;
75 ogg_uint32_t flags = 0;
77 /* check for cpuid support on i386 */
78 #if defined(__i386__)
79 asm volatile ("pushfl \n\t"
80 "pushfl \n\t"
81 "popl %0 \n\t"
82 "movl %0,%1 \n\t"
83 "xorl $0x200000,%0 \n\t"
84 "pushl %0 \n\t"
85 "popfl \n\t"
86 "pushfl \n\t"
87 "popl %0 \n\t"
88 "popfl"
89 : "=r" (eax),
90 "=r" (ebx)
92 : "cc");
94 if (eax == ebx) /* no cpuid */
95 return 0;
96 #endif
98 /*cpuid(0, &eax, &ebx, &ecx, &edx); */
99 /* Intel */
100 cpuid(1, &eax, &ebx, &ecx, &edx);
101 if ((edx & 0x00800000) == 0)
102 return 0;
103 flags |= CPU_X86_MMX;
104 if (edx & 0x02000000)
105 flags |= CPU_X86_MMXEXT | CPU_X86_SSE;
106 if (edx & 0x04000000)
107 flags |= CPU_X86_SSE2;
109 /* AMD */
110 cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
111 if(eax >= 0x80000001) {
112 cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
113 if ((edx & 0x00800000) != 0) {
114 flags |= CPU_X86_MMX;
115 if (edx & 0x80000000)
116 flags |= CPU_X86_3DNOW;
117 if (edx & 0x40000000)
118 flags |= CPU_X86_3DNOWEXT;
119 if (edx & 0x00400000)
120 flags |= CPU_X86_MMXEXT;
124 return flags;
127 #else /* no supported cpu architecture */
129 static ogg_uint32_t cpu_get_flags (void) {
130 return 0;
133 #endif /* USE_ASM */
135 ogg_uint32_t cpu_init (void)
137 ogg_uint32_t cpu_flags = cpu_get_flags();
139 #ifdef DEBUG
140 if (cpu_flags) {
141 TH_DEBUG("vectorized instruction sets supported:");
142 if (cpu_flags & CPU_X86_MMX) TH_DEBUG(" mmx");
143 if (cpu_flags & CPU_X86_MMXEXT) TH_DEBUG(" mmxext");
144 if (cpu_flags & CPU_X86_SSE) TH_DEBUG(" sse");
145 if (cpu_flags & CPU_X86_SSE2) TH_DEBUG(" sse2");
146 if (cpu_flags & CPU_X86_3DNOW) TH_DEBUG(" 3dnow");
147 if (cpu_flags & CPU_X86_3DNOWEXT) TH_DEBUG(" 3dnowext");
148 TH_DEBUG("\n");
150 #endif
152 return cpu_flags;