LCOV - code coverage report
Current view: top level - gcc/config/i386 - driver-i386.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 20.5 % 386 79
Test Date: 2026-02-28 14:20:25 Functions: 50.0 % 8 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Subroutines for the gcc driver.
       2              :    Copyright (C) 2006-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify
       7              : it under the terms of the GNU General Public License as published by
       8              : the Free Software Foundation; either version 3, or (at your option)
       9              : any later version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful,
      12              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : GNU General Public License for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #define IN_TARGET_CODE 1
      21              : 
      22              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "tm.h"
      26              : #include "diagnostic.h"
      27              : 
      28              : const char *host_detect_local_cpu (int argc, const char **argv);
      29              : 
      30              : #if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__))
      31              : #include "cpuid.h"
      32              : #include "common/config/i386/cpuinfo.h"
      33              : #include "common/config/i386/i386-isas.h"
      34              : 
      35              : struct cache_desc
      36              : {
      37              :   unsigned sizekb;
      38              :   unsigned assoc;
      39              :   unsigned line;
      40              : };
      41              : 
      42              : /* Returns command line parameters that describe size and
      43              :    cache line size of the processor caches.  */
      44              : 
      45              : static char *
      46           11 : describe_cache (struct cache_desc level1, struct cache_desc level2)
      47              : {
      48           11 :   char size[100], line[100], size2[100];
      49              : 
      50              :   /* At the moment, gcc does not use the information
      51              :      about the associativity of the cache.  */
      52              : 
      53           11 :   snprintf (size, sizeof (size),
      54              :             "--param l1-cache-size=%u ", level1.sizekb);
      55           11 :   snprintf (line, sizeof (line),
      56              :             "--param l1-cache-line-size=%u ", level1.line);
      57              : 
      58           11 :   snprintf (size2, sizeof (size2),
      59              :             "--param l2-cache-size=%u ", level2.sizekb);
      60              : 
      61           11 :   return concat (size, line, size2, NULL);
      62              : }
      63              : 
      64              : /* Detect L2 cache parameters using CPUID extended function 0x80000006.  */
      65              : 
      66              : static void
      67           11 : detect_l2_cache (struct cache_desc *level2)
      68              : {
      69           11 :   unsigned eax, ebx, ecx, edx;
      70           11 :   unsigned assoc;
      71              : 
      72           11 :   __cpuid (0x80000006, eax, ebx, ecx, edx);
      73              : 
      74           11 :   level2->sizekb = (ecx >> 16) & 0xffff;
      75           11 :   level2->line = ecx & 0xff;
      76              : 
      77           11 :   assoc = (ecx >> 12) & 0xf;
      78           11 :   if (assoc == 6)
      79              :     assoc = 8;
      80            0 :   else if (assoc == 8)
      81              :     assoc = 16;
      82            0 :   else if (assoc >= 0xa && assoc <= 0xc)
      83            0 :     assoc = 32 + (assoc - 0xa) * 16;
      84            0 :   else if (assoc >= 0xd && assoc <= 0xe)
      85            0 :     assoc = 96 + (assoc - 0xd) * 32;
      86              : 
      87           11 :   level2->assoc = assoc;
      88           11 : }
      89              : 
      90              : /* Returns the description of caches for an AMD processor.  */
      91              : 
      92              : static const char *
      93           11 : detect_caches_amd (unsigned max_ext_level)
      94              : {
      95           11 :   unsigned eax, ebx, ecx, edx;
      96              : 
      97           11 :   struct cache_desc level1, level2 = {0, 0, 0};
      98              : 
      99           11 :   if (max_ext_level < 0x80000005)
     100              :     return "";
     101              : 
     102           11 :   __cpuid (0x80000005, eax, ebx, ecx, edx);
     103              : 
     104           11 :   level1.sizekb = (ecx >> 24) & 0xff;
     105           11 :   level1.assoc = (ecx >> 16) & 0xff;
     106           11 :   level1.line = ecx & 0xff;
     107              : 
     108           11 :   if (max_ext_level >= 0x80000006)
     109           11 :     detect_l2_cache (&level2);
     110              : 
     111           11 :   return describe_cache (level1, level2);
     112              : }
     113              : 
     114              : /* Decodes the size, the associativity and the cache line size of
     115              :    L1/L2 caches of an Intel processor.  Values are based on
     116              :    "Intel Processor Identification and the CPUID Instruction"
     117              :    [Application Note 485], revision -032, December 2007.  */
     118              : 
     119              : static void
     120            0 : decode_caches_intel (unsigned reg, bool xeon_mp,
     121              :                      struct cache_desc *level1, struct cache_desc *level2)
     122              : {
     123            0 :   int i;
     124              : 
     125            0 :   for (i = 24; i >= 0; i -= 8)
     126            0 :     switch ((reg >> i) & 0xff)
     127              :       {
     128            0 :       case 0x0a:
     129            0 :         level1->sizekb = 8; level1->assoc = 2; level1->line = 32;
     130            0 :         break;
     131            0 :       case 0x0c:
     132            0 :         level1->sizekb = 16; level1->assoc = 4; level1->line = 32;
     133            0 :         break;
     134            0 :       case 0x0d:
     135            0 :         level1->sizekb = 16; level1->assoc = 4; level1->line = 64;
     136            0 :         break;
     137            0 :       case 0x0e:
     138            0 :         level1->sizekb = 24; level1->assoc = 6; level1->line = 64;
     139            0 :         break;
     140            0 :       case 0x21:
     141            0 :         level2->sizekb = 256; level2->assoc = 8; level2->line = 64;
     142            0 :         break;
     143            0 :       case 0x24:
     144            0 :         level2->sizekb = 1024; level2->assoc = 16; level2->line = 64;
     145            0 :         break;
     146            0 :       case 0x2c:
     147            0 :         level1->sizekb = 32; level1->assoc = 8; level1->line = 64;
     148            0 :         break;
     149            0 :       case 0x39:
     150            0 :         level2->sizekb = 128; level2->assoc = 4; level2->line = 64;
     151            0 :         break;
     152            0 :       case 0x3a:
     153            0 :         level2->sizekb = 192; level2->assoc = 6; level2->line = 64;
     154            0 :         break;
     155            0 :       case 0x3b:
     156            0 :         level2->sizekb = 128; level2->assoc = 2; level2->line = 64;
     157            0 :         break;
     158            0 :       case 0x3c:
     159            0 :         level2->sizekb = 256; level2->assoc = 4; level2->line = 64;
     160            0 :         break;
     161            0 :       case 0x3d:
     162            0 :         level2->sizekb = 384; level2->assoc = 6; level2->line = 64;
     163            0 :         break;
     164            0 :       case 0x3e:
     165            0 :         level2->sizekb = 512; level2->assoc = 4; level2->line = 64;
     166            0 :         break;
     167            0 :       case 0x41:
     168            0 :         level2->sizekb = 128; level2->assoc = 4; level2->line = 32;
     169            0 :         break;
     170            0 :       case 0x42:
     171            0 :         level2->sizekb = 256; level2->assoc = 4; level2->line = 32;
     172            0 :         break;
     173            0 :       case 0x43:
     174            0 :         level2->sizekb = 512; level2->assoc = 4; level2->line = 32;
     175            0 :         break;
     176            0 :       case 0x44:
     177            0 :         level2->sizekb = 1024; level2->assoc = 4; level2->line = 32;
     178            0 :         break;
     179            0 :       case 0x45:
     180            0 :         level2->sizekb = 2048; level2->assoc = 4; level2->line = 32;
     181            0 :         break;
     182            0 :       case 0x48:
     183            0 :         level2->sizekb = 3072; level2->assoc = 12; level2->line = 64;
     184            0 :         break;
     185            0 :       case 0x49:
     186            0 :         if (xeon_mp)
     187              :           break;
     188            0 :         level2->sizekb = 4096; level2->assoc = 16; level2->line = 64;
     189            0 :         break;
     190            0 :       case 0x4e:
     191            0 :         level2->sizekb = 6144; level2->assoc = 24; level2->line = 64;
     192            0 :         break;
     193            0 :       case 0x60:
     194            0 :         level1->sizekb = 16; level1->assoc = 8; level1->line = 64;
     195            0 :         break;
     196            0 :       case 0x66:
     197            0 :         level1->sizekb = 8; level1->assoc = 4; level1->line = 64;
     198            0 :         break;
     199            0 :       case 0x67:
     200            0 :         level1->sizekb = 16; level1->assoc = 4; level1->line = 64;
     201            0 :         break;
     202            0 :       case 0x68:
     203            0 :         level1->sizekb = 32; level1->assoc = 4; level1->line = 64;
     204            0 :         break;
     205            0 :       case 0x78:
     206            0 :         level2->sizekb = 1024; level2->assoc = 4; level2->line = 64;
     207            0 :         break;
     208            0 :       case 0x79:
     209            0 :         level2->sizekb = 128; level2->assoc = 8; level2->line = 64;
     210            0 :         break;
     211            0 :       case 0x7a:
     212            0 :         level2->sizekb = 256; level2->assoc = 8; level2->line = 64;
     213            0 :         break;
     214            0 :       case 0x7b:
     215            0 :         level2->sizekb = 512; level2->assoc = 8; level2->line = 64;
     216            0 :         break;
     217            0 :       case 0x7c:
     218            0 :         level2->sizekb = 1024; level2->assoc = 8; level2->line = 64;
     219            0 :         break;
     220            0 :       case 0x7d:
     221            0 :         level2->sizekb = 2048; level2->assoc = 8; level2->line = 64;
     222            0 :         break;
     223            0 :       case 0x7f:
     224            0 :         level2->sizekb = 512; level2->assoc = 2; level2->line = 64;
     225            0 :         break;
     226            0 :       case 0x80:
     227            0 :         level2->sizekb = 512; level2->assoc = 8; level2->line = 64;
     228            0 :         break;
     229            0 :       case 0x82:
     230            0 :         level2->sizekb = 256; level2->assoc = 8; level2->line = 32;
     231            0 :         break;
     232            0 :       case 0x83:
     233            0 :         level2->sizekb = 512; level2->assoc = 8; level2->line = 32;
     234            0 :         break;
     235            0 :       case 0x84:
     236            0 :         level2->sizekb = 1024; level2->assoc = 8; level2->line = 32;
     237            0 :         break;
     238            0 :       case 0x85:
     239            0 :         level2->sizekb = 2048; level2->assoc = 8; level2->line = 32;
     240            0 :         break;
     241            0 :       case 0x86:
     242            0 :         level2->sizekb = 512; level2->assoc = 4; level2->line = 64;
     243            0 :         break;
     244            0 :       case 0x87:
     245            0 :         level2->sizekb = 1024; level2->assoc = 8; level2->line = 64;
     246              : 
     247              :       default:
     248              :         break;
     249              :       }
     250            0 : }
     251              : 
     252              : /* Detect cache parameters using CPUID function 2.  */
     253              : 
     254              : static void
     255            0 : detect_caches_cpuid2 (bool xeon_mp,
     256              :                       struct cache_desc *level1, struct cache_desc *level2)
     257              : {
     258            0 :   unsigned regs[4];
     259            0 :   int nreps, i;
     260              : 
     261            0 :   __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
     262              : 
     263            0 :   nreps = regs[0] & 0x0f;
     264            0 :   regs[0] &= ~0x0f;
     265              : 
     266            0 :   while (--nreps >= 0)
     267              :     {
     268            0 :       for (i = 0; i < 4; i++)
     269            0 :         if (regs[i] && !((regs[i] >> 31) & 1))
     270            0 :           decode_caches_intel (regs[i], xeon_mp, level1, level2);
     271              : 
     272            0 :       if (nreps)
     273            0 :         __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
     274              :     }
     275            0 : }
     276              : 
     277              : /* Detect cache parameters using CPUID function 4. This
     278              :    method doesn't require hardcoded tables.  */
     279              : 
     280              : enum cache_type
     281              : {
     282              :   CACHE_END = 0,
     283              :   CACHE_DATA = 1,
     284              :   CACHE_INST = 2,
     285              :   CACHE_UNIFIED = 3
     286              : };
     287              : 
     288              : static void
     289            0 : detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2,
     290              :                       struct cache_desc *level3)
     291              : {
     292            0 :   struct cache_desc *cache;
     293              : 
     294            0 :   unsigned eax, ebx, ecx, edx;
     295            0 :   int count;
     296              : 
     297            0 :   for (count = 0;; count++)
     298              :     {
     299            0 :       __cpuid_count(4, count, eax, ebx, ecx, edx);
     300            0 :       switch (eax & 0x1f)
     301              :         {
     302            0 :         case CACHE_END:
     303            0 :           return;
     304            0 :         case CACHE_DATA:
     305            0 :         case CACHE_UNIFIED:
     306            0 :           {
     307            0 :             switch ((eax >> 5) & 0x07)
     308              :               {
     309              :               case 1:
     310              :                 cache = level1;
     311              :                 break;
     312            0 :               case 2:
     313            0 :                 cache = level2;
     314            0 :                 break;
     315            0 :               case 3:
     316            0 :                 cache = level3;
     317            0 :                 break;
     318              :               default:
     319              :                 cache = NULL;
     320              :               }
     321              : 
     322            0 :             if (cache)
     323              :               {
     324            0 :                 unsigned sets = ecx + 1;
     325            0 :                 unsigned part = ((ebx >> 12) & 0x03ff) + 1;
     326              : 
     327            0 :                 cache->assoc = ((ebx >> 22) & 0x03ff) + 1;
     328            0 :                 cache->line = (ebx & 0x0fff) + 1;
     329              : 
     330            0 :                 cache->sizekb = (cache->assoc * part
     331            0 :                                  * cache->line * sets) / 1024;
     332              :               }
     333              :           }
     334            0 :         default:
     335            0 :           break;
     336              :         }
     337            0 :     }
     338              : }
     339              : 
     340              : /* Returns the description of caches for an Intel processor.  */
     341              : 
     342              : static const char *
     343            0 : detect_caches_intel (bool xeon_mp, unsigned max_level,
     344              :                      unsigned max_ext_level, unsigned *l2sizekb)
     345              : {
     346            0 :   struct cache_desc level1 = {0, 0, 0}, level2 = {0, 0, 0}, level3 = {0, 0, 0};
     347              : 
     348            0 :   if (max_level >= 4)
     349            0 :     detect_caches_cpuid4 (&level1, &level2, &level3);
     350            0 :   else if (max_level >= 2)
     351            0 :     detect_caches_cpuid2 (xeon_mp, &level1, &level2);
     352              :   else
     353              :     return "";
     354              : 
     355            0 :   if (level1.sizekb == 0)
     356              :     return "";
     357              : 
     358              :   /* Let the L3 replace the L2. This assumes inclusive caches
     359              :      and single threaded program for now. */
     360            0 :   if (level3.sizekb)
     361            0 :     level2 = level3;
     362              : 
     363              :   /* Intel CPUs are equipped with AMD style L2 cache info.  Try this
     364              :      method if other methods fail to provide L2 cache parameters.  */
     365            0 :   if (level2.sizekb == 0 && max_ext_level >= 0x80000006)
     366            0 :     detect_l2_cache (&level2);
     367              : 
     368            0 :   *l2sizekb = level2.sizekb;
     369              : 
     370            0 :   return describe_cache (level1, level2);
     371              : }
     372              : 
     373              : /* Extended features */
     374              : #define has_feature(f) \
     375              :   has_cpu_feature (&cpu_model, cpu_features2, f)
     376              : 
     377              : /* This will be called by the spec parser in gcc.cc when it sees
     378              :    a %:local_cpu_detect(args) construct.  Currently it will be
     379              :    called with either "arch [32|64]" or "tune [32|64]" as argument
     380              :    depending on if -march=native or -mtune=native is to be substituted.
     381              : 
     382              :    It returns a string containing new command line parameters to be
     383              :    put at the place of the above two options, depending on what CPU
     384              :    this is executed.  E.g. "-march=k8" on an AMD64 machine
     385              :    for -march=native.
     386              : 
     387              :    ARGC and ARGV are set depending on the actual arguments given
     388              :    in the spec.  */
     389              : 
     390         1348 : const char *host_detect_local_cpu (int argc, const char **argv)
     391              : {
     392         1348 :   enum processor_type processor = PROCESSOR_I386;
     393         1348 :   const char *cpu = "i386";
     394              : 
     395         1348 :   const char *cache = "";
     396         1348 :   const char *options = "";
     397              : 
     398         1348 :   unsigned int ebx, ecx, edx;
     399              : 
     400         1348 :   unsigned int max_level, ext_level;
     401              : 
     402         1348 :   unsigned int vendor;
     403         1348 :   unsigned int model, family;
     404              : 
     405         1348 :   bool arch;
     406              : 
     407         1348 :   unsigned int l2sizekb = 0;
     408              : 
     409         1348 :   if (argc < 2)
     410              :     return NULL;
     411              : 
     412         1348 :   arch = !strcmp (argv[0], "arch");
     413              : 
     414         1348 :   if (!arch && strcmp (argv[0], "tune"))
     415              :     return NULL;
     416              : 
     417         1348 :   bool codegen_x86_64;
     418              : 
     419         1348 :   if (!strcmp (argv[1], "32"))
     420              :     codegen_x86_64 = false;
     421         1348 :   else if (!strcmp (argv[1], "64"))
     422              :     codegen_x86_64 = true;
     423              :   else
     424              :     return NULL;
     425              : 
     426         1348 :   struct __processor_model cpu_model = { };
     427         1348 :   struct __processor_model2 cpu_model2 = { };
     428         1348 :   unsigned int cpu_features2[SIZE_OF_CPU_FEATURES] = { };
     429              : 
     430         1348 :   if (cpu_indicator_init (&cpu_model, &cpu_model2, cpu_features2) != 0)
     431            0 :     goto done;
     432              : 
     433         1348 :   vendor = cpu_model.__cpu_vendor;
     434         1348 :   family = cpu_model2.__cpu_family;
     435         1348 :   model = cpu_model2.__cpu_model;
     436         1348 :   max_level = cpu_model2.__cpu_max_level;
     437         1348 :   ext_level = cpu_model2.__cpu_ext_level;
     438              : 
     439         1348 :   if (!arch)
     440              :     {
     441           11 :       if (vendor == VENDOR_AMD
     442           11 :           || vendor == VENDOR_CENTAUR
     443              :           || vendor == VENDOR_CYRIX
     444            0 :           || vendor == VENDOR_NSC)
     445           11 :         cache = detect_caches_amd (ext_level);
     446            0 :       else if (vendor == VENDOR_INTEL
     447            0 :                          || vendor == VENDOR_ZHAOXIN)
     448              :         {
     449            0 :           bool xeon_mp = (family == 15 && model == 6);
     450            0 :           cache = detect_caches_intel (xeon_mp, max_level,
     451              :                                        ext_level, &l2sizekb);
     452              :         }
     453              :     }
     454              : 
     455         1348 :   if (vendor == VENDOR_AMD)
     456              :     {
     457         1348 :       unsigned int name;
     458              : 
     459              :       /* Detect geode processor by its processor signature.  */
     460         1348 :       if (ext_level >= 0x80000002)
     461         1348 :         __cpuid (0x80000002, name, ebx, ecx, edx);
     462              :       else
     463              :         name = 0;
     464              : 
     465         1348 :       if (name == signature_NSC_ebx)
     466              :         processor = PROCESSOR_GEODE;
     467         1348 :       else if (has_feature (FEATURE_MOVBE) && family == 22)
     468              :         processor = PROCESSOR_BTVER2;
     469         1348 :       else if (has_feature (FEATURE_AVX512BMM))
     470              :         processor = PROCESSOR_ZNVER6;
     471         1348 :       else if (has_feature (FEATURE_AVX512VP2INTERSECT))
     472              :         processor = PROCESSOR_ZNVER5;
     473         1348 :       else if (has_feature (FEATURE_AVX512F))
     474              :         processor = PROCESSOR_ZNVER4;
     475         1348 :       else if (has_feature (FEATURE_VAES))
     476              :         processor = PROCESSOR_ZNVER3;
     477         1348 :       else if (has_feature (FEATURE_CLWB))
     478              :         processor = PROCESSOR_ZNVER2;
     479            0 :       else if (has_feature (FEATURE_CLZERO))
     480              :         processor = PROCESSOR_ZNVER1;
     481            0 :       else if (has_feature (FEATURE_AVX2))
     482              :         processor = PROCESSOR_BDVER4;
     483            0 :       else if (has_feature (FEATURE_XSAVEOPT))
     484              :         processor = PROCESSOR_BDVER3;
     485            0 :       else if (has_feature (FEATURE_BMI))
     486              :         processor = PROCESSOR_BDVER2;
     487            0 :       else if (has_feature (FEATURE_XOP))
     488              :         processor = PROCESSOR_BDVER1;
     489            0 :       else if (has_feature (FEATURE_SSE4_A)
     490            0 :                && has_feature (FEATURE_SSSE3))
     491              :         processor = PROCESSOR_BTVER1;
     492            0 :       else if (has_feature (FEATURE_SSE4_A))
     493              :         processor = PROCESSOR_AMDFAM10;
     494            0 :       else if (has_feature (FEATURE_SSE2)
     495            0 :                || has_feature (FEATURE_LM))
     496              :         processor = PROCESSOR_K8;
     497            0 :       else if (has_feature (FEATURE_3DNOWP) && family == 6)
     498              :         processor = PROCESSOR_ATHLON;
     499            0 :       else if (has_feature (FEATURE_MMX))
     500              :         processor = PROCESSOR_K6;
     501              :       else
     502              :         processor = PROCESSOR_PENTIUM;
     503              :     }
     504            0 :   else if (vendor == VENDOR_CENTAUR)
     505              :     {
     506            0 :       processor = PROCESSOR_GENERIC;
     507              : 
     508            0 :       switch (family)
     509              :         {
     510              :         default:
     511              :           /* We have no idea.  */
     512              :           break;
     513              : 
     514            0 :         case 5:
     515            0 :           if (has_feature (FEATURE_3DNOW)
     516            0 :               || has_feature (FEATURE_MMX))
     517              :             processor = PROCESSOR_I486;
     518              :           break;
     519              : 
     520            0 :         case 6:
     521            0 :           if (has_feature (FEATURE_LM))
     522              :             processor = PROCESSOR_K8;
     523            0 :           else if (model >= 9)
     524              :             processor = PROCESSOR_PENTIUMPRO;
     525            0 :           else if (model >= 6)
     526              :             processor = PROCESSOR_I486;
     527              :         }
     528              :     }
     529            0 :   else if (vendor == VENDOR_ZHAOXIN)
     530              :     {
     531            0 :       processor = PROCESSOR_GENERIC;
     532              : 
     533            0 :       switch (family)
     534              :         {
     535            0 :         case 7:
     536            0 :           if (model >= 0x6b)
     537              :             processor = PROCESSOR_SHIJIDADAO;
     538            0 :           else if (model == 0x5b)
     539              :             processor = PROCESSOR_YONGFENG;
     540            0 :           else if (model == 0x3b)
     541              :             processor = PROCESSOR_LUJIAZUI;
     542              :           break;
     543              :         default:
     544              :           break;
     545              :         }
     546              :     }
     547              :   else
     548              :     {
     549            0 :       switch (family)
     550              :         {
     551              :         case 4:
     552              :           processor = PROCESSOR_I486;
     553              :           break;
     554              :         case 5:
     555              :           processor = PROCESSOR_PENTIUM;
     556              :           break;
     557              :         case 6:
     558              :         case 18:
     559              :         case 19:
     560              :           processor = PROCESSOR_PENTIUMPRO;
     561              :           break;
     562            0 :         case 15:
     563            0 :           processor = PROCESSOR_PENTIUM4;
     564            0 :           break;
     565              :         default:
     566              :           /* We have no idea.  */
     567              :           processor = PROCESSOR_GENERIC;
     568              :         }
     569              :     }
     570              : 
     571            0 :   switch (processor)
     572              :     {
     573              :     case PROCESSOR_I386:
     574              :       /* Default.  */
     575              :       break;
     576            0 :     case PROCESSOR_I486:
     577            0 :       if (arch && vendor == VENDOR_CENTAUR)
     578              :         {
     579            0 :           if (model >= 6)
     580              :             cpu = "c3";
     581            0 :           else if (has_feature (FEATURE_3DNOW))
     582              :             cpu = "winchip2";
     583              :           else
     584              :             /* Assume WinChip C6.  */
     585            0 :             cpu = "winchip-c6";
     586              :         }
     587              :       else
     588              :         cpu = "i486";
     589              :       break;
     590            0 :     case PROCESSOR_PENTIUM:
     591            0 :       if (arch && has_feature (FEATURE_MMX))
     592              :         cpu = "pentium-mmx";
     593              :       else
     594              :         cpu = "pentium";
     595              :       break;
     596            0 :     case PROCESSOR_PENTIUMPRO:
     597            0 :       cpu = get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2);
     598            0 :       if (cpu == NULL)
     599              :         {
     600            0 :           if (arch)
     601              :             {
     602              :               /* This is unknown CPU.  */
     603            0 :               if (has_feature (FEATURE_AVX512F))
     604              :                 {
     605              :                   /* Assume Diamond Rapids.  */
     606            0 :                   if (has_feature (FEATURE_AMX_FP8))
     607              :                     cpu = "diamondrapids";
     608              :                   /* Assume Nova Lake.  */
     609            0 :                   else if (has_feature (FEATURE_AVX10_2))
     610              :                     cpu = "novalake";
     611              :                   /* Assume Granite Rapids D.  */
     612            0 :                   else if (has_feature (FEATURE_AMX_COMPLEX))
     613              :                     cpu = "graniterapids-d";
     614              :                   /* Assume Granite Rapids.  */
     615            0 :                   else if (has_feature (FEATURE_AMX_FP16))
     616              :                     cpu = "graniterapids";
     617              :                   /* Assume Tiger Lake */
     618            0 :                   else if (has_feature (FEATURE_AVX512VP2INTERSECT))
     619              :                     cpu = "tigerlake";
     620              :                   /* Assume Sapphire Rapids.  */
     621            0 :                   else if (has_feature (FEATURE_TSXLDTRK))
     622              :                     cpu = "sapphirerapids";
     623              :                   /* Assume Cooper Lake */
     624            0 :                   else if (has_feature (FEATURE_AVX512BF16))
     625              :                     cpu = "cooperlake";
     626              :                   /* Assume Ice Lake Server.  */
     627            0 :                   else if (has_feature (FEATURE_WBNOINVD))
     628              :                     cpu = "icelake-server";
     629              :                   /* Assume Ice Lake.  */
     630            0 :                   else if (has_feature (FEATURE_AVX512BITALG))
     631              :                     cpu = "icelake-client";
     632              :                   /* Assume Cannon Lake.  */
     633            0 :                   else if (has_feature (FEATURE_AVX512VBMI))
     634              :                     cpu = "cannonlake";
     635              :                   /* Assume Xeon Phi Processors.  Support has been removed
     636              :                      since GCC 15.  */
     637            0 :                   else if (!has_feature (FEATURE_AVX512VL))
     638            0 :                     error ("Xeon Phi ISA support has been removed since "
     639              :                            "GCC 15, use GCC 14 for the Xeon Phi ISAs or "
     640              :                            "%<-march=broadwell%> for all the other ISAs "
     641              :                            "supported on this machine.");
     642              :                   /* Assume Skylake with AVX-512.  */
     643              :                   else
     644              :                     cpu = "skylake-avx512";
     645              :                 }
     646            0 :               else if (has_feature (FEATURE_AVX))
     647              :                 {
     648              :                   /* Assume Clearwater Forest.  */
     649            0 :                   if (has_feature (FEATURE_USER_MSR))
     650              :                     cpu = "clearwaterforest";
     651            0 :                   else if (has_feature (FEATURE_SM3))
     652              :                     {
     653            0 :                         if (has_feature (FEATURE_KL))
     654              :                           /* Assume Arrow Lake S.  */
     655              :                           cpu = "arrowlake-s";
     656              :                         else
     657              :                           /* Assume Panther Lake.  */
     658            0 :                           cpu = "pantherlake";
     659              :                     }
     660              :                   /* Assume Sierra Forest.  */
     661            0 :                   else if (has_feature (FEATURE_CLDEMOTE))
     662              :                     cpu = "sierraforest";
     663              :                   /* Assume Arrow Lake.  */
     664            0 :                   else if (has_feature (FEATURE_AVXVNNIINT8))
     665              :                     cpu = "arrowlake";
     666              :                   /* Assume Alder Lake.  */
     667            0 :                   else if (has_feature (FEATURE_SERIALIZE))
     668              :                     cpu = "alderlake";
     669              :                   /* Assume Skylake.  */
     670            0 :                   else if (has_feature (FEATURE_CLFLUSHOPT))
     671              :                     cpu = "skylake";
     672              :                   /* Assume Broadwell.  */
     673            0 :                   else if (has_feature (FEATURE_ADX))
     674              :                     cpu = "broadwell";
     675              :                   /* Assume Haswell.  */
     676            0 :                   else if (has_feature (FEATURE_AVX2))
     677              :                     cpu = "haswell";
     678              :                   /* Assume Sandy Bridge.  */
     679              :                   else
     680            0 :                     cpu = "sandybridge";
     681              :               }
     682            0 :               else if (has_feature (FEATURE_SSE4_2))
     683              :                 {
     684            0 :                   if (has_feature (FEATURE_GFNI))
     685              :                     /* Assume Tremont.  */
     686              :                     cpu = "tremont";
     687            0 :                   else if (has_feature (FEATURE_SGX))
     688              :                     /* Assume Goldmont Plus.  */
     689              :                     cpu = "goldmont-plus";
     690            0 :                   else if (has_feature (FEATURE_XSAVE))
     691              :                     /* Assume Goldmont.  */
     692              :                     cpu = "goldmont";
     693            0 :                   else if (has_feature (FEATURE_MOVBE))
     694              :                     /* Assume Silvermont.  */
     695              :                     cpu = "silvermont";
     696              :                   else
     697              :                     /* Assume Nehalem.  */
     698            0 :                     cpu = "nehalem";
     699              :                 }
     700            0 :               else if (has_feature (FEATURE_SSSE3))
     701              :                 {
     702            0 :                   if (has_feature (FEATURE_MOVBE))
     703              :                     /* Assume Bonnell.  */
     704              :                     cpu = "bonnell";
     705              :                   else
     706              :                     /* Assume Core 2.  */
     707            0 :                     cpu = "core2";
     708              :                 }
     709            0 :               else if (has_feature (FEATURE_LM))
     710              :                 /* Perhaps some emulator?  Assume x86-64, otherwise gcc
     711              :                    -march=native would be unusable for 64-bit compilations,
     712              :                    as all the CPUs below are 32-bit only.  */
     713              :                 cpu = "x86-64";
     714            0 :               else if (has_feature (FEATURE_SSE3))
     715              :                 {
     716            0 :                   if (vendor == VENDOR_CENTAUR)
     717              :                     /* C7 / Eden "Esther" */
     718              :                     cpu = "c7";
     719              :                   else
     720              :                     /* It is Core Duo.  */
     721            0 :                     cpu = "pentium-m";
     722              :                 }
     723            0 :               else if (has_feature (FEATURE_SSE2))
     724              :                 /* It is Pentium M.  */
     725              :                 cpu = "pentium-m";
     726            0 :               else if (has_feature (FEATURE_SSE))
     727              :                 {
     728            0 :                   if (vendor == VENDOR_CENTAUR)
     729              :                     {
     730            0 :                       if (model >= 9)
     731              :                         /* Eden "Nehemiah" */
     732              :                         cpu = "nehemiah";
     733              :                       else
     734            0 :                         cpu = "c3-2";
     735              :                     }
     736              :                   else
     737              :                     /* It is Pentium III.  */
     738              :                     cpu = "pentium3";
     739              :                 }
     740            0 :               else if (has_feature (FEATURE_MMX))
     741              :                 /* It is Pentium II.  */
     742              :                 cpu = "pentium2";
     743              :               else
     744              :                 /* Default to Pentium Pro.  */
     745            0 :                 cpu = "pentiumpro";
     746              :             }
     747              :           else
     748              :             /* For -mtune, we default to -mtune=generic.  */
     749              :             cpu = "generic";
     750              :         }
     751              :       break;
     752            0 :     case PROCESSOR_PENTIUM4:
     753            0 :       if (has_feature (FEATURE_SSE3))
     754              :         {
     755            0 :           if (has_feature (FEATURE_LM))
     756              :             cpu = "nocona";
     757              :           else
     758         1348 :             cpu = "prescott";
     759              :         }
     760              :       else
     761              :         cpu = "pentium4";
     762              :       break;
     763              :     case PROCESSOR_GEODE:
     764              :       cpu = "geode";
     765              :       break;
     766            0 :     case PROCESSOR_K6:
     767            0 :       if (arch && has_feature (FEATURE_3DNOW))
     768              :         cpu = "k6-3";
     769              :       else
     770              :         cpu = "k6";
     771              :       break;
     772            0 :     case PROCESSOR_ATHLON:
     773            0 :       if (arch && has_feature (FEATURE_SSE))
     774              :         cpu = "athlon-4";
     775              :       else
     776              :         cpu = "athlon";
     777              :       break;
     778            0 :     case PROCESSOR_K8:
     779            0 :       if (arch)
     780              :         {
     781            0 :           if (vendor == VENDOR_CENTAUR)
     782              :             {
     783            0 :               if (has_feature (FEATURE_SSE4_1))
     784              :                 /* Nano 3000 | Nano dual / quad core | Eden X4 */
     785              :                 cpu = "nano-3000";
     786            0 :               else if (has_feature (FEATURE_SSSE3))
     787              :                 /* Nano 1000 | Nano 2000 */
     788              :                 cpu = "nano";
     789            0 :               else if (has_feature (FEATURE_SSE3))
     790              :                 /* Eden X2 */
     791              :                 cpu = "eden-x2";
     792              :               else
     793              :                 /* Default to k8 */
     794            0 :                 cpu = "k8";
     795              :             }
     796            0 :           else if (has_feature (FEATURE_SSE3))
     797              :             cpu = "k8-sse3";
     798              :           else
     799            0 :             cpu = "k8";
     800              :         }
     801              :       else
     802              :         /* For -mtune, we default to -mtune=k8 */
     803              :         cpu = "k8";
     804              :       break;
     805              :     case PROCESSOR_AMDFAM10:
     806              :       cpu = "amdfam10";
     807              :       break;
     808              :     case PROCESSOR_BDVER1:
     809              :       cpu = "bdver1";
     810              :       break;
     811              :     case PROCESSOR_BDVER2:
     812              :       cpu = "bdver2";
     813              :       break;
     814              :     case PROCESSOR_BDVER3:
     815              :       cpu = "bdver3";
     816              :       break;
     817              :     case PROCESSOR_BDVER4:
     818              :       cpu = "bdver4";
     819              :       break;
     820              :     case PROCESSOR_ZNVER1:
     821              :       cpu = "znver1";
     822              :       break;
     823              :     case PROCESSOR_ZNVER2:
     824              :       cpu = "znver2";
     825              :       break;
     826              :     case PROCESSOR_ZNVER3:
     827              :       cpu = "znver3";
     828              :       break;
     829              :     case PROCESSOR_ZNVER4:
     830              :       cpu = "znver4";
     831              :       break;
     832              :     case PROCESSOR_ZNVER5:
     833              :       cpu = "znver5";
     834              :       break;
     835              :     case PROCESSOR_ZNVER6:
     836              :       cpu = "znver6";
     837              :       break;
     838              :     case PROCESSOR_BTVER1:
     839              :       cpu = "btver1";
     840              :       break;
     841              :     case PROCESSOR_BTVER2:
     842              :       cpu = "btver2";
     843              :       break;
     844              :     case PROCESSOR_LUJIAZUI:
     845              :       cpu = "lujiazui";
     846              :       break;
     847              :     case PROCESSOR_YONGFENG:
     848              :       cpu = "yongfeng";
     849              :       break;
     850              :     case PROCESSOR_SHIJIDADAO:
     851              :       cpu = "shijidadao";
     852              :       break;
     853              : 
     854            0 :     default:
     855              :       /* Use something reasonable.  */
     856            0 :       if (arch)
     857              :         {
     858            0 :           if (has_feature (FEATURE_SSSE3))
     859              :             cpu = "core2";
     860            0 :           else if (has_feature (FEATURE_SSE3))
     861              :             {
     862            0 :               if (has_feature (FEATURE_LM))
     863              :                 cpu = "nocona";
     864              :               else
     865         1348 :                 cpu = "prescott";
     866              :             }
     867            0 :           else if (has_feature (FEATURE_LM))
     868              :             /* Perhaps some emulator?  Assume x86-64, otherwise gcc
     869              :                -march=native would be unusable for 64-bit compilations,
     870              :                as all the CPUs below are 32-bit only.  */
     871              :             cpu = "x86-64";
     872            0 :           else if (has_feature (FEATURE_SSE2))
     873              :             cpu = "pentium4";
     874            0 :           else if (has_feature (FEATURE_CMOV))
     875              :             cpu = "pentiumpro";
     876            0 :           else if (has_feature (FEATURE_MMX))
     877              :             cpu = "pentium-mmx";
     878            0 :           else if (has_feature (FEATURE_CMPXCHG8B))
     879            0 :             cpu = "pentium";
     880              :         }
     881              :       else
     882              :         cpu = "generic";
     883              :     }
     884              : 
     885         1348 :   if (arch)
     886              :     {
     887              :       unsigned int i;
     888              :       const char *const neg_option = " -mno-";
     889       156429 :       for (i = 0; i < ARRAY_SIZE (isa_names_table); i++)
     890       155092 :         if (isa_names_table[i].option)
     891              :           {
     892       140385 :             if (has_feature (isa_names_table[i].feature))
     893              :               {
     894        52143 :                 if (codegen_x86_64
     895            0 :                     || (isa_names_table[i].feature != FEATURE_UINTR
     896            0 :                         && isa_names_table[i].feature != FEATURE_APX_F))
     897        52143 :                   options = concat (options, " ",
     898              :                                     isa_names_table[i].option, NULL);
     899              :               }
     900              :             else
     901        88242 :               options = concat (options, neg_option,
     902              :                                 isa_names_table[i].option + 2, NULL);
     903              :           }
     904              :     }
     905              : 
     906           11 : done:
     907         1348 :   return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
     908              : }
     909              : #else
     910              : 
     911              : /* If we are compiling with GCC where %EBX register is fixed, then the
     912              :    driver will just ignore -march and -mtune "native" target and will leave
     913              :    to the newly built compiler to generate code for its default target.  */
     914              : 
     915              : const char *host_detect_local_cpu (int, const char **)
     916              : {
     917              :   return NULL;
     918              : }
     919              : #endif /* __GNUC__ */
        

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.