LCOV - code coverage report
Current view: top level - gcc/common/config/i386 - cpuinfo.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 28.1 % 854 240
Test Date: 2026-07-11 15:47:05 Functions: 57.1 % 7 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Get CPU type and Features for x86 processors.
       2              :    Copyright (C) 2012-2026 Free Software Foundation, Inc.
       3              :    Contributed by Sriraman Tallam (tmsriram@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       170968 : has_cpu_feature (struct __processor_model *cpu_model,
      57              :                  unsigned int *cpu_features2,
      58              :                  enum processor_features feature)
      59              : {
      60       170968 :   unsigned index, offset;
      61       170968 :   unsigned f = feature;
      62              : 
      63       143208 :   if (f < 32)
      64              :     {
      65              :       /* The first 32 features.  */
      66        38567 :       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       121297 :       f -= 32;
      73       121297 :       index = f / 32;
      74       121297 :       offset = f % 32;
      75       110193 :       return cpu_features2[index] & (1U << offset);
      76              :     }
      77              : }
      78              : 
      79              : /* Save FEATURE to either CPU_MODEL or CPU_FEATURES2.  */
      80              : 
      81              : static inline void
      82        65236 : set_cpu_feature (struct __processor_model *cpu_model,
      83              :                  unsigned int *cpu_features2,
      84              :                  enum processor_features feature)
      85              : {
      86        65236 :   unsigned index, offset;
      87        65236 :   unsigned f = feature;
      88              : 
      89        65236 :   if (f < 32)
      90              :     {
      91              :       /* The first 32 features.  */
      92        24984 :       cpu_model->__cpu_features[0] |= (1U << f);
      93              :     }
      94              :   else
      95              :     {
      96              :       /* The rest of features.  cpu_features2[i] contains features from
      97              :          (32 + i * 32) to (31 + 32 + i * 32), inclusively.  */
      98        40252 :       f -= 32;
      99        40252 :       index = f / 32;
     100        40252 :       offset = f % 32;
     101        40252 :       cpu_features2[index] |= (1U << offset);
     102              :     }
     103        61072 : }
     104              : 
     105              : /* Drop FEATURE from either CPU_MODEL or CPU_FEATURES2.  */
     106              : 
     107              : static inline void
     108            0 : reset_cpu_feature (struct __processor_model *cpu_model,
     109              :                    unsigned int *cpu_features2,
     110              :                    enum processor_features feature)
     111              : {
     112            0 :   unsigned index, offset;
     113            0 :   unsigned f = feature;
     114              : 
     115            0 :   if (f < 32)
     116              :     {
     117              :       /* The first 32 features.  */
     118            0 :       cpu_model->__cpu_features[0] &= ~(1U << f);
     119              :     }
     120              :   else
     121              :     {
     122              :       /* The rest of features.  cpu_features2[i] contains features from
     123              :          (32 + i * 32) to (31 + 32 + i * 32), inclusively.  */
     124            0 :       f -= 32;
     125            0 :       index = f / 32;
     126            0 :       offset = f % 32;
     127            0 :       cpu_features2[index] &= ~(1U << offset);
     128              :     }
     129              : }
     130              : 
     131              : /* Get the specific type of AMD CPU and return AMD CPU name.  Return
     132              :    NULL for unknown AMD CPU.  */
     133              : 
     134              : static inline const char *
     135         1388 : get_amd_cpu (struct __processor_model *cpu_model,
     136              :              struct __processor_model2 *cpu_model2,
     137              :              unsigned int *cpu_features2)
     138              : {
     139         1388 :   const char *cpu = NULL;
     140         1388 :   unsigned int family = cpu_model2->__cpu_family;
     141         1388 :   unsigned int model = cpu_model2->__cpu_model;
     142              : 
     143         1388 :   switch (family)
     144              :     {
     145            0 :     case 0x10:
     146              :       /* AMD Family 10h.  */
     147            0 :       cpu = "amdfam10";
     148            0 :       cpu_model->__cpu_type = AMDFAM10H;
     149            0 :       switch (model)
     150              :         {
     151            0 :         case 0x2:
     152              :           /* Barcelona.  */
     153            0 :           CHECK___builtin_cpu_is ("amdfam10h");
     154            0 :           CHECK___builtin_cpu_is ("barcelona");
     155            0 :           cpu_model->__cpu_subtype = AMDFAM10H_BARCELONA;
     156            0 :           break;
     157            0 :         case 0x4:
     158              :           /* Shanghai.  */
     159            0 :           CHECK___builtin_cpu_is ("amdfam10h");
     160            0 :           CHECK___builtin_cpu_is ("shanghai");
     161            0 :           cpu_model->__cpu_subtype = AMDFAM10H_SHANGHAI;
     162            0 :           break;
     163            0 :         case 0x8:
     164              :           /* Istanbul.  */
     165            0 :           CHECK___builtin_cpu_is ("amdfam10h");
     166            0 :           CHECK___builtin_cpu_is ("istanbul");
     167            0 :           cpu_model->__cpu_subtype = AMDFAM10H_ISTANBUL;
     168            0 :           break;
     169              :         default:
     170              :           break;
     171              :         }
     172              :       break;
     173            0 :     case 0x14:
     174              :       /* AMD Family 14h "btver1". */
     175            0 :       cpu = "btver1";
     176            0 :       CHECK___builtin_cpu_is ("btver1");
     177            0 :       cpu_model->__cpu_type = AMD_BTVER1;
     178            0 :       break;
     179            0 :     case 0x15:
     180              :       /* AMD Family 15h "Bulldozer".  */
     181            0 :       cpu_model->__cpu_type = AMDFAM15H;
     182            0 :       if (model == 0x2)
     183              :         {
     184              :           /* Bulldozer version 2 "Piledriver" */
     185            0 :           cpu = "bdver2";
     186            0 :           CHECK___builtin_cpu_is ("bdver2");
     187            0 :           cpu_model->__cpu_subtype = AMDFAM15H_BDVER2;
     188              :         }
     189            0 :       else if (model <= 0xf)
     190              :         {
     191              :           /* Bulldozer version 1.  */
     192            0 :           cpu = "bdver1";
     193            0 :           CHECK___builtin_cpu_is ("bdver1");
     194            0 :           cpu_model->__cpu_subtype = AMDFAM15H_BDVER1;
     195              :         }
     196            0 :       else if (model <= 0x2f)
     197              :         {
     198              :           /* Bulldozer version 2 "Piledriver" */
     199            0 :           cpu = "bdver2";
     200            0 :           CHECK___builtin_cpu_is ("bdver2");
     201            0 :           cpu_model->__cpu_subtype = AMDFAM15H_BDVER2;
     202              :         }
     203            0 :       else if (model <= 0x4f)
     204              :         {
     205              :           /* Bulldozer version 3 "Steamroller"  */
     206            0 :           cpu = "bdver3";
     207            0 :           CHECK___builtin_cpu_is ("bdver3");
     208            0 :           cpu_model->__cpu_subtype = AMDFAM15H_BDVER3;
     209              :         }
     210            0 :       else if (model <= 0x7f)
     211              :         {
     212              :           /* Bulldozer version 4 "Excavator"   */
     213            0 :           cpu = "bdver4";
     214            0 :           CHECK___builtin_cpu_is ("bdver4");
     215            0 :           cpu_model->__cpu_subtype = AMDFAM15H_BDVER4;
     216              :         }
     217            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     218              :                                 FEATURE_AVX2))
     219              :         {
     220            0 :           cpu = "bdver4";
     221            0 :           CHECK___builtin_cpu_is ("bdver4");
     222            0 :           cpu_model->__cpu_subtype = AMDFAM15H_BDVER4;
     223              :         }
     224            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     225              :                                 FEATURE_XSAVEOPT))
     226              :         {
     227            0 :           cpu = "bdver3";
     228            0 :           CHECK___builtin_cpu_is ("bdver3");
     229            0 :           cpu_model->__cpu_subtype = AMDFAM15H_BDVER3;
     230              :         }
     231            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     232              :                                 FEATURE_BMI))
     233              :         {
     234            0 :           cpu = "bdver2";
     235            0 :           CHECK___builtin_cpu_is ("bdver2");
     236            0 :           cpu_model->__cpu_subtype = AMDFAM15H_BDVER2;
     237              :         }
     238            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     239              :                                 FEATURE_XOP))
     240              :         {
     241            0 :           cpu = "bdver1";
     242            0 :           CHECK___builtin_cpu_is ("bdver1");
     243            0 :           cpu_model->__cpu_subtype = AMDFAM15H_BDVER1;
     244              :         }
     245              :       break;
     246            0 :     case 0x16:
     247              :       /* AMD Family 16h "btver2" */
     248            0 :       cpu = "btver2";
     249            0 :       CHECK___builtin_cpu_is ("btver2");
     250            0 :       cpu_model->__cpu_type = AMD_BTVER2;
     251            0 :       break;
     252         1388 :     case 0x17:
     253         1388 :       cpu_model->__cpu_type = AMDFAM17H;
     254         1388 :       if (model <= 0x1f)
     255              :         {
     256              :           /* AMD family 17h version 1.  */
     257            0 :           cpu = "znver1";
     258            0 :           CHECK___builtin_cpu_is ("znver1");
     259            0 :           cpu_model->__cpu_subtype = AMDFAM17H_ZNVER1;
     260              :         }
     261         1388 :       else if (model >= 0x30)
     262              :         {
     263         1388 :           cpu = "znver2";
     264         1388 :           CHECK___builtin_cpu_is ("znver2");
     265         1388 :           cpu_model->__cpu_subtype = AMDFAM17H_ZNVER2;
     266              :         }
     267            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     268              :                                 FEATURE_CLWB))
     269              :         {
     270            0 :           cpu = "znver2";
     271            0 :           CHECK___builtin_cpu_is ("znver2");
     272            0 :           cpu_model->__cpu_subtype = AMDFAM17H_ZNVER2;
     273              :         }
     274            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     275              :                                 FEATURE_CLZERO))
     276              :         {
     277            0 :           cpu = "znver1";
     278            0 :           CHECK___builtin_cpu_is ("znver1");
     279            0 :           cpu_model->__cpu_subtype = AMDFAM17H_ZNVER1;
     280              :         }
     281              :       break;
     282            0 :     case 0x19:
     283            0 :       cpu_model->__cpu_type = AMDFAM19H;
     284              :       /* AMD family 19h.  */
     285            0 :       if (model <= 0x0f)
     286              :         {
     287            0 :           cpu = "znver3";
     288            0 :           CHECK___builtin_cpu_is ("znver3");
     289            0 :           cpu_model->__cpu_subtype = AMDFAM19H_ZNVER3;
     290              :         }
     291            0 :       else if ((model >= 0x10 && model <= 0x1f)
     292            0 :                 || (model >= 0x60 && model <= 0xaf))
     293              :         {
     294            0 :           cpu = "znver4";
     295            0 :           CHECK___builtin_cpu_is ("znver4");
     296            0 :           cpu_model->__cpu_subtype = AMDFAM19H_ZNVER4;
     297              :         }
     298            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     299              :                                 FEATURE_AVX512F))
     300              :         {
     301            0 :           cpu = "znver4";
     302            0 :           CHECK___builtin_cpu_is ("znver4");
     303            0 :           cpu_model->__cpu_subtype = AMDFAM19H_ZNVER4;
     304              :         }
     305            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     306              :                                 FEATURE_VAES))
     307              :         {
     308            0 :           cpu = "znver3";
     309            0 :           CHECK___builtin_cpu_is ("znver3");
     310            0 :           cpu_model->__cpu_subtype = AMDFAM19H_ZNVER3;
     311              :         }
     312              :       break;
     313            0 :     case 0x1a:
     314            0 :       cpu_model->__cpu_type = AMDFAM1AH;
     315            0 :       if (model <= 0x4f || (model >= 0x60 && model <= 0x77) ||
     316            0 :           (model >= 0xd0 && model <= 0xd7))
     317              :         {
     318            0 :           cpu = "znver5";
     319            0 :           CHECK___builtin_cpu_is ("znver5");
     320            0 :           cpu_model->__cpu_subtype = AMDFAM1AH_ZNVER5;
     321              :         }
     322            0 :       else if ((model >= 0x50 && model <= 0x5f) ||
     323            0 :                (model >= 0x80 && model <= 0xcf) ||
     324            0 :                (model >= 0xd8 && model <= 0xe7))
     325              :         {
     326            0 :           cpu = "znver6";
     327            0 :           CHECK___builtin_cpu_is ("znver6");
     328            0 :           cpu_model->__cpu_subtype = AMDFAM1AH_ZNVER6;
     329              :         }
     330            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     331              :                                 FEATURE_AVX512VP2INTERSECT))
     332              :         {
     333            0 :           cpu = "znver5";
     334            0 :           CHECK___builtin_cpu_is ("znver5");
     335            0 :           cpu_model->__cpu_subtype = AMDFAM1AH_ZNVER5;
     336              :         }
     337            0 :       else if (has_cpu_feature (cpu_model, cpu_features2,
     338              :                                 FEATURE_AVX512BMM))
     339              :         {
     340            0 :           cpu = "znver6";
     341            0 :           CHECK___builtin_cpu_is ("znver6");
     342            0 :           cpu_model->__cpu_subtype = AMDFAM1AH_ZNVER6;
     343              :         }
     344              :       break;
     345              :     default:
     346              :       break;
     347              :     }
     348              : 
     349         1388 :   return cpu;
     350              : }
     351              : 
     352              : /* Get the specific type of HYGON CPU and return HYGON CPU name.  Return
     353              :    NULL for unknown HYGON CPU.  */
     354              : 
     355              : static inline const char *
     356            0 : get_hygon_cpu (struct __processor_model *cpu_model,
     357              :                struct __processor_model2 *cpu_model2,
     358              :                unsigned int *cpu_features2 __attribute__((unused)))
     359              : {
     360            0 :   const char *cpu = NULL;
     361            0 :   unsigned int family = cpu_model2->__cpu_family;
     362            0 :   unsigned int model = cpu_model2->__cpu_model;
     363              : 
     364            0 :   switch (family)
     365              :     {
     366            0 :     case 0x18:
     367            0 :       cpu_model->__cpu_type = HYGONFAM18H;
     368            0 :       if (model == 0x4)
     369              :         {
     370            0 :           cpu = "c86-4g-m4";
     371            0 :           CHECK___builtin_cpu_is ("c86-4g-m4");
     372            0 :           cpu_model->__cpu_subtype = HYGONFAM18H_C86_4G_M4;
     373              :         }
     374            0 :       else if (model == 0x6)
     375              :         {
     376            0 :           cpu = "c86-4g-m6";
     377            0 :           CHECK___builtin_cpu_is ("c86-4g-m6");
     378            0 :           cpu_model->__cpu_subtype = HYGONFAM18H_C86_4G_M6;
     379              :         }
     380            0 :       else if (model == 0x7)
     381              :         {
     382            0 :           cpu = "c86-4g-m7";
     383            0 :           CHECK___builtin_cpu_is ("c86-4g-m7");
     384            0 :           cpu_model->__cpu_subtype = HYGONFAM18H_C86_4G_M7;
     385              :         }
     386            0 :       else if (model == 0x8)
     387              :         {
     388            0 :           cpu = "c86-4g-m8";
     389            0 :           CHECK___builtin_cpu_is ("c86-4g-m8");
     390            0 :           cpu_model->__cpu_subtype = HYGONFAM18H_C86_4G_M8;
     391              :         }
     392              :       break;
     393              :     default:
     394              :       break;
     395              :     }
     396              : 
     397            0 :   return cpu;
     398              : }
     399              : 
     400              : /* Get the specific type of Intel CPU and return Intel CPU name.  Return
     401              :    NULL for unknown Intel CPU.  */
     402              : 
     403              : static inline const char *
     404            0 : get_intel_cpu (struct __processor_model *cpu_model,
     405              :                struct __processor_model2 *cpu_model2,
     406              :                unsigned int *cpu_features2)
     407              : {
     408            0 :   const char *cpu = NULL;
     409              : 
     410              :   /* Parse family and model for family 0x6.  */
     411            0 :   if (cpu_model2->__cpu_family == 0x6)
     412            0 :     switch (cpu_model2->__cpu_model)
     413              :       {
     414            0 :       case 0x1c:
     415            0 :       case 0x26:
     416              :         /* Bonnell.  */
     417            0 :         cpu = "bonnell";
     418            0 :         CHECK___builtin_cpu_is ("atom");
     419            0 :         cpu_model->__cpu_type = INTEL_BONNELL;
     420            0 :         break;
     421            0 :       case 0x37:
     422            0 :       case 0x4a:
     423            0 :       case 0x4d:
     424            0 :       case 0x5d:
     425              :         /* Silvermont.  */
     426            0 :       case 0x4c:
     427            0 :       case 0x5a:
     428            0 :       case 0x75:
     429              :         /* Airmont.  */
     430            0 :         cpu = "silvermont";
     431            0 :         CHECK___builtin_cpu_is ("silvermont");
     432            0 :         cpu_model->__cpu_type = INTEL_SILVERMONT;
     433            0 :         break;
     434            0 :       case 0x5c:
     435            0 :       case 0x5f:
     436              :         /* Goldmont.  */
     437            0 :         cpu = "goldmont";
     438            0 :         CHECK___builtin_cpu_is ("goldmont");
     439            0 :         cpu_model->__cpu_type = INTEL_GOLDMONT;
     440            0 :         break;
     441            0 :       case 0x7a:
     442              :         /* Goldmont Plus.  */
     443            0 :         cpu = "goldmont-plus";
     444            0 :         CHECK___builtin_cpu_is ("goldmont-plus");
     445            0 :         cpu_model->__cpu_type = INTEL_GOLDMONT_PLUS;
     446            0 :         break;
     447            0 :       case 0x86:
     448            0 :       case 0x96:
     449            0 :       case 0x9c:
     450              :         /* Tremont.  */
     451            0 :         cpu = "tremont";
     452            0 :         CHECK___builtin_cpu_is ("tremont");
     453            0 :         cpu_model->__cpu_type = INTEL_TREMONT;
     454            0 :         break;
     455            0 :       case 0x17:
     456            0 :       case 0x1d:
     457              :         /* Penryn.  */
     458            0 :       case 0x0f:
     459              :         /* Merom.  */
     460            0 :         cpu = "core2";
     461            0 :         CHECK___builtin_cpu_is ("core2");
     462            0 :         cpu_model->__cpu_type = INTEL_CORE2;
     463            0 :         break;
     464            0 :       case 0x1a:
     465            0 :       case 0x1e:
     466            0 :       case 0x1f:
     467            0 :       case 0x2e:
     468              :         /* Nehalem.  */
     469            0 :         cpu = "nehalem";
     470            0 :         CHECK___builtin_cpu_is ("corei7");
     471            0 :         CHECK___builtin_cpu_is ("nehalem");
     472            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     473            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_NEHALEM;
     474            0 :         break;
     475            0 :       case 0x25:
     476            0 :       case 0x2c:
     477            0 :       case 0x2f:
     478              :         /* Westmere.  */
     479            0 :         cpu = "westmere";
     480            0 :         CHECK___builtin_cpu_is ("corei7");
     481            0 :         CHECK___builtin_cpu_is ("westmere");
     482            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     483            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_WESTMERE;
     484            0 :         break;
     485            0 :       case 0x2a:
     486            0 :       case 0x2d:
     487              :         /* Sandy Bridge.  */
     488            0 :         cpu = "sandybridge";
     489            0 :         CHECK___builtin_cpu_is ("corei7");
     490            0 :         CHECK___builtin_cpu_is ("sandybridge");
     491            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     492            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_SANDYBRIDGE;
     493            0 :         break;
     494            0 :       case 0x3a:
     495            0 :       case 0x3e:
     496              :         /* Ivy Bridge.  */
     497            0 :         cpu = "ivybridge";
     498            0 :         CHECK___builtin_cpu_is ("corei7");
     499            0 :         CHECK___builtin_cpu_is ("ivybridge");
     500            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     501            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_IVYBRIDGE;
     502            0 :         break;
     503            0 :       case 0x3c:
     504            0 :       case 0x3f:
     505            0 :       case 0x45:
     506            0 :       case 0x46:
     507              :         /* Haswell.  */
     508            0 :         cpu = "haswell";
     509            0 :         CHECK___builtin_cpu_is ("corei7");
     510            0 :         CHECK___builtin_cpu_is ("haswell");
     511            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     512            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_HASWELL;
     513            0 :         break;
     514            0 :       case 0x3d:
     515            0 :       case 0x47:
     516            0 :       case 0x4f:
     517            0 :       case 0x56:
     518              :         /* Broadwell.  */
     519            0 :         cpu = "broadwell";
     520            0 :         CHECK___builtin_cpu_is ("corei7");
     521            0 :         CHECK___builtin_cpu_is ("broadwell");
     522            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     523            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_BROADWELL;
     524            0 :         break;
     525            0 :       case 0x4e:
     526            0 :       case 0x5e:
     527              :         /* Skylake.  */
     528            0 :       case 0x8e:
     529            0 :       case 0x9e:
     530              :         /* Kaby Lake.  */
     531            0 :       case 0xa5:
     532            0 :       case 0xa6:
     533              :         /* Comet Lake.  */
     534            0 :         cpu = "skylake";
     535            0 :         CHECK___builtin_cpu_is ("corei7");
     536            0 :         CHECK___builtin_cpu_is ("skylake");
     537            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     538            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE;
     539            0 :         break;
     540            0 :       case 0x55:
     541            0 :         CHECK___builtin_cpu_is ("corei7");
     542            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     543            0 :         if (has_cpu_feature (cpu_model, cpu_features2,
     544              :                             FEATURE_AVX512BF16))
     545              :           {
     546              :             /* Cooper Lake.  */
     547            0 :             cpu = "cooperlake";
     548            0 :             CHECK___builtin_cpu_is ("cooperlake");
     549            0 :             cpu_model->__cpu_subtype = INTEL_COREI7_COOPERLAKE;
     550              :           }
     551            0 :         else if (has_cpu_feature (cpu_model, cpu_features2,
     552              :                                   FEATURE_AVX512VNNI))
     553              :           {
     554              :             /* Cascade Lake.  */
     555            0 :             cpu = "cascadelake";
     556            0 :             CHECK___builtin_cpu_is ("cascadelake");
     557            0 :             cpu_model->__cpu_subtype = INTEL_COREI7_CASCADELAKE;
     558              :           }
     559              :         else
     560              :           {
     561              :             /* Skylake with AVX-512 support.  */
     562            0 :             cpu = "skylake-avx512";
     563            0 :             CHECK___builtin_cpu_is ("skylake-avx512");
     564            0 :             cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512;
     565              :           }
     566              :         break;
     567            0 :       case 0x66:
     568              :         /* Cannon Lake.  */
     569            0 :         cpu = "cannonlake";
     570            0 :         CHECK___builtin_cpu_is ("corei7");
     571            0 :         CHECK___builtin_cpu_is ("cannonlake");
     572            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     573            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_CANNONLAKE;
     574            0 :         break;
     575            0 :       case 0x7e:
     576            0 :       case 0x7d:
     577            0 :       case 0x9d:
     578              :         /* Ice Lake client.  */
     579            0 :         cpu = "icelake-client";
     580            0 :         CHECK___builtin_cpu_is ("corei7");
     581            0 :         CHECK___builtin_cpu_is ("icelake-client");
     582            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     583            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_CLIENT;
     584            0 :         break;
     585            0 :       case 0x6a:
     586            0 :       case 0x6c:
     587              :         /* Ice Lake server.  */
     588            0 :         cpu = "icelake-server";
     589            0 :         CHECK___builtin_cpu_is ("corei7");
     590            0 :         CHECK___builtin_cpu_is ("icelake-server");
     591            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     592            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_SERVER;
     593            0 :         break;
     594            0 :       case 0xa7:
     595              :         /* Rocket Lake.  */
     596            0 :         cpu = "rocketlake";
     597            0 :         CHECK___builtin_cpu_is ("corei7");
     598            0 :         CHECK___builtin_cpu_is ("rocketlake");
     599            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     600            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ROCKETLAKE;
     601            0 :         break;
     602            0 :       case 0x8c:
     603            0 :       case 0x8d:
     604              :         /* Tiger Lake.  */
     605            0 :         cpu = "tigerlake";
     606            0 :         CHECK___builtin_cpu_is ("corei7");
     607            0 :         CHECK___builtin_cpu_is ("tigerlake");
     608            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     609            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_TIGERLAKE;
     610            0 :         break;
     611            0 :       case 0xbe:
     612              :         /* Alder Lake N, E-core only.  */
     613            0 :       case 0x97:
     614            0 :       case 0x9a:
     615              :         /* Alder Lake.  */
     616            0 :       case 0xb7:
     617            0 :       case 0xba:
     618            0 :       case 0xbf:
     619              :         /* Raptor Lake.  */
     620            0 :       case 0xaa:
     621            0 :       case 0xac:
     622              :         /* Meteor Lake.  */
     623            0 :         cpu = "alderlake";
     624            0 :         CHECK___builtin_cpu_is ("corei7");
     625            0 :         CHECK___builtin_cpu_is ("alderlake");
     626            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     627            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ALDERLAKE;
     628            0 :         break;
     629            0 :       case 0x8f:
     630              :         /* Sapphire Rapids.  */
     631            0 :       case 0xcf:
     632              :         /* Emerald Rapids.  */
     633            0 :         cpu = "sapphirerapids";
     634            0 :         CHECK___builtin_cpu_is ("corei7");
     635            0 :         CHECK___builtin_cpu_is ("sapphirerapids");
     636            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     637            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_SAPPHIRERAPIDS;
     638            0 :         break;
     639            0 :       case 0xaf:
     640              :         /* Sierra Forest.  */
     641            0 :         cpu = "sierraforest";
     642            0 :         CHECK___builtin_cpu_is ("sierraforest");
     643            0 :         cpu_model->__cpu_type = INTEL_SIERRAFOREST;
     644            0 :         break;
     645            0 :       case 0xad:
     646              :         /* Granite Rapids.  */
     647            0 :         cpu = "graniterapids";
     648            0 :         CHECK___builtin_cpu_is ("corei7");
     649            0 :         CHECK___builtin_cpu_is ("graniterapids");
     650            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     651            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS;
     652            0 :         break;
     653            0 :       case 0xae:
     654              :         /* Granite Rapids D.  */
     655            0 :         cpu = "graniterapids-d";
     656            0 :         CHECK___builtin_cpu_is ("corei7");
     657            0 :         CHECK___builtin_cpu_is ("graniterapids-d");
     658            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     659            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS_D;
     660            0 :         break;
     661            0 :       case 0xb6:
     662              :         /* Grand Ridge.  */
     663            0 :         cpu = "grandridge";
     664            0 :         CHECK___builtin_cpu_is ("grandridge");
     665            0 :         cpu_model->__cpu_type = INTEL_GRANDRIDGE;
     666            0 :         break;
     667            0 :       case 0xb5:
     668            0 :       case 0xc5:
     669              :         /* Arrow Lake.  */
     670            0 :         cpu = "arrowlake";
     671            0 :         CHECK___builtin_cpu_is ("corei7");
     672            0 :         CHECK___builtin_cpu_is ("arrowlake");
     673            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     674            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ARROWLAKE;
     675            0 :         break;
     676            0 :       case 0xc6:
     677              :         /* Arrow Lake S.  */
     678            0 :       case 0xbd:
     679              :         /* Lunar Lake.  */
     680            0 :         cpu = "arrowlake-s";
     681            0 :         CHECK___builtin_cpu_is ("corei7");
     682            0 :         CHECK___builtin_cpu_is ("arrowlake-s");
     683            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     684            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ARROWLAKE_S;
     685            0 :         break;
     686            0 :       case 0xdd:
     687              :         /* Clearwater Forest.  */
     688            0 :         cpu = "clearwaterforest";
     689            0 :         CHECK___builtin_cpu_is ("clearwaterforest");
     690            0 :         cpu_model->__cpu_type = INTEL_CLEARWATERFOREST;
     691            0 :         break;
     692            0 :       case 0xcc:
     693              :         /* Panther Lake.  */
     694            0 :       case 0xd5:
     695              :         /* Wildcat Lake.  */
     696            0 :         cpu = "pantherlake";
     697            0 :         CHECK___builtin_cpu_is ("corei7");
     698            0 :         CHECK___builtin_cpu_is ("pantherlake");
     699            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     700            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_PANTHERLAKE;
     701            0 :         break;
     702              :       default:
     703              :         break;
     704              :       }
     705              :   /* Parse family and model for family 0x12.  */
     706            0 :   else if (cpu_model2->__cpu_family == 0x12)
     707            0 :     switch (cpu_model2->__cpu_model)
     708              :       {
     709            0 :       case 0x01:
     710            0 :       case 0x03:
     711              :         /* Nova Lake.  */
     712            0 :         cpu = "novalake";
     713            0 :         CHECK___builtin_cpu_is ("corei7");
     714            0 :         CHECK___builtin_cpu_is ("novalake");
     715            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     716            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_NOVALAKE;
     717            0 :         break;
     718              :       default:
     719              :         break;
     720              :       }
     721              :   /* Parse family and model for family 0x13.  */
     722            0 :   else if (cpu_model2->__cpu_family == 0x13)
     723            0 :     switch (cpu_model2->__cpu_model)
     724              :       {
     725            0 :       case 0x01:
     726              :         /* Diamond Rapids.  */
     727            0 :         cpu = "diamondrapids";
     728            0 :         CHECK___builtin_cpu_is ("corei7");
     729            0 :         CHECK___builtin_cpu_is ("diamondrapids");
     730            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     731            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_DIAMONDRAPIDS;
     732            0 :         break;
     733              :       default:
     734              :         break;
     735              :       }
     736              : 
     737            0 :   return cpu;
     738              : }
     739              : 
     740              : /* Get the specific type of ZHAOXIN CPU and return ZHAOXIN CPU name.
     741              :    Return NULL for unknown ZHAOXIN CPU.  */
     742              : 
     743              : static inline const char *
     744            0 : get_zhaoxin_cpu (struct __processor_model *cpu_model,
     745              :                  struct __processor_model2 *cpu_model2,
     746              :                  unsigned int *cpu_features2)
     747              : {
     748            0 :   const char *cpu = NULL;
     749            0 :   unsigned int family = cpu_model2->__cpu_family;
     750            0 :   unsigned int model = cpu_model2->__cpu_model;
     751              : 
     752            0 :   switch (family)
     753              :     {
     754              :     /* ZHAOXIN family 7h.  */
     755            0 :     case 0x07:
     756            0 :       cpu_model->__cpu_type = ZHAOXIN_FAM7H;
     757            0 :       if (model == 0x3b)
     758              :         {
     759            0 :           cpu = "lujiazui";
     760            0 :           CHECK___builtin_cpu_is ("lujiazui");
     761            0 :           reset_cpu_feature (cpu_model, cpu_features2, FEATURE_AVX);
     762            0 :           reset_cpu_feature (cpu_model, cpu_features2, FEATURE_F16C);
     763            0 :           cpu_model->__cpu_subtype = ZHAOXIN_FAM7H_LUJIAZUI;
     764              :         }
     765            0 :      else if (model == 0x5b)
     766              :         {
     767            0 :           cpu = "yongfeng";
     768            0 :           CHECK___builtin_cpu_is ("yongfeng");
     769            0 :           cpu_model->__cpu_subtype = ZHAOXIN_FAM7H_YONGFENG;
     770              :         }
     771            0 :      else if (model >= 0x6b)
     772              :         {
     773            0 :           cpu = "shijidadao";
     774            0 :           CHECK___builtin_cpu_is ("shijidadao");
     775            0 :           cpu_model->__cpu_subtype = ZHAOXIN_FAM7H_SHIJIDADAO;
     776              :         }
     777              :       break;
     778              :     default:
     779              :       break;
     780              :     }
     781              : 
     782            0 :   return cpu;
     783              : }
     784              : 
     785              : /* ECX and EDX are output of CPUID at level one.  */
     786              : static inline void
     787         1388 : get_available_features (struct __processor_model *cpu_model,
     788              :                         struct __processor_model2 *cpu_model2,
     789              :                         unsigned int *cpu_features2,
     790              :                         unsigned int ecx, unsigned int edx)
     791              : {
     792         1388 :   unsigned int max_cpuid_level = cpu_model2->__cpu_max_level;
     793         1388 :   unsigned int eax, ebx;
     794         1388 :   unsigned int ext_level;
     795              : 
     796              :   /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv.  */
     797              : #define XCR_XFEATURE_ENABLED_MASK       0x0
     798              : #define XSTATE_FP                       0x1
     799              : #define XSTATE_SSE                      0x2
     800              : #define XSTATE_YMM                      0x4
     801              : #define XSTATE_OPMASK                   0x20
     802              : #define XSTATE_ZMM                      0x40
     803              : #define XSTATE_HI_ZMM                   0x80
     804              : #define XSTATE_TILECFG                  0x20000
     805              : #define XSTATE_TILEDATA         0x40000
     806              : #define XSTATE_APX_F                    0x80000
     807              : 
     808              : #define XCR_AVX_ENABLED_MASK \
     809              :   (XSTATE_SSE | XSTATE_YMM)
     810              : #define XCR_AVX512F_ENABLED_MASK \
     811              :   (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
     812              : #define XCR_AMX_ENABLED_MASK \
     813              :   (XSTATE_TILECFG | XSTATE_TILEDATA)
     814              : #define XCR_APX_F_ENABLED_MASK XSTATE_APX_F
     815              : 
     816              :   /* Check if AVX, AVX512 and APX are usable.  */
     817         1388 :   int avx_usable = 0;
     818         1388 :   int avx512_usable = 0;
     819         1388 :   int amx_usable = 0;
     820         1388 :   int apx_usable = 0;
     821              :   /* Check if KL is usable.  */
     822         1388 :   int has_kl = 0;
     823              :   /* Record AVX10 version.  */
     824         1388 :   int avx10_set = 0;
     825         1388 :   int version = 0;
     826         1388 :   if ((ecx & bit_OSXSAVE))
     827              :     {
     828              :       /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
     829              :          ZMM16-ZMM31 states are supported by OSXSAVE.  */
     830         1388 :       unsigned int xcrlow;
     831         1388 :       unsigned int xcrhigh;
     832         1388 :       __asm__ (".byte 0x0f, 0x01, 0xd0"
     833              :                : "=a" (xcrlow), "=d" (xcrhigh)
     834              :                : "c" (XCR_XFEATURE_ENABLED_MASK));
     835         1388 :       if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
     836              :         {
     837         1388 :           avx_usable = 1;
     838         1388 :           avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
     839         1388 :                            == XCR_AVX512F_ENABLED_MASK);
     840              :         }
     841         1388 :       amx_usable = ((xcrlow & XCR_AMX_ENABLED_MASK)
     842         1388 :                     == XCR_AMX_ENABLED_MASK);
     843         1388 :       apx_usable = ((xcrlow & XCR_APX_F_ENABLED_MASK)
     844         1388 :                     == XCR_APX_F_ENABLED_MASK);
     845              :     }
     846              : 
     847              : #define set_feature(f) \
     848              :   set_cpu_feature (cpu_model, cpu_features2, f)
     849              : 
     850         1388 :   if (edx & bit_CMOV)
     851         1388 :     set_feature (FEATURE_CMOV);
     852         1388 :   if (edx & bit_MMX)
     853         1388 :     set_feature (FEATURE_MMX);
     854         1388 :   if (edx & bit_SSE)
     855         1388 :     set_feature (FEATURE_SSE);
     856         1388 :   if (edx & bit_SSE2)
     857         1388 :     set_feature (FEATURE_SSE2);
     858         1388 :   if (edx & bit_CMPXCHG8B)
     859         1388 :     set_feature (FEATURE_CMPXCHG8B);
     860         1388 :   if (edx & bit_FXSAVE)
     861         1388 :     set_feature (FEATURE_FXSAVE);
     862              : 
     863         1388 :   if (ecx & bit_POPCNT)
     864         1388 :     set_feature (FEATURE_POPCNT);
     865         1388 :   if (ecx & bit_AES)
     866         1388 :     set_feature (FEATURE_AES);
     867         1388 :   if (ecx & bit_PCLMUL)
     868         1388 :     set_feature (FEATURE_PCLMUL);
     869         1388 :   if (ecx & bit_SSE3)
     870         1388 :     set_feature (FEATURE_SSE3);
     871         1388 :   if (ecx & bit_SSSE3)
     872         1388 :     set_feature (FEATURE_SSSE3);
     873         1388 :   if (ecx & bit_SSE4_1)
     874         1388 :     set_feature (FEATURE_SSE4_1);
     875         1388 :   if (ecx & bit_SSE4_2)
     876         1388 :     set_feature (FEATURE_SSE4_2);
     877         1388 :   if (ecx & bit_OSXSAVE)
     878         1388 :     set_feature (FEATURE_OSXSAVE);
     879         1388 :   if (ecx & bit_CMPXCHG16B)
     880         1388 :     set_feature (FEATURE_CMPXCHG16B);
     881         1388 :   if (ecx & bit_MOVBE)
     882         1388 :     set_feature (FEATURE_MOVBE);
     883         1388 :   if (ecx & bit_AES)
     884         1388 :     set_feature (FEATURE_AES);
     885         1388 :   if (ecx & bit_RDRND)
     886         1388 :     set_feature (FEATURE_RDRND);
     887         1388 :   if (ecx & bit_XSAVE)
     888         1388 :     set_feature (FEATURE_XSAVE);
     889         1388 :   if (avx_usable)
     890              :     {
     891         1388 :       if (ecx & bit_AVX)
     892         1388 :         set_feature (FEATURE_AVX);
     893         1388 :       if (ecx & bit_FMA)
     894         1388 :         set_feature (FEATURE_FMA);
     895         1388 :       if (ecx & bit_F16C)
     896         1388 :         set_feature (FEATURE_F16C);
     897              :     }
     898              : 
     899              :   /* Get Advanced Features at level 7 (eax = 7, ecx = 0/1). */
     900         1388 :   if (max_cpuid_level >= 7)
     901              :     {
     902         1388 :       unsigned int max_subleaf_level;
     903              : 
     904         1388 :       __cpuid_count (7, 0, max_subleaf_level, ebx, ecx, edx);
     905         1388 :       if (ebx & bit_BMI)
     906         1388 :         set_feature (FEATURE_BMI);
     907         1388 :       if (ebx & bit_SGX)
     908            0 :         set_feature (FEATURE_SGX);
     909         1388 :       if (ebx & bit_HLE)
     910            0 :         set_feature (FEATURE_HLE);
     911         1388 :       if (ebx & bit_RTM)
     912            0 :         set_feature (FEATURE_RTM);
     913         1388 :       if (avx_usable)
     914              :         {
     915         1388 :           if (ebx & bit_AVX2)
     916         1388 :             set_feature (FEATURE_AVX2);
     917         1388 :           if (ecx & bit_VPCLMULQDQ)
     918            0 :             set_feature (FEATURE_VPCLMULQDQ);
     919         1388 :           if (ecx & bit_VAES)
     920            0 :             set_feature (FEATURE_VAES);
     921              :         }
     922         1388 :       if (ebx & bit_BMI2)
     923         1388 :         set_feature (FEATURE_BMI2);
     924         1388 :       if (ebx & bit_FSGSBASE)
     925         1388 :         set_feature (FEATURE_FSGSBASE);
     926         1388 :       if (ebx & bit_RDSEED)
     927         1388 :         set_feature (FEATURE_RDSEED);
     928         1388 :       if (ebx & bit_ADX)
     929         1388 :         set_feature (FEATURE_ADX);
     930         1388 :       if (ebx & bit_SHA)
     931         1388 :         set_feature (FEATURE_SHA);
     932         1388 :       if (ebx & bit_CLFLUSHOPT)
     933         1388 :         set_feature (FEATURE_CLFLUSHOPT);
     934         1388 :       if (ebx & bit_CLWB)
     935         1388 :         set_feature (FEATURE_CLWB);
     936              :       /* NB: bit_OSPKE indicates that OS supports PKU.  */
     937         1388 :       if (ecx & bit_OSPKE)
     938            0 :         set_feature (FEATURE_PKU);
     939         1388 :       if (ecx & bit_RDPID)
     940         1388 :         set_feature (FEATURE_RDPID);
     941         1388 :       if (ecx & bit_GFNI)
     942            0 :         set_feature (FEATURE_GFNI);
     943         1388 :       if (ecx & bit_MOVDIRI)
     944            0 :         set_feature (FEATURE_MOVDIRI);
     945         1388 :       if (ecx & bit_MOVDIR64B)
     946            0 :         set_feature (FEATURE_MOVDIR64B);
     947         1388 :       if (ecx & bit_ENQCMD)
     948            0 :         set_feature (FEATURE_ENQCMD);
     949         1388 :       if (ecx & bit_CLDEMOTE)
     950            0 :         set_feature (FEATURE_CLDEMOTE);
     951         1388 :       if (ecx & bit_WAITPKG)
     952            0 :         set_feature (FEATURE_WAITPKG);
     953         1388 :       if (ecx & bit_SHSTK)
     954            0 :         set_feature (FEATURE_SHSTK);
     955         1388 :       if (ecx & bit_KL)
     956            0 :         has_kl = 1;
     957         1388 :       if (edx & bit_SERIALIZE)
     958            0 :         set_feature (FEATURE_SERIALIZE);
     959         1388 :       if (edx & bit_TSXLDTRK)
     960            0 :         set_feature (FEATURE_TSXLDTRK);
     961         1388 :       if (edx & bit_PCONFIG)
     962            0 :         set_feature (FEATURE_PCONFIG);
     963         1388 :       if (edx & bit_IBT)
     964            0 :         set_feature (FEATURE_IBT);
     965         1388 :       if (edx & bit_UINTR)
     966            0 :         set_feature (FEATURE_UINTR);
     967         1388 :       if (amx_usable)
     968              :         {
     969            0 :           if (edx & bit_AMX_TILE)
     970            0 :             set_feature (FEATURE_AMX_TILE);
     971            0 :           if (edx & bit_AMX_INT8)
     972            0 :             set_feature (FEATURE_AMX_INT8);
     973            0 :           if (edx & bit_AMX_BF16)
     974            0 :             set_feature (FEATURE_AMX_BF16);
     975              :         }
     976         1388 :       if (avx512_usable)
     977              :         {
     978            0 :           if (ebx & bit_AVX512F)
     979            0 :             set_feature (FEATURE_AVX512F);
     980            0 :           if (ebx & bit_AVX512VL)
     981            0 :             set_feature (FEATURE_AVX512VL);
     982            0 :           if (ebx & bit_AVX512BW)
     983            0 :             set_feature (FEATURE_AVX512BW);
     984            0 :           if (ebx & bit_AVX512DQ)
     985            0 :             set_feature (FEATURE_AVX512DQ);
     986            0 :           if (ebx & bit_AVX512CD)
     987            0 :             set_feature (FEATURE_AVX512CD);
     988            0 :           if (ebx & bit_AVX512IFMA)
     989            0 :             set_feature (FEATURE_AVX512IFMA);
     990            0 :           if (ecx & bit_AVX512VBMI)
     991            0 :             set_feature (FEATURE_AVX512VBMI);
     992            0 :           if (ecx & bit_AVX512VBMI2)
     993            0 :             set_feature (FEATURE_AVX512VBMI2);
     994            0 :           if (ecx & bit_AVX512VNNI)
     995            0 :             set_feature (FEATURE_AVX512VNNI);
     996            0 :           if (ecx & bit_AVX512BITALG)
     997            0 :             set_feature (FEATURE_AVX512BITALG);
     998            0 :           if (ecx & bit_AVX512VPOPCNTDQ)
     999            0 :             set_feature (FEATURE_AVX512VPOPCNTDQ);
    1000            0 :           if (edx & bit_AVX512VP2INTERSECT)
    1001            0 :             set_feature (FEATURE_AVX512VP2INTERSECT);
    1002            0 :           if (edx & bit_AVX512FP16)
    1003            0 :             set_feature (FEATURE_AVX512FP16);
    1004              :         }
    1005              : 
    1006         1388 :       if (max_subleaf_level >= 1)
    1007              :         {
    1008            0 :           __cpuid_count (7, 1, eax, ebx, ecx, edx);
    1009            0 :           if (eax & bit_HRESET)
    1010            0 :             set_feature (FEATURE_HRESET);
    1011            0 :           if (eax & bit_CMPCCXADD)
    1012            0 :             set_feature(FEATURE_CMPCCXADD);
    1013            0 :           if (edx & bit_PREFETCHI)
    1014            0 :             set_feature (FEATURE_PREFETCHI);
    1015            0 :           if (eax & bit_RAOINT)
    1016            0 :             set_feature (FEATURE_RAOINT);
    1017            0 :           if (edx & bit_USER_MSR)
    1018            0 :             set_feature (FEATURE_USER_MSR);
    1019            0 :           if (eax & bit_MOVRS)
    1020            0 :             set_feature (FEATURE_MOVRS);
    1021            0 :           if (avx_usable)
    1022              :             {
    1023            0 :               if (eax & bit_AVXVNNI)
    1024            0 :                 set_feature (FEATURE_AVXVNNI);
    1025            0 :               if (eax & bit_AVXIFMA)
    1026            0 :                 set_feature (FEATURE_AVXIFMA);
    1027            0 :               if (edx & bit_AVXVNNIINT8)
    1028            0 :                 set_feature (FEATURE_AVXVNNIINT8);
    1029            0 :               if (edx & bit_AVXNECONVERT)
    1030            0 :                 set_feature (FEATURE_AVXNECONVERT);
    1031            0 :               if (edx & bit_AVXVNNIINT16)
    1032            0 :                 set_feature (FEATURE_AVXVNNIINT16);
    1033            0 :               if (eax & bit_SM3)
    1034            0 :                 set_feature (FEATURE_SM3);
    1035            0 :               if (eax & bit_SHA512)
    1036            0 :                 set_feature (FEATURE_SHA512);
    1037            0 :               if (eax & bit_SM4)
    1038            0 :                 set_feature (FEATURE_SM4);
    1039              :             }
    1040            0 :           if (avx512_usable)
    1041              :             {
    1042            0 :               if (eax & bit_AVX512BF16)
    1043            0 :                 set_feature (FEATURE_AVX512BF16);
    1044              :               /* AVX10 has the same XSTATE with AVX512.  */
    1045            0 :               if (edx & bit_AVX10)
    1046            0 :                 avx10_set = 1;
    1047              :             }
    1048            0 :           if (amx_usable)
    1049              :             {
    1050            0 :               if (eax & bit_AMX_FP16)
    1051            0 :                 set_feature (FEATURE_AMX_FP16);
    1052            0 :               if (edx & bit_AMX_COMPLEX)
    1053            0 :                 set_feature (FEATURE_AMX_COMPLEX);
    1054              :             }
    1055            0 :           if (apx_usable)
    1056              :             {
    1057            0 :               if (edx & bit_APX_F)
    1058            0 :                 set_feature (FEATURE_APX_F);
    1059              :             }
    1060              :         }
    1061              :     }
    1062              : 
    1063              :   /* Get Advanced Features at level 0xd (eax = 0xd, ecx = 1). */
    1064         1388 :   if (max_cpuid_level >= 0xd)
    1065              :     {
    1066         1388 :       __cpuid_count (0xd, 1, eax, ebx, ecx, edx);
    1067         1388 :       if (eax & bit_XSAVEOPT)
    1068         1388 :         set_feature (FEATURE_XSAVEOPT);
    1069         1388 :       if (eax & bit_XSAVEC)
    1070         1388 :         set_feature (FEATURE_XSAVEC);
    1071         1388 :       if (eax & bit_XSAVES)
    1072         1388 :         set_feature (FEATURE_XSAVES);
    1073              :     }
    1074              : 
    1075              :   /* Get Advanced Features at level 0x14 (eax = 0x14, ecx = 0). */
    1076         1388 :   if (max_cpuid_level >= 0x14)
    1077              :     {
    1078            0 :       __cpuid_count (0x14, 0, eax, ebx, ecx, edx);
    1079            0 :       if (ebx & bit_PTWRITE)
    1080            0 :         set_feature (FEATURE_PTWRITE);
    1081              :     }
    1082              : 
    1083              :   /* Get Advanced Features at level 0x19 (eax = 0x19).  */
    1084            0 :   if (max_cpuid_level >= 0x19)
    1085              :     {
    1086            0 :       __cpuid (0x19, eax, ebx, ecx, edx);
    1087              :       /* Check if OS support keylocker.  */
    1088            0 :       if (ebx & bit_AESKLE)
    1089              :         {
    1090            0 :           set_feature (FEATURE_AESKLE);
    1091            0 :           if (ebx & bit_WIDEKL)
    1092            0 :             set_feature (FEATURE_WIDEKL);
    1093            0 :           if (has_kl)
    1094            0 :             set_feature (FEATURE_KL);
    1095              :         }
    1096              :     }
    1097              : 
    1098              :   /* Get Advanced Features at level 0x1e (eax = 0x1e, ecx = 1). */
    1099            0 :   if (max_cpuid_level >= 0x1e)
    1100              :     {
    1101            0 :       __cpuid_count (0x1e, 1, eax, ebx, ecx, edx);
    1102            0 :       if (amx_usable)
    1103              :         {
    1104            0 :           if (eax & bit_AMX_AVX512)
    1105            0 :             set_feature (FEATURE_AMX_AVX512);
    1106            0 :           if (eax & bit_AMX_FP8)
    1107            0 :             set_feature (FEATURE_AMX_FP8);
    1108            0 :           if (eax & bit_AMX_MOVRS)
    1109            0 :             set_feature (FEATURE_AMX_MOVRS);
    1110              :         }
    1111              :     }
    1112              : 
    1113              :   /* Get Advanced Features at level 0x21 (eax = 0x21).  */
    1114            0 :   if (max_cpuid_level >= 0x21)
    1115              :     {
    1116            0 :       __cpuid (0x21, eax, ebx, ecx, edx);
    1117            0 :       if (eax & bit_AVX512BMM)
    1118              :         {
    1119            0 :           set_feature (FEATURE_AVX512BMM);
    1120              :         }
    1121              :     }
    1122              : 
    1123              :   /* Get Advanced Features at level 0x24 (eax = 0x24, ecx = 0).  */
    1124         1388 :   if (avx10_set && max_cpuid_level >= 0x24)
    1125              :     {
    1126            0 :       __cpuid_count (0x24, 0, eax, ebx, ecx, edx);
    1127            0 :       version = ebx & 0xff;
    1128            0 :       switch (version)
    1129              :         {
    1130            0 :         case 2:
    1131            0 :           set_feature (FEATURE_AVX10_2);
    1132              :           /* Fall through.  */
    1133            0 :         case 1:
    1134            0 :           set_feature (FEATURE_AVX10_1);
    1135            0 :           break;
    1136            0 :         default:
    1137            0 :           set_feature (FEATURE_AVX10_1);
    1138            0 :           break;
    1139              :         }
    1140              :     }
    1141              : 
    1142              :   /* Check cpuid level of extended features.  */
    1143         1388 :   __cpuid (0x80000000, ext_level, ebx, ecx, edx);
    1144              : 
    1145         1388 :   cpu_model2->__cpu_ext_level = ext_level;
    1146              : 
    1147         1388 :   if (ext_level >= 0x80000001)
    1148              :     {
    1149         1388 :       __cpuid (0x80000001, eax, ebx, ecx, edx);
    1150              : 
    1151         1388 :       if (ecx & bit_SSE4a)
    1152         1388 :         set_feature (FEATURE_SSE4_A);
    1153         1388 :       if (ecx & bit_LAHF_LM)
    1154         1388 :         set_feature (FEATURE_LAHF_LM);
    1155         1388 :       if (ecx & bit_ABM)
    1156         1388 :         set_feature (FEATURE_ABM);
    1157         1388 :       if (ecx & bit_LWP)
    1158            0 :         set_feature (FEATURE_LWP);
    1159         1388 :       if (ecx & bit_TBM)
    1160            0 :         set_feature (FEATURE_TBM);
    1161         1388 :       if (ecx & bit_LZCNT)
    1162         1388 :         set_feature (FEATURE_LZCNT);
    1163         1388 :       if (ecx & bit_PRFCHW)
    1164         1388 :         set_feature (FEATURE_PRFCHW);
    1165         1388 :       if (ecx & bit_MWAITX)
    1166         1388 :         set_feature (FEATURE_MWAITX);
    1167              : 
    1168         1388 :       if (edx & bit_LM)
    1169         1388 :         set_feature (FEATURE_LM);
    1170         1388 :       if (edx & bit_3DNOWP)
    1171            0 :         set_feature (FEATURE_3DNOWP);
    1172         1388 :       if (edx & bit_3DNOW)
    1173            0 :         set_feature (FEATURE_3DNOW);
    1174              : 
    1175         1388 :       if (avx_usable)
    1176              :         {
    1177         1388 :           if (ecx & bit_FMA4)
    1178            0 :             set_feature (FEATURE_FMA4);
    1179         1388 :           if (ecx & bit_XOP)
    1180            0 :             set_feature (FEATURE_XOP);
    1181              :         }
    1182              :     }
    1183              : 
    1184         1388 :   if (ext_level >= 0x80000008)
    1185              :     {
    1186         1388 :       __cpuid (0x80000008, eax, ebx, ecx, edx);
    1187         1388 :       if (ebx & bit_CLZERO)
    1188         1388 :         set_feature (FEATURE_CLZERO);
    1189         1388 :       if (ebx & bit_WBNOINVD)
    1190         1388 :         set_feature (FEATURE_WBNOINVD);
    1191              :     }
    1192              : 
    1193         1388 :   if (ext_level >= 0x80000021)
    1194              :     {
    1195            0 :       __cpuid (0x80000021, eax, ebx, ecx, edx);
    1196            0 :       if (eax & bit_AMD_PREFETCHI)
    1197              :         {
    1198            0 :           set_feature (FEATURE_PREFETCHI);
    1199              :         }
    1200              :     }
    1201              : 
    1202              : #undef set_feature
    1203         1388 : }
    1204              : 
    1205              : static inline int
    1206         1388 : cpu_indicator_init (struct __processor_model *cpu_model,
    1207              :                     struct __processor_model2 *cpu_model2,
    1208              :                     unsigned int *cpu_features2)
    1209              : {
    1210         1388 :   unsigned int eax, ebx, ecx, edx;
    1211              : 
    1212         1388 :   int max_level;
    1213         1388 :   unsigned int vendor;
    1214         1388 :   unsigned int model, family;
    1215         1388 :   unsigned int extended_model, extended_family;
    1216              : 
    1217              :   /* This function needs to run just once.  */
    1218         1388 :   if (cpu_model->__cpu_vendor)
    1219              :     return 0;
    1220              : 
    1221              :   /* Assume cpuid insn present. Run in level 0 to get vendor id. */
    1222         1388 :   if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx))
    1223              :     {
    1224            0 :       cpu_model->__cpu_vendor = VENDOR_OTHER;
    1225            0 :       return -1;
    1226              :     }
    1227              : 
    1228         1388 :   vendor = ebx;
    1229         1388 :   max_level = eax;
    1230              : 
    1231         1388 :   if (max_level < 1)
    1232              :     {
    1233            0 :       cpu_model->__cpu_vendor = VENDOR_OTHER;
    1234            0 :       return -1;
    1235              :     }
    1236              : 
    1237         1388 :   if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
    1238              :     {
    1239            0 :       cpu_model->__cpu_vendor = VENDOR_OTHER;
    1240            0 :       return -1;
    1241              :     }
    1242              : 
    1243         1388 :   cpu_model2->__cpu_max_level = max_level;
    1244              : 
    1245         1388 :   model = (eax >> 4) & 0x0f;
    1246         1388 :   family = (eax >> 8) & 0x0f;
    1247         1388 :   extended_model = (eax >> 12) & 0xf0;
    1248         1388 :   extended_family = (eax >> 20) & 0xff;
    1249              : 
    1250              :   /* Find available features. */
    1251         1388 :   get_available_features (cpu_model, cpu_model2, cpu_features2,
    1252              :                           ecx, edx);
    1253              : 
    1254         1388 :   if (vendor == signature_INTEL_ebx)
    1255              :     {
    1256              :       /* Adjust model and family for Intel CPUS. */
    1257            0 :       if (family == 0x0f)
    1258              :         {
    1259            0 :           family += extended_family;
    1260            0 :           model += extended_model;
    1261              :         }
    1262            0 :       else if (family == 0x06)
    1263            0 :         model += extended_model;
    1264              : 
    1265            0 :       cpu_model2->__cpu_family = family;
    1266            0 :       cpu_model2->__cpu_model = model;
    1267              : 
    1268              :       /* Get CPU type.  */
    1269            0 :       get_intel_cpu (cpu_model, cpu_model2, cpu_features2);
    1270            0 :       cpu_model->__cpu_vendor = VENDOR_INTEL;
    1271              :     }
    1272         1388 :   else if (vendor == signature_AMD_ebx)
    1273              :     {
    1274              :       /* Adjust model and family for AMD CPUS. */
    1275         1388 :       if (family == 0x0f)
    1276              :         {
    1277         1388 :           family += extended_family;
    1278         1388 :           model += extended_model;
    1279              :         }
    1280              : 
    1281         1388 :       cpu_model2->__cpu_family = family;
    1282         1388 :       cpu_model2->__cpu_model = model;
    1283              : 
    1284              :       /* Get CPU type.  */
    1285         1388 :       get_amd_cpu (cpu_model, cpu_model2, cpu_features2);
    1286         1388 :       cpu_model->__cpu_vendor = VENDOR_AMD;
    1287              :     }
    1288            0 :   else if (vendor == signature_CENTAUR_ebx && family < 0x07)
    1289            0 :     cpu_model->__cpu_vendor = VENDOR_CENTAUR;
    1290            0 :   else if (vendor == signature_SHANGHAI_ebx
    1291            0 :            || vendor == signature_CENTAUR_ebx)
    1292              :     {
    1293              :       /* Adjust model and family for ZHAOXIN CPUS.  */
    1294            0 :       if (family == 0x07)
    1295            0 :         model += extended_model;
    1296              : 
    1297            0 :       cpu_model2->__cpu_family = family;
    1298            0 :       cpu_model2->__cpu_model = model;
    1299              : 
    1300              :       /* Get CPU type.  */
    1301            0 :       get_zhaoxin_cpu (cpu_model, cpu_model2, cpu_features2);
    1302            0 :       cpu_model->__cpu_vendor = VENDOR_ZHAOXIN;
    1303              :     }
    1304            0 :   else if (vendor == signature_CYRIX_ebx)
    1305            0 :     cpu_model->__cpu_vendor = VENDOR_CYRIX;
    1306            0 :   else if (vendor == signature_NSC_ebx)
    1307            0 :     cpu_model->__cpu_vendor = VENDOR_NSC;
    1308            0 :   else if (vendor == signature_HYGON_ebx)
    1309              :     {
    1310              :       /* Adjust model and family for HYGON CPUS.  */
    1311            0 :       if (family == 0x0f)
    1312              :         {
    1313            0 :           family += extended_family;
    1314            0 :           model += extended_model;
    1315              :         }
    1316            0 :       cpu_model2->__cpu_family = family;
    1317            0 :       cpu_model2->__cpu_model = model;
    1318              : 
    1319              :       /* Get CPU type.  */
    1320            0 :       get_hygon_cpu (cpu_model, cpu_model2, cpu_features2);
    1321            0 :       cpu_model->__cpu_vendor = VENDOR_HYGON;
    1322              :     }
    1323              :   else
    1324            0 :     cpu_model->__cpu_vendor = VENDOR_OTHER;
    1325              : 
    1326         1388 :   if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_LM)
    1327         1388 :       && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE2))
    1328              :     {
    1329         1388 :       CHECK___builtin_cpu_supports ("x86-64");
    1330         1388 :       set_cpu_feature (cpu_model, cpu_features2,
    1331              :                        FEATURE_X86_64_BASELINE);
    1332         1388 :       if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_CMPXCHG16B)
    1333         1388 :           && has_cpu_feature (cpu_model, cpu_features2, FEATURE_POPCNT)
    1334         1388 :           && has_cpu_feature (cpu_model, cpu_features2, FEATURE_LAHF_LM)
    1335         2776 :           && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE4_2))
    1336              :         {
    1337         1388 :           CHECK___builtin_cpu_supports ("x86-64-v2");
    1338         1388 :           set_cpu_feature (cpu_model, cpu_features2,
    1339              :                            FEATURE_X86_64_V2);
    1340         1388 :           if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_AVX2)
    1341         1388 :               && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI)
    1342         1388 :               && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI2)
    1343         1388 :               && has_cpu_feature (cpu_model, cpu_features2, FEATURE_F16C)
    1344         1388 :               && has_cpu_feature (cpu_model, cpu_features2, FEATURE_FMA)
    1345         1388 :               && has_cpu_feature (cpu_model, cpu_features2,
    1346              :                                   FEATURE_LZCNT)
    1347         2776 :               && has_cpu_feature (cpu_model, cpu_features2,
    1348              :                                   FEATURE_MOVBE))
    1349              :             {
    1350         1388 :               CHECK___builtin_cpu_supports ("x86-64-v3");
    1351         1388 :               set_cpu_feature (cpu_model, cpu_features2,
    1352              :                                FEATURE_X86_64_V3);
    1353         1388 :               if (has_cpu_feature (cpu_model, cpu_features2,
    1354              :                                    FEATURE_AVX512BW)
    1355            0 :                   && has_cpu_feature (cpu_model, cpu_features2,
    1356              :                                       FEATURE_AVX512CD)
    1357            0 :                   && has_cpu_feature (cpu_model, cpu_features2,
    1358              :                                       FEATURE_AVX512DQ)
    1359         1388 :                   && has_cpu_feature (cpu_model, cpu_features2,
    1360              :                                       FEATURE_AVX512VL))
    1361              :                 {
    1362            0 :                   CHECK___builtin_cpu_supports ("x86-64-v4");
    1363            0 :                   set_cpu_feature (cpu_model, cpu_features2,
    1364              :                                    FEATURE_X86_64_V4);
    1365              :                 }
    1366              :             }
    1367              :         }
    1368              :     }
    1369              : 
    1370         1388 :   gcc_assert (cpu_model->__cpu_vendor < VENDOR_MAX);
    1371         1388 :   gcc_assert (cpu_model->__cpu_type < CPU_TYPE_MAX);
    1372         1388 :   gcc_assert (cpu_model->__cpu_subtype < CPU_SUBTYPE_MAX);
    1373              : 
    1374              :   return 0;
    1375              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.