comparison spandsp-0.0.3/spandsp-0.0.3/src/testcpuid.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
4:26cd8f1ef0b1 5:f762bf195c4b
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * testcpuid.c - Check the CPU type, to identify special features, like SSE.
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 * Stitched together from bits of testing code found here and there
8 *
9 * Copyright (C) 2004 Steve Underwood
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2, as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * $Id: testcpuid.c,v 1.9 2006/10/24 13:45:27 steveu Exp $
27 */
28
29 /*! \file */
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #include <inttypes.h>
36
37 /* Make this file just disappear if we are not on an x86 machine */
38 #if defined(__i386__) // || defined(__x86_64__)
39
40 #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
41 #define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
42 #define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */
43 #define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
44 #define X86_EFLAGS_SF 0x00000080 /* Sign Flag */
45 #define X86_EFLAGS_TF 0x00000100 /* Trap Flag */
46 #define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */
47 #define X86_EFLAGS_DF 0x00000400 /* Direction Flag */
48 #define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */
49 #define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
50 #define X86_EFLAGS_NT 0x00004000 /* Nested Task */
51 #define X86_EFLAGS_RF 0x00010000 /* Resume Flag */
52 #define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
53 #define X86_EFLAGS_AC 0x00040000 /* Alignment Check */
54 #define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */
55 #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
56 #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
57
58 /* Standard macro to see if a specific flag is changeable */
59 static __inline__ int flag_is_changeable_p(uint32_t flag)
60 {
61 uint32_t f1;
62 uint32_t f2;
63
64 __asm__ __volatile__ (
65 " pushfl\n"
66 " pushfl\n"
67 " popl %0\n"
68 " movl %0,%1\n"
69 " xorl %2,%0\n"
70 " pushl %0\n"
71 " popfl\n"
72 " pushfl\n"
73 " popl %0\n"
74 " popfl\n"
75 : "=&r" (f1), "=&r" (f2)
76 : "ir" (flag));
77
78 return ((f1^f2) & flag) != 0;
79 }
80 /*- End of function --------------------------------------------------------*/
81
82 /* Probe for the CPUID instruction */
83 static int have_cpuid_p(void)
84 {
85 return flag_is_changeable_p(X86_EFLAGS_ID);
86 }
87 /*- End of function --------------------------------------------------------*/
88
89 int has_MMX(void)
90 {
91 int result;
92
93 if (!have_cpuid_p())
94 return 0;
95 /*endif*/
96 __asm__ __volatile__ (
97 " push %%ebx;\n"
98 " mov $1,%%eax;\n"
99 " cpuid;\n"
100 " xor %%eax,%%eax;\n"
101 " test $0x800000,%%edx;\n"
102 " jz 1f;\n" /* no MMX support */
103 " inc %%eax;\n" /* MMX support */
104 "1:\n"
105 " pop %%ebx;\n"
106 : "=a" (result)
107 :
108 : "ecx", "edx");
109 return result;
110 }
111 /*- End of function --------------------------------------------------------*/
112
113 int has_SIMD(void)
114 {
115 int result;
116
117 if (!have_cpuid_p())
118 return 0;
119 /*endif*/
120 __asm__ __volatile__ (
121 " push %%ebx;\n"
122 " mov $1,%%eax;\n"
123 " cpuid;\n"
124 " xor %%eax,%%eax;\n"
125 " test $0x02000000,%%edx;\n"
126 " jz 1f;\n" /* no SIMD support */
127 " inc %%eax;\n" /* SIMD support */
128 "1:\n"
129 " pop %%ebx;\n"
130 : "=a" (result)
131 :
132 : "ecx", "edx");
133 return result;
134 }
135 /*- End of function --------------------------------------------------------*/
136
137 int has_SIMD2(void)
138 {
139 int result;
140
141 if (!have_cpuid_p())
142 return 0;
143 /*endif*/
144 __asm__ __volatile__ (
145 " push %%ebx;\n"
146 " mov $1,%%eax;\n"
147 " cpuid;\n"
148 " xor %%eax,%%eax;\n"
149 " test $0x04000000,%%edx;\n"
150 " jz 1f;\n" /* no SIMD2 support */
151 " inc %%eax;\n" /* SIMD2 support */
152 "1:\n"
153 " pop %%ebx;\n"
154 : "=a" (result)
155 :
156 : "ecx", "edx");
157 return result;
158 }
159 /*- End of function --------------------------------------------------------*/
160
161 int has_3DNow(void)
162 {
163 int result;
164
165 if (!have_cpuid_p())
166 return 0;
167 /*endif*/
168 __asm__ __volatile__ (
169 " push %%ebx;\n"
170 " mov $0x80000000,%%eax;\n"
171 " cpuid;\n"
172 " xor %%ecx,%%ecx;\n"
173 " cmp $0x80000000,%%eax;\n"
174 " jbe 1f;\n" /* no extended MSR(1), so no 3DNow! */
175 " mov $0x80000001,%%eax;\n"
176 " cpuid;\n"
177 " xor %%ecx,%%ecx;\n"
178 " test $0x80000000,%%edx;\n"
179 " jz 1f;\n" /* no 3DNow! support */
180 " inc %%ecx;\n" /* 3DNow! support */
181 "1:\n"
182 " pop %%ebx;\n"
183 : "=c" (result)
184 :
185 : "eax", "edx");
186 return result;
187 }
188 /*- End of function --------------------------------------------------------*/
189
190 #if defined(TESTBED)
191 int main(int argc, char *argv[])
192 {
193 int result;
194
195 result = has_MMX();
196 printf("MMX is %x\n", result);
197 result = has_SIMD();
198 printf("SIMD is %x\n", result);
199 result = has_SIMD2();
200 printf("SIMD2 is %x\n", result);
201 result = has_3DNow();
202 printf("3DNow is %x\n", result);
203 return 0;
204 }
205 /*- End of function --------------------------------------------------------*/
206 #endif
207
208 #endif
209 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.