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