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