1 /**
2 * @namespace biewlib
3 * @file biewlib/sysdep/ia32/cpu_info.c
4 * @brief This file contains function for retrieving CPU information for
5 * 32-bit Intel x86 compatible platform
6 * @version -
7 * @remark this source file is part of Binary vIEW project (BIEW).
8 * The Binary vIEW (BIEW) is copyright (C) 1995 Nickols_K.
9 * All rights reserved. This software is redistributable under the
10 * licence given in the file "Licence.en" ("Licence.ru" in russian
11 * translation) distributed in the BIEW archive.
12 * @note Requires POSIX compatible development system
13 * @remark I used such form of this file because of build-in assembler
14 * allow write calling convention independed code. In addition,
15 * GNU C compiler is ported under multiple OS's. If somebody will
16 * port it under ABC-xyz platform, then more easy find compiler
17 * with build-in assembler, instead rewriting of makefile with .s
18 * (or .asm) extensions for choosen development system.
19 *
20 * @author Nickols_K
21 * @since 1999
22 * @note Development, fixes and improvements
23 **/
24 #include <stdio.h>
25 #include <string.h>
26
27 #include "biewlib/biewlib.h"
28
29 #define CPU_CLONE 0x000F
30 #define __HAVE_FPU 0x8000
31 #define __HAVE_CPUID 0x4000
32 #define __HAVE_MMX 0x2000
33 #define __HAVE_SSE 0x1000
34
35 #if !defined(__DISABLE_ASM) && (defined(__GNUC__) && defined(NDEBUG))
36
__cpu_type(void)37 static unsigned __NEAR__ __FASTCALL__ __cpu_type( void )
38 {
39 register unsigned retval;
40 __asm __volatile(
41 " pushl %%esp\n"
42 " pushfl\n"
43 " movl %%esp, %%edx\n"
44 " andl $~3, %%esp\n"
45 " pushfl\n"
46 " popl %0\n"
47 " movl %0, %%ecx\n"
48 " xorl $0x40000, %0\n"
49 " pushl %0\n"
50 " popfl\n"
51 " pushfl\n"
52 " popl %0\n"
53 " xorl %%ecx, %0\n"
54 " shrl $0x12, %0\n"
55 " andl $1, %0\n"
56 " pushl %%ecx\n"
57 " popfl\n"
58 " movl %%edx, %%esp\n"
59 " cmpl $0, %0\n"
60 " jnz 4f\n"
61 " movl $3, %0\n"
62 " jmp 1f\n"
63 "4:\n"
64 " pushfl\n"
65 " popl %0\n"
66 " movl %0, %%ecx\n"
67 " xorl $0x200000, %0\n"
68 " pushl %0\n"
69 " popfl\n"
70 " pushfl\n"
71 " popl %0\n"
72 " xorl %%ecx, %0\n"
73 " jnz 5f\n"
74 " movl $4, %0\n"
75 " jmp 1f\n"
76 "5:\n"
77 " movl $1, %0\n"
78 ".short 0xA20F\n" /* cpuid */
79 " movb %h0, %b0\n"
80 " andl $0x0F, %0\n"
81 " orl $0x4000, %0\n"
82 " testl $0x800000, %%edx\n"
83 " jz 0f\n"
84 " orl $0x2000, %0\n"
85 "0:\n"
86 " testl $0x2000000, %%edx\n"
87 " jz 1f\n"
88 " orl $0x1000, %0\n"
89 "1:\n"
90 " popfl\n"
91 " popl %%esp" : /* end assembler block */
92 "=a"(retval) : /* means: return through eax */
93 "0"(3) : /* means: initialize eax with 3 */
94 "ecx","edx","ebx"); /* means: modified registers: ecx, edx, (after cpuid: ebx) */
95 return retval;
96 }
97
__cpu_name(char * buff)98 static void __NEAR__ __FASTCALL__ __cpu_name(char *buff)
99 {
100 __asm __volatile("xorl %%eax, %%eax\n"
101 " .short 0xA20F\n" /* cpuid */
102 " movl %%ebx, %%eax\n"
103 " stosl\n"
104 " movl %%edx, %%eax\n"
105 " stosl\n"
106 " movl %%ecx, %%eax\n"
107 " stosl\n"
108 " xorb %%al, %%al\n"
109 " stosb\n" :
110 :
111 "D"(buff) : /* assume es == ds */
112 "eax","ebx","ecx","edx");
113 }
114
__extended_name(char * buff)115 static void __NEAR__ __FASTCALL__ __extended_name(char *buff)
116 {
117 __asm __volatile("movl $0x80000002, %%eax\n"
118 ".short 0xA20F\n" /* cpuid */
119 " stosl\n"
120 " movl %%ebx, %%eax\n"
121 " stosl\n"
122 " movl %%ecx, %%eax\n"
123 " stosl\n"
124 " movl %%edx, %%eax\n"
125 " stosl\n"
126 " movl $0x80000003, %%eax\n"
127 ".short 0xA20F\n" /* cpuid */
128 " stosl\n"
129 " movl %%ebx, %%eax\n"
130 " stosl\n"
131 " movl %%ecx, %%eax\n"
132 " stosl\n"
133 " movl %%edx, %%eax\n"
134 " stosl\n"
135 " movl $0x80000004, %%eax\n"
136 ".short 0xA20F\n" /* cpuid */
137 " stosl\n"
138 " movl %%ebx, %%eax\n"
139 " stosl\n"
140 " movl %%ecx, %%eax\n"
141 " stosl\n"
142 " movl %%edx, %%eax\n"
143 " stosl\n"
144 " xorb %%al, %%al\n"
145 " stosb\n" :
146 :
147 "D"(buff) : /* assume es == ds */
148 "eax","ebx","ecx","edx");
149 }
150
__cpuid_edx(unsigned long * __r_eax)151 static unsigned long __NEAR__ __FASTCALL__ __cpuid_edx(unsigned long *__r_eax)
152 {
153 register unsigned long r_eax,r_edx,r_ecx,r_ebx;
154 r_eax=*__r_eax;
155 __asm __volatile(
156 ".short 0xA20F": /* cpuid */
157 "=a"(r_eax),"=d"(r_edx),"=b"(r_ebx),"=c"(r_ecx):
158 "0"(r_eax));
159 *__r_eax=r_eax;
160 return r_edx;
161 }
162
__cpuid_ebxecx(unsigned long * __r_eax)163 static unsigned long __NEAR__ __FASTCALL__ __cpuid_ebxecx(unsigned long *__r_eax)
164 {
165 register unsigned long r_eax,r_edx,r_ecx,r_ebx;
166 r_eax=*__r_eax;
167 __asm __volatile(
168 ".short 0xA20F": /* cpuid */
169 "=a"(r_eax),"=d"(r_edx),"=b"(r_ebx),"=c"(r_ecx):
170 "0"(r_eax));
171 *__r_eax=r_ecx;
172 return r_ebx;
173 }
174
__fpu_type(void)175 static unsigned __NEAR__ __FASTCALL__ __fpu_type( void )
176 {
177 unsigned __cw;
178 register unsigned retval;
179 __asm __volatile("fninit\n" /* initialize 80387 (nowait) */
180 " movl $0x20, %%ecx\n"
181 "1:\n"
182 " loop 1b\n" /* wait for it to complete */
183 " fnstcw %1\n" /* store control word */
184 " movl $0x10, %%ecx\n"
185 "2:\n"
186 " loop 2b\n" /* wait for it to complete */
187 /* Determine if we have an FPU */
188 " movl %1, %%eax\n"
189 " andb $0x0F, %%ah\n"
190 " cmpb $0x03, %%ah\n"
191 " jnz 3f\n" /* no 80387 FPU found */
192 " movl $3, %0\n"
193 " jmp 4f\n"
194 "3:\n"
195 " xorl %0, %0\n"
196 "4:\n" :
197 "=r"(retval) :
198 "m"(__cw) :
199 "eax","ecx");
200 return retval;
201 }
202
__OPS_nop(volatile unsigned * time_val)203 static unsigned long __NEAR__ __FASTCALL__ __OPS_nop(volatile unsigned *time_val)
204 {
205 register unsigned long retval;
206 __asm __volatile(
207 "1:\n"
208 " cmpl $0, (%1)\n"
209 " jz 1b\n"
210 "2:\n"
211 " cmpl $0, (%1)\n"
212 " jz 3f\n"
213 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
214 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
215 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
216 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
217 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
218 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
219 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
220 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
221 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
222 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
223 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
224 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
225 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
226 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
227 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
228 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
229 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
230 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
231 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
232 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
233 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
234 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
235 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
236 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
237 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
238 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
239 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
240 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
241 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
242 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
243 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
244 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
245 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
246 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
247 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
248 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
249 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
250 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
251 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
252 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
253 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
254 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
255 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
256 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
257 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
258 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
259 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
260 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
261 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
262 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
263 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
264 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
265 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
266 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
267 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
268 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
269 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
270 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
271 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
272 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
273 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
274 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
275 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
276 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
277 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
278 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
279 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
280 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
281 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
282 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
283 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
284 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
285 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
286 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
287 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
288 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
289 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
290 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
291 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
292 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
293 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
294 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
295 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
296 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
297 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
298 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
299 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
300 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
301 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
302 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
303 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
304 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
305 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
306 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
307 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
308 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
309 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
310 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
311 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
312 ".byte 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
313 " inc %0\n"
314 " jmp 2b\n"
315 "3:" :
316 "=a"(retval) :
317 "r"(time_val),
318 "0"(0));
319 return retval;
320 }
321
__OPS_std(volatile unsigned * counter,char * arr8byte)322 static unsigned long __NEAR__ __FASTCALL__ __OPS_std(volatile unsigned *counter,char *arr8byte)
323 {
324 register unsigned long retval;
325 __asm __volatile("xorl %0, %0\n"
326 "1:\n"
327 " cmpl $0, (%1)\n"
328 " jz 1b\n"
329 "2:\n"
330 " cmpl $0, (%1)\n"
331 " jnz 3f\n"
332 " jmp 4f\n"
333 "3:\n"
334 " pushl %0\n"
335
336 " movl $0x14, %%eax\n"
337 " movl $0x07, %%ecx\n"
338 " mull %%ecx\n"
339 " imull %%ecx\n"
340 " divl %%ecx\n"
341 " idivl %%ecx\n"
342 " addl %%ecx, %%eax\n"
343 " adcl $0x01, %%eax\n"
344 " subl %%ecx, %%eax\n"
345 " sbbl $0x01, %%eax\n"
346 " pushl %%esi\n"
347 " pushl %%edi\n"
348 " movl %2, %%esi\n"
349 " movsl\n"
350 " call 5f\n"
351 " cmpsl\n"
352 " popl %%edi\n"
353 " popl %%esi\n"
354 " pushl %%eax\n"
355 " pushl %%edx\n"
356 " popl %%edx\n"
357 " popl %%eax\n"
358 " movl $0x14, %%eax\n"
359 " movl $0x07, %%ecx\n"
360 " mull %%ecx\n"
361 " imull %%ecx\n"
362 " divl %%ecx\n"
363 " idivl %%ecx\n"
364 " addl %%ecx, %%eax\n"
365 " adcl $0x01, %%eax\n"
366 " subl %%ecx, %%eax\n"
367 " sbbl $0x01, %%eax\n"
368 " pushl %%esi\n"
369 " pushl %%edi\n"
370 " movl %2, %%esi\n"
371 " movsl\n"
372 " call 5f\n"
373 " cmpsl\n"
374 " popl %%edi\n"
375 " popl %%esi\n"
376 " pushl %%eax\n"
377 " pushl %%edx\n"
378 " popl %%edx\n"
379 " popl %%eax\n"
380 " movl $0x14, %%eax\n"
381 " movl $0x07, %%ecx\n"
382 " mull %%ecx\n"
383 " imull %%ecx\n"
384 " divl %%ecx\n"
385 " idivl %%ecx\n"
386 " addl %%ecx, %%eax\n"
387 " adcl $0x01, %%eax\n"
388 " subl %%ecx, %%eax\n"
389 " sbbl $0x01, %%eax\n"
390 " pushl %%esi\n"
391 " pushl %%edi\n"
392 " movl %2, %%esi\n"
393 " movsl\n"
394 " call 5f\n"
395 " cmpsl\n"
396 " popl %%edi\n"
397 " popl %%esi\n"
398 " pushl %%eax\n"
399 " pushl %%edx\n"
400 " popl %%edx\n"
401 " popl %%eax\n"
402 " movl $0x14, %%eax\n"
403 " movl $0x07, %%ecx\n"
404 " mull %%ecx\n"
405 " imull %%ecx\n"
406 " divl %%ecx\n"
407 " idivl %%ecx\n"
408 " adcl $0x01, %%eax\n"
409 " subl %%ecx, %%eax\n"
410 " sbbl $0x01, %%eax\n"
411 " pushl %%edx\n"
412 " popl %%edx\n"
413
414 " popl %0\n"
415 " incl %0\n"
416 " jmp 2b\n"
417 "5: ret\n"
418 "4:\n" :
419 "=a"(retval) :
420 "S"(counter),
421 "D"(arr8byte) :
422 "edx","ecx");
423 return retval;
424 }
425
__FOPS_nowait(volatile unsigned * counter,char * arr18bytes)426 static unsigned long __NEAR__ __FASTCALL__ __FOPS_nowait(volatile unsigned *counter,char *arr18bytes)
427 {
428 register unsigned long retval;
429 __asm __volatile("xorl %0, %0\n"
430 "1:\n"
431 " cmpl $0, (%1)\n"
432 " jz 1b\n"
433 "2:\n"
434 " cmpl $0, (%1)\n"
435 " jz 3f\n"
436
437 " fninit\n"
438 " fldt 8(%2)\n"
439 " fstpt 8(%2)\n"
440 " fstp %%st(1)\n"
441 " fldz\n"
442 " fld1\n"
443 " fcompp\n"
444 " fnstsw 4(%2)\n"
445 " fnstcw (%2)\n"
446 " fldcw (%2)\n"
447 " fldpi\n"
448 " fstp %%st(1)\n"
449 " fst %%st(2)\n"
450 " fst %%st(3)\n"
451 " f2xm1\n"
452 " fabs\n"
453 " fchs\n"
454 " fprem\n"
455 " fptan\n"
456 " fsqrt\n"
457 " frndint\n"
458 " faddp %%st,%%st(1)\n"
459 " fstp %%st(1)\n"
460 " fmulp %%st,%%st(1)\n"
461 " fstp %%st(1)\n"
462 " fld1\n"
463 " fstp %%st(1)\n"
464 " fpatan\n"
465 " fstp %%st(1)\n"
466 " fscale\n"
467 " fstp %%st(1)\n"
468 " fdivrp %%st, %%st(1)\n"
469 " fstp %%st(1)\n"
470 " fsubp %%st, %%st(1)\n"
471 " fstp %%st(1)\n"
472 " fyl2x\n"
473 " fstp %%st(1)\n"
474 " fyl2xp1\n"
475 " fstp %%st(1)\n"
476 " fbld 8(%2)\n"
477 " fbstp 8(%2)\n"
478 " filds (%2)\n"
479 " fistps (%2)\n"
480 " fldt 4(%2)\n"
481 " fstpt 4(%2)\n"
482 " fstp %%st(1)\n"
483 " fldz\n"
484 " fld1\n"
485 " fcompp\n"
486 " fnstsw 4(%2)\n"
487 " fnstcw (%2)\n"
488 " fldcw (%2)\n"
489 " fldpi\n"
490 " fstp %%st(1)\n"
491 " fst %%st(2)\n"
492 " fst %%st(3)\n"
493 " f2xm1\n"
494 " fabs\n"
495 " fchs\n"
496 " fprem\n"
497 " fptan\n"
498 " fsqrt\n"
499 " frndint\n"
500 " faddp %%st,%%st(1)\n"
501 " fstp %%st(1)\n"
502 " fmulp %%st,%%st(1)\n"
503 " fstp %%st(1)\n"
504 " fld1\n"
505 " fstp %%st(1)\n"
506 " fpatan\n"
507 " fstp %%st(1)\n"
508 " fscale\n"
509 " fstp %%st(1)\n"
510 " fdivrp %%st, %%st(1)\n"
511 " fstp %%st(1)\n"
512 " fsubp %%st, %%st(1)\n"
513 " fstp %%st(1)\n"
514 " fyl2x\n"
515 " fstp %%st(1)\n"
516 " fyl2xp1\n"
517 " fstp %%st(1)\n"
518 " filds (%2)\n"
519 " fistps (%2)\n"
520 " incl %0\n"
521 " jmp 2b\n"
522 "3:" :
523 "=a"(retval) :
524 "S"(counter),
525 "D"(arr18bytes) :
526 "st","st(1)","st(2)","st(3)");
527 return retval;
528 }
529
__FOPS_w_wait(volatile unsigned * counter,char * arr14bytes)530 static unsigned long __NEAR__ __FASTCALL__ __FOPS_w_wait(volatile unsigned *counter,char *arr14bytes)
531 {
532 return __FOPS_nowait(counter,arr14bytes);
533 }
534
__MOPS_std(volatile unsigned * counter,char * arr)535 static unsigned long __NEAR__ __FASTCALL__ __MOPS_std(volatile unsigned *counter,char *arr)
536 {
537 register unsigned long retval;
538 retval=0;
539 while(*counter==0);
540 while(*counter!=0){
541 __asm __volatile(
542 "movd %0,%%mm0\n"
543 "packssdw %%mm0,%%mm5 \n"
544 "packsswb %%mm0,%%mm4 \n"
545 "packuswb %%mm0,%%mm7 \n"
546 "paddb %%mm3,%%mm2 \n"
547 "paddd %%mm5,%%mm1 \n"
548 "psubsb %%mm4,%%mm6 \n"
549 "psubusb %%mm3,%%mm4 \n"
550 "pand %%mm1,%%mm3 \n"
551 "pcmpeqd %%mm0,%%mm0 \n"
552 "pcmpgtb %%mm2,%%mm2 \n"
553 "pmaddwd %%mm7,%%mm7 \n"
554 "pmullw %%mm6,%%mm6 \n"
555 "por %%mm2,%%mm4 \n"
556 "psllq %%mm0,%%mm6 \n"
557 "psrad %%mm1,%%mm3 \n"
558 "psubb %%mm1,%%mm1 \n"
559 "psubsw %%mm2,%%mm7 \n"
560 "psubusw %%mm3,%%mm1 \n"
561 "punpckhdq %%mm0,%%mm4 \n"
562 "punpcklwd %%mm2,%%mm0 \n"
563 "pxor %%mm4,%%mm2 \n"
564 "packssdw %%mm0,%%mm5 \n"
565 "packsswb %%mm0,%%mm4 \n"
566 "packuswb %%mm0,%%mm7 \n"
567 "paddb %%mm3,%%mm2 \n"
568 "paddd %%mm5,%%mm1 \n"
569 "psubsb %%mm4,%%mm6 \n"
570 "psubusb %%mm3,%%mm4 \n"
571 "pand %%mm1,%%mm3 \n"
572 "pcmpeqd %%mm0,%%mm0 \n"
573 "pcmpgtb %%mm2,%%mm2 \n"
574 "pmaddwd %%mm7,%%mm7 \n"
575 "pmullw %%mm6,%%mm6 \n"
576 "por %%mm2,%%mm4 \n"
577 "psllq %%mm0,%%mm6 \n"
578 "psrad %%mm1,%%mm3 \n"
579 "psubb %%mm1,%%mm1 \n"
580 "psubsw %%mm2,%%mm7 \n"
581 "psubusw %%mm3,%%mm1 \n"
582 "punpckhdq %%mm0,%%mm4 \n"
583 "punpcklwd %%mm2,%%mm0 \n"
584 "pxor %%mm4,%%mm2 \n"
585 "movd %0,%%mm0 \n"
586 "packssdw %%mm0,%%mm5 \n"
587 "packsswb %%mm0,%%mm4 \n"
588 "packuswb %%mm0,%%mm7 \n"
589 "paddb %%mm3,%%mm2 \n"
590 "paddd %%mm5,%%mm1 \n"
591 "psubsb %%mm4,%%mm6 \n"
592 "psubusb %%mm3,%%mm4 \n"
593 "pand %%mm1,%%mm3 \n"
594 "pcmpeqd %%mm0,%%mm0 \n"
595 "pcmpgtb %%mm2,%%mm2 \n"
596 "pmaddwd %%mm7,%%mm7 \n"
597 "pmullw %%mm6,%%mm6 \n"
598 "por %%mm2,%%mm4 \n"
599 "psllq %%mm0,%%mm6 \n"
600 "psrad %%mm1,%%mm3 \n"
601 "psubb %%mm1,%%mm1 \n"
602 "psubsw %%mm2,%%mm7 \n"
603 "psubusw %%mm3,%%mm1 \n"
604 "punpckhdq %%mm0,%%mm4 \n"
605 "punpcklwd %%mm2,%%mm0 \n"
606 "pxor %%mm4,%%mm2 \n"
607 "packssdw %%mm0,%%mm5 \n"
608 "packsswb %%mm0,%%mm4 \n"
609 "packuswb %%mm0,%%mm7 \n"
610 "paddb %%mm3,%%mm2 \n"
611 "paddd %%mm5,%%mm1 \n"
612 "psubsb %%mm4,%%mm6 \n"
613 "psubusb %%mm3,%%mm4 \n"
614 "pand %%mm1,%%mm3 \n"
615 "pcmpeqd %%mm0,%%mm0 \n"
616 "pcmpgtb %%mm2,%%mm2 \n"
617 "pmaddwd %%mm7,%%mm7 \n"
618 "pmullw %%mm6,%%mm6 \n"
619 "por %%mm2,%%mm4 \n"
620 "psllq %%mm0,%%mm6 \n"
621 "psrad %%mm1,%%mm3 \n"
622 "psubb %%mm1,%%mm1 \n"
623 "psubsw %%mm2,%%mm7 \n"
624 "psubusw %%mm3,%%mm1 \n"
625 "punpckhdq %%mm0,%%mm4 \n"
626 "punpcklwd %%mm2,%%mm0 \n"
627 "pxor %%mm4,%%mm2"
628 ::"r"(retval)
629 :"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
630 retval++;
631 }
632 return retval;
633 }
634
__SSEOPS_std(volatile unsigned * counter,char * arr)635 static unsigned long __NEAR__ __FASTCALL__ __SSEOPS_std(volatile unsigned *counter,char *arr)
636 {
637 register unsigned long retval;
638 retval=0;
639 while(*counter==0);
640 while(*counter!=0){
641 __asm __volatile(
642 "movaps (%0), %%xmm0 \n"
643 "movhps (%0),%%xmm1 \n"
644 "movlps (%0),%%xmm2 \n"
645 "movups (%0),%%xmm3 \n"
646 "addps %%xmm0,%%xmm1 \n"
647 "addss %%xmm0,%%xmm1 \n"
648 "cvtps2pi %%xmm1,%%mm0 \n"
649 "cvttps2pi %%xmm2,%%mm1 \n"
650 "maxps %%xmm0,%%xmm1 \n"
651 "maxss %%xmm0,%%xmm1 \n"
652 "minps %%xmm0,%%xmm1 \n"
653 "minss %%xmm0,%%xmm1 \n"
654 "mulps %%xmm0,%%xmm1 \n"
655 "mulss %%xmm0,%%xmm1 \n"
656 "andps %%xmm0,%%xmm1 \n"
657 "orps %%xmm0,%%xmm1 \n"
658 "xorps %%xmm1,%%xmm1 \n"
659 "divps %%xmm0,%%xmm1 \n"
660 "divss %%xmm0,%%xmm1 \n"
661 "rcpps %%xmm0,%%xmm1 \n"
662 "rcpss %%xmm0,%%xmm1 \n"
663 "rsqrtps %%xmm0,%%xmm1 \n"
664 "rsqrtss %%xmm0,%%xmm1 \n"
665 "sqrtps %%xmm0,%%xmm1 \n"
666 "sqrtss %%xmm0,%%xmm1 \n"
667 "subps %%xmm0,%%xmm1 \n"
668 "subss %%xmm0,%%xmm1 \n"
669 "ucomiss %%xmm0,%%xmm1 \n"
670 "unpckhps %%xmm0,%%xmm1 \n"
671 "unpcklps %%xmm0,%%xmm1 \n"
672 "movaps (%0),%%xmm0 \n"
673 "movhps (%0),%%xmm1 \n"
674 "movlps (%0),%%xmm2 \n"
675 "movups (%0),%%xmm3 \n"
676 "addps %%xmm0,%%xmm1 \n"
677 "addss %%xmm0,%%xmm1 \n"
678 "cvtps2pi %%xmm1,%%mm0 \n"
679 "cvttps2pi %%xmm2,%%mm1 \n"
680 "maxps %%xmm0,%%xmm1 \n"
681 "maxss %%xmm0,%%xmm1 \n"
682 "minps %%xmm0,%%xmm1 \n"
683 "minss %%xmm0,%%xmm1 \n"
684 "mulps %%xmm0,%%xmm1 \n"
685 "mulss %%xmm0,%%xmm1 \n"
686 "andps %%xmm0,%%xmm1 \n"
687 "orps %%xmm0,%%xmm1 \n"
688 "xorps %%xmm1,%%xmm1 \n"
689 "divps %%xmm0,%%xmm1 \n"
690 "divss %%xmm0,%%xmm1 \n"
691 "rcpps %%xmm0,%%xmm1 \n"
692 "rcpss %%xmm0,%%xmm1 \n"
693 "rsqrtps %%xmm0,%%xmm1 \n"
694 "rsqrtss %%xmm0,%%xmm1 \n"
695 "sqrtps %%xmm0,%%xmm1 \n"
696 "sqrtss %%xmm0,%%xmm1 \n"
697 "subps %%xmm0,%%xmm1 \n"
698 "subss %%xmm0,%%xmm1 \n"
699 "ucomiss %%xmm0,%%xmm1 \n"
700 "unpckhps %%xmm0,%%xmm1 \n"
701 "unpcklps %%xmm0,%%xmm1 \n"
702 ::"r"(arr)
703 :"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7");
704 retval++;
705 }
706 return retval;
707 }
708
709 #define __ASMPART_DEFINED 1
710 #include "biewlib/sysdep/ia16/cmn_ix86.c"
711
712 #elif defined(__WATCOMC__) && __WATCOMC__ >= 1100
713
714 #include "biewlib/sysdep/ia32/cpu_info.wc"
715
716 #define __ASMPART_DEFINED 1
717 #include "biewlib/sysdep/ia16/cmn_ix86.c"
718
719 #elif defined(__WATCOMC__) && defined(__QNX4__)
720
721 #include "biewlib/sysdep/ia32/qnx/cpu_info.qnx"
722
723 #define __ASMPART_DEFINED 1
724 #include "biewlib/sysdep/ia16/cmn_ix86.c"
725
726 #else
727
728 #include "biewlib/sysdep/generic/cpu_info.c"
729
730 #endif
731