Ensure correct output for DAMAX with softfp
[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 #if defined(_MSC_VER) && !defined(__clang__)
44 #define C_INLINE __inline
45 #else
46 #define C_INLINE inline
47 #endif
48
49 /*
50 #ifdef NO_AVX
51 #define CPUTYPE_HASWELL CPUTYPE_NEHALEM
52 #define CORE_HASWELL CORE_NEHALEM
53 #define CPUTYPE_SKYLAKEX CPUTYPE_NEHALEM
54 #define CORE_SKYLAKEX CORE_NEHALEM
55 #define CPUTYPE_SANDYBRIDGE CPUTYPE_NEHALEM
56 #define CORE_SANDYBRIDGE CORE_NEHALEM
57 #define CPUTYPE_BULLDOZER CPUTYPE_BARCELONA
58 #define CORE_BULLDOZER CORE_BARCELONA
59 #define CPUTYPE_PILEDRIVER CPUTYPE_BARCELONA
60 #define CORE_PILEDRIVER CORE_BARCELONA
61 #endif
62 */
63
64 #if defined(_MSC_VER) && !defined(__clang__)
65
66 void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
67 {
68   int cpuInfo[4] = {-1};
69   __cpuid(cpuInfo, op);
70   *eax = cpuInfo[0];
71   *ebx = cpuInfo[1];
72   *ecx = cpuInfo[2];
73   *edx = cpuInfo[3];
74 }
75
76 void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, int *edx)
77 {
78   int cpuInfo[4] = {-1};
79   __cpuidex(cpuInfo, op, count);
80   *eax = cpuInfo[0];
81   *ebx = cpuInfo[1];
82   *ecx = cpuInfo[2];
83   *edx = cpuInfo[3];
84 }
85
86 #else
87
88 #ifndef CPUIDEMU
89
90 #if defined(__APPLE__) && defined(__i386__)
91 void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx);
92 void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, int *edx);
93 #else
94 static C_INLINE void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx){
95 #if defined(__i386__) && defined(__PIC__)
96   __asm__ __volatile__
97     ("mov %%ebx, %%edi;"
98      "cpuid;"
99      "xchgl %%ebx, %%edi;"
100      : "=a" (*eax), "=D" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (op), "c" (0) : "cc");
101 #else
102   __asm__ __volatile__
103     ("cpuid": "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (op) , "c" (0) : "cc");
104 #endif
105 }
106
107 static C_INLINE void cpuid_count(int op, int count ,int *eax, int *ebx, int *ecx, int *edx){
108 #if defined(__i386__) && defined(__PIC__)
109   __asm__ __volatile__
110     ("mov %%ebx, %%edi;"
111      "cpuid;"
112      "xchgl %%ebx, %%edi;"
113      : "=a" (*eax), "=D" (*ebx), "=c" (*ecx), "=d" (*edx) : "0" (op), "2" (count) : "cc");
114 #else
115   __asm__ __volatile__
116     ("cpuid": "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "0" (op), "2" (count) : "cc");
117 #endif
118 }
119 #endif
120
121 #else
122
123 typedef struct {
124   unsigned int id, a, b, c, d;
125 } idlist_t;
126
127 typedef struct {
128   char *vendor;
129   char *name;
130   int start, stop;
131 } vendor_t;
132
133 extern idlist_t idlist[];
134 extern vendor_t vendor[];
135
136 static int cv = VENDOR;
137
138 void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx){
139
140   static int current = 0;
141
142   int start = vendor[cv].start;
143   int stop  = vendor[cv].stop;
144   int count = stop - start;
145
146   if ((current < start) || (current > stop)) current = start;
147
148   while ((count > 0) && (idlist[current].id != op)) {
149
150     current ++;
151     if (current > stop) current = start;
152     count --;
153
154   }
155
156   *eax = idlist[current].a;
157   *ebx = idlist[current].b;
158   *ecx = idlist[current].c;
159   *edx = idlist[current].d;
160 }
161
162 void cpuid_count (unsigned int op, unsigned int count, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
163   return cpuid (op, eax, ebx, ecx, edx);
164 }
165
166 #endif
167
168 #endif // _MSC_VER
169
170 static C_INLINE int have_cpuid(void){
171   int eax, ebx, ecx, edx;
172
173   cpuid(0, &eax, &ebx, &ecx, &edx);
174   return eax;
175 }
176
177 static C_INLINE int have_excpuid(void){
178   int eax, ebx, ecx, edx;
179
180   cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
181   return eax & 0xffff;
182 }
183
184 #ifndef NO_AVX
185 static C_INLINE void xgetbv(int op, int * eax, int * edx){
186   //Use binary code for xgetbv
187 #if defined(_MSC_VER) && !defined(__clang__)
188   *eax = __xgetbv(op);
189 #else
190   __asm__ __volatile__
191     (".byte 0x0f, 0x01, 0xd0": "=a" (*eax), "=d" (*edx) : "c" (op) : "cc");
192 #endif
193 }
194 #endif
195
196 int support_avx(){
197 #ifndef NO_AVX
198   int eax, ebx, ecx, edx;
199   int ret=0;
200
201   cpuid(1, &eax, &ebx, &ecx, &edx);
202   if ((ecx & (1 << 28)) != 0 && (ecx & (1 << 27)) != 0 && (ecx & (1 << 26)) != 0){
203     xgetbv(0, &eax, &edx);
204     if((eax & 6) == 6){
205       ret=1;  //OS support AVX
206     }
207   }
208   return ret;
209 #else
210   return 0;
211 #endif
212 }
213
214 int support_avx2(){
215 #ifndef NO_AVX2
216   int eax, ebx, ecx=0, edx;
217   int ret=0;
218
219   if (!support_avx()) 
220     return 0;
221   cpuid(7, &eax, &ebx, &ecx, &edx);
222   if((ebx & (1<<7)) != 0)
223       ret=1;  //OS supports AVX2
224   return ret;
225 #else
226   return 0;
227 #endif
228 }
229
230 int support_avx512(){
231 #if !defined(NO_AVX) && !defined(NO_AVX512)
232   int eax, ebx, ecx, edx;
233   int ret=0;
234
235   if (!support_avx()) 
236     return 0;
237   cpuid(7, &eax, &ebx, &ecx, &edx);
238   if((ebx & 32) != 32){
239       ret=0;  //OS does not even support AVX2
240   }
241   if((ebx & (1<<31)) != 0){
242     xgetbv(0, &eax, &edx); 
243     if((eax & 0xe0) == 0xe0)
244       ret=1;  //OS supports AVX512VL
245   }
246   return ret;
247 #else
248   return 0;
249 #endif
250 }
251
252
253 int get_vendor(void){
254   int eax, ebx, ecx, edx;
255   char vendor[13];
256
257   cpuid(0, &eax, &ebx, &ecx, &edx);
258
259   *(int *)(&vendor[0]) = ebx;
260   *(int *)(&vendor[4]) = edx;
261   *(int *)(&vendor[8]) = ecx;
262   vendor[12] = (char)0;
263
264   if (!strcmp(vendor, "GenuineIntel")) return VENDOR_INTEL;
265   if (!strcmp(vendor, " UMC UMC UMC")) return VENDOR_UMC;
266   if (!strcmp(vendor, "AuthenticAMD")) return VENDOR_AMD;
267   if (!strcmp(vendor, "CyrixInstead")) return VENDOR_CYRIX;
268   if (!strcmp(vendor, "NexGenDriven")) return VENDOR_NEXGEN;
269   if (!strcmp(vendor, "CentaurHauls")) return VENDOR_CENTAUR;
270   if (!strcmp(vendor, "RiseRiseRise")) return VENDOR_RISE;
271   if (!strcmp(vendor, " SiS SiS SiS")) return VENDOR_SIS;
272   if (!strcmp(vendor, "GenuineTMx86")) return VENDOR_TRANSMETA;
273   if (!strcmp(vendor, "Geode by NSC")) return VENDOR_NSC;
274   if (!strcmp(vendor, "HygonGenuine")) return VENDOR_HYGON;
275
276   if ((eax == 0) || ((eax & 0x500) != 0)) return VENDOR_INTEL;
277
278   return VENDOR_UNKNOWN;
279 }
280
281 int get_cputype(int gettype){
282   int eax, ebx, ecx, edx;
283   int extend_family, family;
284   int extend_model, model;
285   int type, stepping;
286   int feature = 0;
287
288   cpuid(1, &eax, &ebx, &ecx, &edx);
289
290   switch (gettype) {
291   case GET_EXFAMILY :
292     return BITMASK(eax, 20, 0xff);
293   case GET_EXMODEL :
294     return BITMASK(eax, 16, 0x0f);
295   case GET_TYPE :
296     return BITMASK(eax, 12, 0x03);
297   case GET_FAMILY :
298     return BITMASK(eax,  8, 0x0f);
299   case GET_MODEL :
300     return BITMASK(eax,  4, 0x0f);
301   case GET_APICID :
302     return BITMASK(ebx, 24, 0x0f);
303   case GET_LCOUNT :
304     return BITMASK(ebx, 16, 0x0f);
305   case GET_CHUNKS :
306     return BITMASK(ebx,  8, 0x0f);
307   case GET_STEPPING :
308     return BITMASK(eax,  0, 0x0f);
309   case GET_BLANDID :
310     return BITMASK(ebx,  0, 0xff);
311   case GET_NUMSHARE :
312     if (have_cpuid() < 4) return 0;
313     cpuid(4, &eax, &ebx, &ecx, &edx);
314     return BITMASK(eax, 14, 0xfff);
315   case GET_NUMCORES :
316     if (have_cpuid() < 4) return 0;
317     cpuid(4, &eax, &ebx, &ecx, &edx);
318     return BITMASK(eax, 26, 0x3f);
319
320   case GET_FEATURE :
321     if ((edx & (1 <<  3)) != 0) feature |= HAVE_PSE;
322     if ((edx & (1 << 15)) != 0) feature |= HAVE_CMOV;
323     if ((edx & (1 << 19)) != 0) feature |= HAVE_CFLUSH;
324     if ((edx & (1 << 23)) != 0) feature |= HAVE_MMX;
325     if ((edx & (1 << 25)) != 0) feature |= HAVE_SSE;
326     if ((edx & (1 << 26)) != 0) feature |= HAVE_SSE2;
327     if ((edx & (1 << 27)) != 0) {
328       if (BITMASK(ebx, 16, 0x0f) > 0) feature |= HAVE_HIT;
329     }
330     if ((ecx & (1 <<  0)) != 0) feature |= HAVE_SSE3;
331     if ((ecx & (1 <<  9)) != 0) feature |= HAVE_SSSE3;
332     if ((ecx & (1 << 19)) != 0) feature |= HAVE_SSE4_1;
333     if ((ecx & (1 << 20)) != 0) feature |= HAVE_SSE4_2;
334 #ifndef NO_AVX
335     if (support_avx()) feature |= HAVE_AVX;
336     if (support_avx2()) feature |= HAVE_AVX2;
337     if (support_avx512()) feature |= HAVE_AVX512VL;
338     if ((ecx & (1 << 12)) != 0) feature |= HAVE_FMA3;
339 #endif
340
341     if (have_excpuid() >= 0x01) {
342       cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
343       if ((ecx & (1 <<  6)) != 0) feature |= HAVE_SSE4A;
344       if ((ecx & (1 <<  7)) != 0) feature |= HAVE_MISALIGNSSE;
345 #ifndef NO_AVX
346       if ((ecx & (1 <<  16)) != 0) feature |= HAVE_FMA4;
347 #endif
348       if ((edx & (1 << 30)) != 0) feature |= HAVE_3DNOWEX;
349       if ((edx & (1 << 31)) != 0) feature |= HAVE_3DNOW;
350     }
351
352     if (have_excpuid() >= 0x1a) {
353       cpuid(0x8000001a, &eax, &ebx, &ecx, &edx);
354       if ((eax & (1 <<  0)) != 0) feature |= HAVE_128BITFPU;
355       if ((eax & (1 <<  1)) != 0) feature |= HAVE_FASTMOVU;
356     }
357
358   }
359   return feature;
360 }
361
362 int get_cacheinfo(int type, cache_info_t *cacheinfo){
363   int eax, ebx, ecx, edx, cpuid_level;
364   int info[15];
365   int i;
366   cache_info_t LC1, LD1, L2, L3,
367     ITB, DTB, LITB, LDTB,
368     L2ITB, L2DTB, L2LITB, L2LDTB;
369
370   LC1.size    = 0; LC1.associative = 0; LC1.linesize = 0; LC1.shared = 0;
371   LD1.size    = 0; LD1.associative    = 0; LD1.linesize    = 0; LD1.shared    = 0;
372   L2.size     = 0; L2.associative     = 0; L2.linesize     = 0; L2.shared     = 0;
373   L3.size     = 0; L3.associative     = 0; L3.linesize     = 0; L3.shared     = 0;
374   ITB.size    = 0; ITB.associative    = 0; ITB.linesize    = 0; ITB.shared    = 0;
375   DTB.size    = 0; DTB.associative    = 0; DTB.linesize    = 0; DTB.shared    = 0;
376   LITB.size   = 0; LITB.associative   = 0; LITB.linesize   = 0; LITB.shared   = 0;
377   LDTB.size   = 0; LDTB.associative   = 0; LDTB.linesize   = 0; LDTB.shared   = 0;
378   L2ITB.size  = 0; L2ITB.associative  = 0; L2ITB.linesize  = 0; L2ITB.shared  = 0;
379   L2DTB.size  = 0; L2DTB.associative  = 0; L2DTB.linesize  = 0; L2DTB.shared  = 0;
380   L2LITB.size = 0; L2LITB.associative = 0; L2LITB.linesize = 0; L2LITB.shared = 0;
381   L2LDTB.size = 0; L2LDTB.associative = 0; L2LDTB.linesize = 0; L2LDTB.shared = 0;
382
383   cpuid(0, &cpuid_level, &ebx, &ecx, &edx);
384
385   if (cpuid_level > 1) {
386     int numcalls =0 ;
387     cpuid(2, &eax, &ebx, &ecx, &edx);
388     numcalls = BITMASK(eax, 0, 0xff); //FIXME some systems may require repeated calls to read all entries
389     info[ 0] = BITMASK(eax,  8, 0xff);
390     info[ 1] = BITMASK(eax, 16, 0xff);
391     info[ 2] = BITMASK(eax, 24, 0xff);
392
393     info[ 3] = BITMASK(ebx,  0, 0xff);
394     info[ 4] = BITMASK(ebx,  8, 0xff);
395     info[ 5] = BITMASK(ebx, 16, 0xff);
396     info[ 6] = BITMASK(ebx, 24, 0xff);
397
398     info[ 7] = BITMASK(ecx,  0, 0xff);
399     info[ 8] = BITMASK(ecx,  8, 0xff);
400     info[ 9] = BITMASK(ecx, 16, 0xff);
401     info[10] = BITMASK(ecx, 24, 0xff);
402
403     info[11] = BITMASK(edx,  0, 0xff);
404     info[12] = BITMASK(edx,  8, 0xff);
405     info[13] = BITMASK(edx, 16, 0xff);
406     info[14] = BITMASK(edx, 24, 0xff);
407
408     for (i = 0; i < 15; i++){
409       switch (info[i]){
410
411         /* This table is from http://www.sandpile.org/ia32/cpuid.htm */
412
413       case 0x01 :
414         ITB.size        =     4;
415         ITB.associative =     4;
416         ITB.linesize     =   32;
417         break;
418       case 0x02 :
419         LITB.size        = 4096;
420         LITB.associative =    0;
421         LITB.linesize    =    2;
422         break;
423       case 0x03 :
424         DTB.size        =     4;
425         DTB.associative =     4;
426         DTB.linesize     =   64;
427         break;
428       case 0x04 :
429         LDTB.size        = 4096;
430         LDTB.associative =    4;
431         LDTB.linesize    =    8;
432         break;
433       case 0x05 :
434         LDTB.size        = 4096;
435         LDTB.associative =    4;
436         LDTB.linesize    =   32;
437         break;
438       case 0x06 :
439         LC1.size        = 8;
440         LC1.associative = 4;
441         LC1.linesize    = 32;
442         break;
443       case 0x08 :
444         LC1.size        = 16;
445         LC1.associative = 4;
446         LC1.linesize    = 32;
447         break;
448       case 0x09 :
449         LC1.size        = 32;
450         LC1.associative = 4;
451         LC1.linesize    = 64;
452         break;
453       case 0x0a :
454         LD1.size        = 8;
455         LD1.associative = 2;
456         LD1.linesize    = 32;
457         break;
458       case 0x0c :
459         LD1.size        = 16;
460         LD1.associative = 4;
461         LD1.linesize    = 32;
462         break;
463       case 0x0d :
464         LD1.size        = 16;
465         LD1.associative = 4;
466         LD1.linesize    = 64;
467         break;
468       case 0x0e :
469         LD1.size        = 24;
470         LD1.associative = 6;
471         LD1.linesize    = 64;
472         break;
473       case 0x10 :
474         LD1.size        = 16;
475         LD1.associative = 4;
476         LD1.linesize    = 32;
477         break;
478       case 0x15 :
479         LC1.size        = 16;
480         LC1.associative = 4;
481         LC1.linesize    = 32;
482         break;
483       case 0x1a :
484         L2.size         = 96;
485         L2.associative  = 6;
486         L2.linesize     = 64;
487         break;
488       case 0x21 :
489         L2.size         = 256;
490         L2.associative  = 8;
491         L2.linesize     = 64;
492         break;
493       case 0x22 :
494         L3.size         = 512;
495         L3.associative  = 4;
496         L3.linesize     = 64;
497         break;
498       case 0x23 :
499         L3.size         = 1024;
500         L3.associative  = 8;
501         L3.linesize     = 64;
502         break;
503       case 0x25 :
504         L3.size         = 2048;
505         L3.associative  = 8;
506         L3.linesize     = 64;
507         break;
508       case 0x29 :
509         L3.size         = 4096;
510         L3.associative  = 8;
511         L3.linesize     = 64;
512         break;
513       case 0x2c :
514         LD1.size        = 32;
515         LD1.associative = 8;
516         LD1.linesize    = 64;
517         break;
518       case 0x30 :
519         LC1.size        = 32;
520         LC1.associative = 8;
521         LC1.linesize    = 64;
522         break;
523       case 0x39 :
524         L2.size         = 128;
525         L2.associative  = 4;
526         L2.linesize     = 64;
527         break;
528       case 0x3a :
529         L2.size         = 192;
530         L2.associative  = 6;
531         L2.linesize     = 64;
532         break;
533       case 0x3b :
534         L2.size         = 128;
535         L2.associative  = 2;
536         L2.linesize     = 64;
537         break;
538       case 0x3c :
539         L2.size         = 256;
540         L2.associative  = 4;
541         L2.linesize     = 64;
542         break;
543       case 0x3d :
544         L2.size         = 384;
545         L2.associative  = 6;
546         L2.linesize     = 64;
547         break;
548       case 0x3e :
549         L2.size         = 512;
550         L2.associative  = 4;
551         L2.linesize     = 64;
552         break;
553       case 0x41 :
554         L2.size         = 128;
555         L2.associative  = 4;
556         L2.linesize     = 32;
557         break;
558       case 0x42 :
559         L2.size         = 256;
560         L2.associative  = 4;
561         L2.linesize     = 32;
562         break;
563       case 0x43 :
564         L2.size         = 512;
565         L2.associative  = 4;
566         L2.linesize     = 32;
567         break;
568       case 0x44 :
569         L2.size         = 1024;
570         L2.associative  = 4;
571         L2.linesize     = 32;
572         break;
573       case 0x45 :
574         L2.size         = 2048;
575         L2.associative  = 4;
576         L2.linesize     = 32;
577         break;
578       case 0x46 :
579         L3.size         = 4096;
580         L3.associative  = 4;
581         L3.linesize     = 64;
582         break;
583       case 0x47 :
584         L3.size         = 8192;
585         L3.associative  = 8;
586         L3.linesize     = 64;
587         break;
588       case 0x48 :
589         L2.size         = 3184;
590         L2.associative  = 12;
591         L2.linesize     = 64;
592         break;
593       case 0x49 :
594         if ((get_cputype(GET_FAMILY) == 0x0f) && (get_cputype(GET_MODEL) == 0x06)) {
595           L3.size         = 4096;
596           L3.associative  = 16;
597           L3.linesize     = 64;
598         } else {
599           L2.size         = 4096;
600           L2.associative  = 16;
601           L2.linesize     = 64;
602         }
603         break;
604       case 0x4a :
605         L3.size         = 6144;
606         L3.associative  = 12;
607         L3.linesize     = 64;
608         break;
609       case 0x4b :
610         L3.size         = 8192;
611         L3.associative  = 16;
612         L3.linesize     = 64;
613         break;
614       case 0x4c :
615         L3.size         = 12280;
616         L3.associative  = 12;
617         L3.linesize     = 64;
618         break;
619       case 0x4d :
620         L3.size         = 16384;
621         L3.associative  = 16;
622         L3.linesize     = 64;
623         break;
624       case 0x4e :
625         L2.size         = 6144;
626         L2.associative  = 24;
627         L2.linesize     = 64;
628         break;
629       case 0x4f :
630         ITB.size         = 4;
631         ITB.associative  = 0;
632         ITB.linesize     = 32;
633         break;
634       case 0x50 :
635         ITB.size         = 4;
636         ITB.associative  = 0;
637         ITB.linesize     = 64;
638         LITB.size        = 4096;
639         LITB.associative = 0;
640         LITB.linesize    = 64;
641         LITB.shared      = 1;
642         break;
643       case 0x51 :
644         ITB.size        = 4;
645         ITB.associative = 0;
646         ITB.linesize     = 128;
647         LITB.size        = 4096;
648         LITB.associative = 0;
649         LITB.linesize    = 128;
650         LITB.shared      = 1;
651         break;
652       case 0x52 :
653         ITB.size         = 4;
654         ITB.associative  = 0;
655         ITB.linesize     = 256;
656         LITB.size        = 4096;
657         LITB.associative = 0;
658         LITB.linesize    = 256;
659         LITB.shared      = 1;
660         break;
661       case 0x55 :
662         LITB.size        = 4096;
663         LITB.associative = 0;
664         LITB.linesize    = 7;
665         LITB.shared      = 1;
666         break;
667       case 0x56 :
668         LDTB.size        = 4096;
669         LDTB.associative = 4;
670         LDTB.linesize    = 16;
671         break;
672       case 0x57 :
673         LDTB.size        = 4096;
674         LDTB.associative = 4;
675         LDTB.linesize    = 16;
676         break;
677       case 0x5b :
678         DTB.size         = 4;
679         DTB.associative  = 0;
680         DTB.linesize     = 64;
681         LDTB.size        = 4096;
682         LDTB.associative = 0;
683         LDTB.linesize    = 64;
684         LDTB.shared      = 1;
685         break;
686       case 0x5c :
687         DTB.size         = 4;
688         DTB.associative  = 0;
689         DTB.linesize     = 128;
690         LDTB.size        = 4096;
691         LDTB.associative = 0;
692         LDTB.linesize    = 128;
693         LDTB.shared      = 1;
694         break;
695       case 0x5d :
696         DTB.size         = 4;
697         DTB.associative  = 0;
698         DTB.linesize     = 256;
699         LDTB.size        = 4096;
700         LDTB.associative = 0;
701         LDTB.linesize    = 256;
702         LDTB.shared      = 1;
703         break;
704       case 0x60 :
705         LD1.size        = 16;
706         LD1.associative = 8;
707         LD1.linesize    = 64;
708         break;
709       case 0x63 :
710         DTB.size        = 2048;
711         DTB.associative = 4;
712         DTB.linesize    = 32;
713         LDTB.size       = 4096;
714         LDTB.associative= 4;
715         LDTB.linesize   = 32;
716         break;
717       case 0x66 :
718         LD1.size        = 8;
719         LD1.associative = 4;
720         LD1.linesize    = 64;
721         break;
722       case 0x67 :
723         LD1.size        = 16;
724         LD1.associative = 4;
725         LD1.linesize    = 64;
726         break;
727       case 0x68 :
728         LD1.size        = 32;
729         LD1.associative = 4;
730         LD1.linesize    = 64;
731         break;
732       case 0x70 :
733         LC1.size        = 12;
734         LC1.associative = 8;
735         break;
736       case 0x71 :
737         LC1.size        = 16;
738         LC1.associative = 8;
739         break;
740       case 0x72 :
741         LC1.size        = 32;
742         LC1.associative = 8;
743         break;
744       case 0x73 :
745         LC1.size        = 64;
746         LC1.associative = 8;
747         break;
748       case 0x76 :
749         ITB.size        = 2048;
750         ITB.associative = 0;
751         ITB.linesize    = 8;
752         LITB.size       = 4096;
753         LITB.associative= 0;
754         LITB.linesize   = 8;
755         break;
756       case 0x77 :
757         LC1.size        = 16;
758         LC1.associative = 4;
759         LC1.linesize    = 64;
760         break;
761       case 0x78 :
762         L2.size        = 1024;
763         L2.associative = 4;
764         L2.linesize    = 64;
765         break;
766       case 0x79 :
767         L2.size         = 128;
768         L2.associative  = 8;
769         L2.linesize     = 64;
770         break;
771       case 0x7a :
772         L2.size         = 256;
773         L2.associative  = 8;
774         L2.linesize     = 64;
775         break;
776       case 0x7b :
777         L2.size         = 512;
778         L2.associative  = 8;
779         L2.linesize     = 64;
780         break;
781       case 0x7c :
782         L2.size         = 1024;
783         L2.associative  = 8;
784         L2.linesize     = 64;
785         break;
786       case 0x7d :
787         L2.size         = 2048;
788         L2.associative  = 8;
789         L2.linesize     = 64;
790         break;
791       case 0x7e :
792         L2.size         = 256;
793         L2.associative  = 8;
794         L2.linesize     = 128;
795         break;
796       case 0x7f :
797         L2.size         = 512;
798         L2.associative  = 2;
799         L2.linesize     = 64;
800         break;
801       case 0x81 :
802         L2.size         = 128;
803         L2.associative  = 8;
804         L2.linesize     = 32;
805         break;
806       case 0x82 :
807         L2.size         = 256;
808         L2.associative  = 8;
809         L2.linesize     = 32;
810         break;
811       case 0x83 :
812         L2.size         = 512;
813         L2.associative  = 8;
814         L2.linesize     = 32;
815         break;
816       case 0x84 :
817         L2.size         = 1024;
818         L2.associative  = 8;
819         L2.linesize     = 32;
820         break;
821       case 0x85 :
822         L2.size         = 2048;
823         L2.associative  = 8;
824         L2.linesize     = 32;
825         break;
826       case 0x86 :
827         L2.size         = 512;
828         L2.associative  = 4;
829         L2.linesize     = 64;
830         break;
831       case 0x87 :
832         L2.size         = 1024;
833         L2.associative  = 8;
834         L2.linesize     = 64;
835         break;
836       case 0x88 :
837         L3.size         = 2048;
838         L3.associative  = 4;
839         L3.linesize     = 64;
840         break;
841       case 0x89 :
842         L3.size         = 4096;
843         L3.associative  = 4;
844         L3.linesize     = 64;
845         break;
846       case 0x8a :
847         L3.size         = 8192;
848         L3.associative  = 4;
849         L3.linesize     = 64;
850         break;
851       case 0x8d :
852         L3.size         = 3096;
853         L3.associative  = 12;
854         L3.linesize     = 128;
855         break;
856       case 0x90 :
857         ITB.size        = 4;
858         ITB.associative = 0;
859         ITB.linesize    = 64;
860         break;
861       case 0x96 :
862         DTB.size        = 4;
863         DTB.associative = 0;
864         DTB.linesize    = 32;
865         break;
866       case 0x9b :
867         L2DTB.size        = 4;
868         L2DTB.associative = 0;
869         L2DTB.linesize    = 96;
870         break;
871       case 0xb0 :
872         ITB.size        = 4;
873         ITB.associative = 4;
874         ITB.linesize    = 128;
875         break;
876       case 0xb1 :
877         LITB.size        = 4096;
878         LITB.associative = 4;
879         LITB.linesize    = 4;
880         break;
881       case 0xb2 :
882         ITB.size        = 4;
883         ITB.associative = 4;
884         ITB.linesize    = 64;
885         break;
886       case 0xb3 :
887         DTB.size        = 4;
888         DTB.associative = 4;
889         DTB.linesize    = 128;
890         break;
891       case 0xb4 :
892         DTB.size        = 4;
893         DTB.associative = 4;
894         DTB.linesize    = 256;
895         break;
896       case 0xba :
897         DTB.size        = 4;
898         DTB.associative = 4;
899         DTB.linesize    = 64;
900         break;
901       case 0xd0 :
902         L3.size         = 512;
903         L3.associative  = 4;
904         L3.linesize     = 64;
905         break;
906       case 0xd1 :
907         L3.size         = 1024;
908         L3.associative  = 4;
909         L3.linesize     = 64;
910         break;
911       case 0xd2 :
912         L3.size         = 2048;
913         L3.associative  = 4;
914         L3.linesize     = 64;
915         break;
916       case 0xd6 :
917         L3.size         = 1024;
918         L3.associative  = 8;
919         L3.linesize     = 64;
920         break;
921       case 0xd7 :
922         L3.size         = 2048;
923         L3.associative  = 8;
924         L3.linesize     = 64;
925         break;
926       case 0xd8 :
927         L3.size         = 4096;
928         L3.associative  = 8;
929         L3.linesize     = 64;
930         break;
931       case 0xdc :
932         L3.size         = 2048;
933         L3.associative  = 12;
934         L3.linesize     = 64;
935         break;
936       case 0xdd :
937         L3.size         = 4096;
938         L3.associative  = 12;
939         L3.linesize     = 64;
940         break;
941       case 0xde :
942         L3.size         = 8192;
943         L3.associative  = 12;
944         L3.linesize     = 64;
945         break;
946       case 0xe2 :
947         L3.size         = 2048;
948         L3.associative  = 16;
949         L3.linesize     = 64;
950         break;
951       case 0xe3 :
952         L3.size         = 4096;
953         L3.associative  = 16;
954         L3.linesize     = 64;
955         break;
956       case 0xe4 :
957         L3.size         = 8192;
958         L3.associative  = 16;
959         L3.linesize     = 64;
960         break;
961       }
962     }
963   }
964
965   if (get_vendor() == VENDOR_INTEL) {
966       if(LD1.size<=0 || LC1.size<=0){
967         //If we didn't detect L1 correctly before,
968         int count;
969         for (count=0;count <4;count++) {
970         cpuid_count(4, count, &eax, &ebx, &ecx, &edx);
971         switch (eax &0x1f) {
972         case 0:
973           continue;
974           case 1:
975           case 3:
976           {
977             switch ((eax >>5) &0x07)
978             {
979             case 1:
980             {
981 //            fprintf(stderr,"L1 data cache...\n");
982             int sets = ecx+1;
983             int lines = (ebx & 0x0fff) +1;
984             ebx>>=12;
985             int part = (ebx&0x03ff)+1;
986             ebx >>=10;
987             int assoc = (ebx&0x03ff)+1;
988             LD1.size = (assoc*part*lines*sets)/1024;
989             LD1.associative = assoc;
990             LD1.linesize= lines;
991             break;
992             }
993             default: 
994               break;
995            }
996           break;
997           }
998          case 2:
999           {
1000             switch ((eax >>5) &0x07)
1001             {
1002             case 1:
1003             {
1004 //            fprintf(stderr,"L1 instruction cache...\n");
1005             int sets = ecx+1;
1006             int lines = (ebx & 0x0fff) +1;
1007             ebx>>=12;
1008             int part = (ebx&0x03ff)+1;
1009             ebx >>=10;
1010             int assoc = (ebx&0x03ff)+1;
1011             LC1.size = (assoc*part*lines*sets)/1024;
1012             LC1.associative = assoc;
1013             LC1.linesize= lines;
1014             break;
1015             }
1016             default: 
1017               break;
1018            }
1019           break;
1020           
1021           }
1022           default:
1023           break;
1024         }
1025       }
1026     }
1027     cpuid(0x80000000, &cpuid_level, &ebx, &ecx, &edx);
1028     if (cpuid_level >= 0x80000006) {
1029       if(L2.size<=0){
1030         //If we didn't detect L2 correctly before,
1031         cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
1032
1033         L2.size         = BITMASK(ecx, 16, 0xffff);
1034         L2.associative  = BITMASK(ecx, 12, 0x0f);
1035
1036         switch (L2.associative){
1037         case 0x06:
1038           L2.associative = 8;
1039           break;
1040         case 0x08:
1041           L2.associative = 16;
1042           break;
1043         }
1044
1045         L2.linesize     = BITMASK(ecx,  0, 0xff);
1046       }
1047     }
1048   }
1049
1050   if ((get_vendor() == VENDOR_AMD) ||
1051       (get_vendor() == VENDOR_HYGON) ||
1052       (get_vendor() == VENDOR_CENTAUR)) {
1053     cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
1054
1055     LDTB.size        = 4096;
1056     LDTB.associative = BITMASK(eax, 24, 0xff);
1057     if (LDTB.associative == 0xff) LDTB.associative = 0;
1058     LDTB.linesize    = BITMASK(eax, 16, 0xff);
1059
1060     LITB.size        = 4096;
1061     LITB.associative = BITMASK(eax,  8, 0xff);
1062     if (LITB.associative == 0xff) LITB.associative = 0;
1063     LITB.linesize    = BITMASK(eax,  0, 0xff);
1064
1065     DTB.size        = 4;
1066     DTB.associative = BITMASK(ebx, 24, 0xff);
1067     if (DTB.associative == 0xff) DTB.associative = 0;
1068     DTB.linesize    = BITMASK(ebx, 16, 0xff);
1069
1070     ITB.size        = 4;
1071     ITB.associative = BITMASK(ebx,  8, 0xff);
1072     if (ITB.associative == 0xff) ITB.associative = 0;
1073     ITB.linesize    = BITMASK(ebx,  0, 0xff);
1074
1075     LD1.size        = BITMASK(ecx, 24, 0xff);
1076     LD1.associative = BITMASK(ecx, 16, 0xff);
1077     if (LD1.associative == 0xff) LD1.associative = 0;
1078     LD1.linesize    = BITMASK(ecx,  0, 0xff);
1079
1080     LC1.size        = BITMASK(ecx, 24, 0xff);
1081     LC1.associative = BITMASK(ecx, 16, 0xff);
1082     if (LC1.associative == 0xff) LC1.associative = 0;
1083     LC1.linesize    = BITMASK(ecx,  0, 0xff);
1084
1085     cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
1086
1087     L2LDTB.size        = 4096;
1088     L2LDTB.associative = BITMASK(eax, 24, 0xff);
1089     if (L2LDTB.associative == 0xff) L2LDTB.associative = 0;
1090     L2LDTB.linesize    = BITMASK(eax, 16, 0xff);
1091
1092     L2LITB.size        = 4096;
1093     L2LITB.associative = BITMASK(eax,  8, 0xff);
1094     if (L2LITB.associative == 0xff) L2LITB.associative = 0;
1095     L2LITB.linesize    = BITMASK(eax,  0, 0xff);
1096
1097     L2DTB.size        = 4;
1098     L2DTB.associative = BITMASK(ebx, 24, 0xff);
1099     if (L2DTB.associative == 0xff) L2DTB.associative = 0;
1100     L2DTB.linesize    = BITMASK(ebx, 16, 0xff);
1101
1102     L2ITB.size        = 4;
1103     L2ITB.associative = BITMASK(ebx,  8, 0xff);
1104     if (L2ITB.associative == 0xff) L2ITB.associative = 0;
1105     L2ITB.linesize    = BITMASK(ebx,  0, 0xff);
1106
1107     if(L2.size <= 0){
1108       //If we didn't detect L2 correctly before,
1109       L2.size        = BITMASK(ecx, 16, 0xffff);
1110       L2.associative = BITMASK(ecx, 12, 0xf);
1111       switch (L2.associative){
1112       case 0x06:
1113         L2.associative = 8;
1114         break;
1115       case 0x08:
1116         L2.associative = 16;
1117         break;
1118       }
1119
1120       if (L2.associative == 0xff) L2.associative = 0;
1121       L2.linesize    = BITMASK(ecx,  0, 0xff);
1122     }
1123
1124     L3.size        = BITMASK(edx, 18, 0x3fff) * 512;
1125     L3.associative = BITMASK(edx, 12, 0xf);
1126     if (L3.associative == 0xff) L2.associative = 0;
1127     L3.linesize    = BITMASK(edx,  0, 0xff);
1128
1129   }
1130
1131     switch (type) {
1132
1133     case CACHE_INFO_L1_I :
1134       *cacheinfo = LC1;
1135       break;
1136     case CACHE_INFO_L1_D :
1137       *cacheinfo = LD1;
1138       break;
1139     case CACHE_INFO_L2 :
1140       *cacheinfo = L2;
1141       break;
1142     case CACHE_INFO_L3 :
1143       *cacheinfo = L3;
1144       break;
1145     case CACHE_INFO_L1_DTB :
1146       *cacheinfo = DTB;
1147       break;
1148     case CACHE_INFO_L1_ITB :
1149       *cacheinfo = ITB;
1150       break;
1151     case CACHE_INFO_L1_LDTB :
1152       *cacheinfo = LDTB;
1153       break;
1154     case CACHE_INFO_L1_LITB :
1155       *cacheinfo = LITB;
1156       break;
1157     case CACHE_INFO_L2_DTB :
1158       *cacheinfo = L2DTB;
1159       break;
1160     case CACHE_INFO_L2_ITB :
1161       *cacheinfo = L2ITB;
1162       break;
1163     case CACHE_INFO_L2_LDTB :
1164       *cacheinfo = L2LDTB;
1165       break;
1166     case CACHE_INFO_L2_LITB :
1167       *cacheinfo = L2LITB;
1168       break;
1169     }
1170   return 0;
1171 }
1172
1173 int get_cpuname(void){
1174
1175   int family, exfamily, model, vendor, exmodel;
1176
1177   if (!have_cpuid()) return CPUTYPE_80386;
1178
1179   family   = get_cputype(GET_FAMILY);
1180   exfamily = get_cputype(GET_EXFAMILY);
1181   model    = get_cputype(GET_MODEL);
1182   exmodel  = get_cputype(GET_EXMODEL);
1183
1184   vendor = get_vendor();
1185
1186   if (vendor == VENDOR_INTEL){
1187     switch (family) {
1188     case 0x4:
1189       return CPUTYPE_80486;
1190     case 0x5:
1191       return CPUTYPE_PENTIUM;
1192     case 0x6:
1193       switch (exmodel) {
1194       case 0:
1195         switch (model) {
1196         case  1:
1197         case  3:
1198         case  5:
1199         case  6:
1200           return CPUTYPE_PENTIUM2;
1201         case  7:
1202         case  8:
1203         case 10:
1204         case 11:
1205           return CPUTYPE_PENTIUM3;
1206         case  9:
1207         case 13:
1208         case 14:
1209           return CPUTYPE_PENTIUMM;
1210         case 15:
1211           return CPUTYPE_CORE2;
1212         }
1213         break;
1214       case 1:
1215         switch (model) {
1216         case  6:
1217           return CPUTYPE_CORE2;
1218         case  7:
1219           return CPUTYPE_PENRYN;
1220         case 10:
1221         case 11:
1222         case 14:
1223         case 15:
1224           return CPUTYPE_NEHALEM;
1225         case 12:
1226           return CPUTYPE_ATOM;
1227         case 13:
1228           return CPUTYPE_DUNNINGTON;
1229         }
1230         break;
1231       case  2:
1232         switch (model) {
1233         case 5:
1234           //Intel Core (Clarkdale) / Core (Arrandale)
1235           // Pentium (Clarkdale) / Pentium Mobile (Arrandale)
1236           // Xeon (Clarkdale), 32nm
1237           return CPUTYPE_NEHALEM;
1238         case 10:
1239           //Intel Core i5-2000 /i7-2000 (Sandy Bridge)
1240           if(support_avx())
1241             return CPUTYPE_SANDYBRIDGE;
1242           else
1243             return CPUTYPE_NEHALEM; //OS doesn't support AVX
1244         case 12:
1245           //Xeon Processor 5600 (Westmere-EP)
1246           return CPUTYPE_NEHALEM;
1247         case 13:
1248           //Intel Core i7-3000 / Xeon E5 (Sandy Bridge)
1249           if(support_avx())
1250             return CPUTYPE_SANDYBRIDGE;
1251           else
1252             return CPUTYPE_NEHALEM;
1253         case 14:
1254           // Xeon E7540
1255         case 15:
1256           //Xeon Processor E7 (Westmere-EX)
1257           return CPUTYPE_NEHALEM;
1258         }
1259         break;
1260       case 3:
1261         switch (model) {
1262         case  7:
1263             // Bay Trail        
1264             return CPUTYPE_ATOM;        
1265         case 10:
1266         case 14:
1267           // Ivy Bridge
1268           if(support_avx())
1269             return CPUTYPE_SANDYBRIDGE;
1270           else
1271             return CPUTYPE_NEHALEM;
1272         case 12:
1273         case 15:
1274           if(support_avx2())
1275             return CPUTYPE_HASWELL;
1276           if(support_avx())
1277             return CPUTYPE_SANDYBRIDGE;
1278           else
1279             return CPUTYPE_NEHALEM;
1280         case 13:
1281           //Broadwell
1282           if(support_avx2())
1283             return CPUTYPE_HASWELL;
1284           if(support_avx())
1285             return CPUTYPE_SANDYBRIDGE;
1286           else
1287             return CPUTYPE_NEHALEM;
1288         }
1289         break;
1290       case 4:
1291         switch (model) {
1292         case 5:
1293         case 6:
1294           if(support_avx2())
1295             return CPUTYPE_HASWELL;
1296           if(support_avx())
1297             return CPUTYPE_SANDYBRIDGE;
1298           else
1299             return CPUTYPE_NEHALEM;
1300         case 7:
1301         case 15:
1302           //Broadwell
1303           if(support_avx2())
1304             return CPUTYPE_HASWELL;
1305           if(support_avx())
1306             return CPUTYPE_SANDYBRIDGE;
1307           else
1308             return CPUTYPE_NEHALEM;
1309         case 14:
1310           //Skylake
1311           if(support_avx2())
1312             return CPUTYPE_HASWELL;
1313           if(support_avx())
1314             return CPUTYPE_SANDYBRIDGE;
1315           else
1316             return CPUTYPE_NEHALEM;
1317         case 12:
1318           // Braswell
1319         case 13:
1320           // Avoton
1321             return CPUTYPE_NEHALEM;
1322         }
1323         break;
1324       case 5:
1325         switch (model) {
1326         case 6:
1327           //Broadwell
1328           if(support_avx2())
1329             return CPUTYPE_HASWELL;
1330           if(support_avx())
1331             return CPUTYPE_SANDYBRIDGE;
1332           else
1333             return CPUTYPE_NEHALEM;
1334         case 5:
1335           // Skylake X
1336           if(support_avx512())
1337             return CPUTYPE_SKYLAKEX;
1338           if(support_avx2())
1339             return CPUTYPE_HASWELL;
1340           if(support_avx())
1341             return CPUTYPE_SANDYBRIDGE;
1342           else
1343           return CPUTYPE_NEHALEM;
1344         case 14:
1345           // Skylake
1346           if(support_avx2())
1347             return CPUTYPE_HASWELL;
1348           if(support_avx())
1349             return CPUTYPE_SANDYBRIDGE;
1350           else
1351             return CPUTYPE_NEHALEM;
1352         case 7:
1353             // Xeon Phi Knights Landing
1354           if(support_avx2())
1355             return CPUTYPE_HASWELL;
1356           if(support_avx())
1357             return CPUTYPE_SANDYBRIDGE;
1358           else
1359             return CPUTYPE_NEHALEM;
1360         case 12:
1361             // Apollo Lake
1362         case 15:
1363             // Denverton                
1364             return CPUTYPE_NEHALEM;
1365         }
1366         break;
1367       case 6:
1368         switch (model) {
1369         case 6: // Cannon Lake
1370           if(support_avx512())
1371             return CPUTYPE_SKYLAKEX;
1372           if(support_avx2())
1373             return CPUTYPE_HASWELL;
1374           if(support_avx())
1375             return CPUTYPE_SANDYBRIDGE;
1376           else
1377           return CPUTYPE_NEHALEM;
1378         }
1379       break;  
1380       case 9:
1381       case 8:      
1382         switch (model) {
1383         case 14: // Kaby Lake and refreshes
1384           if(support_avx2())
1385             return CPUTYPE_HASWELL;
1386           if(support_avx())
1387             return CPUTYPE_SANDYBRIDGE;
1388           else
1389             return CPUTYPE_NEHALEM;
1390         }
1391         break;    
1392       }
1393       break;
1394     case 0x7:
1395       return CPUTYPE_ITANIUM;
1396     case 0xf:
1397       switch (exfamily) {
1398       case 0 :
1399         return CPUTYPE_PENTIUM4;
1400       case 1 :
1401         return CPUTYPE_ITANIUM;
1402       }
1403       break;
1404     }
1405     return CPUTYPE_INTEL_UNKNOWN;
1406   }
1407
1408   if (vendor == VENDOR_AMD){
1409     switch (family) {
1410     case 0x4:
1411       return CPUTYPE_AMD5X86;
1412     case 0x5:
1413       return CPUTYPE_AMDK6;
1414     case 0x6:
1415       return CPUTYPE_ATHLON;
1416     case 0xf:
1417       switch (exfamily) {
1418       case  0:
1419       case  2:
1420         return CPUTYPE_OPTERON;
1421       case  1:
1422       case  3:
1423       case  7:
1424       case 10:
1425         return CPUTYPE_BARCELONA;
1426       case  5:
1427         return CPUTYPE_BOBCAT;
1428       case  6:
1429         switch (model) {
1430         case 1:
1431           //AMD Bulldozer Opteron 6200 / Opteron 4200 / AMD FX-Series
1432           if(support_avx())
1433             return CPUTYPE_BULLDOZER;
1434           else
1435             return CPUTYPE_BARCELONA; //OS don't support AVX.
1436         case 2: //AMD Piledriver
1437         case 3: //AMD Richland
1438           if(support_avx())
1439             return CPUTYPE_PILEDRIVER;
1440           else
1441             return CPUTYPE_BARCELONA; //OS don't support AVX.
1442         case 5: // New EXCAVATOR CPUS
1443           if(support_avx())
1444             return CPUTYPE_EXCAVATOR;
1445           else
1446             return CPUTYPE_BARCELONA; //OS don't support AVX.
1447         case 0:
1448         case 8:
1449           switch(exmodel){
1450           case 1: //AMD Trinity
1451             if(support_avx())
1452               return CPUTYPE_PILEDRIVER;
1453             else
1454               return CPUTYPE_BARCELONA; //OS don't support AVX.
1455           case 3:
1456             if(support_avx())
1457               return CPUTYPE_STEAMROLLER;
1458             else
1459               return CPUTYPE_BARCELONA; //OS don't support AVX.
1460
1461           case 6:
1462             if(support_avx())
1463               return CPUTYPE_EXCAVATOR;
1464             else
1465               return CPUTYPE_BARCELONA; //OS don't support AVX.
1466           }
1467           break;
1468         }
1469         break;
1470       case 8:
1471         switch (model) {
1472         case 1:
1473           // AMD Ryzen
1474         case 8:
1475           // AMD Ryzen2
1476           if(support_avx())
1477 #ifndef NO_AVX2
1478             return CPUTYPE_ZEN;
1479 #else
1480             return CPUTYPE_SANDYBRIDGE; // Zen is closer in architecture to Sandy Bridge than to Excavator
1481 #endif
1482           else
1483             return CPUTYPE_BARCELONA;
1484         }
1485       }
1486       break;
1487     }
1488     return CPUTYPE_AMD_UNKNOWN;
1489   }
1490
1491   if (vendor == VENDOR_HYGON){
1492     switch (family) {
1493     case 0xf:
1494       switch (exfamily) {
1495       case 9:
1496           //Hygon Dhyana
1497           if(support_avx())
1498 #ifndef NO_AVX2
1499             return CPUTYPE_ZEN;
1500 #else
1501             return CPUTYPE_SANDYBRIDGE; // closer in architecture to Sandy Bridge than to Excavator
1502 #endif
1503           else
1504             return CPUTYPE_BARCELONA;
1505         }
1506       break;
1507     }
1508     return CPUTYPE_HYGON_UNKNOWN;
1509   }
1510
1511   if (vendor == VENDOR_CYRIX){
1512     switch (family) {
1513     case 0x4:
1514       return CPUTYPE_CYRIX5X86;
1515     case 0x5:
1516       return CPUTYPE_CYRIXM1;
1517     case 0x6:
1518       return CPUTYPE_CYRIXM2;
1519     }
1520     return CPUTYPE_CYRIX_UNKNOWN;
1521   }
1522
1523   if (vendor == VENDOR_NEXGEN){
1524     switch (family) {
1525     case 0x5:
1526       return CPUTYPE_NEXGENNX586;
1527     }
1528     return CPUTYPE_NEXGEN_UNKNOWN;
1529   }
1530
1531   if (vendor == VENDOR_CENTAUR){
1532     switch (family) {
1533     case 0x5:
1534       return CPUTYPE_CENTAURC6;
1535       break;
1536     case 0x6:
1537       return CPUTYPE_NANO;
1538       break;
1539
1540     }
1541     return CPUTYPE_VIAC3;
1542   }
1543
1544   if (vendor == VENDOR_RISE){
1545     switch (family) {
1546     case 0x5:
1547       return CPUTYPE_RISEMP6;
1548     }
1549     return CPUTYPE_RISE_UNKNOWN;
1550   }
1551
1552   if (vendor == VENDOR_SIS){
1553     switch (family) {
1554     case 0x5:
1555       return CPUTYPE_SYS55X;
1556     }
1557     return CPUTYPE_SIS_UNKNOWN;
1558   }
1559
1560   if (vendor == VENDOR_TRANSMETA){
1561     switch (family) {
1562     case 0x5:
1563       return CPUTYPE_CRUSOETM3X;
1564     }
1565     return CPUTYPE_TRANSMETA_UNKNOWN;
1566   }
1567
1568   if (vendor == VENDOR_NSC){
1569     switch (family) {
1570     case 0x5:
1571       return CPUTYPE_NSGEODE;
1572     }
1573     return CPUTYPE_NSC_UNKNOWN;
1574   }
1575
1576   return CPUTYPE_UNKNOWN;
1577 }
1578
1579 static char *cpuname[] = {
1580   "UNKNOWN",
1581   "INTEL_UNKNOWN",
1582   "UMC_UNKNOWN",
1583   "AMD_UNKNOWN",
1584   "CYRIX_UNKNOWN",
1585   "NEXGEN_UNKNOWN",
1586   "CENTAUR_UNKNOWN",
1587   "RISE_UNKNOWN",
1588   "SIS_UNKNOWN",
1589   "TRANSMETA_UNKNOWN",
1590   "NSC_UNKNOWN",
1591   "80386",
1592   "80486",
1593   "PENTIUM",
1594   "PENTIUM2",
1595   "PENTIUM3",
1596   "PENTIUMM",
1597   "PENTIUM4",
1598   "CORE2",
1599   "PENRYN",
1600   "DUNNINGTON",
1601   "NEHALEM",
1602   "ATOM",
1603   "ITANIUM",
1604   "ITANIUM2",
1605   "5X86",
1606   "K6",
1607   "ATHLON",
1608   "DURON",
1609   "OPTERON",
1610   "BARCELONA",
1611   "SHANGHAI",
1612   "ISTANBUL",
1613   "CYRIX5X86",
1614   "CYRIXM1",
1615   "CYRIXM2",
1616   "NEXGENNX586",
1617   "CENTAURC6",
1618   "RISEMP6",
1619   "SYS55X",
1620   "TM3X00",
1621   "NSGEODE",
1622   "VIAC3",
1623   "NANO",
1624   "SANDYBRIDGE",
1625   "BOBCAT",
1626   "BULLDOZER",
1627   "PILEDRIVER",
1628   "HASWELL",
1629   "STEAMROLLER",
1630   "EXCAVATOR",
1631   "ZEN",
1632   "SKYLAKEX",
1633   "DHYANA"
1634 };
1635
1636 static char *lowercpuname[] = {
1637   "unknown",
1638   "intel_unknown",
1639   "umc_unknown",
1640   "amd_unknown",
1641   "cyrix_unknown",
1642   "nexgen_unknown",
1643   "centaur_unknown",
1644   "rise_unknown",
1645   "sis_unknown",
1646   "transmeta_unknown",
1647   "nsc_unknown",
1648   "80386",
1649   "80486",
1650   "pentium",
1651   "pentium2",
1652   "pentium3",
1653   "pentiumm",
1654   "pentium4",
1655   "core2",
1656   "penryn",
1657   "dunnington",
1658   "nehalem",
1659   "atom",
1660   "itanium",
1661   "itanium2",
1662   "5x86",
1663   "k6",
1664   "athlon",
1665   "duron",
1666   "opteron",
1667   "barcelona",
1668   "shanghai",
1669   "istanbul",
1670   "cyrix5x86",
1671   "cyrixm1",
1672   "cyrixm2",
1673   "nexgennx586",
1674   "centaurc6",
1675   "risemp6",
1676   "sys55x",
1677   "tms3x00",
1678   "nsgeode",
1679   "nano",
1680   "sandybridge",
1681   "bobcat",
1682   "bulldozer",
1683   "piledriver",
1684   "haswell",
1685   "steamroller",
1686   "excavator",
1687   "zen",
1688   "skylakex",
1689   "dhyana"
1690 };
1691
1692 static char *corename[] = {
1693   "UNKNOWN",
1694   "80486",
1695   "P5",
1696   "P6",
1697   "KATMAI",
1698   "COPPERMINE",
1699   "NORTHWOOD",
1700   "PRESCOTT",
1701   "BANIAS",
1702   "ATHLON",
1703   "OPTERON",
1704   "BARCELONA",
1705   "VIAC3",
1706   "YONAH",
1707   "CORE2",
1708   "PENRYN",
1709   "DUNNINGTON",
1710   "NEHALEM",
1711   "ATOM",
1712   "NANO",
1713   "SANDYBRIDGE",
1714   "BOBCAT",
1715   "BULLDOZER",
1716   "PILEDRIVER",
1717   "HASWELL",
1718   "STEAMROLLER",
1719   "EXCAVATOR",
1720   "ZEN",
1721   "SKYLAKEX",
1722   "DHYANA"
1723 };
1724
1725 static char *corename_lower[] = {
1726   "unknown",
1727   "80486",
1728   "p5",
1729   "p6",
1730   "katmai",
1731   "coppermine",
1732   "northwood",
1733   "prescott",
1734   "banias",
1735   "athlon",
1736   "opteron",
1737   "barcelona",
1738   "viac3",
1739   "yonah",
1740   "core2",
1741   "penryn",
1742   "dunnington",
1743   "nehalem",
1744   "atom",
1745   "nano",
1746   "sandybridge",
1747   "bobcat",
1748   "bulldozer",
1749   "piledriver",
1750   "haswell",
1751   "steamroller",
1752   "excavator",
1753   "zen",
1754   "skylakex",
1755   "dhyana"
1756 };
1757
1758
1759 char *get_cpunamechar(void){
1760   return cpuname[get_cpuname()];
1761 }
1762
1763 char *get_lower_cpunamechar(void){
1764   return lowercpuname[get_cpuname()];
1765 }
1766
1767
1768 int get_coretype(void){
1769
1770   int family, exfamily, model, exmodel, vendor;
1771
1772   if (!have_cpuid()) return CORE_80486;
1773
1774   family   = get_cputype(GET_FAMILY);
1775   exfamily = get_cputype(GET_EXFAMILY);
1776   model    = get_cputype(GET_MODEL);
1777   exmodel  = get_cputype(GET_EXMODEL);
1778
1779   vendor = get_vendor();
1780
1781   if (vendor == VENDOR_INTEL){
1782     switch (family) {
1783     case  4:
1784       return CORE_80486;
1785     case  5:
1786       return CORE_P5;
1787     case  6:
1788       switch (exmodel) {
1789       case  0:
1790         switch (model) {
1791         case  0:
1792         case  1:
1793         case  2:
1794         case  3:
1795         case  4:
1796         case  5:
1797         case  6:
1798           return CORE_P6;
1799         case  7:
1800           return CORE_KATMAI;
1801         case  8:
1802         case 10:
1803         case 11:
1804           return CORE_COPPERMINE;
1805         case  9:
1806         case 13:
1807         case 14:
1808           return CORE_BANIAS;
1809         case 15:
1810           return CORE_CORE2;
1811         }
1812         break;
1813       case  1:
1814         switch (model) {
1815         case  6:
1816           return CORE_CORE2;
1817         case  7:
1818           return CORE_PENRYN;
1819         case 10:
1820         case 11:
1821         case 14:
1822         case 15:
1823           return CORE_NEHALEM;
1824         case 12:
1825           return CORE_ATOM;
1826         case 13:
1827           return CORE_DUNNINGTON;
1828         }
1829         break;
1830       case  2:
1831         switch (model) {
1832         case 5:
1833           //Intel Core (Clarkdale) / Core (Arrandale)
1834           // Pentium (Clarkdale) / Pentium Mobile (Arrandale)
1835           // Xeon (Clarkdale), 32nm
1836           return CORE_NEHALEM;
1837         case 10:
1838           //Intel Core i5-2000 /i7-2000 (Sandy Bridge)
1839           if(support_avx())
1840             return CORE_SANDYBRIDGE;
1841           else
1842             return CORE_NEHALEM; //OS doesn't support AVX
1843         case 12:
1844           //Xeon Processor 5600 (Westmere-EP)
1845           return CORE_NEHALEM;
1846         case 13:
1847           //Intel Core i7-3000 / Xeon E5 (Sandy Bridge)
1848           if(support_avx())
1849             return CORE_SANDYBRIDGE;
1850           else
1851             return CORE_NEHALEM; //OS doesn't support AVX
1852         case 14:
1853           //Xeon E7540
1854         case 15:
1855           //Xeon Processor E7 (Westmere-EX)
1856           return CORE_NEHALEM;
1857         }
1858         break;
1859       case 3:
1860         switch (model) {
1861         case 7:
1862           return CORE_ATOM;             
1863         case 10:
1864         case 14:
1865           if(support_avx())
1866             return CORE_SANDYBRIDGE;
1867           else
1868             return CORE_NEHALEM; //OS doesn't support AVX
1869         case 12:
1870         case 15:
1871           if(support_avx())
1872 #ifndef NO_AVX2
1873             return CORE_HASWELL;
1874 #else
1875             return CORE_SANDYBRIDGE;
1876 #endif
1877           else
1878             return CORE_NEHALEM;
1879         case 13:
1880           //broadwell
1881           if(support_avx())
1882 #ifndef NO_AVX2
1883             return CORE_HASWELL;
1884 #else
1885             return CORE_SANDYBRIDGE;
1886 #endif
1887           else
1888             return CORE_NEHALEM;
1889         }
1890         break;
1891       case 4:
1892         switch (model) {
1893         case 5:
1894         case 6:
1895           if(support_avx())
1896 #ifndef NO_AVX2
1897             return CORE_HASWELL;
1898 #else
1899             return CORE_SANDYBRIDGE;
1900 #endif
1901           else
1902             return CORE_NEHALEM;
1903         case 7:
1904         case 15:
1905           //broadwell
1906           if(support_avx())
1907 #ifndef NO_AVX2
1908             return CORE_HASWELL;
1909 #else
1910             return CORE_SANDYBRIDGE;
1911 #endif
1912           else
1913             return CORE_NEHALEM;
1914         case 14:
1915           //Skylake
1916           if(support_avx())
1917 #ifndef NO_AVX2
1918             return CORE_HASWELL;
1919 #else
1920             return CORE_SANDYBRIDGE;
1921 #endif
1922           else
1923             return CORE_NEHALEM;
1924         case 12:
1925           // Braswell
1926         case 13:
1927           // Avoton
1928             return CORE_NEHALEM;
1929         }
1930         break;
1931       case 5:
1932         switch (model) {
1933         case 6:
1934           //broadwell
1935           if(support_avx())
1936 #ifndef NO_AVX2
1937             return CORE_HASWELL;
1938 #else
1939             return CORE_SANDYBRIDGE;
1940 #endif
1941           else
1942             return CORE_NEHALEM;
1943         case 5:
1944          // Skylake X
1945 #ifndef NO_AVX512
1946             return CORE_SKYLAKEX;
1947 #else
1948           if(support_avx())
1949 #ifndef NO_AVX2
1950             return CORE_HASWELL;
1951 #else
1952             return CORE_SANDYBRIDGE;
1953 #endif
1954           else
1955             return CORE_NEHALEM;
1956 #endif                  
1957         case 14:
1958           // Skylake
1959           if(support_avx())
1960 #ifndef NO_AVX2
1961             return CORE_HASWELL;
1962 #else
1963             return CORE_SANDYBRIDGE;
1964 #endif
1965           else
1966             return CORE_NEHALEM;
1967         case 7:
1968           // Phi Knights Landing
1969           if(support_avx())
1970 #ifndef NO_AVX2
1971             return CORE_HASWELL;
1972 #else
1973             return CORE_SANDYBRIDGE;
1974 #endif
1975           else
1976             return CORE_NEHALEM;
1977         case 12:
1978           // Apollo Lake
1979             return CORE_NEHALEM;
1980         }
1981         break;
1982       case 9:
1983       case 8:
1984         if (model == 14) { // Kaby Lake 
1985           if(support_avx())
1986 #ifndef NO_AVX2
1987             return CORE_HASWELL;
1988 #else
1989             return CORE_SANDYBRIDGE;
1990 #endif
1991           else
1992             return CORE_NEHALEM;
1993         }
1994       }
1995       break;
1996
1997       case 15:
1998         if (model <= 0x2) return CORE_NORTHWOOD;
1999         else return CORE_PRESCOTT;
2000     }
2001   }
2002
2003   if (vendor == VENDOR_AMD){
2004     if (family <= 0x5) return CORE_80486;
2005     if (family <= 0xe) return CORE_ATHLON;
2006     if (family == 0xf){
2007       if ((exfamily == 0) || (exfamily == 2)) return CORE_OPTERON;
2008       else if (exfamily == 5) return CORE_BOBCAT;
2009       else if (exfamily == 6) {
2010         switch (model) {
2011         case 1:
2012           //AMD Bulldozer Opteron 6200 / Opteron 4200 / AMD FX-Series
2013           if(support_avx())
2014             return CORE_BULLDOZER;
2015           else
2016             return CORE_BARCELONA; //OS don't support AVX.
2017         case 2: //AMD Piledriver
2018         case 3: //AMD Richland
2019           if(support_avx())
2020             return CORE_PILEDRIVER;
2021           else
2022             return CORE_BARCELONA; //OS don't support AVX.
2023     case 5: // New EXCAVATOR
2024           if(support_avx())
2025             return CORE_EXCAVATOR;
2026           else
2027             return CORE_BARCELONA; //OS don't support AVX.
2028         case 0:
2029         case 8:
2030           switch(exmodel){
2031           case 1: //AMD Trinity
2032             if(support_avx())
2033               return CORE_PILEDRIVER;
2034             else
2035               return CORE_BARCELONA; //OS don't support AVX.
2036
2037           case 3:
2038             if(support_avx())
2039               return CORE_STEAMROLLER;
2040             else
2041               return CORE_BARCELONA; //OS don't support AVX.
2042
2043           case 6:
2044             if(support_avx())
2045               return CORE_EXCAVATOR;
2046             else
2047               return CORE_BARCELONA; //OS don't support AVX.
2048           }
2049           break;
2050         }
2051       } else if (exfamily == 8) {
2052         switch (model) {
2053         case 1:
2054           // AMD Ryzen
2055         case 8:
2056           // Ryzen 2            
2057           if(support_avx())
2058 #ifndef NO_AVX2
2059             return CORE_ZEN;
2060 #else
2061             return CORE_SANDYBRIDGE; // Zen is closer in architecture to Sandy Bridge than to Excavator
2062 #endif
2063           else
2064             return CORE_BARCELONA;
2065         }
2066       } else {
2067         return CORE_BARCELONA;
2068       }
2069     }
2070   }
2071
2072   if (vendor == VENDOR_HYGON){
2073     if (family == 0xf){
2074         if (exfamily == 9) {
2075           if(support_avx())
2076 #ifndef NO_AVX2
2077             return CORE_ZEN;
2078 #else
2079             return CORE_SANDYBRIDGE; // closer in architecture to Sandy Bridge than to Excavator
2080 #endif
2081           else
2082             return CORE_BARCELONA;
2083         } else {
2084                 return CORE_BARCELONA;
2085         }
2086     }
2087   }
2088
2089   if (vendor == VENDOR_CENTAUR) {
2090     switch (family) {
2091     case 0x6:
2092       return CORE_NANO;
2093       break;
2094     }
2095     return CORE_VIAC3;
2096   }
2097
2098   return CORE_UNKNOWN;
2099 }
2100
2101 void get_cpuconfig(void){
2102
2103   cache_info_t info;
2104   int features;
2105
2106   printf("#define %s\n", cpuname[get_cpuname()]);
2107
2108
2109   if (get_coretype() != CORE_P5) {
2110
2111     get_cacheinfo(CACHE_INFO_L1_I, &info);
2112     if (info.size > 0) {
2113       printf("#define L1_CODE_SIZE %d\n", info.size * 1024);
2114       printf("#define L1_CODE_ASSOCIATIVE %d\n", info.associative);
2115       printf("#define L1_CODE_LINESIZE %d\n", info.linesize);
2116     }
2117
2118     get_cacheinfo(CACHE_INFO_L1_D, &info);
2119     if (info.size > 0) {
2120       printf("#define L1_DATA_SIZE %d\n", info.size * 1024);
2121       printf("#define L1_DATA_ASSOCIATIVE %d\n", info.associative);
2122       printf("#define L1_DATA_LINESIZE %d\n", info.linesize);
2123     }
2124
2125     get_cacheinfo(CACHE_INFO_L2, &info);
2126     if (info.size > 0) {
2127       printf("#define L2_SIZE %d\n", info.size * 1024);
2128       printf("#define L2_ASSOCIATIVE %d\n", info.associative);
2129       printf("#define L2_LINESIZE %d\n", info.linesize);
2130     } else {
2131       //fall back for some virtual machines.
2132       printf("#define L2_SIZE 1048576\n");
2133       printf("#define L2_ASSOCIATIVE 6\n");
2134       printf("#define L2_LINESIZE 64\n");
2135     }
2136
2137
2138     get_cacheinfo(CACHE_INFO_L3, &info);
2139     if (info.size > 0) {
2140       printf("#define L3_SIZE %d\n", info.size * 1024);
2141       printf("#define L3_ASSOCIATIVE %d\n", info.associative);
2142       printf("#define L3_LINESIZE %d\n", info.linesize);
2143     }
2144
2145     get_cacheinfo(CACHE_INFO_L1_ITB, &info);
2146     if (info.size > 0) {
2147       printf("#define ITB_SIZE %d\n", info.size * 1024);
2148       printf("#define ITB_ASSOCIATIVE %d\n", info.associative);
2149       printf("#define ITB_ENTRIES %d\n", info.linesize);
2150     }
2151
2152     get_cacheinfo(CACHE_INFO_L1_DTB, &info);
2153     if (info.size > 0) {
2154       printf("#define DTB_SIZE %d\n", info.size * 1024);
2155       printf("#define DTB_ASSOCIATIVE %d\n", info.associative);
2156       printf("#define DTB_DEFAULT_ENTRIES %d\n", info.linesize);
2157     } else {
2158       //fall back for some virtual machines.
2159       printf("#define DTB_DEFAULT_ENTRIES 32\n");
2160     }
2161
2162     features = get_cputype(GET_FEATURE);
2163
2164     if (features & HAVE_CMOV )   printf("#define HAVE_CMOV\n");
2165     if (features & HAVE_MMX  )   printf("#define HAVE_MMX\n");
2166     if (features & HAVE_SSE  )   printf("#define HAVE_SSE\n");
2167     if (features & HAVE_SSE2 )   printf("#define HAVE_SSE2\n");
2168     if (features & HAVE_SSE3 )   printf("#define HAVE_SSE3\n");
2169     if (features & HAVE_SSSE3)   printf("#define HAVE_SSSE3\n");
2170     if (features & HAVE_SSE4_1)   printf("#define HAVE_SSE4_1\n");
2171     if (features & HAVE_SSE4_2)   printf("#define HAVE_SSE4_2\n");
2172     if (features & HAVE_SSE4A)   printf("#define HAVE_SSE4A\n");
2173     if (features & HAVE_SSE5 )   printf("#define HAVE_SSSE5\n");
2174     if (features & HAVE_AVX )    printf("#define HAVE_AVX\n");
2175     if (features & HAVE_AVX2 )    printf("#define HAVE_AVX2\n");
2176     if (features & HAVE_AVX512VL )    printf("#define HAVE_AVX512VL\n");
2177     if (features & HAVE_3DNOWEX) printf("#define HAVE_3DNOWEX\n");
2178     if (features & HAVE_3DNOW)   printf("#define HAVE_3DNOW\n");
2179     if (features & HAVE_FMA4 )    printf("#define HAVE_FMA4\n");
2180     if (features & HAVE_FMA3 )    printf("#define HAVE_FMA3\n");
2181     if (features & HAVE_CFLUSH)  printf("#define HAVE_CFLUSH\n");
2182     if (features & HAVE_HIT)     printf("#define HAVE_HIT 1\n");
2183     if (features & HAVE_MISALIGNSSE) printf("#define HAVE_MISALIGNSSE\n");
2184     if (features & HAVE_128BITFPU)   printf("#define HAVE_128BITFPU\n");
2185     if (features & HAVE_FASTMOVU)    printf("#define HAVE_FASTMOVU\n");
2186
2187     printf("#define NUM_SHAREDCACHE %d\n", get_cputype(GET_NUMSHARE) + 1);
2188     printf("#define NUM_CORES %d\n", get_cputype(GET_NUMCORES) + 1);
2189
2190     features = get_coretype();
2191     if (features > 0) printf("#define CORE_%s\n", corename[features]);
2192   } else {
2193     printf("#define DTB_DEFAULT_ENTRIES 16\n");
2194     printf("#define L1_CODE_SIZE 8192\n");
2195     printf("#define L1_DATA_SIZE 8192\n");
2196     printf("#define L2_SIZE 0\n");
2197   }
2198 }
2199
2200 void get_architecture(void){
2201 #ifndef __64BIT__
2202     printf("X86");
2203 #else
2204     printf("X86_64");
2205 #endif
2206 }
2207
2208 void get_subarchitecture(void){
2209     printf("%s", get_cpunamechar());
2210 }
2211
2212 void get_subdirname(void){
2213 #ifndef __64BIT__
2214     printf("x86");
2215 #else
2216     printf("x86_64");
2217 #endif
2218 }
2219
2220 char *get_corename(void){
2221   return corename[get_coretype()];
2222 }
2223
2224 void get_libname(void){
2225   printf("%s",   corename_lower[get_coretype()]);
2226 }
2227
2228 /* This if for Makefile */
2229 void get_sse(void){
2230
2231   int features;
2232
2233   features = get_cputype(GET_FEATURE);
2234
2235   if (features & HAVE_MMX  )   printf("HAVE_MMX=1\n");
2236   if (features & HAVE_SSE  )   printf("HAVE_SSE=1\n");
2237   if (features & HAVE_SSE2 )   printf("HAVE_SSE2=1\n");
2238   if (features & HAVE_SSE3 )   printf("HAVE_SSE3=1\n");
2239   if (features & HAVE_SSSE3)   printf("HAVE_SSSE3=1\n");
2240   if (features & HAVE_SSE4_1)   printf("HAVE_SSE4_1=1\n");
2241   if (features & HAVE_SSE4_2)   printf("HAVE_SSE4_2=1\n");
2242   if (features & HAVE_SSE4A)   printf("HAVE_SSE4A=1\n");
2243   if (features & HAVE_SSE5 )   printf("HAVE_SSSE5=1\n");
2244   if (features & HAVE_AVX )    printf("HAVE_AVX=1\n");
2245   if (features & HAVE_AVX2 )    printf("HAVE_AVX2=1\n");
2246   if (features & HAVE_AVX512VL )    printf("HAVE_AVX512VL=1\n");
2247   if (features & HAVE_3DNOWEX) printf("HAVE_3DNOWEX=1\n");
2248   if (features & HAVE_3DNOW)   printf("HAVE_3DNOW=1\n");
2249   if (features & HAVE_FMA4 )    printf("HAVE_FMA4=1\n");
2250   if (features & HAVE_FMA3 )    printf("HAVE_FMA3=1\n");
2251
2252 }