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