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 	break;
976 	}
977       }
978       break;
979     case 0x7:
980       return CPUTYPE_ITANIUM;
981     case 0xf:
982       switch (exfamily) {
983       case 0 :
984 	return CPUTYPE_PENTIUM4;
985       case 1 :
986 	return CPUTYPE_ITANIUM;
987       }
988       break;
989     }
990     return CPUTYPE_INTEL_UNKNOWN;
991   }
992 
993   if (vendor == VENDOR_AMD){
994     switch (family) {
995     case 0x4:
996       return CPUTYPE_AMD5X86;
997     case 0x5:
998       return CPUTYPE_AMDK6;
999     case 0x6:
1000       return CPUTYPE_ATHLON;
1001     case 0xf:
1002       switch (exfamily) {
1003       case  0:
1004       case  2:
1005 	return CPUTYPE_OPTERON;
1006       case  1:
1007       case 10:
1008 	return CPUTYPE_BARCELONA;
1009       }
1010       break;
1011     }
1012     return CPUTYPE_AMD_UNKNOWN;
1013   }
1014 
1015   if (vendor == VENDOR_CYRIX){
1016     switch (family) {
1017     case 0x4:
1018       return CPUTYPE_CYRIX5X86;
1019     case 0x5:
1020       return CPUTYPE_CYRIXM1;
1021     case 0x6:
1022       return CPUTYPE_CYRIXM2;
1023     }
1024     return CPUTYPE_CYRIX_UNKNOWN;
1025   }
1026 
1027   if (vendor == VENDOR_NEXGEN){
1028     switch (family) {
1029     case 0x5:
1030       return CPUTYPE_NEXGENNX586;
1031     }
1032     return CPUTYPE_NEXGEN_UNKNOWN;
1033   }
1034 
1035   if (vendor == VENDOR_CENTAUR){
1036     switch (family) {
1037     case 0x5:
1038       return CPUTYPE_CENTAURC6;
1039       break;
1040     case 0x6:
1041       return CPUTYPE_NANO;
1042       break;
1043 
1044     }
1045     return CPUTYPE_VIAC3;
1046   }
1047 
1048   if (vendor == VENDOR_RISE){
1049     switch (family) {
1050     case 0x5:
1051       return CPUTYPE_RISEMP6;
1052     }
1053     return CPUTYPE_RISE_UNKNOWN;
1054   }
1055 
1056   if (vendor == VENDOR_SIS){
1057     switch (family) {
1058     case 0x5:
1059       return CPUTYPE_SYS55X;
1060     }
1061     return CPUTYPE_SIS_UNKNOWN;
1062   }
1063 
1064   if (vendor == VENDOR_TRANSMETA){
1065     switch (family) {
1066     case 0x5:
1067       return CPUTYPE_CRUSOETM3X;
1068     }
1069     return CPUTYPE_TRANSMETA_UNKNOWN;
1070   }
1071 
1072   if (vendor == VENDOR_NSC){
1073     switch (family) {
1074     case 0x5:
1075       return CPUTYPE_NSGEODE;
1076     }
1077     return CPUTYPE_NSC_UNKNOWN;
1078   }
1079 
1080   return CPUTYPE_UNKNOWN;
1081 }
1082 
1083 static char *cpuname[] = {
1084   "UNKNOWN",
1085   "INTEL_UNKNOWN",
1086   "UMC_UNKNOWN",
1087   "AMD_UNKNOWN",
1088   "CYRIX_UNKNOWN",
1089   "NEXGEN_UNKNOWN",
1090   "CENTAUR_UNKNOWN",
1091   "RISE_UNKNOWN",
1092   "SIS_UNKNOWN",
1093   "TRANSMETA_UNKNOWN",
1094   "NSC_UNKNOWN",
1095   "80386",
1096   "80486",
1097   "PENTIUM",
1098   "PENTIUM2",
1099   "PENTIUM3",
1100   "PENTIUMM",
1101   "PENTIUM4",
1102   "CORE2",
1103   "PENRYN",
1104   "DUNNINGTON",
1105   "NEHALEM",
1106   "ATOM",
1107   "ITANIUM",
1108   "ITANIUM2",
1109   "5X86",
1110   "K6",
1111   "ATHLON",
1112   "DURON",
1113   "OPTERON",
1114   "BARCELONA",
1115   "SHANGHAI",
1116   "ISTANBUL",
1117   "CYRIX5X86",
1118   "CYRIXM1",
1119   "CYRIXM2",
1120   "NEXGENNX586",
1121   "CENTAURC6",
1122   "RISEMP6",
1123   "SYS55X",
1124   "TM3X00",
1125   "NSGEODE",
1126   "VIAC3",
1127   "NANO",
1128 };
1129 
1130 static char *lowercpuname[] = {
1131   "unknown",
1132   "intel_unknown",
1133   "umc_unknown",
1134   "amd_unknown",
1135   "cyrix_unknown",
1136   "nexgen_unknown",
1137   "centaur_unknown",
1138   "rise_unknown",
1139   "sis_unknown",
1140   "transmeta_unknown",
1141   "nsc_unknown",
1142   "80386",
1143   "80486",
1144   "pentium",
1145   "pentium2",
1146   "pentium3",
1147   "pentiumm",
1148   "pentium4",
1149   "core2",
1150   "penryn",
1151   "dunnington",
1152   "nehalem",
1153   "atom",
1154   "itanium",
1155   "itanium2",
1156   "5x86",
1157   "k6",
1158   "athlon",
1159   "duron",
1160   "opteron",
1161   "barcelona",
1162   "shanghai",
1163   "istanbul",
1164   "cyrix5x86",
1165   "cyrixm1",
1166   "cyrixm2",
1167   "nexgennx586",
1168   "centaurc6",
1169   "risemp6",
1170   "sys55x",
1171   "tms3x00",
1172   "nsgeode",
1173   "nano",
1174 };
1175 
1176 static char *corename[] = {
1177   "UNKOWN",
1178   "80486",
1179   "P5",
1180   "P6",
1181   "KATMAI",
1182   "COPPERMINE",
1183   "NORTHWOOD",
1184   "PRESCOTT",
1185   "BANIAS",
1186   "ATHLON",
1187   "OPTERON",
1188   "BARCELONA",
1189   "VIAC3",
1190   "YONAH",
1191   "CORE2",
1192   "PENRYN",
1193   "DUNNINGTON",
1194   "NEHALEM",
1195   "ATOM",
1196   "NANO",
1197 };
1198 
1199 static char *corename_lower[] = {
1200   "unknown",
1201   "80486",
1202   "p5",
1203   "p6",
1204   "katmai",
1205   "coppermine",
1206   "northwood",
1207   "prescott",
1208   "banias",
1209   "athlon",
1210   "opteron",
1211   "barcelona",
1212   "viac3",
1213   "yonah",
1214   "core2",
1215   "penryn",
1216   "dunnington",
1217   "nehalem",
1218   "atom",
1219   "nano",
1220 };
1221 
1222 
get_cpunamechar(void)1223 char *get_cpunamechar(void){
1224   return cpuname[get_cpuname()];
1225 }
1226 
get_lower_cpunamechar(void)1227 char *get_lower_cpunamechar(void){
1228   return lowercpuname[get_cpuname()];
1229 }
1230 
1231 
get_coretype(void)1232 int get_coretype(void){
1233 
1234   int family, exfamily, model, exmodel, vendor;
1235 
1236   if (!have_cpuid()) return CORE_80486;
1237 
1238   family   = get_cputype(GET_FAMILY);
1239   exfamily = get_cputype(GET_EXFAMILY);
1240   model    = get_cputype(GET_MODEL);
1241   exmodel  = get_cputype(GET_EXMODEL);
1242 
1243   vendor = get_vendor();
1244 
1245   if (vendor == VENDOR_INTEL){
1246     switch (family) {
1247     case  4:
1248       return CORE_80486;
1249     case  5:
1250       return CORE_P5;
1251     case  6:
1252       switch (exmodel) {
1253       case  0:
1254 	switch (model) {
1255 	case  0:
1256 	case  1:
1257 	case  2:
1258 	case  3:
1259 	case  4:
1260 	case  5:
1261 	case  6:
1262 	  return CORE_P6;
1263 	case  7:
1264 	  return CORE_KATMAI;
1265 	case  8:
1266 	case 10:
1267 	case 11:
1268 	  return CORE_COPPERMINE;
1269 	case  9:
1270 	case 13:
1271 	case 14:
1272 	  return CORE_BANIAS;
1273 	case 15:
1274 	  return CORE_CORE2;
1275 	}
1276 	break;
1277       case  1:
1278 	switch (model) {
1279 	case  6:
1280 	  return CORE_CORE2;
1281 	case  7:
1282 	  return CORE_PENRYN;
1283 	case 10:
1284 	case 11:
1285 	case 14:
1286 	case 15:
1287 	  return CORE_NEHALEM;
1288 	case 12:
1289 	  return CORE_ATOM;
1290 	case 13:
1291 	  return CORE_DUNNINGTON;
1292 	break;
1293 	}
1294       }
1295       case 15:
1296       if (model <= 0x2) return CORE_NORTHWOOD;
1297       return CORE_PRESCOTT;
1298     }
1299   }
1300 
1301   if (vendor == VENDOR_AMD){
1302     if (family <= 0x5) return CORE_80486;
1303     if (family <= 0xe) return CORE_ATHLON;
1304     if (family == 0xf){
1305       if ((exfamily == 0) || (exfamily == 2)) return CORE_OPTERON; else return CORE_BARCELONA;
1306     }
1307   }
1308 
1309   if (vendor == VENDOR_CENTAUR) {
1310     switch (family) {
1311     case 0x6:
1312       return CORE_NANO;
1313       break;
1314     }
1315     return CORE_VIAC3;
1316   }
1317 
1318   return CORE_UNKNOWN;
1319 }
1320 
get_cpuconfig(void)1321 void get_cpuconfig(void){
1322 
1323   cache_info_t info;
1324   int features;
1325 
1326   printf("#define %s\n", cpuname[get_cpuname()]);
1327 
1328 
1329   if (get_coretype() != CORE_P5) {
1330 
1331     get_cacheinfo(CACHE_INFO_L1_I, &info);
1332     if (info.size > 0) {
1333       printf("#define L1_CODE_SIZE %d\n", info.size * 1024);
1334       printf("#define L1_CODE_ASSOCIATIVE %d\n", info.associative);
1335       printf("#define L1_CODE_LINESIZE %d\n", info.linesize);
1336     }
1337 
1338     get_cacheinfo(CACHE_INFO_L1_D, &info);
1339     if (info.size > 0) {
1340       printf("#define L1_DATA_SIZE %d\n", info.size * 1024);
1341       printf("#define L1_DATA_ASSOCIATIVE %d\n", info.associative);
1342       printf("#define L1_DATA_LINESIZE %d\n", info.linesize);
1343     }
1344 
1345     get_cacheinfo(CACHE_INFO_L2, &info);
1346     if (info.size > 0) {
1347       printf("#define L2_SIZE %d\n", info.size * 1024);
1348       printf("#define L2_ASSOCIATIVE %d\n", info.associative);
1349       printf("#define L2_LINESIZE %d\n", info.linesize);
1350     }
1351 
1352     get_cacheinfo(CACHE_INFO_L3, &info);
1353     if (info.size > 0) {
1354       printf("#define L3_SIZE %d\n", info.size * 1024);
1355       printf("#define L3_ASSOCIATIVE %d\n", info.associative);
1356       printf("#define L3_LINESIZE %d\n", info.linesize);
1357     }
1358 
1359     get_cacheinfo(CACHE_INFO_L1_ITB, &info);
1360     if (info.size > 0) {
1361       printf("#define ITB_SIZE %d\n", info.size * 1024);
1362       printf("#define ITB_ASSOCIATIVE %d\n", info.associative);
1363       printf("#define ITB_ENTRIES %d\n", info.linesize);
1364     }
1365 
1366     get_cacheinfo(CACHE_INFO_L1_DTB, &info);
1367     if (info.size > 0) {
1368       printf("#define DTB_SIZE %d\n", info.size * 1024);
1369       printf("#define DTB_ASSOCIATIVE %d\n", info.associative);
1370       printf("#define DTB_ENTRIES %d\n", info.linesize);
1371     }
1372 
1373     features = get_cputype(GET_FEATURE);
1374 
1375     if (features & HAVE_CMOV )   printf("#define HAVE_CMOV\n");
1376     if (features & HAVE_MMX  )   printf("#define HAVE_MMX\n");
1377     if (features & HAVE_SSE  )   printf("#define HAVE_SSE\n");
1378     if (features & HAVE_SSE2 )   printf("#define HAVE_SSE2\n");
1379     if (features & HAVE_SSE3 )   printf("#define HAVE_SSE3\n");
1380     if (features & HAVE_SSSE3)   printf("#define HAVE_SSSE3\n");
1381     if (features & HAVE_SSE4_1)   printf("#define HAVE_SSE4_1\n");
1382     if (features & HAVE_SSE4_2)   printf("#define HAVE_SSE4_2\n");
1383     if (features & HAVE_SSE4A)   printf("#define HAVE_SSE4A\n");
1384     if (features & HAVE_SSE5 )   printf("#define HAVE_SSSE5\n");
1385     if (features & HAVE_3DNOWEX) printf("#define HAVE_3DNOWEX\n");
1386     if (features & HAVE_3DNOW)   printf("#define HAVE_3DNOW\n");
1387     if (features & HAVE_CFLUSH)  printf("#define HAVE_CFLUSH\n");
1388     if (features & HAVE_HIT)     printf("#define HAVE_HIT 1\n");
1389     if (features & HAVE_MISALIGNSSE) printf("#define HAVE_MISALIGNSSE\n");
1390     if (features & HAVE_128BITFPU)   printf("#define HAVE_128BITFPU\n");
1391     if (features & HAVE_FASTMOVU)    printf("#define HAVE_FASTMOVU\n");
1392 
1393     printf("#define NUM_SHAREDCACHE %d\n", get_cputype(GET_NUMSHARE) + 1);
1394     printf("#define NUM_CORES %d\n", get_cputype(GET_NUMCORES) + 1);
1395 
1396     features = get_coretype();
1397     if (features > 0) printf("#define CORE_%s\n", corename[features]);
1398   } else {
1399     printf("#define DTB_ENTRIES 16\n");
1400     printf("#define L1_CODE_SIZE 8192\n");
1401     printf("#define L1_DATA_SIZE 8192\n");
1402     printf("#define L2_SIZE 0\n");
1403   }
1404 }
1405 
get_architecture(void)1406 void get_architecture(void){
1407 #ifndef __64BIT__
1408     printf("X86");
1409 #else
1410     printf("X86_64");
1411 #endif
1412 }
1413 
get_subarchitecture(void)1414 void get_subarchitecture(void){
1415     printf("%s", get_cpunamechar());
1416 }
1417 
get_subdirname(void)1418 void get_subdirname(void){
1419 #ifndef __64BIT__
1420     printf("x86");
1421 #else
1422     printf("x86_64");
1423 #endif
1424 }
1425 
get_corename(void)1426 char *get_corename(void){
1427   return corename[get_coretype()];
1428 }
1429 
get_libname(void)1430 void get_libname(void){
1431   printf("%s",   corename_lower[get_coretype()]);
1432 }
1433 
1434 /* This if for Makefile */
get_sse(void)1435 void get_sse(void){
1436 
1437   int features;
1438 
1439   features = get_cputype(GET_FEATURE);
1440 
1441   if (features & HAVE_MMX  )   printf("HAVE_MMX=1\n");
1442   if (features & HAVE_SSE  )   printf("HAVE_SSE=1\n");
1443   if (features & HAVE_SSE2 )   printf("HAVE_SSE2=1\n");
1444   if (features & HAVE_SSE3 )   printf("HAVE_SSE3=1\n");
1445   if (features & HAVE_SSSE3)   printf("HAVE_SSSE3=1\n");
1446   if (features & HAVE_SSE4_1)   printf("HAVE_SSE4_1=1\n");
1447   if (features & HAVE_SSE4_2)   printf("HAVE_SSE4_2=1\n");
1448   if (features & HAVE_SSE4A)   printf("HAVE_SSE4A=1\n");
1449   if (features & HAVE_SSE5 )   printf("HAVE_SSSE5=1\n");
1450   if (features & HAVE_3DNOWEX) printf("HAVE_3DNOWEX=1\n");
1451   if (features & HAVE_3DNOW)   printf("HAVE_3DNOW=1\n");
1452 
1453 }
1454