1 /**
2  * @namespace   biewlib
3  * @file        biewlib/sysdep/x86_64/cpu_info.c
4  * @brief       This file contains function for retrieving CPU information for
5  *              64-bit AMD 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       2009
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 
do_cpuid(unsigned int ax,unsigned int * p)37 static inline void do_cpuid(unsigned int ax, unsigned int *p)
38 {
39 	__asm __volatile(
40 	"cpuid"
41 	: "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
42 	:  "0" (ax)
43 	);
44 }
45 
46 
__cpu_type(void)47 static unsigned __NEAR__ __FASTCALL__ __cpu_type( void )
48 {
49    return 8|__HAVE_CPUID|__HAVE_MMX|__HAVE_SSE|__HAVE_FPU;
50 }
51 
__cpu_name(char * buff)52 static void __NEAR__ __FASTCALL__ __cpu_name(char *buff)
53 {
54     unsigned int p[4];
55     do_cpuid(0,p);
56     memcpy(&buff[0],&p[1],4);
57     memcpy(&buff[4],&p[3],4);
58     memcpy(&buff[8],&p[2],4);
59     buff[12]='\0';
60 }
61 
__extended_name(char * buff)62 static void __NEAR__ __FASTCALL__ __extended_name(char *buff)
63 {
64 /*
65     unsigned int p[4];
66     do_cpuid(0x80000002,p);
67     memcpy(&buff[0], &p[0],4);
68     memcpy(&buff[4], &p[1],4);
69     memcpy(&buff[8], &p[2],4);
70     memcpy(&buff[12],&p[3],4);
71     do_cpuid(0x80000003,p);
72     memcpy(&buff[16],&p[0],4);
73     memcpy(&buff[20],&p[1],4);
74     memcpy(&buff[24],&p[2],4);
75     memcpy(&buff[28],&p[3],4);
76     do_cpuid(0x80000004,p);
77     memcpy(&buff[32],&p[0],4);
78     memcpy(&buff[36],&p[1],4);
79     memcpy(&buff[40],&p[2],4);
80     memcpy(&buff[44],&p[3],4);
81     buff[48]='\0';
82 */
83    __asm __volatile("movl	$0x80000002, %%eax\n"
84       "cpuid\n"
85       "	stosl\n"
86       "	movl	%%ebx, %%eax\n"
87       "	stosl\n"
88       "	movl	%%ecx, %%eax\n"
89       "	stosl\n"
90       "	movl	%%edx, %%eax\n"
91       "	stosl\n"
92       "	movl	$0x80000003, %%eax\n"
93       "cpuid\n"
94       "	stosl\n"
95       "	movl	%%ebx, %%eax\n"
96       "	stosl\n"
97       "	movl	%%ecx, %%eax\n"
98       "	stosl\n"
99       "	movl	%%edx, %%eax\n"
100       "	stosl\n"
101       "	movl	$0x80000004, %%eax\n"
102       "cpuid\n"
103       "	stosl\n"
104       "	movl	%%ebx, %%eax\n"
105       "	stosl\n"
106       "	movl	%%ecx, %%eax\n"
107       "	stosl\n"
108       "	movl	%%edx, %%eax\n"
109       "	stosl\n"
110       "	xorb	%%al, %%al\n"
111       "	stosb\n"	:
112                    	:
113       "D"(buff)		:
114       "eax","ebx","ecx","edx");
115 }
116 
__cpuid_edx(unsigned long * __r_eax)117 static unsigned long __NEAR__ __FASTCALL__ __cpuid_edx(unsigned long *__r_eax)
118 {
119   unsigned int p[4];
120   do_cpuid(*__r_eax,p);
121   *__r_eax=p[0];
122   return p[3];
123 }
124 
__cpuid_ebxecx(unsigned long * __r_eax)125 static unsigned long __NEAR__ __FASTCALL__ __cpuid_ebxecx(unsigned long *__r_eax)
126 {
127   unsigned int p[4];
128   do_cpuid(*__r_eax,p);
129   *__r_eax=p[2];
130   return p[1];
131 }
132 
__fpu_type(void)133 static unsigned __NEAR__ __FASTCALL__ __fpu_type( void )
134 {
135    return 8;
136 }
137 
__OPS_nop(volatile unsigned * time_val)138 static unsigned long __NEAR__ __FASTCALL__ __OPS_nop(volatile unsigned *time_val)
139 {
140   register unsigned long retval;
141    __asm __volatile(
142 "1:\n"
143       "	cmpl	$0, (%1)\n"
144       "	jz	1b\n"
145 "2:\n"
146       "	cmpl	$0, (%1)\n"
147       "	jz	3f\n"
148 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
149 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
150 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
151 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
152 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
153 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
154 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
155 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
156 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
157 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
158 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
159 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
160 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
161 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
162 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
163 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
164 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
165 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
166 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
167 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
168 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
169 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
170 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
171 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
172 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
173 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
174 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
175 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
176 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
177 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
178 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
179 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
180 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
181 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
182 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
183 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
184 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
185 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
186 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
187 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
188 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
189 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
190 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
191 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
192 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
193 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
194 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
195 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
196 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
197 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
198 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
199 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
200 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
201 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
202 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
203 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
204 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
205 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
206 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
207 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
208 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
209 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
210 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
211 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\n"
212 ".byte  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90\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       "	inc	%0\n"
249       "	jmp	2b\n"
250 "3:"			:
251       "=a"(retval)	:
252       "r"(time_val),
253       "0"(0));
254   return retval;
255 }
__OPS_std(volatile unsigned * counter,char * arr8byte)256 static unsigned long __NEAR__ __FASTCALL__ __OPS_std(volatile unsigned *counter,char *arr8byte)
257 {
258   unsigned long retval;
259   register long long dummy;
260    retval=0;
261    while(*counter==0);
262    while(*counter!=0){
263    __asm __volatile(
264       "pushq	%0\n"
265 
266       "movq	$0x14, %0\n"
267       "movq	$0x07, %%rcx\n"
268       "mulq	%%rcx\n"
269       "imulq	%%rcx\n"
270       "divq	%%rcx\n"
271       "idivq	%%rcx\n"
272       "addq	%%rcx, %0\n"
273       "adcq	$0x01, %0\n"
274       "subq	%%rcx, %0\n"
275       "sbbq	$0x01, %0\n"
276       "pushq	%2\n"
277       "pushq	%1\n"
278       "movq	%2, %2\n"
279       "movsq\n"
280       "cmpsq\n"
281       "popq	%1\n"
282       "popq	%2\n"
283       "pushq	%0\n"
284       "pushq	%%rdx\n"
285       "popq	%%rdx\n"
286       "popq	%0\n"
287       "movq	$0x14, %0\n"
288       "movq	$0x07, %%rcx\n"
289       "mulq	%%rcx\n"
290       "imulq	%%rcx\n"
291       "divq	%%rcx\n"
292       "idivq	%%rcx\n"
293       "addq	%%rcx, %0\n"
294       "adcq	$0x01, %0\n"
295       "subq	%%rcx, %0\n"
296       "sbbq	$0x01, %0\n"
297       "pushq	%2\n"
298       "pushq	%1\n"
299       "movq	%2, %2\n"
300       "movsq\n"
301       "cmpsq\n"
302       "popq	%1\n"
303       "popq	%2\n"
304       "pushq	%0\n"
305       "pushq	%%rdx\n"
306       "popq	%%rdx\n"
307       "popq	%0\n"
308       "movq	$0x14, %0\n"
309       "movq	$0x07, %%rcx\n"
310       "mulq	%%rcx\n"
311       "imulq	%%rcx\n"
312       "divq	%%rcx\n"
313       "idivq	%%rcx\n"
314       "addq	%%rcx, %0\n"
315       "adcq	$0x01, %0\n"
316       "subq	%%rcx, %0\n"
317       "sbbq	$0x01, %0\n"
318       "pushq	%2\n"
319       "pushq	%1\n"
320       "movq	%2, %2\n"
321       "movsq\n"
322       "cmpsq\n"
323       "popq	%1\n"
324       "popq	%2\n"
325       "pushq	%0\n"
326       "pushq	%%rdx\n"
327       "popq	%%rdx\n"
328       "popq	%0\n"
329       "movq	$0x14, %0\n"
330       "movq	$0x07, %%rcx\n"
331       "mulq	%%rcx\n"
332       "imulq	%%rcx\n"
333       "divq	%%rcx\n"
334       "idivq	%%rcx\n"
335       "adcq	$0x01, %0\n"
336       "subq	%%rcx, %0\n"
337       "sbbq	$0x01, %0\n"
338       "pushq	%%rdx\n"
339       "popq	%%rdx\n"
340       "popq	%0\n"
341 :"=r"(dummy)
342 :"S"(counter),"D"(arr8byte)
343 :"rcx","rdx","cc");
344      retval++;
345   }
346   return retval;
347 }
348 
__FOPS_nowait(volatile unsigned * counter,char * arr18bytes)349 static unsigned long __NEAR__ __FASTCALL__ __FOPS_nowait(volatile unsigned *counter,char *arr18bytes)
350 {
351   register unsigned long retval,dummy;
352    retval=0;
353    while(*counter==0);
354    while(*counter!=0){
355    __asm __volatile(
356       "	fninit\n"
357       "	fldt	8(%1)\n"
358       "	fstpt	8(%1)\n"
359       "	fstp	%%st(0)\n"
360       "	fldz\n"
361       "	fld1\n"
362       "	fcompp\n"
363       "	fnstsw	4(%1)\n"
364       "	fnstcw	(%1)\n"
365       "	fldcw	(%1)\n"
366       "	fldpi\n"
367       "	fstp	%%st(1)\n"
368       "	fst	%%st(2)\n"
369       "	fst	%%st(3)\n"
370       "	f2xm1\n"
371       "	fabs\n"
372       "	fchs\n"
373       "	fprem\n"
374       "	fptan\n"
375       "	fsqrt\n"
376       "	frndint\n"
377       "	faddp	%%st,%%st(1)\n"
378       "	fstp	%%st(1)\n"
379       "	fmulp	%%st,%%st(1)\n"
380       "	fstp	%%st(1)\n"
381       "	fld1\n"
382       "	fstp	%%st(1)\n"
383       "	fpatan\n"
384       "	fstp	%%st(1)\n"
385       "	fscale\n"
386       "	fstp	%%st(1)\n"
387       "	fdivrp	%%st, %%st(1)\n"
388       "	fstp	%%st(1)\n"
389       "	fsubp	%%st, %%st(1)\n"
390       "	fstp	%%st(1)\n"
391       "	fyl2x\n"
392       "	fstp	%%st(1)\n"
393       "	fyl2xp1\n"
394       "	fstp	%%st(1)\n"
395       "	fbld	8(%1)\n"
396       "	fbstp	8(%1)\n"
397       "	filds	(%1)\n"
398       "	fistps	(%1)\n"
399       "	fldt	4(%1)\n"
400       "	fstpt	4(%1)\n"
401       "	fstp	%%st(1)\n"
402       "	fldz\n"
403       "	fld1\n"
404       "	fcompp\n"
405       "	fnstsw	4(%1)\n"
406       "	fnstcw	(%1)\n"
407       "	fldcw	(%1)\n"
408       "	fldpi\n"
409       "	fstp	%%st(1)\n"
410       "	fst	%%st(2)\n"
411       "	fst	%%st(3)\n"
412       "	f2xm1\n"
413       "	fabs\n"
414       "	fchs\n"
415       "	fprem\n"
416       "	fptan\n"
417       "	fsqrt\n"
418       "	frndint\n"
419       "	faddp	%%st,%%st(1)\n"
420       "	fstp	%%st(1)\n"
421       "	fmulp	%%st,%%st(1)\n"
422       "	fstp	%%st(1)\n"
423       "	fld1\n"
424       "	fstp	%%st(1)\n"
425       "	fpatan\n"
426       "	fstp	%%st(1)\n"
427       "	fscale\n"
428       "	fstp	%%st(1)\n"
429       "	fdivrp	%%st, %%st(1)\n"
430       "	fstp	%%st(1)\n"
431       "	fsubp	%%st, %%st(1)\n"
432       "	fstp	%%st(1)\n"
433       "	fyl2x\n"
434       "	fstp	%%st(1)\n"
435       "	fyl2xp1\n"
436       "	fstp	%%st(1)\n"
437       "	filds	(%1)\n"
438       "	fistps	(%1)"
439      ::"r"(counter),"r"(arr18bytes)
440      :"st","st(1)","st(2)","st(3)");
441      retval++;
442   }
443   return retval;
444 }
445 
__FOPS_w_wait(volatile unsigned * counter,char * arr14bytes)446 static unsigned long __NEAR__ __FASTCALL__ __FOPS_w_wait(volatile unsigned *counter,char *arr14bytes)
447 {
448   return __FOPS_nowait(counter,arr14bytes);
449 }
450 
__MOPS_std(volatile unsigned * counter,char * arr)451 static unsigned long __NEAR__ __FASTCALL__ __MOPS_std(volatile unsigned *counter,char *arr)
452 {
453   register unsigned long retval;
454    retval=0;
455    while(*counter==0);
456    while(*counter!=0){
457     __asm __volatile(
458 "movd	%0,%%mm0\n"
459 "packssdw %%mm0,%%mm5 \n"
460 "packsswb %%mm0,%%mm4 \n"
461 "packuswb %%mm0,%%mm7 \n"
462 "paddb    %%mm3,%%mm2 \n"
463 "paddd    %%mm5,%%mm1 \n"
464 "psubsb   %%mm4,%%mm6 \n"
465 "psubusb  %%mm3,%%mm4 \n"
466 "pand     %%mm1,%%mm3 \n"
467 "pcmpeqd  %%mm0,%%mm0 \n"
468 "pcmpgtb  %%mm2,%%mm2 \n"
469 "pmaddwd  %%mm7,%%mm7 \n"
470 "pmullw   %%mm6,%%mm6 \n"
471 "por      %%mm2,%%mm4 \n"
472 "psllq    %%mm0,%%mm6 \n"
473 "psrad    %%mm1,%%mm3 \n"
474 "psubb    %%mm1,%%mm1 \n"
475 "psubsw   %%mm2,%%mm7 \n"
476 "psubusw  %%mm3,%%mm1 \n"
477 "punpckhdq %%mm0,%%mm4 \n"
478 "punpcklwd %%mm2,%%mm0 \n"
479 "pxor     %%mm4,%%mm2 \n"
480 "packssdw %%mm0,%%mm5 \n"
481 "packsswb %%mm0,%%mm4 \n"
482 "packuswb %%mm0,%%mm7 \n"
483 "paddb    %%mm3,%%mm2 \n"
484 "paddd    %%mm5,%%mm1 \n"
485 "psubsb   %%mm4,%%mm6 \n"
486 "psubusb  %%mm3,%%mm4 \n"
487 "pand     %%mm1,%%mm3 \n"
488 "pcmpeqd  %%mm0,%%mm0 \n"
489 "pcmpgtb  %%mm2,%%mm2 \n"
490 "pmaddwd  %%mm7,%%mm7 \n"
491 "pmullw   %%mm6,%%mm6 \n"
492 "por      %%mm2,%%mm4 \n"
493 "psllq    %%mm0,%%mm6 \n"
494 "psrad    %%mm1,%%mm3 \n"
495 "psubb    %%mm1,%%mm1 \n"
496 "psubsw   %%mm2,%%mm7 \n"
497 "psubusw  %%mm3,%%mm1 \n"
498 "punpckhdq %%mm0,%%mm4 \n"
499 "punpcklwd %%mm2,%%mm0 \n"
500 "pxor     %%mm4,%%mm2 \n"
501 "movd     %0,%%mm0 \n"
502 "packssdw %%mm0,%%mm5 \n"
503 "packsswb %%mm0,%%mm4 \n"
504 "packuswb %%mm0,%%mm7 \n"
505 "paddb    %%mm3,%%mm2 \n"
506 "paddd    %%mm5,%%mm1 \n"
507 "psubsb   %%mm4,%%mm6 \n"
508 "psubusb  %%mm3,%%mm4 \n"
509 "pand     %%mm1,%%mm3 \n"
510 "pcmpeqd  %%mm0,%%mm0 \n"
511 "pcmpgtb  %%mm2,%%mm2 \n"
512 "pmaddwd  %%mm7,%%mm7 \n"
513 "pmullw   %%mm6,%%mm6 \n"
514 "por      %%mm2,%%mm4 \n"
515 "psllq    %%mm0,%%mm6 \n"
516 "psrad    %%mm1,%%mm3 \n"
517 "psubb    %%mm1,%%mm1 \n"
518 "psubsw   %%mm2,%%mm7 \n"
519 "psubusw  %%mm3,%%mm1 \n"
520 "punpckhdq %%mm0,%%mm4 \n"
521 "punpcklwd %%mm2,%%mm0 \n"
522 "pxor     %%mm4,%%mm2 \n"
523 "packssdw %%mm0,%%mm5 \n"
524 "packsswb %%mm0,%%mm4 \n"
525 "packuswb %%mm0,%%mm7 \n"
526 "paddb    %%mm3,%%mm2 \n"
527 "paddd    %%mm5,%%mm1 \n"
528 "psubsb   %%mm4,%%mm6 \n"
529 "psubusb  %%mm3,%%mm4 \n"
530 "pand     %%mm1,%%mm3 \n"
531 "pcmpeqd  %%mm0,%%mm0 \n"
532 "pcmpgtb  %%mm2,%%mm2 \n"
533 "pmaddwd  %%mm7,%%mm7 \n"
534 "pmullw   %%mm6,%%mm6 \n"
535 "por      %%mm2,%%mm4 \n"
536 "psllq    %%mm0,%%mm6 \n"
537 "psrad    %%mm1,%%mm3 \n"
538 "psubb    %%mm1,%%mm1 \n"
539 "psubsw   %%mm2,%%mm7 \n"
540 "psubusw  %%mm3,%%mm1 \n"
541 "punpckhdq %%mm0,%%mm4 \n"
542 "punpcklwd %%mm2,%%mm0 \n"
543 "pxor     %%mm4,%%mm2"
544   ::"r"(retval)
545   :"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
546   retval++;
547   }
548   return retval;
549 }
550 
__SSEOPS_std(volatile unsigned * counter,char * arr)551 static unsigned long __NEAR__ __FASTCALL__ __SSEOPS_std(volatile unsigned *counter,char *arr)
552 {
553   register unsigned long retval;
554    retval=0;
555    while(*counter==0);
556    while(*counter!=0){
557     __asm __volatile(
558 "movaps   (%0), %%xmm0 \n"
559 "movhps   (%0),%%xmm1 \n"
560 "movlps   (%0),%%xmm2 \n"
561 "movups   (%0),%%xmm3 \n"
562 "addps    %%xmm0,%%xmm1 \n"
563 "addss    %%xmm0,%%xmm1 \n"
564 "cvtps2pi %%xmm1,%%mm0 \n"
565 "cvttps2pi %%xmm2,%%mm1 \n"
566 "maxps    %%xmm0,%%xmm1 \n"
567 "maxss    %%xmm0,%%xmm1 \n"
568 "minps    %%xmm0,%%xmm1 \n"
569 "minss    %%xmm0,%%xmm1 \n"
570 "mulps    %%xmm0,%%xmm1 \n"
571 "mulss    %%xmm0,%%xmm1 \n"
572 "andps    %%xmm0,%%xmm1 \n"
573 "orps     %%xmm0,%%xmm1 \n"
574 "xorps    %%xmm1,%%xmm1 \n"
575 "divps    %%xmm0,%%xmm1 \n"
576 "divss    %%xmm0,%%xmm1 \n"
577 "rcpps    %%xmm0,%%xmm1 \n"
578 "rcpss    %%xmm0,%%xmm1 \n"
579 "rsqrtps  %%xmm0,%%xmm1 \n"
580 "rsqrtss  %%xmm0,%%xmm1 \n"
581 "sqrtps   %%xmm0,%%xmm1 \n"
582 "sqrtss   %%xmm0,%%xmm1 \n"
583 "subps    %%xmm0,%%xmm1 \n"
584 "subss    %%xmm0,%%xmm1 \n"
585 "ucomiss  %%xmm0,%%xmm1 \n"
586 "unpckhps %%xmm0,%%xmm1 \n"
587 "unpcklps %%xmm0,%%xmm1 \n"
588 "movaps   (%0),%%xmm0 \n"
589 "movhps   (%0),%%xmm1 \n"
590 "movlps   (%0),%%xmm2 \n"
591 "movups   (%0),%%xmm3 \n"
592 "addps    %%xmm0,%%xmm1 \n"
593 "addss    %%xmm0,%%xmm1 \n"
594 "cvtps2pi %%xmm1,%%mm0 \n"
595 "cvttps2pi %%xmm2,%%mm1 \n"
596 "maxps    %%xmm0,%%xmm1 \n"
597 "maxss    %%xmm0,%%xmm1 \n"
598 "minps    %%xmm0,%%xmm1 \n"
599 "minss    %%xmm0,%%xmm1 \n"
600 "mulps    %%xmm0,%%xmm1 \n"
601 "mulss    %%xmm0,%%xmm1 \n"
602 "andps    %%xmm0,%%xmm1 \n"
603 "orps     %%xmm0,%%xmm1 \n"
604 "xorps    %%xmm1,%%xmm1 \n"
605 "divps    %%xmm0,%%xmm1 \n"
606 "divss    %%xmm0,%%xmm1 \n"
607 "rcpps    %%xmm0,%%xmm1 \n"
608 "rcpss    %%xmm0,%%xmm1 \n"
609 "rsqrtps  %%xmm0,%%xmm1 \n"
610 "rsqrtss  %%xmm0,%%xmm1 \n"
611 "sqrtps   %%xmm0,%%xmm1 \n"
612 "sqrtss   %%xmm0,%%xmm1 \n"
613 "subps    %%xmm0,%%xmm1 \n"
614 "subss    %%xmm0,%%xmm1 \n"
615 "ucomiss  %%xmm0,%%xmm1 \n"
616 "unpckhps %%xmm0,%%xmm1 \n"
617 "unpcklps %%xmm0,%%xmm1 \n"
618 ::"r"(arr)
619 :"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7");
620   retval++;
621   }
622   return retval;
623 }
624 
625 #define __ASMPART_DEFINED 1
626 #include "biewlib/sysdep/ia16/cmn_ix86.c"
627 
628 #elif defined(__WATCOMC__) && __WATCOMC__ >= 1100
629 
630 #include "biewlib/sysdep/x86_64/cpu_info.wc"
631 
632 #define __ASMPART_DEFINED 1
633 #include "biewlib/sysdep/ia16/cmn_ix86.c"
634 
635 #elif defined(__WATCOMC__) && defined(__QNX4__)
636 
637 #include "biewlib/sysdep/x86_64/qnx/cpu_info.qnx"
638 
639 #define __ASMPART_DEFINED 1
640 #include "biewlib/sysdep/ia16/cmn_ix86.c"
641 
642 #else
643 
644 #include "biewlib/sysdep/generic/cpu_info.c"
645 
646 #endif
647