1 /*********************************************************************/
2 /* Copyright 2009, 2010 The University of Texas at Austin.           */
3 /* All rights reserved.                                              */
4 /*                                                                   */
5 /* Redistribution and use in source and binary forms, with or        */
6 /* without modification, are permitted provided that the following   */
7 /* conditions are met:                                               */
8 /*                                                                   */
9 /*   1. Redistributions of source code must retain the above         */
10 /*      copyright notice, this list of conditions and the following  */
11 /*      disclaimer.                                                  */
12 /*                                                                   */
13 /*   2. Redistributions in binary form must reproduce the above      */
14 /*      copyright notice, this list of conditions and the following  */
15 /*      disclaimer in the documentation and/or other materials       */
16 /*      provided with the distribution.                              */
17 /*                                                                   */
18 /*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
19 /*    AUSTIN  ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,    */
20 /*    INCLUDING, BUT  NOT LIMITED  TO, THE IMPLIED  WARRANTIES OF    */
21 /*    MERCHANTABILITY  AND FITNESS FOR  A PARTICULAR  PURPOSE ARE    */
22 /*    DISCLAIMED.  IN  NO EVENT SHALL THE UNIVERSITY  OF TEXAS AT    */
23 /*    AUSTIN OR CONTRIBUTORS BE  LIABLE FOR ANY DIRECT, INDIRECT,    */
24 /*    INCIDENTAL,  SPECIAL, EXEMPLARY,  OR  CONSEQUENTIAL DAMAGES    */
25 /*    (INCLUDING, BUT  NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE    */
26 /*    GOODS  OR  SERVICES; LOSS  OF  USE,  DATA,  OR PROFITS;  OR    */
27 /*    BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF    */
28 /*    LIABILITY, WHETHER  IN CONTRACT, STRICT  LIABILITY, OR TORT    */
29 /*    (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT    */
30 /*    OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF ADVISED  OF  THE    */
31 /*    POSSIBILITY OF SUCH DAMAGE.                                    */
32 /*                                                                   */
33 /* The views and conclusions contained in the software and           */
34 /* documentation are those of the authors and should not be          */
35 /* interpreted as representing official policies, either expressed   */
36 /* or implied, of The University of Texas at Austin.                 */
37 /*********************************************************************/
38 
39 #include <stdio.h>
40 #include <string.h>
41 #include "cpuid.h"
42 
43 #ifndef CPUIDEMU
44 
45 #if defined(__APPLE__) && defined(__i386__)
46 void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx);
47 #else
cpuid(int op,int * eax,int * ebx,int * ecx,int * edx)48 static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx){
49   __asm__ __volatile__
50     ("cpuid": "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (op) : "cc");
51 
52 }
53 #endif
54 
55 #else
56 
57 typedef struct {
58   unsigned int id, a, b, c, d;
59 } idlist_t;
60 
61 typedef struct {
62   char *vendor;
63   char *name;
64   int start, stop;
65 } vendor_t;
66 
67 extern idlist_t idlist[];
68 extern vendor_t vendor[];
69 
70 static int cv = VENDOR;
71 
cpuid(unsigned int op,unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx)72 void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx){
73 
74   static int current = 0;
75 
76   int start = vendor[cv].start;
77   int stop  = vendor[cv].stop;
78   int count = stop - start;
79 
80   if ((current < start) || (current > stop)) current = start;
81 
82   while ((count > 0) && (idlist[current].id != op)) {
83 
84     current ++;
85     if (current > stop) current = start;
86     count --;
87 
88   }
89 
90   *eax = idlist[current].a;
91   *ebx = idlist[current].b;
92   *ecx = idlist[current].c;
93   *edx = idlist[current].d;
94 }
95 
96 #endif
97 
have_cpuid(void)98 static inline int have_cpuid(void){
99   int eax, ebx, ecx, edx;
100 
101   cpuid(0, &eax, &ebx, &ecx, &edx);
102   return eax;
103 }
104 
have_excpuid(void)105 static inline int have_excpuid(void){
106   int eax, ebx, ecx, edx;
107 
108   cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
109   return eax & 0xffff;
110 }
111 
get_vendor(void)112 int get_vendor(void){
113   int eax, ebx, ecx, edx;
114   char vendor[13];
115 
116   cpuid(0, &eax, &ebx, &ecx, &edx);
117 
118   *(int *)(&vendor[0]) = ebx;
119   *(int *)(&vendor[4]) = edx;
120   *(int *)(&vendor[8]) = ecx;
121   vendor[12] = (char)0;
122 
123   if (!strcmp(vendor, "GenuineIntel")) return VENDOR_INTEL;
124   if (!strcmp(vendor, " UMC UMC UMC")) return VENDOR_UMC;
125   if (!strcmp(vendor, "AuthenticAMD")) return VENDOR_AMD;
126   if (!strcmp(vendor, "CyrixInstead")) return VENDOR_CYRIX;
127   if (!strcmp(vendor, "NexGenDriven")) return VENDOR_NEXGEN;
128   if (!strcmp(vendor, "CentaurHauls")) return VENDOR_CENTAUR;
129   if (!strcmp(vendor, "RiseRiseRise")) return VENDOR_RISE;
130   if (!strcmp(vendor, " SiS SiS SiS")) return VENDOR_SIS;
131   if (!strcmp(vendor, "GenuineTMx86")) return VENDOR_TRANSMETA;
132   if (!strcmp(vendor, "Geode by NSC")) return VENDOR_NSC;
133 
134   if ((eax == 0) || ((eax & 0x500) != 0)) return VENDOR_INTEL;
135 
136   return VENDOR_UNKNOWN;
137 }
138 
get_cputype(int gettype)139 int get_cputype(int gettype){
140   int eax, ebx, ecx, edx;
141   int extend_family, family;
142   int extend_model, model;
143   int type, stepping;
144   int feature = 0;
145 
146   cpuid(1, &eax, &ebx, &ecx, &edx);
147 
148   switch (gettype) {
149   case GET_EXFAMILY :
150     return BITMASK(eax, 20, 0xff);
151   case GET_EXMODEL :
152     return BITMASK(eax, 16, 0x0f);
153   case GET_TYPE :
154     return BITMASK(eax, 12, 0x03);
155   case GET_FAMILY :
156     return BITMASK(eax,  8, 0x0f);
157   case GET_MODEL :
158     return BITMASK(eax,  4, 0x0f);
159   case GET_APICID :
160     return BITMASK(ebx, 24, 0x0f);
161   case GET_LCOUNT :
162     return BITMASK(ebx, 16, 0x0f);
163   case GET_CHUNKS :
164     return BITMASK(ebx,  8, 0x0f);
165   case GET_STEPPING :
166     return BITMASK(eax,  0, 0x0f);
167   case GET_BLANDID :
168     return BITMASK(ebx,  0, 0xff);
169   case GET_NUMSHARE :
170     if (have_cpuid() < 4) return 0;
171     cpuid(4, &eax, &ebx, &ecx, &edx);
172     return BITMASK(eax, 14, 0xfff);
173   case GET_NUMCORES :
174     if (have_cpuid() < 4) return 0;
175     cpuid(4, &eax, &ebx, &ecx, &edx);
176     return BITMASK(eax, 26, 0x3f);
177 
178   case GET_FEATURE :
179     if ((edx & (1 <<  3)) != 0) feature |= HAVE_PSE;
180     if ((edx & (1 << 15)) != 0) feature |= HAVE_CMOV;
181     if ((edx & (1 << 19)) != 0) feature |= HAVE_CFLUSH;
182     if ((edx & (1 << 23)) != 0) feature |= HAVE_MMX;
183     if ((edx & (1 << 25)) != 0) feature |= HAVE_SSE;
184     if ((edx & (1 << 26)) != 0) feature |= HAVE_SSE2;
185     if ((edx & (1 << 27)) != 0) {
186       if (BITMASK(ebx, 16, 0x0f) > 0) feature |= HAVE_HIT;
187     }
188     if ((ecx & (1 <<  0)) != 0) feature |= HAVE_SSE3;
189     if ((ecx & (1 <<  9)) != 0) feature |= HAVE_SSSE3;
190     if ((ecx & (1 << 19)) != 0) feature |= HAVE_SSE4_1;
191     if ((ecx & (1 << 20)) != 0) feature |= HAVE_SSE4_2;
192 
193     if (have_excpuid() >= 0x01) {
194       cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
195       if ((ecx & (1 <<  6)) != 0) feature |= HAVE_SSE4A;
196       if ((ecx & (1 <<  7)) != 0) feature |= HAVE_MISALIGNSSE;
197       if ((edx & (1 << 30)) != 0) feature |= HAVE_3DNOWEX;
198       if ((edx & (1 << 31)) != 0) feature |= HAVE_3DNOW;
199     }
200 
201     if (have_excpuid() >= 0x1a) {
202       cpuid(0x8000001a, &eax, &ebx, &ecx, &edx);
203       if ((eax & (1 <<  0)) != 0) feature |= HAVE_128BITFPU;
204       if ((eax & (1 <<  1)) != 0) feature |= HAVE_FASTMOVU;
205     }
206 
207   }
208   return feature;
209 }
210 
get_cacheinfo(int type,cache_info_t * cacheinfo)211 int get_cacheinfo(int type, cache_info_t *cacheinfo){
212   int eax, ebx, ecx, edx, cpuid_level;
213   int info[15];
214   int i;
215   cache_info_t LC1, LD1, L2, L3,
216     ITB, DTB, LITB, LDTB,
217     L2ITB, L2DTB, L2LITB, L2LDTB;
218 
219   LC1.size    = 0; LC1.associative = 0; LC1.linesize = 0; LC1.shared = 0;
220   LD1.size    = 0; LD1.associative    = 0; LD1.linesize    = 0; LD1.shared    = 0;
221   L2.size     = 0; L2.associative     = 0; L2.linesize     = 0; L2.shared     = 0;
222   L3.size     = 0; L3.associative     = 0; L3.linesize     = 0; L3.shared     = 0;
223   ITB.size    = 0; ITB.associative    = 0; ITB.linesize    = 0; ITB.shared    = 0;
224   DTB.size    = 0; DTB.associative    = 0; DTB.linesize    = 0; DTB.shared    = 0;
225   LITB.size   = 0; LITB.associative   = 0; LITB.linesize   = 0; LITB.shared   = 0;
226   LDTB.size   = 0; LDTB.associative   = 0; LDTB.linesize   = 0; LDTB.shared   = 0;
227   L2ITB.size  = 0; L2ITB.associative  = 0; L2ITB.linesize  = 0; L2ITB.shared  = 0;
228   L2DTB.size  = 0; L2DTB.associative  = 0; L2DTB.linesize  = 0; L2DTB.shared  = 0;
229   L2LITB.size = 0; L2LITB.associative = 0; L2LITB.linesize = 0; L2LITB.shared = 0;
230   L2LDTB.size = 0; L2LDTB.associative = 0; L2LDTB.linesize = 0; L2LDTB.shared = 0;
231 
232   cpuid(0, &cpuid_level, &ebx, &ecx, &edx);
233 
234   if (cpuid_level > 1) {
235 
236     cpuid(2, &eax, &ebx, &ecx, &edx);
237 
238     info[ 0] = BITMASK(eax,  8, 0xff);
239     info[ 1] = BITMASK(eax, 16, 0xff);
240     info[ 2] = BITMASK(eax, 24, 0xff);
241 
242     info[ 3] = BITMASK(ebx,  0, 0xff);
243     info[ 4] = BITMASK(ebx,  8, 0xff);
244     info[ 5] = BITMASK(ebx, 16, 0xff);
245     info[ 6] = BITMASK(ebx, 24, 0xff);
246 
247     info[ 7] = BITMASK(ecx,  0, 0xff);
248     info[ 8] = BITMASK(ecx,  8, 0xff);
249     info[ 9] = BITMASK(ecx, 16, 0xff);
250     info[10] = BITMASK(ecx, 24, 0xff);
251 
252     info[11] = BITMASK(edx,  0, 0xff);
253     info[12] = BITMASK(edx,  8, 0xff);
254     info[13] = BITMASK(edx, 16, 0xff);
255     info[14] = BITMASK(edx, 24, 0xff);
256 
257     for (i = 0; i < 15; i++){
258 
259       switch (info[i]){
260 
261 	/* This table is from http://www.sandpile.org/ia32/cpuid.htm */
262 
263       case 0x01 :
264 	ITB.size        =     4;
265 	ITB.associative =     4;
266 	ITB.linesize     =   32;
267 	break;
268       case 0x02 :
269 	LITB.size        = 4096;
270 	LITB.associative =    0;
271 	LITB.linesize    =    2;
272 	break;
273       case 0x03 :
274 	DTB.size        =     4;
275 	DTB.associative =     4;
276 	DTB.linesize     =   64;
277 	break;
278       case 0x04 :
279 	LDTB.size        = 4096;
280 	LDTB.associative =    4;
281 	LDTB.linesize    =    8;
282 	break;
283       case 0x05 :
284 	LDTB.size        = 4096;
285 	LDTB.associative =    4;
286 	LDTB.linesize    =   32;
287 	break;
288       case 0x06 :
289 	LC1.size        = 8;
290 	LC1.associative = 4;
291 	LC1.linesize    = 32;
292 	break;
293       case 0x08 :
294 	LC1.size        = 16;
295 	LC1.associative = 4;
296 	LC1.linesize    = 32;
297 	break;
298       case 0x09 :
299 	LC1.size        = 32;
300 	LC1.associative = 4;
301 	LC1.linesize    = 64;
302 	break;
303       case 0x0a :
304 	LD1.size        = 8;
305 	LD1.associative = 2;
306 	LD1.linesize    = 32;
307 	break;
308       case 0x0c :
309 	LD1.size        = 16;
310 	LD1.associative = 4;
311 	LD1.linesize    = 32;
312 	break;
313       case 0x0d :
314 	LD1.size        = 16;
315 	LD1.associative = 4;
316 	LD1.linesize    = 64;
317 	break;
318       case 0x0e :
319 	LD1.size        = 24;
320 	LD1.associative = 6;
321 	LD1.linesize    = 64;
322 	break;
323       case 0x10 :
324 	LD1.size        = 16;
325 	LD1.associative = 4;
326 	LD1.linesize    = 32;
327 	break;
328       case 0x15 :
329 	LC1.size        = 16;
330 	LC1.associative = 4;
331 	LC1.linesize    = 32;
332 	break;
333       case 0x1a :
334 	L2.size         = 96;
335 	L2.associative  = 6;
336 	L2.linesize     = 64;
337 	break;
338       case 0x21 :
339 	L2.size         = 256;
340 	L2.associative  = 8;
341 	L2.linesize     = 64;
342 	break;
343       case 0x22 :
344 	L3.size         = 512;
345 	L3.associative  = 4;
346 	L3.linesize     = 64;
347 	break;
348       case 0x23 :
349 	L3.size         = 1024;
350 	L3.associative  = 8;
351 	L3.linesize     = 64;
352 	break;
353       case 0x25 :
354 	L3.size         = 2048;
355 	L3.associative  = 8;
356 	L3.linesize     = 64;
357 	break;
358       case 0x29 :
359 	L3.size         = 4096;
360 	L3.associative  = 8;
361 	L3.linesize     = 64;
362 	break;
363       case 0x2c :
364 	LD1.size        = 32;
365 	LD1.associative = 8;
366 	LD1.linesize    = 64;
367 	break;
368       case 0x30 :
369 	LC1.size        = 32;
370 	LC1.associative = 8;
371 	LC1.linesize    = 64;
372 	break;
373       case 0x39 :
374 	L2.size         = 128;
375 	L2.associative  = 4;
376 	L2.linesize     = 64;
377 	break;
378       case 0x3a :
379 	L2.size         = 192;
380 	L2.associative  = 6;
381 	L2.linesize     = 64;
382 	break;
383       case 0x3b :
384 	L2.size         = 128;
385 	L2.associative  = 2;
386 	L2.linesize     = 64;
387 	break;
388       case 0x3c :
389 	L2.size         = 256;
390 	L2.associative  = 4;
391 	L2.linesize     = 64;
392 	break;
393       case 0x3d :
394 	L2.size         = 384;
395 	L2.associative  = 6;
396 	L2.linesize     = 64;
397 	break;
398       case 0x3e :
399 	L2.size         = 512;
400 	L2.associative  = 4;
401 	L2.linesize     = 64;
402 	break;
403       case 0x41 :
404 	L2.size         = 128;
405 	L2.associative  = 4;
406 	L2.linesize     = 32;
407 	break;
408       case 0x42 :
409 	L2.size         = 256;
410 	L2.associative  = 4;
411 	L2.linesize     = 32;
412 	break;
413       case 0x43 :
414 	L2.size         = 512;
415 	L2.associative  = 4;
416 	L2.linesize     = 32;
417 	break;
418       case 0x44 :
419 	L2.size         = 1024;
420 	L2.associative  = 4;
421 	L2.linesize     = 32;
422 	break;
423       case 0x45 :
424 	L2.size         = 2048;
425 	L2.associative  = 4;
426 	L2.linesize     = 32;
427 	break;
428       case 0x46 :
429 	L3.size         = 4096;
430 	L3.associative  = 4;
431 	L3.linesize     = 64;
432 	break;
433       case 0x47 :
434 	L3.size         = 8192;
435 	L3.associative  = 8;
436 	L3.linesize     = 64;
437 	break;
438       case 0x48 :
439 	L2.size         = 3184;
440 	L2.associative  = 12;
441 	L2.linesize     = 64;
442 	break;
443       case 0x49 :
444 	if ((get_cputype(GET_FAMILY) == 0x0f) && (get_cputype(GET_MODEL) == 0x06)) {
445 	  L3.size         = 4096;
446 	  L3.associative  = 16;
447 	  L3.linesize     = 64;
448 	} else {
449 	  L2.size         = 4096;
450 	  L2.associative  = 16;
451 	  L2.linesize     = 64;
452 	}
453 	break;
454       case 0x4a :
455 	L3.size         = 6144;
456 	L3.associative  = 12;
457 	L3.linesize     = 64;
458 	break;
459       case 0x4b :
460 	L3.size         = 8192;
461 	L3.associative  = 16;
462 	L3.linesize     = 64;
463 	break;
464       case 0x4c :
465 	L3.size         = 12280;
466 	L3.associative  = 12;
467 	L3.linesize     = 64;
468 	break;
469       case 0x4d :
470 	L3.size         = 16384;
471 	L3.associative  = 16;
472 	L3.linesize     = 64;
473 	break;
474       case 0x4e :
475 	L2.size         = 6144;
476 	L2.associative  = 24;
477 	L2.linesize     = 64;
478 	break;
479       case 0x4f :
480 	ITB.size         = 4;
481 	ITB.associative  = 0;
482 	ITB.linesize     = 32;
483 	break;
484       case 0x50 :
485 	ITB.size         = 4;
486 	ITB.associative  = 0;
487 	ITB.linesize     = 64;
488 	LITB.size        = 4096;
489 	LITB.associative = 0;
490 	LITB.linesize    = 64;
491 	LITB.shared      = 1;
492 	break;
493       case 0x51 :
494 	ITB.size        = 4;
495 	ITB.associative = 0;
496 	ITB.linesize     = 128;
497 	LITB.size        = 4096;
498 	LITB.associative = 0;
499 	LITB.linesize    = 128;
500 	LITB.shared      = 1;
501 	break;
502       case 0x52 :
503 	ITB.size         = 4;
504 	ITB.associative  = 0;
505 	ITB.linesize     = 256;
506 	LITB.size        = 4096;
507 	LITB.associative = 0;
508 	LITB.linesize    = 256;
509 	LITB.shared      = 1;
510 	break;
511       case 0x55 :
512 	LITB.size        = 4096;
513 	LITB.associative = 0;
514 	LITB.linesize    = 7;
515 	LITB.shared      = 1;
516 	break;
517       case 0x56 :
518 	LDTB.size        = 4096;
519 	LDTB.associative = 4;
520 	LDTB.linesize    = 16;
521 	break;
522       case 0x57 :
523 	LDTB.size        = 4096;
524 	LDTB.associative = 4;
525 	LDTB.linesize    = 16;
526 	break;
527       case 0x5b :
528 	DTB.size         = 4;
529 	DTB.associative  = 0;
530 	DTB.linesize     = 64;
531 	LDTB.size        = 4096;
532 	LDTB.associative = 0;
533 	LDTB.linesize    = 64;
534 	LDTB.shared      = 1;
535 	break;
536       case 0x5c :
537 	DTB.size         = 4;
538 	DTB.associative  = 0;
539 	DTB.linesize     = 128;
540 	LDTB.size        = 4096;
541 	LDTB.associative = 0;
542 	LDTB.linesize    = 128;
543 	LDTB.shared      = 1;
544 	break;
545       case 0x5d :
546 	DTB.size         = 4;
547 	DTB.associative  = 0;
548 	DTB.linesize     = 256;
549 	LDTB.size        = 4096;
550 	LDTB.associative = 0;
551 	LDTB.linesize    = 256;
552 	LDTB.shared      = 1;
553 	break;
554       case 0x60 :
555 	LD1.size        = 16;
556 	LD1.associative = 8;
557 	LD1.linesize    = 64;
558 	break;
559       case 0x66 :
560 	LD1.size        = 8;
561 	LD1.associative = 4;
562 	LD1.linesize    = 64;
563 	break;
564       case 0x67 :
565 	LD1.size        = 16;
566 	LD1.associative = 4;
567 	LD1.linesize    = 64;
568 	break;
569       case 0x68 :
570 	LD1.size        = 32;
571 	LD1.associative = 4;
572 	LD1.linesize    = 64;
573 	break;
574       case 0x70 :
575 	LC1.size        = 12;
576 	LC1.associative = 8;
577 	break;
578       case 0x71 :
579 	LC1.size        = 16;
580 	LC1.associative = 8;
581 	break;
582       case 0x72 :
583 	LC1.size        = 32;
584 	LC1.associative = 8;
585 	break;
586       case 0x73 :
587 	LC1.size        = 64;
588 	LC1.associative = 8;
589 	break;
590       case 0x77 :
591 	LC1.size        = 16;
592 	LC1.associative = 4;
593 	LC1.linesize    = 64;
594 	break;
595       case 0x78 :
596 	L2.size        = 1024;
597 	L2.associative = 4;
598 	L2.linesize    = 64;
599 	break;
600       case 0x79 :
601 	L2.size         = 128;
602 	L2.associative  = 8;
603 	L2.linesize     = 64;
604 	break;
605       case 0x7a :
606 	L2.size         = 256;
607 	L2.associative  = 8;
608 	L2.linesize     = 64;
609 	break;
610       case 0x7b :
611 	L2.size         = 512;
612 	L2.associative  = 8;
613 	L2.linesize     = 64;
614 	break;
615       case 0x7c :
616 	L2.size         = 1024;
617 	L2.associative  = 8;
618 	L2.linesize     = 64;
619 	break;
620       case 0x7d :
621 	L2.size         = 2048;
622 	L2.associative  = 8;
623 	L2.linesize     = 64;
624 	break;
625       case 0x7e :
626 	L2.size         = 256;
627 	L2.associative  = 8;
628 	L2.linesize     = 128;
629 	break;
630       case 0x7f :
631 	L2.size         = 512;
632 	L2.associative  = 2;
633 	L2.linesize     = 64;
634 	break;
635       case 0x81 :
636 	L2.size         = 128;
637 	L2.associative  = 8;
638 	L2.linesize     = 32;
639 	break;
640       case 0x82 :
641 	L2.size         = 256;
642 	L2.associative  = 8;
643 	L2.linesize     = 32;
644 	break;
645       case 0x83 :
646 	L2.size         = 512;
647 	L2.associative  = 8;
648 	L2.linesize     = 32;
649 	break;
650       case 0x84 :
651 	L2.size         = 1024;
652 	L2.associative  = 8;
653 	L2.linesize     = 32;
654 	break;
655       case 0x85 :
656 	L2.size         = 2048;
657 	L2.associative  = 8;
658 	L2.linesize     = 32;
659 	break;
660       case 0x86 :
661 	L2.size         = 512;
662 	L2.associative  = 4;
663 	L2.linesize     = 64;
664 	break;
665       case 0x87 :
666 	L2.size         = 1024;
667 	L2.associative  = 8;
668 	L2.linesize     = 64;
669 	break;
670       case 0x88 :
671 	L3.size         = 2048;
672 	L3.associative  = 4;
673 	L3.linesize     = 64;
674 	break;
675       case 0x89 :
676 	L3.size         = 4096;
677 	L3.associative  = 4;
678 	L3.linesize     = 64;
679 	break;
680       case 0x8a :
681 	L3.size         = 8192;
682 	L3.associative  = 4;
683 	L3.linesize     = 64;
684 	break;
685       case 0x8d :
686 	L3.size         = 3096;
687 	L3.associative  = 12;
688 	L3.linesize     = 128;
689 	break;
690       case 0x90 :
691 	ITB.size        = 4;
692 	ITB.associative = 0;
693 	ITB.linesize    = 64;
694 	break;
695       case 0x96 :
696 	DTB.size        = 4;
697 	DTB.associative = 0;
698 	DTB.linesize    = 32;
699 	break;
700       case 0x9b :
701 	L2DTB.size        = 4;
702 	L2DTB.associative = 0;
703 	L2DTB.linesize    = 96;
704 	break;
705       case 0xb0 :
706 	ITB.size        = 4;
707 	ITB.associative = 4;
708 	ITB.linesize    = 128;
709 	break;
710       case 0xb1 :
711 	LITB.size        = 4096;
712 	LITB.associative = 4;
713 	LITB.linesize    = 4;
714 	break;
715       case 0xb2 :
716 	ITB.size        = 4;
717 	ITB.associative = 4;
718 	ITB.linesize    = 64;
719 	break;
720       case 0xb3 :
721 	DTB.size        = 4;
722 	DTB.associative = 4;
723 	DTB.linesize    = 128;
724 	break;
725       case 0xb4 :
726 	DTB.size        = 4;
727 	DTB.associative = 4;
728 	DTB.linesize    = 256;
729 	break;
730       case 0xba :
731 	DTB.size        = 4;
732 	DTB.associative = 4;
733 	DTB.linesize    = 64;
734 	break;
735       case 0xd0 :
736 	L3.size         = 512;
737 	L3.associative  = 4;
738 	L3.linesize     = 64;
739 	break;
740       case 0xd1 :
741 	L3.size         = 1024;
742 	L3.associative  = 4;
743 	L3.linesize     = 64;
744 	break;
745       case 0xd2 :
746 	L3.size         = 2048;
747 	L3.associative  = 4;
748 	L3.linesize     = 64;
749 	break;
750       case 0xd6 :
751 	L3.size         = 1024;
752 	L3.associative  = 8;
753 	L3.linesize     = 64;
754 	break;
755       case 0xd7 :
756 	L3.size         = 2048;
757 	L3.associative  = 8;
758 	L3.linesize     = 64;
759 	break;
760       case 0xd8 :
761 	L3.size         = 4096;
762 	L3.associative  = 8;
763 	L3.linesize     = 64;
764 	break;
765       case 0xdc :
766 	L3.size         = 2048;
767 	L3.associative  = 12;
768 	L3.linesize     = 64;
769 	break;
770       case 0xdd :
771 	L3.size         = 4096;
772 	L3.associative  = 12;
773 	L3.linesize     = 64;
774 	break;
775       case 0xde :
776 	L3.size         = 8192;
777 	L3.associative  = 12;
778 	L3.linesize     = 64;
779 	break;
780       case 0xe2 :
781 	L3.size         = 2048;
782 	L3.associative  = 16;
783 	L3.linesize     = 64;
784 	break;
785       case 0xe3 :
786 	L3.size         = 4096;
787 	L3.associative  = 16;
788 	L3.linesize     = 64;
789 	break;
790       case 0xe4 :
791 	L3.size         = 8192;
792 	L3.associative  = 16;
793 	L3.linesize     = 64;
794 	break;
795       }
796     }
797   }
798 
799   if (get_vendor() == VENDOR_INTEL) {
800     cpuid(0x80000000, &cpuid_level, &ebx, &ecx, &edx);
801     if (cpuid_level >= 0x80000006) {
802       cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
803 
804       L2.size         = BITMASK(ecx, 16, 0xffff);
805       L2.associative  = BITMASK(ecx, 12, 0x0f);
806       L2.linesize     = BITMASK(ecx,  0, 0xff);
807     }
808   }
809 
810   if ((get_vendor() == VENDOR_AMD) || (get_vendor() == VENDOR_CENTAUR)) {
811     cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
812 
813     LDTB.size        = 4096;
814     LDTB.associative = BITMASK(eax, 24, 0xff);
815     if (LDTB.associative == 0xff) LDTB.associative = 0;
816     LDTB.linesize    = BITMASK(eax, 16, 0xff);
817 
818     LITB.size        = 4096;
819     LITB.associative = BITMASK(eax,  8, 0xff);
820     if (LITB.associative == 0xff) LITB.associative = 0;
821     LITB.linesize    = BITMASK(eax,  0, 0xff);
822 
823     DTB.size        = 4;
824     DTB.associative = BITMASK(ebx, 24, 0xff);
825     if (DTB.associative == 0xff) DTB.associative = 0;
826     DTB.linesize    = BITMASK(ebx, 16, 0xff);
827 
828     ITB.size        = 4;
829     ITB.associative = BITMASK(ebx,  8, 0xff);
830     if (ITB.associative == 0xff) ITB.associative = 0;
831     ITB.linesize    = BITMASK(ebx,  0, 0xff);
832 
833     LD1.size        = BITMASK(ecx, 24, 0xff);
834     LD1.associative = BITMASK(ecx, 16, 0xff);
835     if (LD1.associative == 0xff) LD1.associative = 0;
836     LD1.linesize    = BITMASK(ecx,  0, 0xff);
837 
838     LC1.size        = BITMASK(ecx, 24, 0xff);
839     LC1.associative = BITMASK(ecx, 16, 0xff);
840     if (LC1.associative == 0xff) LC1.associative = 0;
841     LC1.linesize    = BITMASK(ecx,  0, 0xff);
842 
843     cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
844 
845     L2LDTB.size        = 4096;
846     L2LDTB.associative = BITMASK(eax, 24, 0xff);
847     if (L2LDTB.associative == 0xff) L2LDTB.associative = 0;
848     L2LDTB.linesize    = BITMASK(eax, 16, 0xff);
849 
850     L2LITB.size        = 4096;
851     L2LITB.associative = BITMASK(eax,  8, 0xff);
852     if (L2LITB.associative == 0xff) L2LITB.associative = 0;
853     L2LITB.linesize    = BITMASK(eax,  0, 0xff);
854 
855     L2DTB.size        = 4;
856     L2DTB.associative = BITMASK(ebx, 24, 0xff);
857     if (L2DTB.associative == 0xff) L2DTB.associative = 0;
858     L2DTB.linesize    = BITMASK(ebx, 16, 0xff);
859 
860     L2ITB.size        = 4;
861     L2ITB.associative = BITMASK(ebx,  8, 0xff);
862     if (L2ITB.associative == 0xff) L2ITB.associative = 0;
863     L2ITB.linesize    = BITMASK(ebx,  0, 0xff);
864 
865     L2.size        = BITMASK(ecx, 16, 0xffff);
866     L2.associative = BITMASK(ecx, 12, 0xf);
867     if (L2.associative == 0xff) L2.associative = 0;
868     L2.linesize    = BITMASK(ecx,  0, 0xff);
869 
870     L3.size        = BITMASK(edx, 18, 0x3fff) * 512;
871     L3.associative = BITMASK(edx, 12, 0xf);
872     if (L3.associative == 0xff) L2.associative = 0;
873     L3.linesize    = BITMASK(edx,  0, 0xff);
874 
875   }
876 
877     switch (type) {
878 
879     case CACHE_INFO_L1_I :
880       *cacheinfo = LC1;
881       break;
882     case CACHE_INFO_L1_D :
883       *cacheinfo = LD1;
884       break;
885     case CACHE_INFO_L2 :
886       *cacheinfo = L2;
887       break;
888     case CACHE_INFO_L3 :
889       *cacheinfo = L3;
890       break;
891     case CACHE_INFO_L1_DTB :
892       *cacheinfo = DTB;
893       break;
894     case CACHE_INFO_L1_ITB :
895       *cacheinfo = ITB;
896       break;
897     case CACHE_INFO_L1_LDTB :
898       *cacheinfo = LDTB;
899       break;
900     case CACHE_INFO_L1_LITB :
901       *cacheinfo = LITB;
902       break;
903     case CACHE_INFO_L2_DTB :
904       *cacheinfo = L2DTB;
905       break;
906     case CACHE_INFO_L2_ITB :
907       *cacheinfo = L2ITB;
908       break;
909     case CACHE_INFO_L2_LDTB :
910       *cacheinfo = L2LDTB;
911       break;
912     case CACHE_INFO_L2_LITB :
913       *cacheinfo = L2LITB;
914       break;
915     }
916   return 0;
917 }
918 
get_cpuname(void)919 int get_cpuname(void){
920 
921   int family, exfamily, model, vendor, exmodel;
922 
923   if (!have_cpuid()) return CPUTYPE_80386;
924 
925   family   = get_cputype(GET_FAMILY);
926   exfamily = get_cputype(GET_EXFAMILY);
927   model    = get_cputype(GET_MODEL);
928   exmodel  = get_cputype(GET_EXMODEL);
929 
930   vendor = get_vendor();
931 
932   if (vendor == VENDOR_INTEL){
933     switch (family) {
934     case 0x4:
935       return CPUTYPE_80486;
936     case 0x5:
937       return CPUTYPE_PENTIUM;
938     case 0x6:
939       switch (exmodel) {
940       case 0:
941 	switch (model) {
942 	case  1:
943 	case  3:
944 	case  5:
945 	case  6:
946 	  return CPUTYPE_PENTIUM2;
947 	case  7:
948 	case  8:
949 	case 10:
950 	case 11:
951 	  return CPUTYPE_PENTIUM3;
952 	case  9:
953 	case 13:
954 	case 14:
955 	  return CPUTYPE_PENTIUMM;
956 	case 15:
957 	  return CPUTYPE_CORE2;
958 	}
959 	break;
960       case 1:
961 	switch (model) {
962 	case  6:
963 	  return CPUTYPE_CORE2;
964 	case  7:
965 	  return CPUTYPE_PENRYN;
966 	case 10:
967 	case 11:
968 	case 14:
969 	case 15:
970 	  return CPUTYPE_NEHALEM;
971 	case 12:
972 	  return CPUTYPE_ATOM;
973 	case 13:
974 	  return CPUTYPE_DUNNINGTON;
975 	}
976 	break;
977 	  case  2:
978 		  switch (model) {
979 		  case 5:
980 			  //Intel Core (Clarkdale) / Core (Arrandale)
981 			  // Pentium (Clarkdale) / Pentium Mobile (Arrandale)
982 			  // Xeon (Clarkdale), 32nm
983 			  return CPUTYPE_NEHALEM;
984 		  case 10:
985                           //Intel Core i5-2000 /i7-2000 (Sandy Bridge)
986                           return CPUTYPE_NEHALEM;
987 		  case 12:
988 			  //Xeon Processor 5600 (Westmere-EP)
989 			  return CPUTYPE_NEHALEM;
990 		  case 13:
991                           //Intel Core i7-3000 / Xeon E5 (Sandy Bridge)
992                           return CPUTYPE_NEHALEM;
993 		  case 15:
994 			  //Xeon Processor E7 (Westmere-EX)
995 			  return CPUTYPE_NEHALEM;
996 		  }
997 		  break;
998       }
999       break;
1000     case 0x7:
1001       return CPUTYPE_ITANIUM;
1002     case 0xf:
1003       switch (exfamily) {
1004       case 0 :
1005 	return CPUTYPE_PENTIUM4;
1006       case 1 :
1007 	return CPUTYPE_ITANIUM;
1008       }
1009       break;
1010     }
1011     return CPUTYPE_INTEL_UNKNOWN;
1012   }
1013 
1014   if (vendor == VENDOR_AMD){
1015     switch (family) {
1016     case 0x4:
1017       return CPUTYPE_AMD5X86;
1018     case 0x5:
1019       return CPUTYPE_AMDK6;
1020     case 0x6:
1021       return CPUTYPE_ATHLON;
1022     case 0xf:
1023       switch (exfamily) {
1024       case  0:
1025       case  2:
1026 	return CPUTYPE_OPTERON;
1027       case  1:
1028       case 10:
1029 	return CPUTYPE_BARCELONA;
1030       }
1031       break;
1032     }
1033     return CPUTYPE_AMD_UNKNOWN;
1034   }
1035 
1036   if (vendor == VENDOR_CYRIX){
1037     switch (family) {
1038     case 0x4:
1039       return CPUTYPE_CYRIX5X86;
1040     case 0x5:
1041       return CPUTYPE_CYRIXM1;
1042     case 0x6:
1043       return CPUTYPE_CYRIXM2;
1044     }
1045     return CPUTYPE_CYRIX_UNKNOWN;
1046   }
1047 
1048   if (vendor == VENDOR_NEXGEN){
1049     switch (family) {
1050     case 0x5:
1051       return CPUTYPE_NEXGENNX586;
1052     }
1053     return CPUTYPE_NEXGEN_UNKNOWN;
1054   }
1055 
1056   if (vendor == VENDOR_CENTAUR){
1057     switch (family) {
1058     case 0x5:
1059       return CPUTYPE_CENTAURC6;
1060       break;
1061     case 0x6:
1062       return CPUTYPE_NANO;
1063       break;
1064 
1065     }
1066     return CPUTYPE_VIAC3;
1067   }
1068 
1069   if (vendor == VENDOR_RISE){
1070     switch (family) {
1071     case 0x5:
1072       return CPUTYPE_RISEMP6;
1073     }
1074     return CPUTYPE_RISE_UNKNOWN;
1075   }
1076 
1077   if (vendor == VENDOR_SIS){
1078     switch (family) {
1079     case 0x5:
1080       return CPUTYPE_SYS55X;
1081     }
1082     return CPUTYPE_SIS_UNKNOWN;
1083   }
1084 
1085   if (vendor == VENDOR_TRANSMETA){
1086     switch (family) {
1087     case 0x5:
1088       return CPUTYPE_CRUSOETM3X;
1089     }
1090     return CPUTYPE_TRANSMETA_UNKNOWN;
1091   }
1092 
1093   if (vendor == VENDOR_NSC){
1094     switch (family) {
1095     case 0x5:
1096       return CPUTYPE_NSGEODE;
1097     }
1098     return CPUTYPE_NSC_UNKNOWN;
1099   }
1100 
1101   return CPUTYPE_UNKNOWN;
1102 }
1103 
1104 static char *cpuname[] = {
1105   "UNKNOWN",
1106   "INTEL_UNKNOWN",
1107   "UMC_UNKNOWN",
1108   "AMD_UNKNOWN",
1109   "CYRIX_UNKNOWN",
1110   "NEXGEN_UNKNOWN",
1111   "CENTAUR_UNKNOWN",
1112   "RISE_UNKNOWN",
1113   "SIS_UNKNOWN",
1114   "TRANSMETA_UNKNOWN",
1115   "NSC_UNKNOWN",
1116   "80386",
1117   "80486",
1118   "PENTIUM",
1119   "PENTIUM2",
1120   "PENTIUM3",
1121   "PENTIUMM",
1122   "PENTIUM4",
1123   "CORE2",
1124   "PENRYN",
1125   "DUNNINGTON",
1126   "NEHALEM",
1127   "ATOM",
1128   "ITANIUM",
1129   "ITANIUM2",
1130   "5X86",
1131   "K6",
1132   "ATHLON",
1133   "DURON",
1134   "OPTERON",
1135   "BARCELONA",
1136   "SHANGHAI",
1137   "ISTANBUL",
1138   "CYRIX5X86",
1139   "CYRIXM1",
1140   "CYRIXM2",
1141   "NEXGENNX586",
1142   "CENTAURC6",
1143   "RISEMP6",
1144   "SYS55X",
1145   "TM3X00",
1146   "NSGEODE",
1147   "VIAC3",
1148   "NANO",
1149 };
1150 
1151 static char *lowercpuname[] = {
1152   "unknown",
1153   "intel_unknown",
1154   "umc_unknown",
1155   "amd_unknown",
1156   "cyrix_unknown",
1157   "nexgen_unknown",
1158   "centaur_unknown",
1159   "rise_unknown",
1160   "sis_unknown",
1161   "transmeta_unknown",
1162   "nsc_unknown",
1163   "80386",
1164   "80486",
1165   "pentium",
1166   "pentium2",
1167   "pentium3",
1168   "pentiumm",
1169   "pentium4",
1170   "core2",
1171   "penryn",
1172   "dunnington",
1173   "nehalem",
1174   "atom",
1175   "itanium",
1176   "itanium2",
1177   "5x86",
1178   "k6",
1179   "athlon",
1180   "duron",
1181   "opteron",
1182   "barcelona",
1183   "shanghai",
1184   "istanbul",
1185   "cyrix5x86",
1186   "cyrixm1",
1187   "cyrixm2",
1188   "nexgennx586",
1189   "centaurc6",
1190   "risemp6",
1191   "sys55x",
1192   "tms3x00",
1193   "nsgeode",
1194   "nano",
1195 };
1196 
1197 static char *corename[] = {
1198   "UNKOWN",
1199   "80486",
1200   "P5",
1201   "P6",
1202   "KATMAI",
1203   "COPPERMINE",
1204   "NORTHWOOD",
1205   "PRESCOTT",
1206   "BANIAS",
1207   "ATHLON",
1208   "OPTERON",
1209   "BARCELONA",
1210   "VIAC3",
1211   "YONAH",
1212   "CORE2",
1213   "PENRYN",
1214   "DUNNINGTON",
1215   "NEHALEM",
1216   "ATOM",
1217   "NANO",
1218 };
1219 
1220 static char *corename_lower[] = {
1221   "unknown",
1222   "80486",
1223   "p5",
1224   "p6",
1225   "katmai",
1226   "coppermine",
1227   "northwood",
1228   "prescott",
1229   "banias",
1230   "athlon",
1231   "opteron",
1232   "barcelona",
1233   "viac3",
1234   "yonah",
1235   "core2",
1236   "penryn",
1237   "dunnington",
1238   "nehalem",
1239   "atom",
1240   "nano",
1241 };
1242 
1243 
get_cpunamechar(void)1244 char *get_cpunamechar(void){
1245   return cpuname[get_cpuname()];
1246 }
1247 
get_lower_cpunamechar(void)1248 char *get_lower_cpunamechar(void){
1249   return lowercpuname[get_cpuname()];
1250 }
1251 
1252 
get_coretype(void)1253 int get_coretype(void){
1254 
1255   int family, exfamily, model, exmodel, vendor;
1256 
1257   if (!have_cpuid()) return CORE_80486;
1258 
1259   family   = get_cputype(GET_FAMILY);
1260   exfamily = get_cputype(GET_EXFAMILY);
1261   model    = get_cputype(GET_MODEL);
1262   exmodel  = get_cputype(GET_EXMODEL);
1263 
1264   vendor = get_vendor();
1265 
1266   if (vendor == VENDOR_INTEL){
1267     switch (family) {
1268     case  4:
1269       return CORE_80486;
1270     case  5:
1271       return CORE_P5;
1272     case  6:
1273       switch (exmodel) {
1274       case  0:
1275 	switch (model) {
1276 	case  0:
1277 	case  1:
1278 	case  2:
1279 	case  3:
1280 	case  4:
1281 	case  5:
1282 	case  6:
1283 	  return CORE_P6;
1284 	case  7:
1285 	  return CORE_KATMAI;
1286 	case  8:
1287 	case 10:
1288 	case 11:
1289 	  return CORE_COPPERMINE;
1290 	case  9:
1291 	case 13:
1292 	case 14:
1293 	  return CORE_BANIAS;
1294 	case 15:
1295 	  return CORE_CORE2;
1296 	}
1297 	break;
1298       case  1:
1299 	switch (model) {
1300 	case  6:
1301 	  return CORE_CORE2;
1302 	case  7:
1303 	  return CORE_PENRYN;
1304 	case 10:
1305 	case 11:
1306 	case 14:
1307 	case 15:
1308 	  return CORE_NEHALEM;
1309 	case 12:
1310 	  return CORE_ATOM;
1311 	case 13:
1312 	  return CORE_DUNNINGTON;
1313 	}
1314 	break;
1315       case  2:
1316 	switch (model) {
1317 	case 5:
1318 	  //Intel Core (Clarkdale) / Core (Arrandale)
1319 	  // Pentium (Clarkdale) / Pentium Mobile (Arrandale)
1320 	  // Xeon (Clarkdale), 32nm
1321 	  return CORE_NEHALEM;
1322 	case 10:
1323           //Intel Core i5-2000 /i7-2000 (Sandy Bridge)
1324           return CORE_NEHALEM;
1325 	case 12:
1326 	  //Xeon Processor 5600 (Westmere-EP)
1327 	  return CORE_NEHALEM;
1328 	case 13:
1329           //Intel Core i7-3000 / Xeon E5 (Sandy Bridge)
1330           return CORE_NEHALEM;
1331 	case 15:
1332 	  //Xeon Processor E7 (Westmere-EX)
1333 	  return CORE_NEHALEM;
1334 	}
1335 	break;
1336       }
1337       break;
1338 
1339       case 15:
1340 	if (model <= 0x2) return CORE_NORTHWOOD;
1341 	else return CORE_PRESCOTT;
1342     }
1343   }
1344 
1345   if (vendor == VENDOR_AMD){
1346     if (family <= 0x5) return CORE_80486;
1347     if (family <= 0xe) return CORE_ATHLON;
1348     if (family == 0xf){
1349       if ((exfamily == 0) || (exfamily == 2)) return CORE_OPTERON; else return CORE_BARCELONA;
1350     }
1351   }
1352 
1353   if (vendor == VENDOR_CENTAUR) {
1354     switch (family) {
1355     case 0x6:
1356       return CORE_NANO;
1357       break;
1358     }
1359     return CORE_VIAC3;
1360   }
1361 
1362   return CORE_UNKNOWN;
1363 }
1364 
get_cpuconfig(void)1365 void get_cpuconfig(void){
1366 
1367   cache_info_t info;
1368   int features;
1369 
1370   printf("#define %s\n", cpuname[get_cpuname()]);
1371 
1372 
1373   if (get_coretype() != CORE_P5) {
1374 
1375     get_cacheinfo(CACHE_INFO_L1_I, &info);
1376     if (info.size > 0) {
1377       printf("#define L1_CODE_SIZE %d\n", info.size * 1024);
1378       printf("#define L1_CODE_ASSOCIATIVE %d\n", info.associative);
1379       printf("#define L1_CODE_LINESIZE %d\n", info.linesize);
1380     }
1381 
1382     get_cacheinfo(CACHE_INFO_L1_D, &info);
1383     if (info.size > 0) {
1384       printf("#define L1_DATA_SIZE %d\n", info.size * 1024);
1385       printf("#define L1_DATA_ASSOCIATIVE %d\n", info.associative);
1386       printf("#define L1_DATA_LINESIZE %d\n", info.linesize);
1387     }
1388 
1389     get_cacheinfo(CACHE_INFO_L2, &info);
1390     if (info.size > 0) {
1391       printf("#define L2_SIZE %d\n", info.size * 1024);
1392       printf("#define L2_ASSOCIATIVE %d\n", info.associative);
1393       printf("#define L2_LINESIZE %d\n", info.linesize);
1394     }
1395 
1396     get_cacheinfo(CACHE_INFO_L3, &info);
1397     if (info.size > 0) {
1398       printf("#define L3_SIZE %d\n", info.size * 1024);
1399       printf("#define L3_ASSOCIATIVE %d\n", info.associative);
1400       printf("#define L3_LINESIZE %d\n", info.linesize);
1401     }
1402 
1403     get_cacheinfo(CACHE_INFO_L1_ITB, &info);
1404     if (info.size > 0) {
1405       printf("#define ITB_SIZE %d\n", info.size * 1024);
1406       printf("#define ITB_ASSOCIATIVE %d\n", info.associative);
1407       printf("#define ITB_ENTRIES %d\n", info.linesize);
1408     }
1409 
1410     get_cacheinfo(CACHE_INFO_L1_DTB, &info);
1411     if (info.size > 0) {
1412       printf("#define DTB_SIZE %d\n", info.size * 1024);
1413       printf("#define DTB_ASSOCIATIVE %d\n", info.associative);
1414       printf("#define DTB_DEFAULT_ENTRIES %d\n", info.linesize);
1415     }
1416 
1417     features = get_cputype(GET_FEATURE);
1418 
1419     if (features & HAVE_CMOV )   printf("#define HAVE_CMOV\n");
1420     if (features & HAVE_MMX  )   printf("#define HAVE_MMX\n");
1421     if (features & HAVE_SSE  )   printf("#define HAVE_SSE\n");
1422     if (features & HAVE_SSE2 )   printf("#define HAVE_SSE2\n");
1423     if (features & HAVE_SSE3 )   printf("#define HAVE_SSE3\n");
1424     if (features & HAVE_SSSE3)   printf("#define HAVE_SSSE3\n");
1425     if (features & HAVE_SSE4_1)   printf("#define HAVE_SSE4_1\n");
1426     if (features & HAVE_SSE4_2)   printf("#define HAVE_SSE4_2\n");
1427     if (features & HAVE_SSE4A)   printf("#define HAVE_SSE4A\n");
1428     if (features & HAVE_SSE5 )   printf("#define HAVE_SSSE5\n");
1429     if (features & HAVE_3DNOWEX) printf("#define HAVE_3DNOWEX\n");
1430     if (features & HAVE_3DNOW)   printf("#define HAVE_3DNOW\n");
1431     if (features & HAVE_CFLUSH)  printf("#define HAVE_CFLUSH\n");
1432     if (features & HAVE_HIT)     printf("#define HAVE_HIT 1\n");
1433     if (features & HAVE_MISALIGNSSE) printf("#define HAVE_MISALIGNSSE\n");
1434     if (features & HAVE_128BITFPU)   printf("#define HAVE_128BITFPU\n");
1435     if (features & HAVE_FASTMOVU)    printf("#define HAVE_FASTMOVU\n");
1436 
1437     printf("#define NUM_SHAREDCACHE %d\n", get_cputype(GET_NUMSHARE) + 1);
1438     printf("#define NUM_CORES %d\n", get_cputype(GET_NUMCORES) + 1);
1439 
1440     features = get_coretype();
1441     if (features > 0) printf("#define CORE_%s\n", corename[features]);
1442   } else {
1443     printf("#define DTB_DEFAULT_ENTRIES 16\n");
1444     printf("#define L1_CODE_SIZE 8192\n");
1445     printf("#define L1_DATA_SIZE 8192\n");
1446     printf("#define L2_SIZE 0\n");
1447   }
1448 }
1449 
get_architecture(void)1450 void get_architecture(void){
1451 #ifndef __64BIT__
1452     printf("X86");
1453 #else
1454     printf("X86_64");
1455 #endif
1456 }
1457 
get_subarchitecture(void)1458 void get_subarchitecture(void){
1459     printf("%s", get_cpunamechar());
1460 }
1461 
get_subdirname(void)1462 void get_subdirname(void){
1463 #ifndef __64BIT__
1464     printf("x86");
1465 #else
1466     printf("x86_64");
1467 #endif
1468 }
1469 
get_corename(void)1470 char *get_corename(void){
1471   return corename[get_coretype()];
1472 }
1473 
get_libname(void)1474 void get_libname(void){
1475   printf("%s",   corename_lower[get_coretype()]);
1476 }
1477 
1478 /* This if for Makefile */
get_sse(void)1479 void get_sse(void){
1480 
1481   int features;
1482 
1483   features = get_cputype(GET_FEATURE);
1484 
1485   if (features & HAVE_MMX  )   printf("HAVE_MMX=1\n");
1486   if (features & HAVE_SSE  )   printf("HAVE_SSE=1\n");
1487   if (features & HAVE_SSE2 )   printf("HAVE_SSE2=1\n");
1488   if (features & HAVE_SSE3 )   printf("HAVE_SSE3=1\n");
1489   if (features & HAVE_SSSE3)   printf("HAVE_SSSE3=1\n");
1490   if (features & HAVE_SSE4_1)   printf("HAVE_SSE4_1=1\n");
1491   if (features & HAVE_SSE4_2)   printf("HAVE_SSE4_2=1\n");
1492   if (features & HAVE_SSE4A)   printf("HAVE_SSE4A=1\n");
1493   if (features & HAVE_SSE5 )   printf("HAVE_SSSE5=1\n");
1494   if (features & HAVE_3DNOWEX) printf("HAVE_3DNOWEX=1\n");
1495   if (features & HAVE_3DNOW)   printf("HAVE_3DNOW=1\n");
1496 
1497 }
1498