LCOV - code coverage report
Current view: top level - gcc/common/config/i386 - cpuinfo.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 28.2 % 852 240
Test Date: 2026-05-11 19:44:49 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       167345 : has_cpu_feature (struct __processor_model *cpu_model,
      57              :                  unsigned int *cpu_features2,
      58              :                  enum processor_features feature)
      59              : {
      60       167345 :   unsigned index, offset;
      61       167345 :   unsigned f = feature;
      62              : 
      63       140385 :   if (f < 32)
      64              :     {
      65              :       /* The first 32 features.  */
      66        37447 :       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       119114 :       f -= 32;
      73       119114 :       index = f / 32;
      74       119114 :       offset = f % 32;
      75       108330 :       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        63356 : set_cpu_feature (struct __processor_model *cpu_model,
      83              :                  unsigned int *cpu_features2,
      84              :                  enum processor_features feature)
      85              : {
      86        63356 :   unsigned index, offset;
      87        63356 :   unsigned f = feature;
      88              : 
      89        63356 :   if (f < 32)
      90              :     {
      91              :       /* The first 32 features.  */
      92        24264 :       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        39092 :       f -= 32;
      99        39092 :       index = f / 32;
     100        39092 :       offset = f % 32;
     101        39092 :       cpu_features2[index] |= (1U << offset);
     102              :     }
     103        59312 : }
     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         1348 : get_amd_cpu (struct __processor_model *cpu_model,
     136              :              struct __processor_model2 *cpu_model2,
     137              :              unsigned int *cpu_features2)
     138              : {
     139         1348 :   const char *cpu = NULL;
     140         1348 :   unsigned int family = cpu_model2->__cpu_family;
     141         1348 :   unsigned int model = cpu_model2->__cpu_model;
     142              : 
     143         1348 :   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         1348 :     case 0x17:
     253         1348 :       cpu_model->__cpu_type = AMDFAM17H;
     254         1348 :       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         1348 :       else if (model >= 0x30)
     262              :         {
     263         1348 :           cpu = "znver2";
     264         1348 :           CHECK___builtin_cpu_is ("znver2");
     265         1348 :           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         1348 :   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              :       break;
     387              :     default:
     388              :       break;
     389              :     }
     390              : 
     391            0 :   return cpu;
     392              : }
     393              : 
     394              : /* Get the specific type of Intel CPU and return Intel CPU name.  Return
     395              :    NULL for unknown Intel CPU.  */
     396              : 
     397              : static inline const char *
     398            0 : get_intel_cpu (struct __processor_model *cpu_model,
     399              :                struct __processor_model2 *cpu_model2,
     400              :                unsigned int *cpu_features2)
     401              : {
     402            0 :   const char *cpu = NULL;
     403              : 
     404              :   /* Parse family and model for family 0x6.  */
     405            0 :   if (cpu_model2->__cpu_family == 0x6)
     406            0 :     switch (cpu_model2->__cpu_model)
     407              :       {
     408            0 :       case 0x1c:
     409            0 :       case 0x26:
     410              :         /* Bonnell.  */
     411            0 :         cpu = "bonnell";
     412            0 :         CHECK___builtin_cpu_is ("atom");
     413            0 :         cpu_model->__cpu_type = INTEL_BONNELL;
     414            0 :         break;
     415            0 :       case 0x37:
     416            0 :       case 0x4a:
     417            0 :       case 0x4d:
     418            0 :       case 0x5d:
     419              :         /* Silvermont.  */
     420            0 :       case 0x4c:
     421            0 :       case 0x5a:
     422            0 :       case 0x75:
     423              :         /* Airmont.  */
     424            0 :         cpu = "silvermont";
     425            0 :         CHECK___builtin_cpu_is ("silvermont");
     426            0 :         cpu_model->__cpu_type = INTEL_SILVERMONT;
     427            0 :         break;
     428            0 :       case 0x5c:
     429            0 :       case 0x5f:
     430              :         /* Goldmont.  */
     431            0 :         cpu = "goldmont";
     432            0 :         CHECK___builtin_cpu_is ("goldmont");
     433            0 :         cpu_model->__cpu_type = INTEL_GOLDMONT;
     434            0 :         break;
     435            0 :       case 0x7a:
     436              :         /* Goldmont Plus.  */
     437            0 :         cpu = "goldmont-plus";
     438            0 :         CHECK___builtin_cpu_is ("goldmont-plus");
     439            0 :         cpu_model->__cpu_type = INTEL_GOLDMONT_PLUS;
     440            0 :         break;
     441            0 :       case 0x86:
     442            0 :       case 0x96:
     443            0 :       case 0x9c:
     444              :         /* Tremont.  */
     445            0 :         cpu = "tremont";
     446            0 :         CHECK___builtin_cpu_is ("tremont");
     447            0 :         cpu_model->__cpu_type = INTEL_TREMONT;
     448            0 :         break;
     449            0 :       case 0x17:
     450            0 :       case 0x1d:
     451              :         /* Penryn.  */
     452            0 :       case 0x0f:
     453              :         /* Merom.  */
     454            0 :         cpu = "core2";
     455            0 :         CHECK___builtin_cpu_is ("core2");
     456            0 :         cpu_model->__cpu_type = INTEL_CORE2;
     457            0 :         break;
     458            0 :       case 0x1a:
     459            0 :       case 0x1e:
     460            0 :       case 0x1f:
     461            0 :       case 0x2e:
     462              :         /* Nehalem.  */
     463            0 :         cpu = "nehalem";
     464            0 :         CHECK___builtin_cpu_is ("corei7");
     465            0 :         CHECK___builtin_cpu_is ("nehalem");
     466            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     467            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_NEHALEM;
     468            0 :         break;
     469            0 :       case 0x25:
     470            0 :       case 0x2c:
     471            0 :       case 0x2f:
     472              :         /* Westmere.  */
     473            0 :         cpu = "westmere";
     474            0 :         CHECK___builtin_cpu_is ("corei7");
     475            0 :         CHECK___builtin_cpu_is ("westmere");
     476            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     477            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_WESTMERE;
     478            0 :         break;
     479            0 :       case 0x2a:
     480            0 :       case 0x2d:
     481              :         /* Sandy Bridge.  */
     482            0 :         cpu = "sandybridge";
     483            0 :         CHECK___builtin_cpu_is ("corei7");
     484            0 :         CHECK___builtin_cpu_is ("sandybridge");
     485            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     486            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_SANDYBRIDGE;
     487            0 :         break;
     488            0 :       case 0x3a:
     489            0 :       case 0x3e:
     490              :         /* Ivy Bridge.  */
     491            0 :         cpu = "ivybridge";
     492            0 :         CHECK___builtin_cpu_is ("corei7");
     493            0 :         CHECK___builtin_cpu_is ("ivybridge");
     494            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     495            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_IVYBRIDGE;
     496            0 :         break;
     497            0 :       case 0x3c:
     498            0 :       case 0x3f:
     499            0 :       case 0x45:
     500            0 :       case 0x46:
     501              :         /* Haswell.  */
     502            0 :         cpu = "haswell";
     503            0 :         CHECK___builtin_cpu_is ("corei7");
     504            0 :         CHECK___builtin_cpu_is ("haswell");
     505            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     506            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_HASWELL;
     507            0 :         break;
     508            0 :       case 0x3d:
     509            0 :       case 0x47:
     510            0 :       case 0x4f:
     511            0 :       case 0x56:
     512              :         /* Broadwell.  */
     513            0 :         cpu = "broadwell";
     514            0 :         CHECK___builtin_cpu_is ("corei7");
     515            0 :         CHECK___builtin_cpu_is ("broadwell");
     516            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     517            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_BROADWELL;
     518            0 :         break;
     519            0 :       case 0x4e:
     520            0 :       case 0x5e:
     521              :         /* Skylake.  */
     522            0 :       case 0x8e:
     523            0 :       case 0x9e:
     524              :         /* Kaby Lake.  */
     525            0 :       case 0xa5:
     526            0 :       case 0xa6:
     527              :         /* Comet Lake.  */
     528            0 :         cpu = "skylake";
     529            0 :         CHECK___builtin_cpu_is ("corei7");
     530            0 :         CHECK___builtin_cpu_is ("skylake");
     531            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     532            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE;
     533            0 :         break;
     534            0 :       case 0x55:
     535            0 :         CHECK___builtin_cpu_is ("corei7");
     536            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     537            0 :         if (has_cpu_feature (cpu_model, cpu_features2,
     538              :                             FEATURE_AVX512BF16))
     539              :           {
     540              :             /* Cooper Lake.  */
     541            0 :             cpu = "cooperlake";
     542            0 :             CHECK___builtin_cpu_is ("cooperlake");
     543            0 :             cpu_model->__cpu_subtype = INTEL_COREI7_COOPERLAKE;
     544              :           }
     545            0 :         else if (has_cpu_feature (cpu_model, cpu_features2,
     546              :                                   FEATURE_AVX512VNNI))
     547              :           {
     548              :             /* Cascade Lake.  */
     549            0 :             cpu = "cascadelake";
     550            0 :             CHECK___builtin_cpu_is ("cascadelake");
     551            0 :             cpu_model->__cpu_subtype = INTEL_COREI7_CASCADELAKE;
     552              :           }
     553              :         else
     554              :           {
     555              :             /* Skylake with AVX-512 support.  */
     556            0 :             cpu = "skylake-avx512";
     557            0 :             CHECK___builtin_cpu_is ("skylake-avx512");
     558            0 :             cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512;
     559              :           }
     560              :         break;
     561            0 :       case 0x66:
     562              :         /* Cannon Lake.  */
     563            0 :         cpu = "cannonlake";
     564            0 :         CHECK___builtin_cpu_is ("corei7");
     565            0 :         CHECK___builtin_cpu_is ("cannonlake");
     566            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     567            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_CANNONLAKE;
     568            0 :         break;
     569            0 :       case 0x7e:
     570            0 :       case 0x7d:
     571            0 :       case 0x9d:
     572              :         /* Ice Lake client.  */
     573            0 :         cpu = "icelake-client";
     574            0 :         CHECK___builtin_cpu_is ("corei7");
     575            0 :         CHECK___builtin_cpu_is ("icelake-client");
     576            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     577            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_CLIENT;
     578            0 :         break;
     579            0 :       case 0x6a:
     580            0 :       case 0x6c:
     581              :         /* Ice Lake server.  */
     582            0 :         cpu = "icelake-server";
     583            0 :         CHECK___builtin_cpu_is ("corei7");
     584            0 :         CHECK___builtin_cpu_is ("icelake-server");
     585            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     586            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_SERVER;
     587            0 :         break;
     588            0 :       case 0xa7:
     589              :         /* Rocket Lake.  */
     590            0 :         cpu = "rocketlake";
     591            0 :         CHECK___builtin_cpu_is ("corei7");
     592            0 :         CHECK___builtin_cpu_is ("rocketlake");
     593            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     594            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ROCKETLAKE;
     595            0 :         break;
     596            0 :       case 0x8c:
     597            0 :       case 0x8d:
     598              :         /* Tiger Lake.  */
     599            0 :         cpu = "tigerlake";
     600            0 :         CHECK___builtin_cpu_is ("corei7");
     601            0 :         CHECK___builtin_cpu_is ("tigerlake");
     602            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     603            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_TIGERLAKE;
     604            0 :         break;
     605            0 :       case 0xbe:
     606              :         /* Alder Lake N, E-core only.  */
     607            0 :       case 0x97:
     608            0 :       case 0x9a:
     609              :         /* Alder Lake.  */
     610            0 :       case 0xb7:
     611            0 :       case 0xba:
     612            0 :       case 0xbf:
     613              :         /* Raptor Lake.  */
     614            0 :       case 0xaa:
     615            0 :       case 0xac:
     616              :         /* Meteor Lake.  */
     617            0 :         cpu = "alderlake";
     618            0 :         CHECK___builtin_cpu_is ("corei7");
     619            0 :         CHECK___builtin_cpu_is ("alderlake");
     620            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     621            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ALDERLAKE;
     622            0 :         break;
     623            0 :       case 0x8f:
     624              :         /* Sapphire Rapids.  */
     625            0 :       case 0xcf:
     626              :         /* Emerald Rapids.  */
     627            0 :         cpu = "sapphirerapids";
     628            0 :         CHECK___builtin_cpu_is ("corei7");
     629            0 :         CHECK___builtin_cpu_is ("sapphirerapids");
     630            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     631            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_SAPPHIRERAPIDS;
     632            0 :         break;
     633            0 :       case 0xaf:
     634              :         /* Sierra Forest.  */
     635            0 :         cpu = "sierraforest";
     636            0 :         CHECK___builtin_cpu_is ("sierraforest");
     637            0 :         cpu_model->__cpu_type = INTEL_SIERRAFOREST;
     638            0 :         break;
     639            0 :       case 0xad:
     640              :         /* Granite Rapids.  */
     641            0 :         cpu = "graniterapids";
     642            0 :         CHECK___builtin_cpu_is ("corei7");
     643            0 :         CHECK___builtin_cpu_is ("graniterapids");
     644            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     645            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS;
     646            0 :         break;
     647            0 :       case 0xae:
     648              :         /* Granite Rapids D.  */
     649            0 :         cpu = "graniterapids-d";
     650            0 :         CHECK___builtin_cpu_is ("corei7");
     651            0 :         CHECK___builtin_cpu_is ("graniterapids-d");
     652            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     653            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_GRANITERAPIDS_D;
     654            0 :         break;
     655            0 :       case 0xb6:
     656              :         /* Grand Ridge.  */
     657            0 :         cpu = "grandridge";
     658            0 :         CHECK___builtin_cpu_is ("grandridge");
     659            0 :         cpu_model->__cpu_type = INTEL_GRANDRIDGE;
     660            0 :         break;
     661            0 :       case 0xb5:
     662            0 :       case 0xc5:
     663              :         /* Arrow Lake.  */
     664            0 :         cpu = "arrowlake";
     665            0 :         CHECK___builtin_cpu_is ("corei7");
     666            0 :         CHECK___builtin_cpu_is ("arrowlake");
     667            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     668            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ARROWLAKE;
     669            0 :         break;
     670            0 :       case 0xc6:
     671              :         /* Arrow Lake S.  */
     672            0 :       case 0xbd:
     673              :         /* Lunar Lake.  */
     674            0 :         cpu = "arrowlake-s";
     675            0 :         CHECK___builtin_cpu_is ("corei7");
     676            0 :         CHECK___builtin_cpu_is ("arrowlake-s");
     677            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     678            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_ARROWLAKE_S;
     679            0 :         break;
     680            0 :       case 0xdd:
     681              :         /* Clearwater Forest.  */
     682            0 :         cpu = "clearwaterforest";
     683            0 :         CHECK___builtin_cpu_is ("clearwaterforest");
     684            0 :         cpu_model->__cpu_type = INTEL_CLEARWATERFOREST;
     685            0 :         break;
     686            0 :       case 0xcc:
     687              :         /* Panther Lake.  */
     688            0 :       case 0xd5:
     689              :         /* Wildcat Lake.  */
     690            0 :         cpu = "pantherlake";
     691            0 :         CHECK___builtin_cpu_is ("corei7");
     692            0 :         CHECK___builtin_cpu_is ("pantherlake");
     693            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     694            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_PANTHERLAKE;
     695            0 :         break;
     696              :       default:
     697              :         break;
     698              :       }
     699              :   /* Parse family and model for family 0x12.  */
     700            0 :   else if (cpu_model2->__cpu_family == 0x12)
     701            0 :     switch (cpu_model2->__cpu_model)
     702              :       {
     703            0 :       case 0x01:
     704            0 :       case 0x03:
     705              :         /* Nova Lake.  */
     706            0 :         cpu = "novalake";
     707            0 :         CHECK___builtin_cpu_is ("corei7");
     708            0 :         CHECK___builtin_cpu_is ("novalake");
     709            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     710            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_NOVALAKE;
     711            0 :         break;
     712              :       default:
     713              :         break;
     714              :       }
     715              :   /* Parse family and model for family 0x13.  */
     716            0 :   else if (cpu_model2->__cpu_family == 0x13)
     717            0 :     switch (cpu_model2->__cpu_model)
     718              :       {
     719            0 :       case 0x01:
     720              :         /* Diamond Rapids.  */
     721            0 :         cpu = "diamondrapids";
     722            0 :         CHECK___builtin_cpu_is ("corei7");
     723            0 :         CHECK___builtin_cpu_is ("diamondrapids");
     724            0 :         cpu_model->__cpu_type = INTEL_COREI7;
     725            0 :         cpu_model->__cpu_subtype = INTEL_COREI7_DIAMONDRAPIDS;
     726            0 :         break;
     727              :       default:
     728              :         break;
     729              :       }
     730              : 
     731            0 :   return cpu;
     732              : }
     733              : 
     734              : /* Get the specific type of ZHAOXIN CPU and return ZHAOXIN CPU name.
     735              :    Return NULL for unknown ZHAOXIN CPU.  */
     736              : 
     737              : static inline const char *
     738            0 : get_zhaoxin_cpu (struct __processor_model *cpu_model,
     739              :                  struct __processor_model2 *cpu_model2,
     740              :                  unsigned int *cpu_features2)
     741              : {
     742            0 :   const char *cpu = NULL;
     743            0 :   unsigned int family = cpu_model2->__cpu_family;
     744            0 :   unsigned int model = cpu_model2->__cpu_model;
     745              : 
     746            0 :   switch (family)
     747              :     {
     748              :     /* ZHAOXIN family 7h.  */
     749            0 :     case 0x07:
     750            0 :       cpu_model->__cpu_type = ZHAOXIN_FAM7H;
     751            0 :       if (model == 0x3b)
     752              :         {
     753            0 :           cpu = "lujiazui";
     754            0 :           CHECK___builtin_cpu_is ("lujiazui");
     755            0 :           reset_cpu_feature (cpu_model, cpu_features2, FEATURE_AVX);
     756            0 :           reset_cpu_feature (cpu_model, cpu_features2, FEATURE_F16C);
     757            0 :           cpu_model->__cpu_subtype = ZHAOXIN_FAM7H_LUJIAZUI;
     758              :         }
     759            0 :      else if (model == 0x5b)
     760              :         {
     761            0 :           cpu = "yongfeng";
     762            0 :           CHECK___builtin_cpu_is ("yongfeng");
     763            0 :           cpu_model->__cpu_subtype = ZHAOXIN_FAM7H_YONGFENG;
     764              :         }
     765            0 :      else if (model >= 0x6b)
     766              :         {
     767            0 :           cpu = "shijidadao";
     768            0 :           CHECK___builtin_cpu_is ("shijidadao");
     769            0 :           cpu_model->__cpu_subtype = ZHAOXIN_FAM7H_SHIJIDADAO;
     770              :         }
     771              :       break;
     772              :     default:
     773              :       break;
     774              :     }
     775              : 
     776            0 :   return cpu;
     777              : }
     778              : 
     779              : /* ECX and EDX are output of CPUID at level one.  */
     780              : static inline void
     781         1348 : get_available_features (struct __processor_model *cpu_model,
     782              :                         struct __processor_model2 *cpu_model2,
     783              :                         unsigned int *cpu_features2,
     784              :                         unsigned int ecx, unsigned int edx)
     785              : {
     786         1348 :   unsigned int max_cpuid_level = cpu_model2->__cpu_max_level;
     787         1348 :   unsigned int eax, ebx;
     788         1348 :   unsigned int ext_level;
     789              : 
     790              :   /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv.  */
     791              : #define XCR_XFEATURE_ENABLED_MASK       0x0
     792              : #define XSTATE_FP                       0x1
     793              : #define XSTATE_SSE                      0x2
     794              : #define XSTATE_YMM                      0x4
     795              : #define XSTATE_OPMASK                   0x20
     796              : #define XSTATE_ZMM                      0x40
     797              : #define XSTATE_HI_ZMM                   0x80
     798              : #define XSTATE_TILECFG                  0x20000
     799              : #define XSTATE_TILEDATA         0x40000
     800              : #define XSTATE_APX_F                    0x80000
     801              : 
     802              : #define XCR_AVX_ENABLED_MASK \
     803              :   (XSTATE_SSE | XSTATE_YMM)
     804              : #define XCR_AVX512F_ENABLED_MASK \
     805              :   (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
     806              : #define XCR_AMX_ENABLED_MASK \
     807              :   (XSTATE_TILECFG | XSTATE_TILEDATA)
     808              : #define XCR_APX_F_ENABLED_MASK XSTATE_APX_F
     809              : 
     810              :   /* Check if AVX, AVX512 and APX are usable.  */
     811         1348 :   int avx_usable = 0;
     812         1348 :   int avx512_usable = 0;
     813         1348 :   int amx_usable = 0;
     814         1348 :   int apx_usable = 0;
     815              :   /* Check if KL is usable.  */
     816         1348 :   int has_kl = 0;
     817              :   /* Record AVX10 version.  */
     818         1348 :   int avx10_set = 0;
     819         1348 :   int version = 0;
     820         1348 :   if ((ecx & bit_OSXSAVE))
     821              :     {
     822              :       /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and
     823              :          ZMM16-ZMM31 states are supported by OSXSAVE.  */
     824         1348 :       unsigned int xcrlow;
     825         1348 :       unsigned int xcrhigh;
     826         1348 :       __asm__ (".byte 0x0f, 0x01, 0xd0"
     827              :                : "=a" (xcrlow), "=d" (xcrhigh)
     828              :                : "c" (XCR_XFEATURE_ENABLED_MASK));
     829         1348 :       if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK)
     830              :         {
     831         1348 :           avx_usable = 1;
     832         1348 :           avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK)
     833         1348 :                            == XCR_AVX512F_ENABLED_MASK);
     834              :         }
     835         1348 :       amx_usable = ((xcrlow & XCR_AMX_ENABLED_MASK)
     836         1348 :                     == XCR_AMX_ENABLED_MASK);
     837         1348 :       apx_usable = ((xcrlow & XCR_APX_F_ENABLED_MASK)
     838         1348 :                     == XCR_APX_F_ENABLED_MASK);
     839              :     }
     840              : 
     841              : #define set_feature(f) \
     842              :   set_cpu_feature (cpu_model, cpu_features2, f)
     843              : 
     844         1348 :   if (edx & bit_CMOV)
     845         1348 :     set_feature (FEATURE_CMOV);
     846         1348 :   if (edx & bit_MMX)
     847         1348 :     set_feature (FEATURE_MMX);
     848         1348 :   if (edx & bit_SSE)
     849         1348 :     set_feature (FEATURE_SSE);
     850         1348 :   if (edx & bit_SSE2)
     851         1348 :     set_feature (FEATURE_SSE2);
     852         1348 :   if (edx & bit_CMPXCHG8B)
     853         1348 :     set_feature (FEATURE_CMPXCHG8B);
     854         1348 :   if (edx & bit_FXSAVE)
     855         1348 :     set_feature (FEATURE_FXSAVE);
     856              : 
     857         1348 :   if (ecx & bit_POPCNT)
     858         1348 :     set_feature (FEATURE_POPCNT);
     859         1348 :   if (ecx & bit_AES)
     860         1348 :     set_feature (FEATURE_AES);
     861         1348 :   if (ecx & bit_PCLMUL)
     862         1348 :     set_feature (FEATURE_PCLMUL);
     863         1348 :   if (ecx & bit_SSE3)
     864         1348 :     set_feature (FEATURE_SSE3);
     865         1348 :   if (ecx & bit_SSSE3)
     866         1348 :     set_feature (FEATURE_SSSE3);
     867         1348 :   if (ecx & bit_SSE4_1)
     868         1348 :     set_feature (FEATURE_SSE4_1);
     869         1348 :   if (ecx & bit_SSE4_2)
     870         1348 :     set_feature (FEATURE_SSE4_2);
     871         1348 :   if (ecx & bit_OSXSAVE)
     872         1348 :     set_feature (FEATURE_OSXSAVE);
     873         1348 :   if (ecx & bit_CMPXCHG16B)
     874         1348 :     set_feature (FEATURE_CMPXCHG16B);
     875         1348 :   if (ecx & bit_MOVBE)
     876         1348 :     set_feature (FEATURE_MOVBE);
     877         1348 :   if (ecx & bit_AES)
     878         1348 :     set_feature (FEATURE_AES);
     879         1348 :   if (ecx & bit_RDRND)
     880         1348 :     set_feature (FEATURE_RDRND);
     881         1348 :   if (ecx & bit_XSAVE)
     882         1348 :     set_feature (FEATURE_XSAVE);
     883         1348 :   if (avx_usable)
     884              :     {
     885         1348 :       if (ecx & bit_AVX)
     886         1348 :         set_feature (FEATURE_AVX);
     887         1348 :       if (ecx & bit_FMA)
     888         1348 :         set_feature (FEATURE_FMA);
     889         1348 :       if (ecx & bit_F16C)
     890         1348 :         set_feature (FEATURE_F16C);
     891              :     }
     892              : 
     893              :   /* Get Advanced Features at level 7 (eax = 7, ecx = 0/1). */
     894         1348 :   if (max_cpuid_level >= 7)
     895              :     {
     896         1348 :       unsigned int max_subleaf_level;
     897              : 
     898         1348 :       __cpuid_count (7, 0, max_subleaf_level, ebx, ecx, edx);
     899         1348 :       if (ebx & bit_BMI)
     900         1348 :         set_feature (FEATURE_BMI);
     901         1348 :       if (ebx & bit_SGX)
     902            0 :         set_feature (FEATURE_SGX);
     903         1348 :       if (ebx & bit_HLE)
     904            0 :         set_feature (FEATURE_HLE);
     905         1348 :       if (ebx & bit_RTM)
     906            0 :         set_feature (FEATURE_RTM);
     907         1348 :       if (avx_usable)
     908              :         {
     909         1348 :           if (ebx & bit_AVX2)
     910         1348 :             set_feature (FEATURE_AVX2);
     911         1348 :           if (ecx & bit_VPCLMULQDQ)
     912            0 :             set_feature (FEATURE_VPCLMULQDQ);
     913         1348 :           if (ecx & bit_VAES)
     914            0 :             set_feature (FEATURE_VAES);
     915              :         }
     916         1348 :       if (ebx & bit_BMI2)
     917         1348 :         set_feature (FEATURE_BMI2);
     918         1348 :       if (ebx & bit_FSGSBASE)
     919         1348 :         set_feature (FEATURE_FSGSBASE);
     920         1348 :       if (ebx & bit_RDSEED)
     921         1348 :         set_feature (FEATURE_RDSEED);
     922         1348 :       if (ebx & bit_ADX)
     923         1348 :         set_feature (FEATURE_ADX);
     924         1348 :       if (ebx & bit_SHA)
     925         1348 :         set_feature (FEATURE_SHA);
     926         1348 :       if (ebx & bit_CLFLUSHOPT)
     927         1348 :         set_feature (FEATURE_CLFLUSHOPT);
     928         1348 :       if (ebx & bit_CLWB)
     929         1348 :         set_feature (FEATURE_CLWB);
     930              :       /* NB: bit_OSPKE indicates that OS supports PKU.  */
     931         1348 :       if (ecx & bit_OSPKE)
     932            0 :         set_feature (FEATURE_PKU);
     933         1348 :       if (ecx & bit_RDPID)
     934         1348 :         set_feature (FEATURE_RDPID);
     935         1348 :       if (ecx & bit_GFNI)
     936            0 :         set_feature (FEATURE_GFNI);
     937         1348 :       if (ecx & bit_MOVDIRI)
     938            0 :         set_feature (FEATURE_MOVDIRI);
     939         1348 :       if (ecx & bit_MOVDIR64B)
     940            0 :         set_feature (FEATURE_MOVDIR64B);
     941         1348 :       if (ecx & bit_ENQCMD)
     942            0 :         set_feature (FEATURE_ENQCMD);
     943         1348 :       if (ecx & bit_CLDEMOTE)
     944            0 :         set_feature (FEATURE_CLDEMOTE);
     945         1348 :       if (ecx & bit_WAITPKG)
     946            0 :         set_feature (FEATURE_WAITPKG);
     947         1348 :       if (ecx & bit_SHSTK)
     948            0 :         set_feature (FEATURE_SHSTK);
     949         1348 :       if (ecx & bit_KL)
     950            0 :         has_kl = 1;
     951         1348 :       if (edx & bit_SERIALIZE)
     952            0 :         set_feature (FEATURE_SERIALIZE);
     953         1348 :       if (edx & bit_TSXLDTRK)
     954            0 :         set_feature (FEATURE_TSXLDTRK);
     955         1348 :       if (edx & bit_PCONFIG)
     956            0 :         set_feature (FEATURE_PCONFIG);
     957         1348 :       if (edx & bit_IBT)
     958            0 :         set_feature (FEATURE_IBT);
     959         1348 :       if (edx & bit_UINTR)
     960            0 :         set_feature (FEATURE_UINTR);
     961         1348 :       if (amx_usable)
     962              :         {
     963            0 :           if (edx & bit_AMX_TILE)
     964            0 :             set_feature (FEATURE_AMX_TILE);
     965            0 :           if (edx & bit_AMX_INT8)
     966            0 :             set_feature (FEATURE_AMX_INT8);
     967            0 :           if (edx & bit_AMX_BF16)
     968            0 :             set_feature (FEATURE_AMX_BF16);
     969              :         }
     970         1348 :       if (avx512_usable)
     971              :         {
     972            0 :           if (ebx & bit_AVX512F)
     973            0 :             set_feature (FEATURE_AVX512F);
     974            0 :           if (ebx & bit_AVX512VL)
     975            0 :             set_feature (FEATURE_AVX512VL);
     976            0 :           if (ebx & bit_AVX512BW)
     977            0 :             set_feature (FEATURE_AVX512BW);
     978            0 :           if (ebx & bit_AVX512DQ)
     979            0 :             set_feature (FEATURE_AVX512DQ);
     980            0 :           if (ebx & bit_AVX512CD)
     981            0 :             set_feature (FEATURE_AVX512CD);
     982            0 :           if (ebx & bit_AVX512IFMA)
     983            0 :             set_feature (FEATURE_AVX512IFMA);
     984            0 :           if (ecx & bit_AVX512VBMI)
     985            0 :             set_feature (FEATURE_AVX512VBMI);
     986            0 :           if (ecx & bit_AVX512VBMI2)
     987            0 :             set_feature (FEATURE_AVX512VBMI2);
     988            0 :           if (ecx & bit_AVX512VNNI)
     989            0 :             set_feature (FEATURE_AVX512VNNI);
     990            0 :           if (ecx & bit_AVX512BITALG)
     991            0 :             set_feature (FEATURE_AVX512BITALG);
     992            0 :           if (ecx & bit_AVX512VPOPCNTDQ)
     993            0 :             set_feature (FEATURE_AVX512VPOPCNTDQ);
     994            0 :           if (edx & bit_AVX512VP2INTERSECT)
     995            0 :             set_feature (FEATURE_AVX512VP2INTERSECT);
     996            0 :           if (edx & bit_AVX512FP16)
     997            0 :             set_feature (FEATURE_AVX512FP16);
     998              :         }
     999              : 
    1000         1348 :       if (max_subleaf_level >= 1)
    1001              :         {
    1002            0 :           __cpuid_count (7, 1, eax, ebx, ecx, edx);
    1003            0 :           if (eax & bit_HRESET)
    1004            0 :             set_feature (FEATURE_HRESET);
    1005            0 :           if (eax & bit_CMPCCXADD)
    1006            0 :             set_feature(FEATURE_CMPCCXADD);
    1007            0 :           if (edx & bit_PREFETCHI)
    1008            0 :             set_feature (FEATURE_PREFETCHI);
    1009            0 :           if (eax & bit_RAOINT)
    1010            0 :             set_feature (FEATURE_RAOINT);
    1011            0 :           if (edx & bit_USER_MSR)
    1012            0 :             set_feature (FEATURE_USER_MSR);
    1013            0 :           if (eax & bit_MOVRS)
    1014            0 :             set_feature (FEATURE_MOVRS);
    1015            0 :           if (avx_usable)
    1016              :             {
    1017            0 :               if (eax & bit_AVXVNNI)
    1018            0 :                 set_feature (FEATURE_AVXVNNI);
    1019            0 :               if (eax & bit_AVXIFMA)
    1020            0 :                 set_feature (FEATURE_AVXIFMA);
    1021            0 :               if (edx & bit_AVXVNNIINT8)
    1022            0 :                 set_feature (FEATURE_AVXVNNIINT8);
    1023            0 :               if (edx & bit_AVXNECONVERT)
    1024            0 :                 set_feature (FEATURE_AVXNECONVERT);
    1025            0 :               if (edx & bit_AVXVNNIINT16)
    1026            0 :                 set_feature (FEATURE_AVXVNNIINT16);
    1027            0 :               if (eax & bit_SM3)
    1028            0 :                 set_feature (FEATURE_SM3);
    1029            0 :               if (eax & bit_SHA512)
    1030            0 :                 set_feature (FEATURE_SHA512);
    1031            0 :               if (eax & bit_SM4)
    1032            0 :                 set_feature (FEATURE_SM4);
    1033              :             }
    1034            0 :           if (avx512_usable)
    1035              :             {
    1036            0 :               if (eax & bit_AVX512BF16)
    1037            0 :                 set_feature (FEATURE_AVX512BF16);
    1038              :               /* AVX10 has the same XSTATE with AVX512.  */
    1039            0 :               if (edx & bit_AVX10)
    1040            0 :                 avx10_set = 1;
    1041              :             }
    1042            0 :           if (amx_usable)
    1043              :             {
    1044            0 :               if (eax & bit_AMX_FP16)
    1045            0 :                 set_feature (FEATURE_AMX_FP16);
    1046            0 :               if (edx & bit_AMX_COMPLEX)
    1047            0 :                 set_feature (FEATURE_AMX_COMPLEX);
    1048              :             }
    1049            0 :           if (apx_usable)
    1050              :             {
    1051            0 :               if (edx & bit_APX_F)
    1052            0 :                 set_feature (FEATURE_APX_F);
    1053              :             }
    1054              :         }
    1055              :     }
    1056              : 
    1057              :   /* Get Advanced Features at level 0xd (eax = 0xd, ecx = 1). */
    1058         1348 :   if (max_cpuid_level >= 0xd)
    1059              :     {
    1060         1348 :       __cpuid_count (0xd, 1, eax, ebx, ecx, edx);
    1061         1348 :       if (eax & bit_XSAVEOPT)
    1062         1348 :         set_feature (FEATURE_XSAVEOPT);
    1063         1348 :       if (eax & bit_XSAVEC)
    1064         1348 :         set_feature (FEATURE_XSAVEC);
    1065         1348 :       if (eax & bit_XSAVES)
    1066         1348 :         set_feature (FEATURE_XSAVES);
    1067              :     }
    1068              : 
    1069              :   /* Get Advanced Features at level 0x14 (eax = 0x14, ecx = 0). */
    1070         1348 :   if (max_cpuid_level >= 0x14)
    1071              :     {
    1072            0 :       __cpuid_count (0x14, 0, eax, ebx, ecx, edx);
    1073            0 :       if (ebx & bit_PTWRITE)
    1074            0 :         set_feature (FEATURE_PTWRITE);
    1075              :     }
    1076              : 
    1077              :   /* Get Advanced Features at level 0x19 (eax = 0x19).  */
    1078            0 :   if (max_cpuid_level >= 0x19)
    1079              :     {
    1080            0 :       __cpuid (0x19, eax, ebx, ecx, edx);
    1081              :       /* Check if OS support keylocker.  */
    1082            0 :       if (ebx & bit_AESKLE)
    1083              :         {
    1084            0 :           set_feature (FEATURE_AESKLE);
    1085            0 :           if (ebx & bit_WIDEKL)
    1086            0 :             set_feature (FEATURE_WIDEKL);
    1087            0 :           if (has_kl)
    1088            0 :             set_feature (FEATURE_KL);
    1089              :         }
    1090              :     }
    1091              : 
    1092              :   /* Get Advanced Features at level 0x1e (eax = 0x1e, ecx = 1). */
    1093            0 :   if (max_cpuid_level >= 0x1e)
    1094              :     {
    1095            0 :       __cpuid_count (0x1e, 1, eax, ebx, ecx, edx);
    1096            0 :       if (amx_usable)
    1097              :         {
    1098            0 :           if (eax & bit_AMX_AVX512)
    1099            0 :             set_feature (FEATURE_AMX_AVX512);
    1100            0 :           if (eax & bit_AMX_TF32)
    1101            0 :             set_feature (FEATURE_AMX_TF32);
    1102            0 :           if (eax & bit_AMX_FP8)
    1103            0 :             set_feature (FEATURE_AMX_FP8);
    1104            0 :           if (eax & bit_AMX_MOVRS)
    1105            0 :             set_feature (FEATURE_AMX_MOVRS);
    1106              :         }
    1107              :     }
    1108              : 
    1109              :   /* Get Advanced Features at level 0x21 (eax = 0x21).  */
    1110            0 :   if (max_cpuid_level >= 0x21)
    1111              :     {
    1112            0 :       __cpuid (0x21, eax, ebx, ecx, edx);
    1113            0 :       if (eax & bit_AVX512BMM)
    1114              :         {
    1115            0 :           set_feature (FEATURE_AVX512BMM);
    1116              :         }
    1117              :     }
    1118              : 
    1119              :   /* Get Advanced Features at level 0x24 (eax = 0x24, ecx = 0).  */
    1120         1348 :   if (avx10_set && max_cpuid_level >= 0x24)
    1121              :     {
    1122            0 :       __cpuid_count (0x24, 0, eax, ebx, ecx, edx);
    1123            0 :       version = ebx & 0xff;
    1124            0 :       switch (version)
    1125              :         {
    1126            0 :         case 2:
    1127            0 :           set_feature (FEATURE_AVX10_2);
    1128              :           /* Fall through.  */
    1129            0 :         case 1:
    1130            0 :           set_feature (FEATURE_AVX10_1);
    1131            0 :           break;
    1132            0 :         default:
    1133            0 :           set_feature (FEATURE_AVX10_1);
    1134            0 :           break;
    1135              :         }
    1136              :     }
    1137              : 
    1138              :   /* Check cpuid level of extended features.  */
    1139         1348 :   __cpuid (0x80000000, ext_level, ebx, ecx, edx);
    1140              : 
    1141         1348 :   cpu_model2->__cpu_ext_level = ext_level;
    1142              : 
    1143         1348 :   if (ext_level >= 0x80000001)
    1144              :     {
    1145         1348 :       __cpuid (0x80000001, eax, ebx, ecx, edx);
    1146              : 
    1147         1348 :       if (ecx & bit_SSE4a)
    1148         1348 :         set_feature (FEATURE_SSE4_A);
    1149         1348 :       if (ecx & bit_LAHF_LM)
    1150         1348 :         set_feature (FEATURE_LAHF_LM);
    1151         1348 :       if (ecx & bit_ABM)
    1152         1348 :         set_feature (FEATURE_ABM);
    1153         1348 :       if (ecx & bit_LWP)
    1154            0 :         set_feature (FEATURE_LWP);
    1155         1348 :       if (ecx & bit_TBM)
    1156            0 :         set_feature (FEATURE_TBM);
    1157         1348 :       if (ecx & bit_LZCNT)
    1158         1348 :         set_feature (FEATURE_LZCNT);
    1159         1348 :       if (ecx & bit_PRFCHW)
    1160         1348 :         set_feature (FEATURE_PRFCHW);
    1161         1348 :       if (ecx & bit_MWAITX)
    1162         1348 :         set_feature (FEATURE_MWAITX);
    1163              : 
    1164         1348 :       if (edx & bit_LM)
    1165         1348 :         set_feature (FEATURE_LM);
    1166         1348 :       if (edx & bit_3DNOWP)
    1167            0 :         set_feature (FEATURE_3DNOWP);
    1168         1348 :       if (edx & bit_3DNOW)
    1169            0 :         set_feature (FEATURE_3DNOW);
    1170              : 
    1171         1348 :       if (avx_usable)
    1172              :         {
    1173         1348 :           if (ecx & bit_FMA4)
    1174            0 :             set_feature (FEATURE_FMA4);
    1175         1348 :           if (ecx & bit_XOP)
    1176            0 :             set_feature (FEATURE_XOP);
    1177              :         }
    1178              :     }
    1179              : 
    1180         1348 :   if (ext_level >= 0x80000008)
    1181              :     {
    1182         1348 :       __cpuid (0x80000008, eax, ebx, ecx, edx);
    1183         1348 :       if (ebx & bit_CLZERO)
    1184         1348 :         set_feature (FEATURE_CLZERO);
    1185         1348 :       if (ebx & bit_WBNOINVD)
    1186         1348 :         set_feature (FEATURE_WBNOINVD);
    1187              :     }
    1188              : 
    1189         1348 :   if (ext_level >= 0x80000021)
    1190              :     {
    1191            0 :       __cpuid (0x80000021, eax, ebx, ecx, edx);
    1192            0 :       if (eax & bit_AMD_PREFETCHI)
    1193              :         {
    1194            0 :           set_feature (FEATURE_PREFETCHI);
    1195              :         }
    1196              :     }
    1197              : 
    1198              : #undef set_feature
    1199         1348 : }
    1200              : 
    1201              : static inline int
    1202         1348 : cpu_indicator_init (struct __processor_model *cpu_model,
    1203              :                     struct __processor_model2 *cpu_model2,
    1204              :                     unsigned int *cpu_features2)
    1205              : {
    1206         1348 :   unsigned int eax, ebx, ecx, edx;
    1207              : 
    1208         1348 :   int max_level;
    1209         1348 :   unsigned int vendor;
    1210         1348 :   unsigned int model, family;
    1211         1348 :   unsigned int extended_model, extended_family;
    1212              : 
    1213              :   /* This function needs to run just once.  */
    1214         1348 :   if (cpu_model->__cpu_vendor)
    1215              :     return 0;
    1216              : 
    1217              :   /* Assume cpuid insn present. Run in level 0 to get vendor id. */
    1218         1348 :   if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx))
    1219              :     {
    1220            0 :       cpu_model->__cpu_vendor = VENDOR_OTHER;
    1221            0 :       return -1;
    1222              :     }
    1223              : 
    1224         1348 :   vendor = ebx;
    1225         1348 :   max_level = eax;
    1226              : 
    1227         1348 :   if (max_level < 1)
    1228              :     {
    1229            0 :       cpu_model->__cpu_vendor = VENDOR_OTHER;
    1230            0 :       return -1;
    1231              :     }
    1232              : 
    1233         1348 :   if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
    1234              :     {
    1235            0 :       cpu_model->__cpu_vendor = VENDOR_OTHER;
    1236            0 :       return -1;
    1237              :     }
    1238              : 
    1239         1348 :   cpu_model2->__cpu_max_level = max_level;
    1240              : 
    1241         1348 :   model = (eax >> 4) & 0x0f;
    1242         1348 :   family = (eax >> 8) & 0x0f;
    1243         1348 :   extended_model = (eax >> 12) & 0xf0;
    1244         1348 :   extended_family = (eax >> 20) & 0xff;
    1245              : 
    1246              :   /* Find available features. */
    1247         1348 :   get_available_features (cpu_model, cpu_model2, cpu_features2,
    1248              :                           ecx, edx);
    1249              : 
    1250         1348 :   if (vendor == signature_INTEL_ebx)
    1251              :     {
    1252              :       /* Adjust model and family for Intel CPUS. */
    1253            0 :       if (family == 0x0f)
    1254              :         {
    1255            0 :           family += extended_family;
    1256            0 :           model += extended_model;
    1257              :         }
    1258            0 :       else if (family == 0x06)
    1259            0 :         model += extended_model;
    1260              : 
    1261            0 :       cpu_model2->__cpu_family = family;
    1262            0 :       cpu_model2->__cpu_model = model;
    1263              : 
    1264              :       /* Get CPU type.  */
    1265            0 :       get_intel_cpu (cpu_model, cpu_model2, cpu_features2);
    1266            0 :       cpu_model->__cpu_vendor = VENDOR_INTEL;
    1267              :     }
    1268         1348 :   else if (vendor == signature_AMD_ebx)
    1269              :     {
    1270              :       /* Adjust model and family for AMD CPUS. */
    1271         1348 :       if (family == 0x0f)
    1272              :         {
    1273         1348 :           family += extended_family;
    1274         1348 :           model += extended_model;
    1275              :         }
    1276              : 
    1277         1348 :       cpu_model2->__cpu_family = family;
    1278         1348 :       cpu_model2->__cpu_model = model;
    1279              : 
    1280              :       /* Get CPU type.  */
    1281         1348 :       get_amd_cpu (cpu_model, cpu_model2, cpu_features2);
    1282         1348 :       cpu_model->__cpu_vendor = VENDOR_AMD;
    1283              :     }
    1284            0 :   else if (vendor == signature_CENTAUR_ebx && family < 0x07)
    1285            0 :     cpu_model->__cpu_vendor = VENDOR_CENTAUR;
    1286            0 :   else if (vendor == signature_SHANGHAI_ebx
    1287            0 :            || vendor == signature_CENTAUR_ebx)
    1288              :     {
    1289              :       /* Adjust model and family for ZHAOXIN CPUS.  */
    1290            0 :       if (family == 0x07)
    1291            0 :         model += extended_model;
    1292              : 
    1293            0 :       cpu_model2->__cpu_family = family;
    1294            0 :       cpu_model2->__cpu_model = model;
    1295              : 
    1296              :       /* Get CPU type.  */
    1297            0 :       get_zhaoxin_cpu (cpu_model, cpu_model2, cpu_features2);
    1298            0 :       cpu_model->__cpu_vendor = VENDOR_ZHAOXIN;
    1299              :     }
    1300            0 :   else if (vendor == signature_CYRIX_ebx)
    1301            0 :     cpu_model->__cpu_vendor = VENDOR_CYRIX;
    1302            0 :   else if (vendor == signature_NSC_ebx)
    1303            0 :     cpu_model->__cpu_vendor = VENDOR_NSC;
    1304            0 :   else if (vendor == signature_HYGON_ebx)
    1305              :     {
    1306              :       /* Adjust model and family for HYGON CPUS.  */
    1307            0 :       if (family == 0x0f)
    1308              :         {
    1309            0 :           family += extended_family;
    1310            0 :           model += extended_model;
    1311              :         }
    1312            0 :       cpu_model2->__cpu_family = family;
    1313            0 :       cpu_model2->__cpu_model = model;
    1314              : 
    1315              :       /* Get CPU type.  */
    1316            0 :       get_hygon_cpu (cpu_model, cpu_model2, cpu_features2);
    1317            0 :       cpu_model->__cpu_vendor = VENDOR_HYGON;
    1318              :     }
    1319              :   else
    1320            0 :     cpu_model->__cpu_vendor = VENDOR_OTHER;
    1321              : 
    1322         1348 :   if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_LM)
    1323         1348 :       && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE2))
    1324              :     {
    1325         1348 :       CHECK___builtin_cpu_supports ("x86-64");
    1326         1348 :       set_cpu_feature (cpu_model, cpu_features2,
    1327              :                        FEATURE_X86_64_BASELINE);
    1328         1348 :       if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_CMPXCHG16B)
    1329         1348 :           && has_cpu_feature (cpu_model, cpu_features2, FEATURE_POPCNT)
    1330         1348 :           && has_cpu_feature (cpu_model, cpu_features2, FEATURE_LAHF_LM)
    1331         2696 :           && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE4_2))
    1332              :         {
    1333         1348 :           CHECK___builtin_cpu_supports ("x86-64-v2");
    1334         1348 :           set_cpu_feature (cpu_model, cpu_features2,
    1335              :                            FEATURE_X86_64_V2);
    1336         1348 :           if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_AVX2)
    1337         1348 :               && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI)
    1338         1348 :               && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI2)
    1339         1348 :               && has_cpu_feature (cpu_model, cpu_features2, FEATURE_F16C)
    1340         1348 :               && has_cpu_feature (cpu_model, cpu_features2, FEATURE_FMA)
    1341         1348 :               && has_cpu_feature (cpu_model, cpu_features2,
    1342              :                                   FEATURE_LZCNT)
    1343         2696 :               && has_cpu_feature (cpu_model, cpu_features2,
    1344              :                                   FEATURE_MOVBE))
    1345              :             {
    1346         1348 :               CHECK___builtin_cpu_supports ("x86-64-v3");
    1347         1348 :               set_cpu_feature (cpu_model, cpu_features2,
    1348              :                                FEATURE_X86_64_V3);
    1349         1348 :               if (has_cpu_feature (cpu_model, cpu_features2,
    1350              :                                    FEATURE_AVX512BW)
    1351            0 :                   && has_cpu_feature (cpu_model, cpu_features2,
    1352              :                                       FEATURE_AVX512CD)
    1353            0 :                   && has_cpu_feature (cpu_model, cpu_features2,
    1354              :                                       FEATURE_AVX512DQ)
    1355         1348 :                   && has_cpu_feature (cpu_model, cpu_features2,
    1356              :                                       FEATURE_AVX512VL))
    1357              :                 {
    1358            0 :                   CHECK___builtin_cpu_supports ("x86-64-v4");
    1359            0 :                   set_cpu_feature (cpu_model, cpu_features2,
    1360              :                                    FEATURE_X86_64_V4);
    1361              :                 }
    1362              :             }
    1363              :         }
    1364              :     }
    1365              : 
    1366         1348 :   gcc_assert (cpu_model->__cpu_vendor < VENDOR_MAX);
    1367         1348 :   gcc_assert (cpu_model->__cpu_type < CPU_TYPE_MAX);
    1368         1348 :   gcc_assert (cpu_model->__cpu_subtype < CPU_SUBTYPE_MAX);
    1369              : 
    1370              :   return 0;
    1371              : }
        

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.