Mercurial > hg > audiostuff
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 ------------------------------------------------------------*/ |