LCOV - code coverage report
Current view: top level - gcc/config/i386 - driver-i386.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 21.5 % 390 84
Test Date: 2025-03-08 13:07:09 Functions: 55.6 % 9 5
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Subroutines for the gcc driver.
       2                 :             :    Copyright (C) 2006-2025 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                 :             : /* We will emit a warning when using AVX10.1 and AVX512 options with one
     378                 :             :    enabled and the other disabled.  Add this function to avoid push "-mno-"
     379                 :             :    options under this scenario for -march=native.  */
     380                 :             : 
     381                 :         715 : bool check_avx512_features (__processor_model &cpu_model,
     382                 :             :                             unsigned int (&cpu_features2)[SIZE_OF_CPU_FEATURES],
     383                 :             :                             const enum processor_features feature)
     384                 :             : {
     385                 :         715 :   if (has_feature (FEATURE_AVX10_1_256)
     386                 :         715 :       && ((feature == FEATURE_AVX512F)
     387                 :           0 :           || (feature == FEATURE_AVX512CD)
     388                 :             :           || (feature == FEATURE_AVX512DQ)
     389                 :             :           || (feature == FEATURE_AVX512BW)
     390                 :             :           || (feature == FEATURE_AVX512VL)
     391                 :             :           || (feature == FEATURE_AVX512IFMA)
     392                 :             :           || (feature == FEATURE_AVX512VBMI)
     393                 :             :           || (feature == FEATURE_AVX512VBMI2)
     394                 :             :           || (feature == FEATURE_AVX512VNNI)
     395                 :             :           || (feature == FEATURE_AVX512VPOPCNTDQ)
     396                 :             :           || (feature == FEATURE_AVX512BITALG)
     397                 :             :           || (feature == FEATURE_AVX512FP16)
     398                 :             :           || (feature == FEATURE_AVX512BF16)))
     399                 :           0 :     return false;
     400                 :             : 
     401                 :             :   return true;
     402                 :             : }
     403                 :             : 
     404                 :             : /* This will be called by the spec parser in gcc.cc when it sees
     405                 :             :    a %:local_cpu_detect(args) construct.  Currently it will be
     406                 :             :    called with either "arch [32|64]" or "tune [32|64]" as argument
     407                 :             :    depending on if -march=native or -mtune=native is to be substituted.
     408                 :             : 
     409                 :             :    It returns a string containing new command line parameters to be
     410                 :             :    put at the place of the above two options, depending on what CPU
     411                 :             :    this is executed.  E.g. "-march=k8" on an AMD64 machine
     412                 :             :    for -march=native.
     413                 :             : 
     414                 :             :    ARGC and ARGV are set depending on the actual arguments given
     415                 :             :    in the spec.  */
     416                 :             : 
     417                 :          22 : const char *host_detect_local_cpu (int argc, const char **argv)
     418                 :             : {
     419                 :          22 :   enum processor_type processor = PROCESSOR_I386;
     420                 :          22 :   const char *cpu = "i386";
     421                 :             : 
     422                 :          22 :   const char *cache = "";
     423                 :          22 :   const char *options = "";
     424                 :             : 
     425                 :          22 :   unsigned int ebx, ecx, edx;
     426                 :             : 
     427                 :          22 :   unsigned int max_level, ext_level;
     428                 :             : 
     429                 :          22 :   unsigned int vendor;
     430                 :          22 :   unsigned int model, family;
     431                 :             : 
     432                 :          22 :   bool arch;
     433                 :             : 
     434                 :          22 :   unsigned int l2sizekb = 0;
     435                 :             : 
     436                 :          22 :   if (argc < 2)
     437                 :             :     return NULL;
     438                 :             : 
     439                 :          22 :   arch = !strcmp (argv[0], "arch");
     440                 :             : 
     441                 :          22 :   if (!arch && strcmp (argv[0], "tune"))
     442                 :             :     return NULL;
     443                 :             : 
     444                 :          22 :   bool codegen_x86_64;
     445                 :             : 
     446                 :          22 :   if (!strcmp (argv[1], "32"))
     447                 :             :     codegen_x86_64 = false;
     448                 :          22 :   else if (!strcmp (argv[1], "64"))
     449                 :             :     codegen_x86_64 = true;
     450                 :             :   else
     451                 :             :     return NULL;
     452                 :             : 
     453                 :          22 :   struct __processor_model cpu_model = { };
     454                 :          22 :   struct __processor_model2 cpu_model2 = { };
     455                 :          22 :   unsigned int cpu_features2[SIZE_OF_CPU_FEATURES] = { };
     456                 :             : 
     457                 :          22 :   if (cpu_indicator_init (&cpu_model, &cpu_model2, cpu_features2) != 0)
     458                 :           0 :     goto done;
     459                 :             : 
     460                 :          22 :   vendor = cpu_model.__cpu_vendor;
     461                 :          22 :   family = cpu_model2.__cpu_family;
     462                 :          22 :   model = cpu_model2.__cpu_model;
     463                 :          22 :   max_level = cpu_model2.__cpu_max_level;
     464                 :          22 :   ext_level = cpu_model2.__cpu_ext_level;
     465                 :             : 
     466                 :          22 :   if (!arch)
     467                 :             :     {
     468                 :          11 :       if (vendor == VENDOR_AMD
     469                 :          11 :           || vendor == VENDOR_CENTAUR
     470                 :             :           || vendor == VENDOR_CYRIX
     471                 :           0 :           || vendor == VENDOR_NSC)
     472                 :          11 :         cache = detect_caches_amd (ext_level);
     473                 :           0 :       else if (vendor == VENDOR_INTEL
     474                 :           0 :                          || vendor == VENDOR_ZHAOXIN)
     475                 :             :         {
     476                 :           0 :           bool xeon_mp = (family == 15 && model == 6);
     477                 :           0 :           cache = detect_caches_intel (xeon_mp, max_level,
     478                 :             :                                        ext_level, &l2sizekb);
     479                 :             :         }
     480                 :             :     }
     481                 :             : 
     482                 :          22 :   if (vendor == VENDOR_AMD)
     483                 :             :     {
     484                 :          22 :       unsigned int name;
     485                 :             : 
     486                 :             :       /* Detect geode processor by its processor signature.  */
     487                 :          22 :       if (ext_level >= 0x80000002)
     488                 :          22 :         __cpuid (0x80000002, name, ebx, ecx, edx);
     489                 :             :       else
     490                 :             :         name = 0;
     491                 :             : 
     492                 :          22 :       if (name == signature_NSC_ebx)
     493                 :             :         processor = PROCESSOR_GEODE;
     494                 :          22 :       else if (has_feature (FEATURE_MOVBE) && family == 22)
     495                 :             :         processor = PROCESSOR_BTVER2;
     496                 :          22 :       else if (has_feature (FEATURE_AVX512VP2INTERSECT))
     497                 :             :         processor = PROCESSOR_ZNVER5;
     498                 :          22 :       else if (has_feature (FEATURE_AVX512F))
     499                 :             :         processor = PROCESSOR_ZNVER4;
     500                 :          22 :       else if (has_feature (FEATURE_VAES))
     501                 :             :         processor = PROCESSOR_ZNVER3;
     502                 :          22 :       else if (has_feature (FEATURE_CLWB))
     503                 :             :         processor = PROCESSOR_ZNVER2;
     504                 :           0 :       else if (has_feature (FEATURE_CLZERO))
     505                 :             :         processor = PROCESSOR_ZNVER1;
     506                 :           0 :       else if (has_feature (FEATURE_AVX2))
     507                 :             :         processor = PROCESSOR_BDVER4;
     508                 :           0 :       else if (has_feature (FEATURE_XSAVEOPT))
     509                 :             :         processor = PROCESSOR_BDVER3;
     510                 :           0 :       else if (has_feature (FEATURE_BMI))
     511                 :             :         processor = PROCESSOR_BDVER2;
     512                 :           0 :       else if (has_feature (FEATURE_XOP))
     513                 :             :         processor = PROCESSOR_BDVER1;
     514                 :           0 :       else if (has_feature (FEATURE_SSE4_A)
     515                 :           0 :                && has_feature (FEATURE_SSSE3))
     516                 :             :         processor = PROCESSOR_BTVER1;
     517                 :           0 :       else if (has_feature (FEATURE_SSE4_A))
     518                 :             :         processor = PROCESSOR_AMDFAM10;
     519                 :           0 :       else if (has_feature (FEATURE_SSE2)
     520                 :           0 :                || has_feature (FEATURE_LM))
     521                 :             :         processor = PROCESSOR_K8;
     522                 :           0 :       else if (has_feature (FEATURE_3DNOWP) && family == 6)
     523                 :             :         processor = PROCESSOR_ATHLON;
     524                 :           0 :       else if (has_feature (FEATURE_MMX))
     525                 :             :         processor = PROCESSOR_K6;
     526                 :             :       else
     527                 :             :         processor = PROCESSOR_PENTIUM;
     528                 :             :     }
     529                 :           0 :   else if (vendor == VENDOR_CENTAUR)
     530                 :             :     {
     531                 :           0 :       processor = PROCESSOR_GENERIC;
     532                 :             : 
     533                 :           0 :       switch (family)
     534                 :             :         {
     535                 :             :         default:
     536                 :             :           /* We have no idea.  */
     537                 :             :           break;
     538                 :             : 
     539                 :           0 :         case 5:
     540                 :           0 :           if (has_feature (FEATURE_3DNOW)
     541                 :           0 :               || has_feature (FEATURE_MMX))
     542                 :             :             processor = PROCESSOR_I486;
     543                 :             :           break;
     544                 :             : 
     545                 :           0 :         case 6:
     546                 :           0 :           if (has_feature (FEATURE_LM))
     547                 :             :             processor = PROCESSOR_K8;
     548                 :           0 :           else if (model >= 9)
     549                 :             :             processor = PROCESSOR_PENTIUMPRO;
     550                 :           0 :           else if (model >= 6)
     551                 :             :             processor = PROCESSOR_I486;
     552                 :             :         }
     553                 :             :     }
     554                 :           0 :   else if (vendor == VENDOR_ZHAOXIN)
     555                 :             :     {
     556                 :           0 :       processor = PROCESSOR_GENERIC;
     557                 :             : 
     558                 :           0 :       switch (family)
     559                 :             :         {
     560                 :           0 :         case 7:
     561                 :           0 :           if (model >= 0x6b)
     562                 :             :             processor = PROCESSOR_SHIJIDADAO;
     563                 :           0 :           else if (model == 0x5b)
     564                 :             :             processor = PROCESSOR_YONGFENG;
     565                 :           0 :           else if (model == 0x3b)
     566                 :             :             processor = PROCESSOR_LUJIAZUI;
     567                 :             :           break;
     568                 :             :         default:
     569                 :             :           break;
     570                 :             :         }
     571                 :             :     }
     572                 :             :   else
     573                 :             :     {
     574                 :           0 :       switch (family)
     575                 :             :         {
     576                 :             :         case 4:
     577                 :             :           processor = PROCESSOR_I486;
     578                 :             :           break;
     579                 :             :         case 5:
     580                 :             :           processor = PROCESSOR_PENTIUM;
     581                 :             :           break;
     582                 :             :         case 6:
     583                 :             :         case 19:
     584                 :             :           processor = PROCESSOR_PENTIUMPRO;
     585                 :             :           break;
     586                 :           0 :         case 15:
     587                 :           0 :           processor = PROCESSOR_PENTIUM4;
     588                 :           0 :           break;
     589                 :             :         default:
     590                 :             :           /* We have no idea.  */
     591                 :             :           processor = PROCESSOR_GENERIC;
     592                 :             :         }
     593                 :             :     }
     594                 :             : 
     595                 :           0 :   switch (processor)
     596                 :             :     {
     597                 :             :     case PROCESSOR_I386:
     598                 :             :       /* Default.  */
     599                 :             :       break;
     600                 :           0 :     case PROCESSOR_I486:
     601                 :           0 :       if (arch && vendor == VENDOR_CENTAUR)
     602                 :             :         {
     603                 :           0 :           if (model >= 6)
     604                 :             :             cpu = "c3";
     605                 :           0 :           else if (has_feature (FEATURE_3DNOW))
     606                 :             :             cpu = "winchip2";
     607                 :             :           else
     608                 :             :             /* Assume WinChip C6.  */
     609                 :           0 :             cpu = "winchip-c6";
     610                 :             :         }
     611                 :             :       else
     612                 :             :         cpu = "i486";
     613                 :             :       break;
     614                 :           0 :     case PROCESSOR_PENTIUM:
     615                 :           0 :       if (arch && has_feature (FEATURE_MMX))
     616                 :             :         cpu = "pentium-mmx";
     617                 :             :       else
     618                 :             :         cpu = "pentium";
     619                 :             :       break;
     620                 :           0 :     case PROCESSOR_PENTIUMPRO:
     621                 :           0 :       cpu = get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2);
     622                 :           0 :       if (cpu == NULL)
     623                 :             :         {
     624                 :           0 :           if (arch)
     625                 :             :             {
     626                 :             :               /* This is unknown CPU.  */
     627                 :           0 :               if (has_feature (FEATURE_AVX512F))
     628                 :             :                 {
     629                 :             :                   /* Assume Diamond Rapids.  */
     630                 :           0 :                   if (has_feature (FEATURE_AVX10_2_512))
     631                 :             :                     cpu = "diamondrapids";
     632                 :             :                   /* Assume Granite Rapids D.  */
     633                 :           0 :                   else if (has_feature (FEATURE_AMX_COMPLEX))
     634                 :             :                     cpu = "graniterapids-d";
     635                 :             :                   /* Assume Granite Rapids.  */
     636                 :           0 :                   else if (has_feature (FEATURE_AMX_FP16))
     637                 :             :                     cpu = "graniterapids";
     638                 :             :                   /* Assume Tiger Lake */
     639                 :           0 :                   else if (has_feature (FEATURE_AVX512VP2INTERSECT))
     640                 :             :                     cpu = "tigerlake";
     641                 :             :                   /* Assume Sapphire Rapids.  */
     642                 :           0 :                   else if (has_feature (FEATURE_TSXLDTRK))
     643                 :             :                     cpu = "sapphirerapids";
     644                 :             :                   /* Assume Cooper Lake */
     645                 :           0 :                   else if (has_feature (FEATURE_AVX512BF16))
     646                 :             :                     cpu = "cooperlake";
     647                 :             :                   /* Assume Ice Lake Server.  */
     648                 :           0 :                   else if (has_feature (FEATURE_WBNOINVD))
     649                 :             :                     cpu = "icelake-server";
     650                 :             :                   /* Assume Ice Lake.  */
     651                 :           0 :                   else if (has_feature (FEATURE_AVX512BITALG))
     652                 :             :                     cpu = "icelake-client";
     653                 :             :                   /* Assume Cannon Lake.  */
     654                 :           0 :                   else if (has_feature (FEATURE_AVX512VBMI))
     655                 :             :                     cpu = "cannonlake";
     656                 :             :                   /* Assume Xeon Phi Processors.  Support has been removed
     657                 :             :                      since GCC 15.  */
     658                 :           0 :                   else if (!has_feature (FEATURE_AVX512VL))
     659                 :           0 :                     error ("Xeon Phi ISA support has been removed since "
     660                 :             :                            "GCC 15, use GCC 14 for the Xeon Phi ISAs or "
     661                 :             :                            "%<-march=broadwell%> for all the other ISAs "
     662                 :             :                            "supported on this machine.");
     663                 :             :                   /* Assume Skylake with AVX-512.  */
     664                 :             :                   else
     665                 :             :                     cpu = "skylake-avx512";
     666                 :             :                 }
     667                 :           0 :               else if (has_feature (FEATURE_AVX))
     668                 :             :                 {
     669                 :             :                   /* Assume Panther Lake.  */
     670                 :           0 :                   if (has_feature (FEATURE_PREFETCHI))
     671                 :             :                     cpu = "pantherlake";
     672                 :             :                   /* Assume Clearwater Forest.  */
     673                 :           0 :                   else if (has_feature (FEATURE_USER_MSR))
     674                 :             :                     cpu = "clearwaterforest";
     675                 :             :                   /* Assume Arrow Lake S.  */
     676                 :           0 :                   else if (has_feature (FEATURE_SM3))
     677                 :             :                     cpu = "arrowlake-s";
     678                 :             :                   /* Assume Sierra Forest.  */
     679                 :           0 :                   else if (has_feature (FEATURE_AVXVNNIINT8))
     680                 :             :                     cpu = "sierraforest";
     681                 :             :                   /* Assume Alder Lake.  */
     682                 :           0 :                   else if (has_feature (FEATURE_SERIALIZE))
     683                 :             :                     cpu = "alderlake";
     684                 :             :                   /* Assume Skylake.  */
     685                 :           0 :                   else if (has_feature (FEATURE_CLFLUSHOPT))
     686                 :             :                     cpu = "skylake";
     687                 :             :                   /* Assume Broadwell.  */
     688                 :           0 :                   else if (has_feature (FEATURE_ADX))
     689                 :             :                     cpu = "broadwell";
     690                 :             :                   /* Assume Haswell.  */
     691                 :           0 :                   else if (has_feature (FEATURE_AVX2))
     692                 :             :                     cpu = "haswell";
     693                 :             :                   /* Assume Sandy Bridge.  */
     694                 :             :                   else
     695                 :           0 :                     cpu = "sandybridge";
     696                 :             :               }
     697                 :           0 :               else if (has_feature (FEATURE_SSE4_2))
     698                 :             :                 {
     699                 :           0 :                   if (has_feature (FEATURE_GFNI))
     700                 :             :                     /* Assume Tremont.  */
     701                 :             :                     cpu = "tremont";
     702                 :           0 :                   else if (has_feature (FEATURE_SGX))
     703                 :             :                     /* Assume Goldmont Plus.  */
     704                 :             :                     cpu = "goldmont-plus";
     705                 :           0 :                   else if (has_feature (FEATURE_XSAVE))
     706                 :             :                     /* Assume Goldmont.  */
     707                 :             :                     cpu = "goldmont";
     708                 :           0 :                   else if (has_feature (FEATURE_MOVBE))
     709                 :             :                     /* Assume Silvermont.  */
     710                 :             :                     cpu = "silvermont";
     711                 :             :                   else
     712                 :             :                     /* Assume Nehalem.  */
     713                 :           0 :                     cpu = "nehalem";
     714                 :             :                 }
     715                 :           0 :               else if (has_feature (FEATURE_SSSE3))
     716                 :             :                 {
     717                 :           0 :                   if (has_feature (FEATURE_MOVBE))
     718                 :             :                     /* Assume Bonnell.  */
     719                 :             :                     cpu = "bonnell";
     720                 :             :                   else
     721                 :             :                     /* Assume Core 2.  */
     722                 :           0 :                     cpu = "core2";
     723                 :             :                 }
     724                 :           0 :               else if (has_feature (FEATURE_LM))
     725                 :             :                 /* Perhaps some emulator?  Assume x86-64, otherwise gcc
     726                 :             :                    -march=native would be unusable for 64-bit compilations,
     727                 :             :                    as all the CPUs below are 32-bit only.  */
     728                 :             :                 cpu = "x86-64";
     729                 :           0 :               else if (has_feature (FEATURE_SSE3))
     730                 :             :                 {
     731                 :           0 :                   if (vendor == VENDOR_CENTAUR)
     732                 :             :                     /* C7 / Eden "Esther" */
     733                 :             :                     cpu = "c7";
     734                 :             :                   else
     735                 :             :                     /* It is Core Duo.  */
     736                 :           0 :                     cpu = "pentium-m";
     737                 :             :                 }
     738                 :           0 :               else if (has_feature (FEATURE_SSE2))
     739                 :             :                 /* It is Pentium M.  */
     740                 :             :                 cpu = "pentium-m";
     741                 :           0 :               else if (has_feature (FEATURE_SSE))
     742                 :             :                 {
     743                 :           0 :                   if (vendor == VENDOR_CENTAUR)
     744                 :             :                     {
     745                 :           0 :                       if (model >= 9)
     746                 :             :                         /* Eden "Nehemiah" */
     747                 :             :                         cpu = "nehemiah";
     748                 :             :                       else
     749                 :           0 :                         cpu = "c3-2";
     750                 :             :                     }
     751                 :             :                   else
     752                 :             :                     /* It is Pentium III.  */
     753                 :             :                     cpu = "pentium3";
     754                 :             :                 }
     755                 :           0 :               else if (has_feature (FEATURE_MMX))
     756                 :             :                 /* It is Pentium II.  */
     757                 :             :                 cpu = "pentium2";
     758                 :             :               else
     759                 :             :                 /* Default to Pentium Pro.  */
     760                 :           0 :                 cpu = "pentiumpro";
     761                 :             :             }
     762                 :             :           else
     763                 :             :             /* For -mtune, we default to -mtune=generic.  */
     764                 :             :             cpu = "generic";
     765                 :             :         }
     766                 :             :       break;
     767                 :           0 :     case PROCESSOR_PENTIUM4:
     768                 :           0 :       if (has_feature (FEATURE_SSE3))
     769                 :             :         {
     770                 :           0 :           if (has_feature (FEATURE_LM))
     771                 :             :             cpu = "nocona";
     772                 :             :           else
     773                 :          22 :             cpu = "prescott";
     774                 :             :         }
     775                 :             :       else
     776                 :             :         cpu = "pentium4";
     777                 :             :       break;
     778                 :             :     case PROCESSOR_GEODE:
     779                 :             :       cpu = "geode";
     780                 :             :       break;
     781                 :           0 :     case PROCESSOR_K6:
     782                 :           0 :       if (arch && has_feature (FEATURE_3DNOW))
     783                 :             :         cpu = "k6-3";
     784                 :             :       else
     785                 :             :         cpu = "k6";
     786                 :             :       break;
     787                 :           0 :     case PROCESSOR_ATHLON:
     788                 :           0 :       if (arch && has_feature (FEATURE_SSE))
     789                 :             :         cpu = "athlon-4";
     790                 :             :       else
     791                 :             :         cpu = "athlon";
     792                 :             :       break;
     793                 :           0 :     case PROCESSOR_K8:
     794                 :           0 :       if (arch)
     795                 :             :         {
     796                 :           0 :           if (vendor == VENDOR_CENTAUR)
     797                 :             :             {
     798                 :           0 :               if (has_feature (FEATURE_SSE4_1))
     799                 :             :                 /* Nano 3000 | Nano dual / quad core | Eden X4 */
     800                 :             :                 cpu = "nano-3000";
     801                 :           0 :               else if (has_feature (FEATURE_SSSE3))
     802                 :             :                 /* Nano 1000 | Nano 2000 */
     803                 :             :                 cpu = "nano";
     804                 :           0 :               else if (has_feature (FEATURE_SSE3))
     805                 :             :                 /* Eden X2 */
     806                 :             :                 cpu = "eden-x2";
     807                 :             :               else
     808                 :             :                 /* Default to k8 */
     809                 :           0 :                 cpu = "k8";
     810                 :             :             }
     811                 :           0 :           else if (has_feature (FEATURE_SSE3))
     812                 :             :             cpu = "k8-sse3";
     813                 :             :           else
     814                 :           0 :             cpu = "k8";
     815                 :             :         }
     816                 :             :       else
     817                 :             :         /* For -mtune, we default to -mtune=k8 */
     818                 :             :         cpu = "k8";
     819                 :             :       break;
     820                 :             :     case PROCESSOR_AMDFAM10:
     821                 :             :       cpu = "amdfam10";
     822                 :             :       break;
     823                 :             :     case PROCESSOR_BDVER1:
     824                 :             :       cpu = "bdver1";
     825                 :             :       break;
     826                 :             :     case PROCESSOR_BDVER2:
     827                 :             :       cpu = "bdver2";
     828                 :             :       break;
     829                 :             :     case PROCESSOR_BDVER3:
     830                 :             :       cpu = "bdver3";
     831                 :             :       break;
     832                 :             :     case PROCESSOR_BDVER4:
     833                 :             :       cpu = "bdver4";
     834                 :             :       break;
     835                 :             :     case PROCESSOR_ZNVER1:
     836                 :             :       cpu = "znver1";
     837                 :             :       break;
     838                 :             :     case PROCESSOR_ZNVER2:
     839                 :             :       cpu = "znver2";
     840                 :             :       break;
     841                 :             :     case PROCESSOR_ZNVER3:
     842                 :             :       cpu = "znver3";
     843                 :             :       break;
     844                 :             :     case PROCESSOR_ZNVER4:
     845                 :             :       cpu = "znver4";
     846                 :             :       break;
     847                 :             :     case PROCESSOR_ZNVER5:
     848                 :             :       cpu = "znver5";
     849                 :             :       break;
     850                 :             :     case PROCESSOR_BTVER1:
     851                 :             :       cpu = "btver1";
     852                 :             :       break;
     853                 :             :     case PROCESSOR_BTVER2:
     854                 :             :       cpu = "btver2";
     855                 :             :       break;
     856                 :             :     case PROCESSOR_LUJIAZUI:
     857                 :             :       cpu = "lujiazui";
     858                 :             :       break;
     859                 :             :     case PROCESSOR_YONGFENG:
     860                 :             :       cpu = "yongfeng";
     861                 :             :       break;
     862                 :             :     case PROCESSOR_SHIJIDADAO:
     863                 :             :       cpu = "shijidadao";
     864                 :             :       break;
     865                 :             : 
     866                 :           0 :     default:
     867                 :             :       /* Use something reasonable.  */
     868                 :           0 :       if (arch)
     869                 :             :         {
     870                 :           0 :           if (has_feature (FEATURE_SSSE3))
     871                 :             :             cpu = "core2";
     872                 :           0 :           else if (has_feature (FEATURE_SSE3))
     873                 :             :             {
     874                 :           0 :               if (has_feature (FEATURE_LM))
     875                 :             :                 cpu = "nocona";
     876                 :             :               else
     877                 :          22 :                 cpu = "prescott";
     878                 :             :             }
     879                 :           0 :           else if (has_feature (FEATURE_LM))
     880                 :             :             /* Perhaps some emulator?  Assume x86-64, otherwise gcc
     881                 :             :                -march=native would be unusable for 64-bit compilations,
     882                 :             :                as all the CPUs below are 32-bit only.  */
     883                 :             :             cpu = "x86-64";
     884                 :           0 :           else if (has_feature (FEATURE_SSE2))
     885                 :             :             cpu = "pentium4";
     886                 :           0 :           else if (has_feature (FEATURE_CMOV))
     887                 :             :             cpu = "pentiumpro";
     888                 :           0 :           else if (has_feature (FEATURE_MMX))
     889                 :             :             cpu = "pentium-mmx";
     890                 :           0 :           else if (has_feature (FEATURE_CMPXCHG8B))
     891                 :           0 :             cpu = "pentium";
     892                 :             :         }
     893                 :             :       else
     894                 :             :         cpu = "generic";
     895                 :             :     }
     896                 :             : 
     897                 :          22 :   if (arch)
     898                 :             :     {
     899                 :             :       unsigned int i;
     900                 :             :       const char *const neg_option = " -mno-";
     901                 :        1320 :       for (i = 0; i < ARRAY_SIZE (isa_names_table); i++)
     902                 :        1309 :         if (isa_names_table[i].option)
     903                 :             :           {
     904                 :        1177 :             if (has_feature (isa_names_table[i].feature))
     905                 :             :               {
     906                 :         429 :                 if (codegen_x86_64
     907                 :           0 :                     || (isa_names_table[i].feature != FEATURE_UINTR
     908                 :           0 :                         && isa_names_table[i].feature != FEATURE_APX_F))
     909                 :         429 :                   options = concat (options, " ",
     910                 :             :                                     isa_names_table[i].option, NULL);
     911                 :             :               }
     912                 :             :             /* Never push -mno-avx10.1-{256,512} under -march=native to
     913                 :             :                avoid unnecessary warnings when building libraries.
     914                 :             :                Never push -mno-avx10.x-256 under -march=native since
     915                 :             :                there are no such options.  */
     916                 :         748 :             else if (isa_names_table[i].feature != FEATURE_AVX10_1_256
     917                 :             :                      && isa_names_table[i].feature != FEATURE_AVX10_1_512
     918                 :         748 :                      && isa_names_table[i].feature != FEATURE_AVX10_2_256
     919                 :         748 :                      && check_avx512_features (cpu_model, cpu_features2,
     920                 :             :                                                isa_names_table[i].feature))
     921                 :         715 :               options = concat (options, neg_option,
     922                 :             :                                 isa_names_table[i].option + 2, NULL);
     923                 :             :           }
     924                 :             :     }
     925                 :             : 
     926                 :          11 : done:
     927                 :          22 :   return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
     928                 :             : }
     929                 :             : #else
     930                 :             : 
     931                 :             : /* If we are compiling with GCC where %EBX register is fixed, then the
     932                 :             :    driver will just ignore -march and -mtune "native" target and will leave
     933                 :             :    to the newly built compiler to generate code for its default target.  */
     934                 :             : 
     935                 :             : const char *host_detect_local_cpu (int, const char **)
     936                 :             : {
     937                 :             :   return NULL;
     938                 :             : }
     939                 :             : #endif /* __GNUC__ */
        

Generated by: LCOV version 2.1-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.