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