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