Home | History | Annotate | Line # | Download | only in i386
      1 /* Get CPU type and Features for x86 processors.
      2    Copyright (C) 2012-2022 Free Software Foundation, Inc.
      3    Contributed by Sriraman Tallam (tmsriram (at) google.com)
      4 
      5 This file is part of GCC.
      6 
      7 GCC is free software; you can redistribute it and/or modify it under
      8 the terms of the GNU General Public License as published by the Free
      9 Software Foundation; either version 3, or (at your option) any later
     10 version.
     11 
     12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15 for more details.
     16 
     17 Under Section 7 of GPL version 3, you are granted additional
     18 permissions described in the GCC Runtime Library Exception, version
     19 3.1, as published by the Free Software Foundation.
     20 
     21 You should have received a copy of the GNU General Public License and
     22 a copy of the GCC Runtime Library Exception along with this program;
     23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 <http://www.gnu.org/licenses/>.  */
     25 
     26 struct __processor_model
     27 {
     28   unsigned int __cpu_vendor;
     29   unsigned int __cpu_type;
     30   unsigned int __cpu_subtype;
     31   /* The first 32 features are stored as bitmasks in __cpu_features.
     32      The rest of features are stored as bitmasks in a separate array
     33      of unsigned int.  */
     34   unsigned int __cpu_features[1];
     35 };
     36 
     37 struct __processor_model2
     38 {
     39   unsigned int __cpu_family;
     40   unsigned int __cpu_model;
     41   unsigned int __cpu_max_level;
     42   unsigned int __cpu_ext_level;
     43 };
     44 
     45 #ifndef CHECK___builtin_cpu_is
     46 # define CHECK___builtin_cpu_is(cpu)
     47 #endif
     48 
     49 #ifndef CHECK___builtin_cpu_supports
     50 # define CHECK___builtin_cpu_supports(isa)
     51 #endif
     52 
     53 /* Return non-zero if the processor has feature F.  */
     54 
     55 static inline int
     56 has_cpu_feature (struct __processor_model *cpu_model,
     57 		 unsigned int *cpu_features2,
     58 		 enum processor_features feature)
     59 {
     60   unsigned index, offset;
     61   unsigned f = feature;
     62 
     63   if (f < 32)
     64     {
     65       /* The first 32 features.  */
     66       return cpu_model->__cpu_features[0] & (1U << f);
     67     }
     68   else
     69     {
     70       /* The rest of features.  cpu_features2[i] contains features from
     71 	 (32 + i * 32) to (31 + 32 + i * 32), inclusively.  */
     72       f -= 32;
     73       index = f / 32;
     74       offset = f % 32;
     75       return cpu_features2[index] & (1U << offset);
     76     }
     77 }
     78 
     79 static inline void
     80 set_cpu_feature (struct __processor_model *cpu_model,
     81 		 unsigned int *cpu_features2,
     82 		 enum processor_features feature)
     83 {
     84   unsigned index, offset;
     85   unsigned f = feature;
     86 
     87   if (f < 32)
     88     {
     89       /* The first 32 features.  */
     90       cpu_model->__cpu_features[0] |= (1U << f);
     91     }
     92   else
     93     {
     94       /* The rest of features.  cpu_features2[i] contains features from
     95 	 (32 + i * 32) to (31 + 32 + i * 32), inclusively.  */
     96       f -= 32;
     97       index = f / 32;
     98       offset = f % 32;
     99       cpu_features2[index] |= (1U << offset);
    100     }
    101 }
    102 
    103 /* Get the specific type of AMD CPU and return AMD CPU name.  Return
    104    NULL for unknown AMD CPU.  */
    105 
    106 static inline const char *
    107 get_amd_cpu (struct __processor_model *cpu_model,
    108 	     struct __processor_model2 *cpu_model2,
    109 	     unsigned int *cpu_features2)
    110 {
    111   const char *cpu = NULL;
    112   unsigned int family = cpu_model2->__cpu_family;
    113   unsigned int model = cpu_model2->__cpu_model;
    114 
    115   switch (family)
    116     {
    117     case 0x10:
    118       /* AMD Family 10h.  */
    119       cpu = "amdfam10";
    120       cpu_model->__cpu_type = AMDFAM10H;
    121       switch (model)
    122 	{
    123 	case 0x2:
    124 	  /* Barcelona.  */
    125 	  CHECK___builtin_cpu_is ("amdfam10h");
    126 	  CHECK___builtin_cpu_is ("barcelona");
    127 	  cpu_model->__cpu_subtype = AMDFAM10H_BARCELONA;
    128 	  break;
    129 	case 0x4:
    130 	  /* Shanghai.  */
    131 	  CHECK___builtin_cpu_is ("amdfam10h");
    132 	  CHECK___builtin_cpu_is ("shanghai");
    133 	  cpu_model->__cpu_subtype = AMDFAM10H_SHANGHAI;
    134 	  break;
    135 	case 0x8:
    136 	  /* Istanbul.  */
    137 	  CHECK___builtin_cpu_is ("amdfam10h");
    138 	  CHECK___builtin_cpu_is ("istanbul");
    139 	  cpu_model->__cpu_subtype = AMDFAM10H_ISTANBUL;
    140 	  break;
    141 	default:
    142 	  break;
    143 	}
    144       break;
    145     case 0x14:
    146       /* AMD Family 14h "btver1". */
    147       cpu = "btver1";
    148       CHECK___builtin_cpu_is ("btver1");
    149       cpu_model->__cpu_type = AMD_BTVER1;
    150       break;
    151     case 0x15:
    152       /* AMD Family 15h "Bulldozer".  */
    153       cpu_model->__cpu_type = AMDFAM15H;
    154       if (model == 0x2)
    155 	{
    156 	  /* Bulldozer version 2 "Piledriver" */
    157 	  cpu = "bdver2";
    158 	  CHECK___builtin_cpu_is ("bdver2");
    159 	  cpu_model->__cpu_subtype = AMDFAM15H_BDVER2;
    160 	}
    161       else if (model <= 0xf)
    162 	{
    163 	  /* Bulldozer version 1.  */
    164 	  cpu = "bdver1";
    165 	  CHECK___builtin_cpu_is ("bdver1");
    166 	  cpu_model->__cpu_subtype = AMDFAM15H_BDVER1;
    167 	}
    168       else if (model <= 0x2f)
    169 	{
    170 	  /* Bulldozer version 2 "Piledriver" */
    171 	  cpu = "bdver2";
    172 	  CHECK___builtin_cpu_is ("bdver2");
    173 	  cpu_model->__cpu_subtype = AMDFAM15H_BDVER2;
    174 	}
    175       else if (model <= 0x4f)
    176 	{
    177 	  /* Bulldozer version 3 "Steamroller"  */
    178 	  cpu = "bdver3";
    179 	  CHECK___builtin_cpu_is ("bdver3");
    180 	  cpu_model->__cpu_subtype = AMDFAM15H_BDVER3;
    181 	}
    182       else if (model <= 0x7f)
    183 	{
    184 	  /* Bulldozer version 4 "Excavator"   */
    185 	  cpu = "bdver4";
    186 	  CHECK___builtin_cpu_is ("bdver4");
    187 	  cpu_model->__cpu_subtype = AMDFAM15H_BDVER4;
    188 	}
    189       else if (has_cpu_feature (cpu_model, cpu_features2,
    190 				FEATURE_AVX2))
    191 	{
    192 	  cpu = "bdver4";
    193 	  CHECK___builtin_cpu_is ("bdver4");
    194 	  cpu_model->__cpu_subtype = AMDFAM15H_BDVER4;
    195 	}
    196       else if (has_cpu_feature (cpu_model, cpu_features2,
    197 				FEATURE_XSAVEOPT))
    198 	{
    199 	  cpu = "bdver3";
    200 	  CHECK___builtin_cpu_is ("bdver3");
    201 	  cpu_model->__cpu_subtype = AMDFAM15H_BDVER3;
    202 	}
    203       else if (has_cpu_feature (cpu_model, cpu_features2,
    204 				FEATURE_BMI))
    205 	{
    206 	  cpu = "bdver2";
    207 	  CHECK___builtin_cpu_is ("bdver2");
    208 	  cpu_model->__cpu_subtype = AMDFAM15H_BDVER2;
    209 	}
    210       else if (has_cpu_feature (cpu_model, cpu_features2,
    211 				FEATURE_XOP))
    212 	{
    213 	  cpu = "bdver1";
    214 	  CHECK___builtin_cpu_is ("bdver1");
    215 	  cpu_model->__cpu_subtype = AMDFAM15H_BDVER1;
    216 	}
    217       break;
    218     case 0x16:
    219       /* AMD Family 16h "btver2" */
    220       cpu = "btver2";
    221       CHECK___builtin_cpu_is ("btver2");
    222       cpu_model->__cpu_type = AMD_BTVER2;
    223       break;
    224     case 0x17:
    225       cpu_model->__cpu_type = AMDFAM17H;
    226       if (model <= 0x1f)
    227 	{
    228 	  /* AMD family 17h version 1.  */
    229 	  cpu = "znver1";
    230 	  CHECK___builtin_cpu_is ("znver1");
    231 	  cpu_model->__cpu_subtype = AMDFAM17H_ZNVER1;
    232 	}
    233       else if (model >= 0x30)
    234 	{
    235 	  cpu = "znver2";
    236 	  CHECK___builtin_cpu_is ("znver2");
    237 	  cpu_model->__cpu_subtype = AMDFAM17H_ZNVER2;
    238 	}
    239       else if (has_cpu_feature (cpu_model, cpu_features2,
    240 				FEATURE_CLWB))
    241 	{
    242 	  cpu = "znver2";
    243 	  CHECK___builtin_cpu_is ("znver2");
    244 	  cpu_model->__cpu_subtype = AMDFAM17H_ZNVER2;
    245 	}
    246       else if (has_cpu_feature (cpu_model, cpu_features2,
    247 				FEATURE_CLZERO))
    248 	{
    249 	  cpu = "znver1";
    250 	  CHECK___builtin_cpu_is ("znver1");
    251 	  cpu_model->__cpu_subtype = AMDFAM17H_ZNVER1;
    252 	}
    253       break;
    254     case 0x19:
    255       cpu_model->__cpu_type = AMDFAM19H;
    256       /* AMD family 19h.  */
    257       if (model <= 0x0f)
    258 	{
    259 	  cpu = "znver3";
    260 	  CHECK___builtin_cpu_is ("znver3");
    261 	  cpu_model->__cpu_subtype = AMDFAM19H_ZNVER3;
    262 	}
    263       else if ((model >= 0x10 && model <= 0x1f)
    264 		|| (model >= 0x60 && model <= 0xaf))
    265 	{
    266 	  cpu = "znver4";
    267 	  CHECK___builtin_cpu_is ("znver4");
    268 	  cpu_model->__cpu_subtype = AMDFAM19H_ZNVER4;
    269 	}
    270       else if (has_cpu_feature (cpu_model, cpu_features2,
    271 				FEATURE_AVX512F))
    272 	{
    273 	  cpu = "znver4";
    274 	  CHECK___builtin_cpu_is ("znver4");
    275 	  cpu_model->__cpu_subtype = AMDFAM19H_ZNVER4;
    276 	}
    277       else if (has_cpu_feature (cpu_model, cpu_features2,
    278 				FEATURE_VAES))
    279 	{
    280 	  cpu = "znver3";
    281 	  CHECK___builtin_cpu_is ("znver3");
    282 	  cpu_model->__cpu_subtype = AMDFAM19H_ZNVER3;
    283 	}
    284       break;
    285     case 0x1a:
    286       cpu_model->__cpu_type = AMDFAM1AH;
    287       if (model <= 0x77)
    288 	{
    289 	  cpu = "znver5";
    290 	  CHECK___builtin_cpu_is ("znver5");
    291 	  cpu_model->__cpu_subtype = AMDFAM1AH_ZNVER5;
    292 	}
    293       else if (has_cpu_feature (cpu_model, cpu_features2,
    294 				FEATURE_AVX512VP2INTERSECT))
    295 	{
    296 	  cpu = "znver5";
    297 	  CHECK___builtin_cpu_is ("znver5");
    298 	  cpu_model->__cpu_subtype = AMDFAM1AH_ZNVER5;
    299 	}
    300       break;
    301     default:
    302       break;
    303     }
    304 
    305   return cpu;
    306 }
    307 
    308 /* Get the specific type of Intel CPU and return Intel CPU name.  Return
    309    NULL for unknown Intel CPU.  */
    310 
    311 static inline const char *
    312 get_intel_cpu (struct __processor_model *cpu_model,
    313 	       struct __processor_model2 *cpu_model2,
    314 	       unsigned int *cpu_features2)
    315 {
    316   const char *cpu = NULL;
    317 
    318   /* Parse family and model only for model 6. */
    319   if (cpu_model2->__cpu_family != 0x6)
    320     return cpu;
    321 
    322   switch (cpu_model2->__cpu_model)
    323     {
    324     case 0x1c:
    325     case 0x26:
    326       /* Bonnell.  */
    327       cpu = "bonnell";
    328       CHECK___builtin_cpu_is ("atom");
    329       cpu_model->__cpu_type = INTEL_BONNELL;
    330       break;
    331     case 0x37:
    332     case 0x4a:
    333     case 0x4d:
    334     case 0x5d:
    335       /* Silvermont.  */
    336     case 0x4c:
    337     case 0x5a:
    338     case 0x75:
    339       /* Airmont.  */
    340       cpu = "silvermont";
    341       CHECK___builtin_cpu_is ("silvermont");
    342       cpu_model->__cpu_type = INTEL_SILVERMONT;
    343       break;
    344     case 0x5c:
    345     case 0x5f:
    346       /* Goldmont.  */
    347       cpu = "goldmont";
    348       CHECK___builtin_cpu_is ("goldmont");
    349       cpu_model->__cpu_type = INTEL_GOLDMONT;
    350       break;
    351     case 0x7a:
    352       /* Goldmont Plus.  */
    353       cpu = "goldmont-plus";
    354       CHECK___builtin_cpu_is ("goldmont-plus");
    355       cpu_model->__cpu_type = INTEL_GOLDMONT_PLUS;
    356       break;
    357     case 0x86:
    358     case 0x96:
    359     case 0x9c:
    360       /* Tremont.  */
    361       cpu = "tremont";
    362       CHECK___builtin_cpu_is ("tremont");
    363       cpu_model->__cpu_type = INTEL_TREMONT;
    364       break;
    365     case 0x57:
    366       /* Knights Landing.  */
    367       cpu = "knl";
    368       CHECK___builtin_cpu_is ("knl");
    369       cpu_model->__cpu_type = INTEL_KNL;
    370       break;
    371     case 0x85:
    372       /* Knights Mill. */
    373       cpu = "knm";
    374       CHECK___builtin_cpu_is ("knm");
    375       cpu_model->__cpu_type = INTEL_KNM;
    376       break;
    377     case 0x1a:
    378     case 0x1e:
    379     case 0x1f:
    380     case 0x2e:
    381       /* Nehalem.  */
    382       cpu = "nehalem";
    383       CHECK___builtin_cpu_is ("corei7");
    384       CHECK___builtin_cpu_is ("nehalem");
    385       cpu_model->__cpu_type = INTEL_COREI7;
    386       cpu_model->__cpu_subtype = INTEL_COREI7_NEHALEM;
    387       break;
    388     case 0x25:
    389     case 0x2c:
    390     case 0x2f:
    391       /* Westmere.  */
    392       cpu = "westmere";
    393       CHECK___builtin_cpu_is ("corei7");
    394       CHECK___builtin_cpu_is ("westmere");
    395       cpu_model->__cpu_type = INTEL_COREI7;
    396       cpu_model->__cpu_subtype = INTEL_COREI7_WESTMERE;
    397       break;
    398     case 0x2a:
    399     case 0x2d:
    400       /* Sandy Bridge.  */
    401       cpu = "sandybridge";
    402       CHECK___builtin_cpu_is ("corei7");
    403       CHECK___builtin_cpu_is ("sandybridge");
    404       cpu_model->__cpu_type = INTEL_COREI7;
    405       cpu_model->__cpu_subtype = INTEL_COREI7_SANDYBRIDGE;
    406       break;
    407     case 0x3a:
    408     case 0x3e:
    409       /* Ivy Bridge.  */
    410       cpu = "ivybridge";
    411       CHECK___builtin_cpu_is ("corei7");
    412       CHECK___builtin_cpu_is ("ivybridge");
    413       cpu_model->__cpu_type = INTEL_COREI7;
    414       cpu_model->__cpu_subtype = INTEL_COREI7_IVYBRIDGE;
    415       break;
    416     case 0x3c:
    417     case 0x3f:
    418     case 0x45:
    419     case 0x46:
    420       /* Haswell.  */
    421       cpu = "haswell";
    422       CHECK___builtin_cpu_is ("corei7");
    423       CHECK___builtin_cpu_is ("haswell");
    424       cpu_model->__cpu_type = INTEL_COREI7;
    425       cpu_model->__cpu_subtype = INTEL_COREI7_HASWELL;
    426       break;
    427     case 0x3d:
    428     case 0x47:
    429     case 0x4f:
    430     case 0x56:
    431       /* Broadwell.  */
    432       cpu = "broadwell";
    433       CHECK___builtin_cpu_is ("corei7");
    434       CHECK___builtin_cpu_is ("broadwell");
    435       cpu_model->__cpu_type = INTEL_COREI7;
    436       cpu_model->__cpu_subtype = INTEL_COREI7_BROADWELL;
    437       break;
    438     case 0x4e:
    439     case 0x5e:
    440       /* Skylake.  */
    441     case 0x8e:
    442     case 0x9e:
    443       /* Kaby Lake.  */
    444     case 0xa5:
    445     case 0xa6:
    446       /* Comet Lake.  */
    447       cpu = "skylake";
    448       CHECK___builtin_cpu_is ("corei7");
    449       CHECK___builtin_cpu_is ("skylake");
    450       cpu_model->__cpu_type = INTEL_COREI7;
    451       cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE;
    452       break;
    453     case 0xa7:
    454       /* Rocket Lake.  */
    455       cpu = "rocketlake";
    456       CHECK___builtin_cpu_is ("corei7");
    457       CHECK___builtin_cpu_is ("rocketlake");
    458       cpu_model->__cpu_type = INTEL_COREI7;
    459       cpu_model->__cpu_subtype = INTEL_COREI7_ROCKETLAKE;
    460       break;
    461     case 0x55:
    462       CHECK___builtin_cpu_is ("corei7");
    463       cpu_model->__cpu_type = INTEL_COREI7;
    464       if (has_cpu_feature (cpu_model, cpu_features2,
    465 			   FEATURE_AVX512BF16))
    466 	{
    467 	  /* Cooper Lake.  */
    468 	  cpu = "cooperlake";
    469 	  CHECK___builtin_cpu_is ("cooperlake");
    470 	  cpu_model->__cpu_subtype = INTEL_COREI7_COOPERLAKE;
    471 	}
    472       else if (has_cpu_feature (cpu_model, cpu_features2,
    473 				FEATURE_AVX512VNNI))
    474 	{
    475 	  /* Cascade Lake.  */
    476 	  cpu = "cascadelake";
    477 	  CHECK___builtin_cpu_is ("cascadelake");
    478 	  cpu_model->__cpu_subtype = INTEL_COREI7_CASCADELAKE;
    479 	}
    480       else
    481 	{
    482 	  /* Skylake with AVX-512 support.  */
    483 	  cpu = "skylake-avx512";
    484 	  CHECK___builtin_cpu_is ("skylake-avx512");
    485 	  cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512;
    486 	}
    487       break;
    488     case 0x66:
    489       /* Cannon Lake.  */
    490       cpu = "cannonlake";
    491       CHECK___builtin_cpu_is ("corei7");
    492       CHECK___builtin_cpu_is ("cannonlake");
    493       cpu_model->__cpu_type = INTEL_COREI7;
    494       cpu_model->__cpu_subtype = INTEL_COREI7_CANNONLAKE;
    495       break;
    496     case 0x6a:
    497     case 0x6c:
    498       /* Ice Lake server.  */
    499       cpu = "icelake-server";
    500       CHECK___builtin_cpu_is ("corei7");
    501       CHECK___builtin_cpu_is ("icelake-server");
    502       cpu_model->__cpu_type = INTEL_COREI7;
    503       cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_SERVER;
    504       break;
    505     case 0x7e:
    506     case 0x7d:
    507     case 0x9d:
    508        /* Ice Lake client.  */
    509       cpu = "icelake-client";
    510       CHECK___builtin_cpu_is ("corei7");
    511       CHECK___builtin_cpu_is ("icelake-client");
    512       cpu_model->__cpu_type = INTEL_COREI7;
    513       cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_CLIENT;
    514       break;
    515     case 0x8c:
    516     case 0x8d:
    517       /* Tiger Lake.  */
    518       cpu = "tigerlake";
    519       CHECK___builtin_cpu_is ("corei7");
    520       CHECK___builtin_cpu_is ("tigerlake");
    521       cpu_model->__cpu_type = INTEL_COREI7;
    522       cpu_model->__cpu_subtype = INTEL_COREI7_TIGERLAKE;
    523       break;
    524     case 0x97:
    525     case 0x9a:
    526       /* Alder Lake.  */
    527       cpu = "alderlake";
    528       CHECK___builtin_cpu_is ("corei7");
    529       CHECK___builtin_cpu_is ("alderlake");
    530       cpu_model->__cpu_type = INTEL_COREI7;
    531       cpu_model->__cpu_subtype = INTEL_COREI7_ALDERLAKE;
    532       break;
    533     case 0x8f:
    534       /* Sapphire Rapids.  */
    535       cpu = "sapphirerapids";
    536       CHECK___builtin_cpu_is ("corei7");
    537       CHECK___builtin_cpu_is ("sapphirerapids");
    538       cpu_model->__cpu_type = INTEL_COREI7;
    539       cpu_model->__cpu_subtype = INTEL_COREI7_SAPPHIRERAPIDS;
    540       break;
    541     case 0x17:
    542     case 0x1d:
    543       /* Penryn.  */
    544     case 0x0f:
    545       /* Merom.  */
    546       cpu = "core2";
    547       CHECK___builtin_cpu_is ("core2");
    548       cpu_model->__cpu_type = INTEL_CORE2;
    549       break;
    550     default:
    551       break;
    552     }
    553 
    554   return cpu;
    555 }
    556 
    557 /* ECX and EDX are output of CPUID at level one.  */
    558 static inline void
    559 get_available_features (struct __processor_model *cpu_model,
    560 			struct __processor_model2 *cpu_model2,
    561 			unsigned int *cpu_features2,
    562 			unsigned int ecx, unsigned int edx)
    563 {
    564   unsigned int max_cpuid_level = cpu_model2->__cpu_max_level;
    565   unsigned int eax, ebx;
    566   unsigned int ext_level;
    567 
    568   /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv.  */
    569 #define XCR_XFEATURE_ENABLED_MASK	0x0
    570 #define XSTATE_FP			0x1
    571 #define XSTATE_SSE			0x2
    572 #define XSTATE_YMM			0x4
    573 #define XSTATE_OPMASK			0x20
    574 #define XSTATE_ZMM			0x40
    575 #define XSTATE_HI_ZMM			0x80
    576 #define XSTATE_TILECFG			0x20000
    577 #define XSTATE_TILEDATA		0x40000
    578 
    579 #define XCR_AVX_ENABLED_MASK \
    580   (XSTATE_SSE | XSTATE_YMM)
    581 #define XCR_AVX512F_ENABLED_MASK \
    582   (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
    583 #define XCR_AMX_ENABLED_MASK \
    584   (XSTATE_TILECFG | XSTATE_TILEDATA)
    585 
    586   /* Check if AVX and AVX512 are usable.  */
    587   int avx_usable = 0;
    588   int avx512_usable = 0;
    589   int amx_usable = 0;
    590   /* Check if KL is usable.  */
    591   int has_kl = 0;
    592   if ((ecx & bit_OSXSAVE))
    593     {
    594       /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
    595 	 ZMM16-ZMM31 states are supported by OSXSAVE.  */
    596       unsigned int xcrlow;
    597       unsigned int xcrhigh;
    598       __asm__ (".byte 0x0f, 0x01, 0xd0"
    599 	       : "=a" (xcrlow), "=d" (xcrhigh)
    600 	       : "c" (XCR_XFEATURE_ENABLED_MASK));
    601       if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
    602 	{
    603 	  avx_usable = 1;
    604 	  avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
    605 			   == XCR_AVX512F_ENABLED_MASK);
    606 	}
    607       amx_usable = ((xcrlow & XCR_AMX_ENABLED_MASK)
    608 		    == XCR_AMX_ENABLED_MASK);
    609     }
    610 
    611 #define set_feature(f) \
    612   set_cpu_feature (cpu_model, cpu_features2, f)
    613 
    614   if (edx & bit_CMOV)
    615     set_feature (FEATURE_CMOV);
    616   if (edx & bit_MMX)
    617     set_feature (FEATURE_MMX);
    618   if (edx & bit_SSE)
    619     set_feature (FEATURE_SSE);
    620   if (edx & bit_SSE2)
    621     set_feature (FEATURE_SSE2);
    622   if (edx & bit_CMPXCHG8B)
    623     set_feature (FEATURE_CMPXCHG8B);
    624   if (edx & bit_FXSAVE)
    625     set_feature (FEATURE_FXSAVE);
    626 
    627   if (ecx & bit_POPCNT)
    628     set_feature (FEATURE_POPCNT);
    629   if (ecx & bit_AES)
    630     set_feature (FEATURE_AES);
    631   if (ecx & bit_PCLMUL)
    632     set_feature (FEATURE_PCLMUL);
    633   if (ecx & bit_SSE3)
    634     set_feature (FEATURE_SSE3);
    635   if (ecx & bit_SSSE3)
    636     set_feature (FEATURE_SSSE3);
    637   if (ecx & bit_SSE4_1)
    638     set_feature (FEATURE_SSE4_1);
    639   if (ecx & bit_SSE4_2)
    640     set_feature (FEATURE_SSE4_2);
    641   if (ecx & bit_OSXSAVE)
    642     set_feature (FEATURE_OSXSAVE);
    643   if (ecx & bit_CMPXCHG16B)
    644     set_feature (FEATURE_CMPXCHG16B);
    645   if (ecx & bit_MOVBE)
    646     set_feature (FEATURE_MOVBE);
    647   if (ecx & bit_AES)
    648     set_feature (FEATURE_AES);
    649   if (ecx & bit_RDRND)
    650     set_feature (FEATURE_RDRND);
    651   if (ecx & bit_XSAVE)
    652     set_feature (FEATURE_XSAVE);
    653   if (avx_usable)
    654     {
    655       if (ecx & bit_AVX)
    656 	set_feature (FEATURE_AVX);
    657       if (ecx & bit_FMA)
    658 	set_feature (FEATURE_FMA);
    659       if (ecx & bit_F16C)
    660 	set_feature (FEATURE_F16C);
    661     }
    662 
    663   /* Get Advanced Features at level 7 (eax = 7, ecx = 0/1). */
    664   if (max_cpuid_level >= 7)
    665     {
    666       unsigned int max_subleaf_level;
    667 
    668       __cpuid_count (7, 0, max_subleaf_level, ebx, ecx, edx);
    669       if (ebx & bit_BMI)
    670 	set_feature (FEATURE_BMI);
    671       if (ebx & bit_SGX)
    672 	set_feature (FEATURE_SGX);
    673       if (ebx & bit_HLE)
    674 	set_feature (FEATURE_HLE);
    675       if (ebx & bit_RTM)
    676 	set_feature (FEATURE_RTM);
    677       if (avx_usable)
    678 	{
    679 	  if (ebx & bit_AVX2)
    680 	    set_feature (FEATURE_AVX2);
    681 	  if (ecx & bit_VPCLMULQDQ)
    682 	    set_feature (FEATURE_VPCLMULQDQ);
    683 	  if (ecx & bit_VAES)
    684 	    set_feature (FEATURE_VAES);
    685 	}
    686       if (ebx & bit_BMI2)
    687 	set_feature (FEATURE_BMI2);
    688       if (ebx & bit_FSGSBASE)
    689 	set_feature (FEATURE_FSGSBASE);
    690       if (ebx & bit_RDSEED)
    691 	set_feature (FEATURE_RDSEED);
    692       if (ebx & bit_ADX)
    693 	set_feature (FEATURE_ADX);
    694       if (ebx & bit_SHA)
    695 	set_feature (FEATURE_SHA);
    696       if (ebx & bit_CLFLUSHOPT)
    697 	set_feature (FEATURE_CLFLUSHOPT);
    698       if (ebx & bit_CLWB)
    699 	set_feature (FEATURE_CLWB);
    700       if (ecx & bit_PREFETCHWT1)
    701 	set_feature (FEATURE_PREFETCHWT1);
    702       /* NB: bit_OSPKE indicates that OS supports PKU.  */
    703       if (ecx & bit_OSPKE)
    704 	set_feature (FEATURE_PKU);
    705       if (ecx & bit_RDPID)
    706 	set_feature (FEATURE_RDPID);
    707       if (ecx & bit_GFNI)
    708 	set_feature (FEATURE_GFNI);
    709       if (ecx & bit_MOVDIRI)
    710 	set_feature (FEATURE_MOVDIRI);
    711       if (ecx & bit_MOVDIR64B)
    712 	set_feature (FEATURE_MOVDIR64B);
    713       if (ecx & bit_ENQCMD)
    714 	set_feature (FEATURE_ENQCMD);
    715       if (ecx & bit_CLDEMOTE)
    716 	set_feature (FEATURE_CLDEMOTE);
    717       if (ecx & bit_WAITPKG)
    718 	set_feature (FEATURE_WAITPKG);
    719       if (ecx & bit_SHSTK)
    720 	set_feature (FEATURE_SHSTK);
    721       if (ecx & bit_KL)
    722 	has_kl = 1;
    723       if (edx & bit_SERIALIZE)
    724 	set_feature (FEATURE_SERIALIZE);
    725       if (edx & bit_TSXLDTRK)
    726 	set_feature (FEATURE_TSXLDTRK);
    727       if (edx & bit_PCONFIG)
    728 	set_feature (FEATURE_PCONFIG);
    729       if (edx & bit_IBT)
    730 	set_feature (FEATURE_IBT);
    731       if (edx & bit_UINTR)
    732 	set_feature (FEATURE_UINTR);
    733       if (amx_usable)
    734 	{
    735 	  if (edx & bit_AMX_TILE)
    736 	    set_feature (FEATURE_AMX_TILE);
    737 	  if (edx & bit_AMX_INT8)
    738 	    set_feature (FEATURE_AMX_INT8);
    739 	  if (edx & bit_AMX_BF16)
    740 	    set_feature (FEATURE_AMX_BF16);
    741 	}
    742       if (avx512_usable)
    743 	{
    744 	  if (ebx & bit_AVX512F)
    745 	    set_feature (FEATURE_AVX512F);
    746 	  if (ebx & bit_AVX512VL)
    747 	    set_feature (FEATURE_AVX512VL);
    748 	  if (ebx & bit_AVX512BW)
    749 	    set_feature (FEATURE_AVX512BW);
    750 	  if (ebx & bit_AVX512DQ)
    751 	    set_feature (FEATURE_AVX512DQ);
    752 	  if (ebx & bit_AVX512CD)
    753 	    set_feature (FEATURE_AVX512CD);
    754 	  if (ebx & bit_AVX512PF)
    755 	    set_feature (FEATURE_AVX512PF);
    756 	  if (ebx & bit_AVX512ER)
    757 	    set_feature (FEATURE_AVX512ER);
    758 	  if (ebx & bit_AVX512IFMA)
    759 	    set_feature (FEATURE_AVX512IFMA);
    760 	  if (ecx & bit_AVX512VBMI)
    761 	    set_feature (FEATURE_AVX512VBMI);
    762 	  if (ecx & bit_AVX512VBMI2)
    763 	    set_feature (FEATURE_AVX512VBMI2);
    764 	  if (ecx & bit_AVX512VNNI)
    765 	    set_feature (FEATURE_AVX512VNNI);
    766 	  if (ecx & bit_AVX512BITALG)
    767 	    set_feature (FEATURE_AVX512BITALG);
    768 	  if (ecx & bit_AVX512VPOPCNTDQ)
    769 	    set_feature (FEATURE_AVX512VPOPCNTDQ);
    770 	  if (edx & bit_AVX5124VNNIW)
    771 	    set_feature (FEATURE_AVX5124VNNIW);
    772 	  if (edx & bit_AVX5124FMAPS)
    773 	    set_feature (FEATURE_AVX5124FMAPS);
    774 	  if (edx & bit_AVX512VP2INTERSECT)
    775 	    set_feature (FEATURE_AVX512VP2INTERSECT);
    776 	  if (edx & bit_AVX512FP16)
    777 	    set_feature (FEATURE_AVX512FP16);
    778 	}
    779 
    780       if (max_subleaf_level >= 1)
    781 	{
    782 	  __cpuid_count (7, 1, eax, ebx, ecx, edx);
    783 	  if (eax & bit_HRESET)
    784 	    set_feature (FEATURE_HRESET);
    785 	  if (avx_usable)
    786 	    {
    787 	      if (eax & bit_AVXVNNI)
    788 		set_feature (FEATURE_AVXVNNI);
    789 	    }
    790 	  if (avx512_usable)
    791 	    {
    792 	      if (eax & bit_AVX512BF16)
    793 		set_feature (FEATURE_AVX512BF16);
    794 	    }
    795 	}
    796     }
    797 
    798   /* Get Advanced Features at level 0xd (eax = 0xd, ecx = 1). */
    799   if (max_cpuid_level >= 0xd)
    800     {
    801       __cpuid_count (0xd, 1, eax, ebx, ecx, edx);
    802       if (eax & bit_XSAVEOPT)
    803 	set_feature (FEATURE_XSAVEOPT);
    804       if (eax & bit_XSAVEC)
    805 	set_feature (FEATURE_XSAVEC);
    806       if (eax & bit_XSAVES)
    807 	set_feature (FEATURE_XSAVES);
    808     }
    809 
    810   /* Get Advanced Features at level 0x14 (eax = 0x14, ecx = 0). */
    811   if (max_cpuid_level >= 0x14)
    812     {
    813       __cpuid_count (0x14, 0, eax, ebx, ecx, edx);
    814       if (ebx & bit_PTWRITE)
    815 	set_feature (FEATURE_PTWRITE);
    816     }
    817 
    818   /* Get Advanced Features at level 0x19 (eax = 0x19).  */
    819   if (max_cpuid_level >= 0x19)
    820     {
    821       __cpuid (0x19, eax, ebx, ecx, edx);
    822       /* Check if OS support keylocker.  */
    823       if (ebx & bit_AESKLE)
    824 	{
    825 	  set_feature (FEATURE_AESKLE);
    826 	  if (ebx & bit_WIDEKL)
    827 	    set_feature (FEATURE_WIDEKL);
    828 	  if (has_kl)
    829 	    set_feature (FEATURE_KL);
    830 	}
    831     }
    832 
    833   /* Check cpuid level of extended features.  */
    834   __cpuid (0x80000000, ext_level, ebx, ecx, edx);
    835 
    836   cpu_model2->__cpu_ext_level = ext_level;
    837 
    838   if (ext_level >= 0x80000001)
    839     {
    840       __cpuid (0x80000001, eax, ebx, ecx, edx);
    841 
    842       if (ecx & bit_SSE4a)
    843 	set_feature (FEATURE_SSE4_A);
    844       if (ecx & bit_LAHF_LM)
    845 	set_feature (FEATURE_LAHF_LM);
    846       if (ecx & bit_ABM)
    847 	set_feature (FEATURE_ABM);
    848       if (ecx & bit_LWP)
    849 	set_feature (FEATURE_LWP);
    850       if (ecx & bit_TBM)
    851 	set_feature (FEATURE_TBM);
    852       if (ecx & bit_LZCNT)
    853 	set_feature (FEATURE_LZCNT);
    854       if (ecx & bit_PRFCHW)
    855 	set_feature (FEATURE_PRFCHW);
    856       if (ecx & bit_MWAITX)
    857 	set_feature (FEATURE_MWAITX);
    858 
    859       if (edx & bit_LM)
    860 	set_feature (FEATURE_LM);
    861       if (edx & bit_3DNOWP)
    862 	set_feature (FEATURE_3DNOWP);
    863       if (edx & bit_3DNOW)
    864 	set_feature (FEATURE_3DNOW);
    865 
    866       if (avx_usable)
    867 	{
    868 	  if (ecx & bit_FMA4)
    869 	    set_feature (FEATURE_FMA4);
    870 	  if (ecx & bit_XOP)
    871 	    set_feature (FEATURE_XOP);
    872 	}
    873     }
    874 
    875   if (ext_level >= 0x80000008)
    876     {
    877       __cpuid (0x80000008, eax, ebx, ecx, edx);
    878       if (ebx & bit_CLZERO)
    879 	set_feature (FEATURE_CLZERO);
    880       if (ebx & bit_WBNOINVD)
    881 	set_feature (FEATURE_WBNOINVD);
    882     }
    883 
    884 #undef set_feature
    885 }
    886 
    887 static inline int
    888 cpu_indicator_init (struct __processor_model *cpu_model,
    889 		    struct __processor_model2 *cpu_model2,
    890 		    unsigned int *cpu_features2)
    891 {
    892   unsigned int eax, ebx, ecx, edx;
    893 
    894   int max_level;
    895   unsigned int vendor;
    896   unsigned int model, family;
    897   unsigned int extended_model, extended_family;
    898 
    899   /* This function needs to run just once.  */
    900   if (cpu_model->__cpu_vendor)
    901     return 0;
    902 
    903   /* Assume cpuid insn present. Run in level 0 to get vendor id. */
    904   if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx))
    905     {
    906       cpu_model->__cpu_vendor = VENDOR_OTHER;
    907       return -1;
    908     }
    909 
    910   vendor = ebx;
    911   max_level = eax;
    912 
    913   if (max_level < 1)
    914     {
    915       cpu_model->__cpu_vendor = VENDOR_OTHER;
    916       return -1;
    917     }
    918 
    919   if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
    920     {
    921       cpu_model->__cpu_vendor = VENDOR_OTHER;
    922       return -1;
    923     }
    924 
    925   cpu_model2->__cpu_max_level = max_level;
    926 
    927   model = (eax >> 4) & 0x0f;
    928   family = (eax >> 8) & 0x0f;
    929   extended_model = (eax >> 12) & 0xf0;
    930   extended_family = (eax >> 20) & 0xff;
    931 
    932   /* Find available features. */
    933   get_available_features (cpu_model, cpu_model2, cpu_features2,
    934 			  ecx, edx);
    935 
    936   if (vendor == signature_INTEL_ebx)
    937     {
    938       /* Adjust model and family for Intel CPUS. */
    939       if (family == 0x0f)
    940 	{
    941 	  family += extended_family;
    942 	  model += extended_model;
    943 	}
    944       else if (family == 0x06)
    945 	model += extended_model;
    946 
    947       cpu_model2->__cpu_family = family;
    948       cpu_model2->__cpu_model = model;
    949 
    950       /* Get CPU type.  */
    951       get_intel_cpu (cpu_model, cpu_model2, cpu_features2);
    952       cpu_model->__cpu_vendor = VENDOR_INTEL;
    953     }
    954   else if (vendor == signature_AMD_ebx)
    955     {
    956       /* Adjust model and family for AMD CPUS. */
    957       if (family == 0x0f)
    958 	{
    959 	  family += extended_family;
    960 	  model += extended_model;
    961 	}
    962 
    963       cpu_model2->__cpu_family = family;
    964       cpu_model2->__cpu_model = model;
    965 
    966       /* Get CPU type.  */
    967       get_amd_cpu (cpu_model, cpu_model2, cpu_features2);
    968       cpu_model->__cpu_vendor = VENDOR_AMD;
    969     }
    970   else if (vendor == signature_CENTAUR_ebx)
    971     cpu_model->__cpu_vendor = VENDOR_CENTAUR;
    972   else if (vendor == signature_CYRIX_ebx)
    973     cpu_model->__cpu_vendor = VENDOR_CYRIX;
    974   else if (vendor == signature_NSC_ebx)
    975     cpu_model->__cpu_vendor = VENDOR_NSC;
    976   else
    977     cpu_model->__cpu_vendor = VENDOR_OTHER;
    978 
    979   if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_LM)
    980       && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE2))
    981     {
    982       CHECK___builtin_cpu_supports ("x86-64");
    983       set_cpu_feature (cpu_model, cpu_features2,
    984 		       FEATURE_X86_64_BASELINE);
    985       if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_CMPXCHG16B)
    986 	  && has_cpu_feature (cpu_model, cpu_features2, FEATURE_POPCNT)
    987 	  && has_cpu_feature (cpu_model, cpu_features2, FEATURE_LAHF_LM)
    988 	  && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE4_2))
    989 	{
    990 	  CHECK___builtin_cpu_supports ("x86-64-v2");
    991 	  set_cpu_feature (cpu_model, cpu_features2,
    992 			   FEATURE_X86_64_V2);
    993 	  if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_AVX2)
    994 	      && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI)
    995 	      && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI2)
    996 	      && has_cpu_feature (cpu_model, cpu_features2, FEATURE_F16C)
    997 	      && has_cpu_feature (cpu_model, cpu_features2, FEATURE_FMA)
    998 	      && has_cpu_feature (cpu_model, cpu_features2,
    999 				  FEATURE_LZCNT)
   1000 	      && has_cpu_feature (cpu_model, cpu_features2,
   1001 				  FEATURE_MOVBE))
   1002 	    {
   1003 	      CHECK___builtin_cpu_supports ("x86-64-v3");
   1004 	      set_cpu_feature (cpu_model, cpu_features2,
   1005 			       FEATURE_X86_64_V3);
   1006 	      if (has_cpu_feature (cpu_model, cpu_features2,
   1007 				   FEATURE_AVX512BW)
   1008 		  && has_cpu_feature (cpu_model, cpu_features2,
   1009 				      FEATURE_AVX512CD)
   1010 		  && has_cpu_feature (cpu_model, cpu_features2,
   1011 				      FEATURE_AVX512DQ)
   1012 		  && has_cpu_feature (cpu_model, cpu_features2,
   1013 				      FEATURE_AVX512VL))
   1014 		{
   1015 		  CHECK___builtin_cpu_supports ("x86-64-v4");
   1016 		  set_cpu_feature (cpu_model, cpu_features2,
   1017 				   FEATURE_X86_64_V4);
   1018 		}
   1019 	    }
   1020 	}
   1021     }
   1022 
   1023   gcc_assert (cpu_model->__cpu_vendor < VENDOR_MAX);
   1024   gcc_assert (cpu_model->__cpu_type < CPU_TYPE_MAX);
   1025   gcc_assert (cpu_model->__cpu_subtype < CPU_SUBTYPE_MAX);
   1026 
   1027   return 0;
   1028 }
   1029