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