power9 makefile. dgemm based on power8 kernel with following changes : 32x unrolled...
[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 #ifndef 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             return CPUTYPE_NEHALEM;
1363         }
1364         break;
1365       case 6:
1366         switch (model) {
1367         case 6: // Cannon Lake
1368           if(support_avx512())
1369             return CPUTYPE_SKYLAKEX;
1370           if(support_avx2())
1371             return CPUTYPE_HASWELL;
1372           if(support_avx())
1373             return CPUTYPE_SANDYBRIDGE;
1374           else
1375           return CPUTYPE_NEHALEM;
1376         }
1377       break;  
1378       case 9:
1379       case 8: 
1380         switch (model) {
1381         case 14: // Kaby Lake
1382           if(support_avx2())
1383             return CPUTYPE_HASWELL;
1384           if(support_avx())
1385             return CPUTYPE_SANDYBRIDGE;
1386           else
1387             return CPUTYPE_NEHALEM;
1388         }
1389         break;    
1390       }
1391       break;
1392     case 0x7:
1393       return CPUTYPE_ITANIUM;
1394     case 0xf:
1395       switch (exfamily) {
1396       case 0 :
1397         return CPUTYPE_PENTIUM4;
1398       case 1 :
1399         return CPUTYPE_ITANIUM;
1400       }
1401       break;
1402     }
1403     return CPUTYPE_INTEL_UNKNOWN;
1404   }
1405
1406   if (vendor == VENDOR_AMD){
1407     switch (family) {
1408     case 0x4:
1409       return CPUTYPE_AMD5X86;
1410     case 0x5:
1411       return CPUTYPE_AMDK6;
1412     case 0x6:
1413       return CPUTYPE_ATHLON;
1414     case 0xf:
1415       switch (exfamily) {
1416       case  0:
1417       case  2:
1418         return CPUTYPE_OPTERON;
1419       case  1:
1420       case  3:
1421       case  7:
1422       case 10:
1423         return CPUTYPE_BARCELONA;
1424       case  5:
1425         return CPUTYPE_BOBCAT;
1426       case  6:
1427         switch (model) {
1428         case 1:
1429           //AMD Bulldozer Opteron 6200 / Opteron 4200 / AMD FX-Series
1430           if(support_avx())
1431             return CPUTYPE_BULLDOZER;
1432           else
1433             return CPUTYPE_BARCELONA; //OS don't support AVX.
1434         case 2: //AMD Piledriver
1435         case 3: //AMD Richland
1436           if(support_avx())
1437             return CPUTYPE_PILEDRIVER;
1438           else
1439             return CPUTYPE_BARCELONA; //OS don't support AVX.
1440         case 5: // New EXCAVATOR CPUS
1441           if(support_avx())
1442             return CPUTYPE_EXCAVATOR;
1443           else
1444             return CPUTYPE_BARCELONA; //OS don't support AVX.
1445         case 0:
1446         case 8:
1447           switch(exmodel){
1448           case 1: //AMD Trinity
1449             if(support_avx())
1450               return CPUTYPE_PILEDRIVER;
1451             else
1452               return CPUTYPE_BARCELONA; //OS don't support AVX.
1453           case 3:
1454             if(support_avx())
1455               return CPUTYPE_STEAMROLLER;
1456             else
1457               return CPUTYPE_BARCELONA; //OS don't support AVX.
1458
1459           case 6:
1460             if(support_avx())
1461               return CPUTYPE_EXCAVATOR;
1462             else
1463               return CPUTYPE_BARCELONA; //OS don't support AVX.
1464           }
1465           break;
1466         }
1467         break;
1468       case 8:
1469         switch (model) {
1470         case 1:
1471           // AMD Ryzen
1472         case 8:
1473           // AMD Ryzen2
1474           if(support_avx())
1475 #ifndef NO_AVX2
1476             return CPUTYPE_ZEN;
1477 #else
1478             return CPUTYPE_SANDYBRIDGE; // Zen is closer in architecture to Sandy Bridge than to Excavator
1479 #endif
1480           else
1481             return CPUTYPE_BARCELONA;
1482         }
1483       }
1484       break;
1485     }
1486     return CPUTYPE_AMD_UNKNOWN;
1487   }
1488
1489   if (vendor == VENDOR_HYGON){
1490     switch (family) {
1491     case 0xf:
1492       switch (exfamily) {
1493       case 9:
1494           //Hygon Dhyana
1495           if(support_avx())
1496 #ifndef NO_AVX2
1497             return CPUTYPE_ZEN;
1498 #else
1499             return CPUTYPE_SANDYBRIDGE; // closer in architecture to Sandy Bridge than to Excavator
1500 #endif
1501           else
1502             return CPUTYPE_BARCELONA;
1503         }
1504       break;
1505     }
1506     return CPUTYPE_HYGON_UNKNOWN;
1507   }
1508
1509   if (vendor == VENDOR_CYRIX){
1510     switch (family) {
1511     case 0x4:
1512       return CPUTYPE_CYRIX5X86;
1513     case 0x5:
1514       return CPUTYPE_CYRIXM1;
1515     case 0x6:
1516       return CPUTYPE_CYRIXM2;
1517     }
1518     return CPUTYPE_CYRIX_UNKNOWN;
1519   }
1520
1521   if (vendor == VENDOR_NEXGEN){
1522     switch (family) {
1523     case 0x5:
1524       return CPUTYPE_NEXGENNX586;
1525     }
1526     return CPUTYPE_NEXGEN_UNKNOWN;
1527   }
1528
1529   if (vendor == VENDOR_CENTAUR){
1530     switch (family) {
1531     case 0x5:
1532       return CPUTYPE_CENTAURC6;
1533       break;
1534     case 0x6:
1535       return CPUTYPE_NANO;
1536       break;
1537
1538     }
1539     return CPUTYPE_VIAC3;
1540   }
1541
1542   if (vendor == VENDOR_RISE){
1543     switch (family) {
1544     case 0x5:
1545       return CPUTYPE_RISEMP6;
1546     }
1547     return CPUTYPE_RISE_UNKNOWN;
1548   }
1549
1550   if (vendor == VENDOR_SIS){
1551     switch (family) {
1552     case 0x5:
1553       return CPUTYPE_SYS55X;
1554     }
1555     return CPUTYPE_SIS_UNKNOWN;
1556   }
1557
1558   if (vendor == VENDOR_TRANSMETA){
1559     switch (family) {
1560     case 0x5:
1561       return CPUTYPE_CRUSOETM3X;
1562     }
1563     return CPUTYPE_TRANSMETA_UNKNOWN;
1564   }
1565
1566   if (vendor == VENDOR_NSC){
1567     switch (family) {
1568     case 0x5:
1569       return CPUTYPE_NSGEODE;
1570     }
1571     return CPUTYPE_NSC_UNKNOWN;
1572   }
1573
1574   return CPUTYPE_UNKNOWN;
1575 }
1576
1577 static char *cpuname[] = {
1578   "UNKNOWN",
1579   "INTEL_UNKNOWN",
1580   "UMC_UNKNOWN",
1581   "AMD_UNKNOWN",
1582   "CYRIX_UNKNOWN",
1583   "NEXGEN_UNKNOWN",
1584   "CENTAUR_UNKNOWN",
1585   "RISE_UNKNOWN",
1586   "SIS_UNKNOWN",
1587   "TRANSMETA_UNKNOWN",
1588   "NSC_UNKNOWN",
1589   "80386",
1590   "80486",
1591   "PENTIUM",
1592   "PENTIUM2",
1593   "PENTIUM3",
1594   "PENTIUMM",
1595   "PENTIUM4",
1596   "CORE2",
1597   "PENRYN",
1598   "DUNNINGTON",
1599   "NEHALEM",
1600   "ATOM",
1601   "ITANIUM",
1602   "ITANIUM2",
1603   "5X86",
1604   "K6",
1605   "ATHLON",
1606   "DURON",
1607   "OPTERON",
1608   "BARCELONA",
1609   "SHANGHAI",
1610   "ISTANBUL",
1611   "CYRIX5X86",
1612   "CYRIXM1",
1613   "CYRIXM2",
1614   "NEXGENNX586",
1615   "CENTAURC6",
1616   "RISEMP6",
1617   "SYS55X",
1618   "TM3X00",
1619   "NSGEODE",
1620   "VIAC3",
1621   "NANO",
1622   "SANDYBRIDGE",
1623   "BOBCAT",
1624   "BULLDOZER",
1625   "PILEDRIVER",
1626   "HASWELL",
1627   "STEAMROLLER",
1628   "EXCAVATOR",
1629   "ZEN",
1630   "SKYLAKEX",
1631   "DHYANA"
1632 };
1633
1634 static char *lowercpuname[] = {
1635   "unknown",
1636   "intel_unknown",
1637   "umc_unknown",
1638   "amd_unknown",
1639   "cyrix_unknown",
1640   "nexgen_unknown",
1641   "centaur_unknown",
1642   "rise_unknown",
1643   "sis_unknown",
1644   "transmeta_unknown",
1645   "nsc_unknown",
1646   "80386",
1647   "80486",
1648   "pentium",
1649   "pentium2",
1650   "pentium3",
1651   "pentiumm",
1652   "pentium4",
1653   "core2",
1654   "penryn",
1655   "dunnington",
1656   "nehalem",
1657   "atom",
1658   "itanium",
1659   "itanium2",
1660   "5x86",
1661   "k6",
1662   "athlon",
1663   "duron",
1664   "opteron",
1665   "barcelona",
1666   "shanghai",
1667   "istanbul",
1668   "cyrix5x86",
1669   "cyrixm1",
1670   "cyrixm2",
1671   "nexgennx586",
1672   "centaurc6",
1673   "risemp6",
1674   "sys55x",
1675   "tms3x00",
1676   "nsgeode",
1677   "nano",
1678   "sandybridge",
1679   "bobcat",
1680   "bulldozer",
1681   "piledriver",
1682   "haswell",
1683   "steamroller",
1684   "excavator",
1685   "zen",
1686   "skylakex",
1687   "dhyana"
1688 };
1689
1690 static char *corename[] = {
1691   "UNKNOWN",
1692   "80486",
1693   "P5",
1694   "P6",
1695   "KATMAI",
1696   "COPPERMINE",
1697   "NORTHWOOD",
1698   "PRESCOTT",
1699   "BANIAS",
1700   "ATHLON",
1701   "OPTERON",
1702   "BARCELONA",
1703   "VIAC3",
1704   "YONAH",
1705   "CORE2",
1706   "PENRYN",
1707   "DUNNINGTON",
1708   "NEHALEM",
1709   "ATOM",
1710   "NANO",
1711   "SANDYBRIDGE",
1712   "BOBCAT",
1713   "BULLDOZER",
1714   "PILEDRIVER",
1715   "HASWELL",
1716   "STEAMROLLER",
1717   "EXCAVATOR",
1718   "ZEN",
1719   "SKYLAKEX",
1720   "DHYANA"
1721 };
1722
1723 static char *corename_lower[] = {
1724   "unknown",
1725   "80486",
1726   "p5",
1727   "p6",
1728   "katmai",
1729   "coppermine",
1730   "northwood",
1731   "prescott",
1732   "banias",
1733   "athlon",
1734   "opteron",
1735   "barcelona",
1736   "viac3",
1737   "yonah",
1738   "core2",
1739   "penryn",
1740   "dunnington",
1741   "nehalem",
1742   "atom",
1743   "nano",
1744   "sandybridge",
1745   "bobcat",
1746   "bulldozer",
1747   "piledriver",
1748   "haswell",
1749   "steamroller",
1750   "excavator",
1751   "zen",
1752   "skylakex",
1753   "dhyana"
1754 };
1755
1756
1757 char *get_cpunamechar(void){
1758   return cpuname[get_cpuname()];
1759 }
1760
1761 char *get_lower_cpunamechar(void){
1762   return lowercpuname[get_cpuname()];
1763 }
1764
1765
1766 int get_coretype(void){
1767
1768   int family, exfamily, model, exmodel, vendor;
1769
1770   if (!have_cpuid()) return CORE_80486;
1771
1772   family   = get_cputype(GET_FAMILY);
1773   exfamily = get_cputype(GET_EXFAMILY);
1774   model    = get_cputype(GET_MODEL);
1775   exmodel  = get_cputype(GET_EXMODEL);
1776
1777   vendor = get_vendor();
1778
1779   if (vendor == VENDOR_INTEL){
1780     switch (family) {
1781     case  4:
1782       return CORE_80486;
1783     case  5:
1784       return CORE_P5;
1785     case  6:
1786       switch (exmodel) {
1787       case  0:
1788         switch (model) {
1789         case  0:
1790         case  1:
1791         case  2:
1792         case  3:
1793         case  4:
1794         case  5:
1795         case  6:
1796           return CORE_P6;
1797         case  7:
1798           return CORE_KATMAI;
1799         case  8:
1800         case 10:
1801         case 11:
1802           return CORE_COPPERMINE;
1803         case  9:
1804         case 13:
1805         case 14:
1806           return CORE_BANIAS;
1807         case 15:
1808           return CORE_CORE2;
1809         }
1810         break;
1811       case  1:
1812         switch (model) {
1813         case  6:
1814           return CORE_CORE2;
1815         case  7:
1816           return CORE_PENRYN;
1817         case 10:
1818         case 11:
1819         case 14:
1820         case 15:
1821           return CORE_NEHALEM;
1822         case 12:
1823           return CORE_ATOM;
1824         case 13:
1825           return CORE_DUNNINGTON;
1826         }
1827         break;
1828       case  2:
1829         switch (model) {
1830         case 5:
1831           //Intel Core (Clarkdale) / Core (Arrandale)
1832           // Pentium (Clarkdale) / Pentium Mobile (Arrandale)
1833           // Xeon (Clarkdale), 32nm
1834           return CORE_NEHALEM;
1835         case 10:
1836           //Intel Core i5-2000 /i7-2000 (Sandy Bridge)
1837           if(support_avx())
1838             return CORE_SANDYBRIDGE;
1839           else
1840             return CORE_NEHALEM; //OS doesn't support AVX
1841         case 12:
1842           //Xeon Processor 5600 (Westmere-EP)
1843           return CORE_NEHALEM;
1844         case 13:
1845           //Intel Core i7-3000 / Xeon E5 (Sandy Bridge)
1846           if(support_avx())
1847             return CORE_SANDYBRIDGE;
1848           else
1849             return CORE_NEHALEM; //OS doesn't support AVX
1850         case 14:
1851           //Xeon E7540
1852         case 15:
1853           //Xeon Processor E7 (Westmere-EX)
1854           return CORE_NEHALEM;
1855         }
1856         break;
1857       case 3:
1858         switch (model) {
1859         case 7:
1860           return CORE_ATOM;             
1861         case 10:
1862         case 14:
1863           if(support_avx())
1864             return CORE_SANDYBRIDGE;
1865           else
1866             return CORE_NEHALEM; //OS doesn't support AVX
1867         case 12:
1868         case 15:
1869           if(support_avx())
1870 #ifndef NO_AVX2
1871             return CORE_HASWELL;
1872 #else
1873             return CORE_SANDYBRIDGE;
1874 #endif
1875           else
1876             return CORE_NEHALEM;
1877         case 13:
1878           //broadwell
1879           if(support_avx())
1880 #ifndef NO_AVX2
1881             return CORE_HASWELL;
1882 #else
1883             return CORE_SANDYBRIDGE;
1884 #endif
1885           else
1886             return CORE_NEHALEM;
1887         }
1888         break;
1889       case 4:
1890         switch (model) {
1891         case 5:
1892         case 6:
1893           if(support_avx())
1894 #ifndef NO_AVX2
1895             return CORE_HASWELL;
1896 #else
1897             return CORE_SANDYBRIDGE;
1898 #endif
1899           else
1900             return CORE_NEHALEM;
1901         case 7:
1902         case 15:
1903           //broadwell
1904           if(support_avx())
1905 #ifndef NO_AVX2
1906             return CORE_HASWELL;
1907 #else
1908             return CORE_SANDYBRIDGE;
1909 #endif
1910           else
1911             return CORE_NEHALEM;
1912         case 14:
1913           //Skylake
1914           if(support_avx())
1915 #ifndef NO_AVX2
1916             return CORE_HASWELL;
1917 #else
1918             return CORE_SANDYBRIDGE;
1919 #endif
1920           else
1921             return CORE_NEHALEM;
1922         case 12:
1923           // Braswell
1924         case 13:
1925           // Avoton
1926             return CORE_NEHALEM;
1927         }
1928         break;
1929       case 5:
1930         switch (model) {
1931         case 6:
1932           //broadwell
1933           if(support_avx())
1934 #ifndef NO_AVX2
1935             return CORE_HASWELL;
1936 #else
1937             return CORE_SANDYBRIDGE;
1938 #endif
1939           else
1940             return CORE_NEHALEM;
1941         case 5:
1942          // Skylake X
1943 #ifndef NO_AVX512
1944             return CORE_SKYLAKEX;
1945 #else
1946           if(support_avx())
1947 #ifndef NO_AVX2
1948             return CORE_HASWELL;
1949 #else
1950             return CORE_SANDYBRIDGE;
1951 #endif
1952           else
1953             return CORE_NEHALEM;
1954 #endif                  
1955         case 14:
1956           // Skylake
1957           if(support_avx())
1958 #ifndef NO_AVX2
1959             return CORE_HASWELL;
1960 #else
1961             return CORE_SANDYBRIDGE;
1962 #endif
1963           else
1964             return CORE_NEHALEM;
1965         case 7:
1966           // Phi Knights Landing
1967           if(support_avx())
1968 #ifndef NO_AVX2
1969             return CORE_HASWELL;
1970 #else
1971             return CORE_SANDYBRIDGE;
1972 #endif
1973           else
1974             return CORE_NEHALEM;
1975         case 12:
1976           // Apollo Lake
1977             return CORE_NEHALEM;
1978         }
1979         break;
1980       case 9:
1981       case 8:
1982         if (model == 14) { // Kaby Lake 
1983           if(support_avx())
1984 #ifndef NO_AVX2
1985             return CORE_HASWELL;
1986 #else
1987             return CORE_SANDYBRIDGE;
1988 #endif
1989           else
1990             return CORE_NEHALEM;
1991         }
1992       }
1993       break;
1994
1995       case 15:
1996         if (model <= 0x2) return CORE_NORTHWOOD;
1997         else return CORE_PRESCOTT;
1998     }
1999   }
2000
2001   if (vendor == VENDOR_AMD){
2002     if (family <= 0x5) return CORE_80486;
2003     if (family <= 0xe) return CORE_ATHLON;
2004     if (family == 0xf){
2005       if ((exfamily == 0) || (exfamily == 2)) return CORE_OPTERON;
2006       else if (exfamily == 5) return CORE_BOBCAT;
2007       else if (exfamily == 6) {
2008         switch (model) {
2009         case 1:
2010           //AMD Bulldozer Opteron 6200 / Opteron 4200 / AMD FX-Series
2011           if(support_avx())
2012             return CORE_BULLDOZER;
2013           else
2014             return CORE_BARCELONA; //OS don't support AVX.
2015         case 2: //AMD Piledriver
2016         case 3: //AMD Richland
2017           if(support_avx())
2018             return CORE_PILEDRIVER;
2019           else
2020             return CORE_BARCELONA; //OS don't support AVX.
2021     case 5: // New EXCAVATOR
2022           if(support_avx())
2023             return CORE_EXCAVATOR;
2024           else
2025             return CORE_BARCELONA; //OS don't support AVX.
2026         case 0:
2027         case 8:
2028           switch(exmodel){
2029           case 1: //AMD Trinity
2030             if(support_avx())
2031               return CORE_PILEDRIVER;
2032             else
2033               return CORE_BARCELONA; //OS don't support AVX.
2034
2035           case 3:
2036             if(support_avx())
2037               return CORE_STEAMROLLER;
2038             else
2039               return CORE_BARCELONA; //OS don't support AVX.
2040
2041           case 6:
2042             if(support_avx())
2043               return CORE_EXCAVATOR;
2044             else
2045               return CORE_BARCELONA; //OS don't support AVX.
2046           }
2047           break;
2048         }
2049       } else if (exfamily == 8) {
2050         switch (model) {
2051         case 1:
2052           // AMD Ryzen
2053         case 8:
2054           // Ryzen 2            
2055           if(support_avx())
2056 #ifndef NO_AVX2
2057             return CORE_ZEN;
2058 #else
2059             return CORE_SANDYBRIDGE; // Zen is closer in architecture to Sandy Bridge than to Excavator
2060 #endif
2061           else
2062             return CORE_BARCELONA;
2063         }
2064       } else {
2065         return CORE_BARCELONA;
2066       }
2067     }
2068   }
2069
2070   if (vendor == VENDOR_HYGON){
2071     if (family == 0xf){
2072         if (exfamily == 9) {
2073           if(support_avx())
2074 #ifndef NO_AVX2
2075             return CORE_ZEN;
2076 #else
2077             return CORE_SANDYBRIDGE; // closer in architecture to Sandy Bridge than to Excavator
2078 #endif
2079           else
2080             return CORE_BARCELONA;
2081         } else {
2082                 return CORE_BARCELONA;
2083         }
2084     }
2085   }
2086
2087   if (vendor == VENDOR_CENTAUR) {
2088     switch (family) {
2089     case 0x6:
2090       return CORE_NANO;
2091       break;
2092     }
2093     return CORE_VIAC3;
2094   }
2095
2096   return CORE_UNKNOWN;
2097 }
2098
2099 void get_cpuconfig(void){
2100
2101   cache_info_t info;
2102   int features;
2103
2104   printf("#define %s\n", cpuname[get_cpuname()]);
2105
2106
2107   if (get_coretype() != CORE_P5) {
2108
2109     get_cacheinfo(CACHE_INFO_L1_I, &info);
2110     if (info.size > 0) {
2111       printf("#define L1_CODE_SIZE %d\n", info.size * 1024);
2112       printf("#define L1_CODE_ASSOCIATIVE %d\n", info.associative);
2113       printf("#define L1_CODE_LINESIZE %d\n", info.linesize);
2114     }
2115
2116     get_cacheinfo(CACHE_INFO_L1_D, &info);
2117     if (info.size > 0) {
2118       printf("#define L1_DATA_SIZE %d\n", info.size * 1024);
2119       printf("#define L1_DATA_ASSOCIATIVE %d\n", info.associative);
2120       printf("#define L1_DATA_LINESIZE %d\n", info.linesize);
2121     }
2122
2123     get_cacheinfo(CACHE_INFO_L2, &info);
2124     if (info.size > 0) {
2125       printf("#define L2_SIZE %d\n", info.size * 1024);
2126       printf("#define L2_ASSOCIATIVE %d\n", info.associative);
2127       printf("#define L2_LINESIZE %d\n", info.linesize);
2128     } else {
2129       //fall back for some virtual machines.
2130       printf("#define L2_SIZE 1048576\n");
2131       printf("#define L2_ASSOCIATIVE 6\n");
2132       printf("#define L2_LINESIZE 64\n");
2133     }
2134
2135
2136     get_cacheinfo(CACHE_INFO_L3, &info);
2137     if (info.size > 0) {
2138       printf("#define L3_SIZE %d\n", info.size * 1024);
2139       printf("#define L3_ASSOCIATIVE %d\n", info.associative);
2140       printf("#define L3_LINESIZE %d\n", info.linesize);
2141     }
2142
2143     get_cacheinfo(CACHE_INFO_L1_ITB, &info);
2144     if (info.size > 0) {
2145       printf("#define ITB_SIZE %d\n", info.size * 1024);
2146       printf("#define ITB_ASSOCIATIVE %d\n", info.associative);
2147       printf("#define ITB_ENTRIES %d\n", info.linesize);
2148     }
2149
2150     get_cacheinfo(CACHE_INFO_L1_DTB, &info);
2151     if (info.size > 0) {
2152       printf("#define DTB_SIZE %d\n", info.size * 1024);
2153       printf("#define DTB_ASSOCIATIVE %d\n", info.associative);
2154       printf("#define DTB_DEFAULT_ENTRIES %d\n", info.linesize);
2155     } else {
2156       //fall back for some virtual machines.
2157       printf("#define DTB_DEFAULT_ENTRIES 32\n");
2158     }
2159
2160     features = get_cputype(GET_FEATURE);
2161
2162     if (features & HAVE_CMOV )   printf("#define HAVE_CMOV\n");
2163     if (features & HAVE_MMX  )   printf("#define HAVE_MMX\n");
2164     if (features & HAVE_SSE  )   printf("#define HAVE_SSE\n");
2165     if (features & HAVE_SSE2 )   printf("#define HAVE_SSE2\n");
2166     if (features & HAVE_SSE3 )   printf("#define HAVE_SSE3\n");
2167     if (features & HAVE_SSSE3)   printf("#define HAVE_SSSE3\n");
2168     if (features & HAVE_SSE4_1)   printf("#define HAVE_SSE4_1\n");
2169     if (features & HAVE_SSE4_2)   printf("#define HAVE_SSE4_2\n");
2170     if (features & HAVE_SSE4A)   printf("#define HAVE_SSE4A\n");
2171     if (features & HAVE_SSE5 )   printf("#define HAVE_SSSE5\n");
2172     if (features & HAVE_AVX )    printf("#define HAVE_AVX\n");
2173     if (features & HAVE_AVX2 )    printf("#define HAVE_AVX2\n");
2174     if (features & HAVE_AVX512VL )    printf("#define HAVE_AVX512VL\n");
2175     if (features & HAVE_3DNOWEX) printf("#define HAVE_3DNOWEX\n");
2176     if (features & HAVE_3DNOW)   printf("#define HAVE_3DNOW\n");
2177     if (features & HAVE_FMA4 )    printf("#define HAVE_FMA4\n");
2178     if (features & HAVE_FMA3 )    printf("#define HAVE_FMA3\n");
2179     if (features & HAVE_CFLUSH)  printf("#define HAVE_CFLUSH\n");
2180     if (features & HAVE_HIT)     printf("#define HAVE_HIT 1\n");
2181     if (features & HAVE_MISALIGNSSE) printf("#define HAVE_MISALIGNSSE\n");
2182     if (features & HAVE_128BITFPU)   printf("#define HAVE_128BITFPU\n");
2183     if (features & HAVE_FASTMOVU)    printf("#define HAVE_FASTMOVU\n");
2184
2185     printf("#define NUM_SHAREDCACHE %d\n", get_cputype(GET_NUMSHARE) + 1);
2186     printf("#define NUM_CORES %d\n", get_cputype(GET_NUMCORES) + 1);
2187
2188     features = get_coretype();
2189     if (features > 0) printf("#define CORE_%s\n", corename[features]);
2190   } else {
2191     printf("#define DTB_DEFAULT_ENTRIES 16\n");
2192     printf("#define L1_CODE_SIZE 8192\n");
2193     printf("#define L1_DATA_SIZE 8192\n");
2194     printf("#define L2_SIZE 0\n");
2195   }
2196 }
2197
2198 void get_architecture(void){
2199 #ifndef __64BIT__
2200     printf("X86");
2201 #else
2202     printf("X86_64");
2203 #endif
2204 }
2205
2206 void get_subarchitecture(void){
2207     printf("%s", get_cpunamechar());
2208 }
2209
2210 void get_subdirname(void){
2211 #ifndef __64BIT__
2212     printf("x86");
2213 #else
2214     printf("x86_64");
2215 #endif
2216 }
2217
2218 char *get_corename(void){
2219   return corename[get_coretype()];
2220 }
2221
2222 void get_libname(void){
2223   printf("%s",   corename_lower[get_coretype()]);
2224 }
2225
2226 /* This if for Makefile */
2227 void get_sse(void){
2228
2229   int features;
2230
2231   features = get_cputype(GET_FEATURE);
2232
2233   if (features & HAVE_MMX  )   printf("HAVE_MMX=1\n");
2234   if (features & HAVE_SSE  )   printf("HAVE_SSE=1\n");
2235   if (features & HAVE_SSE2 )   printf("HAVE_SSE2=1\n");
2236   if (features & HAVE_SSE3 )   printf("HAVE_SSE3=1\n");
2237   if (features & HAVE_SSSE3)   printf("HAVE_SSSE3=1\n");
2238   if (features & HAVE_SSE4_1)   printf("HAVE_SSE4_1=1\n");
2239   if (features & HAVE_SSE4_2)   printf("HAVE_SSE4_2=1\n");
2240   if (features & HAVE_SSE4A)   printf("HAVE_SSE4A=1\n");
2241   if (features & HAVE_SSE5 )   printf("HAVE_SSSE5=1\n");
2242   if (features & HAVE_AVX )    printf("HAVE_AVX=1\n");
2243   if (features & HAVE_AVX2 )    printf("HAVE_AVX2=1\n");
2244   if (features & HAVE_AVX512VL )    printf("HAVE_AVX512VL=1\n");
2245   if (features & HAVE_3DNOWEX) printf("HAVE_3DNOWEX=1\n");
2246   if (features & HAVE_3DNOW)   printf("HAVE_3DNOW=1\n");
2247   if (features & HAVE_FMA4 )    printf("HAVE_FMA4=1\n");
2248   if (features & HAVE_FMA3 )    printf("HAVE_FMA3=1\n");
2249
2250 }