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