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