[BACK]Return to driver-aarch64.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / gcc / dist / gcc / config / aarch64

Annotation of src/external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c, Revision 1.12

1.1       mrg         1: /* Native CPU detection for aarch64.
1.11      mrg         2:    Copyright (C) 2015-2020 Free Software Foundation, Inc.
1.1       mrg         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:
1.5       mrg        20: #define IN_TARGET_CODE 1
                     21:
1.1       mrg        22: #include "config.h"
                     23: #define INCLUDE_STRING
1.11      mrg        24: #define INCLUDE_SET
1.1       mrg        25: #include "system.h"
                     26: #include "coretypes.h"
                     27: #include "tm.h"
1.2       mrg        28: #include "diagnostic-core.h"
1.1       mrg        29:
                     30: /* Defined in common/config/aarch64/aarch64-common.c.  */
1.11      mrg        31: std::string aarch64_get_extension_string_for_isa_flags (uint64_t, uint64_t);
1.1       mrg        32:
                     33: struct aarch64_arch_extension
                     34: {
                     35:   const char *ext;
1.11      mrg        36:   uint64_t flag;
1.1       mrg        37:   const char *feat_string;
                     38: };
                     39:
1.6       mrg        40: #define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \
                     41:                              SYNTHETIC, FEATURE_STRING) \
1.1       mrg        42:   { EXT_NAME, FLAG_CANONICAL, FEATURE_STRING },
                     43: static struct aarch64_arch_extension aarch64_extensions[] =
                     44: {
                     45: #include "aarch64-option-extensions.def"
                     46: };
                     47:
                     48:
                     49: struct aarch64_core_data
                     50: {
                     51:   const char* name;
                     52:   const char* arch;
1.3       mrg        53:   unsigned char implementer_id; /* Exactly 8 bits */
                     54:   unsigned int part_no; /* 12 bits + 12 bits */
                     55:   unsigned variant;
1.11      mrg        56:   const uint64_t flags;
1.1       mrg        57: };
                     58:
1.3       mrg        59: #define AARCH64_BIG_LITTLE(BIG, LITTLE) \
                     60:   (((BIG)&0xFFFu) << 12 | ((LITTLE) & 0xFFFu))
                     61: #define INVALID_IMP ((unsigned char) -1)
                     62: #define INVALID_CORE ((unsigned)-1)
                     63: #define ALL_VARIANTS ((unsigned)-1)
                     64:
                     65: #define AARCH64_CORE(CORE_NAME, CORE_IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART, VARIANT) \
                     66:   { CORE_NAME, #ARCH, IMP, PART, VARIANT, FLAGS },
1.1       mrg        67:
                     68: static struct aarch64_core_data aarch64_cpu_data[] =
                     69: {
                     70: #include "aarch64-cores.def"
1.3       mrg        71:   { NULL, NULL, INVALID_IMP, INVALID_CORE, ALL_VARIANTS, 0 }
1.1       mrg        72: };
                     73:
                     74:
                     75: struct aarch64_arch_driver_info
                     76: {
                     77:   const char* id;
                     78:   const char* name;
1.11      mrg        79:   const uint64_t flags;
1.1       mrg        80: };
                     81:
                     82: #define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH_REV, FLAGS) \
                     83:   { #ARCH_IDENT, NAME, FLAGS },
                     84:
                     85: static struct aarch64_arch_driver_info aarch64_arches[] =
                     86: {
                     87: #include "aarch64-arches.def"
                     88:   {NULL, NULL, 0}
                     89: };
                     90:
                     91:
                     92: /* Return an aarch64_arch_driver_info for the architecture described
                     93:    by ID, or NULL if ID describes something we don't know about.  */
                     94:
                     95: static struct aarch64_arch_driver_info*
                     96: get_arch_from_id (const char* id)
                     97: {
                     98:   unsigned int i = 0;
                     99:
                    100:   for (i = 0; aarch64_arches[i].id != NULL; i++)
                    101:     {
                    102:       if (strcmp (id, aarch64_arches[i].id) == 0)
                    103:        return &aarch64_arches[i];
                    104:     }
                    105:
                    106:   return NULL;
                    107: }
                    108:
1.3       mrg       109: /* Check wether the CORE array is the same as the big.LITTLE BL_CORE.
                    110:    For an example CORE={0xd08, 0xd03} and
                    111:    BL_CORE=AARCH64_BIG_LITTLE (0xd08, 0xd03) will return true.  */
1.1       mrg       112:
                    113: static bool
1.3       mrg       114: valid_bL_core_p (unsigned int *core, unsigned int bL_core)
1.1       mrg       115: {
1.3       mrg       116:   return AARCH64_BIG_LITTLE (core[0], core[1]) == bL_core
                    117:          || AARCH64_BIG_LITTLE (core[1], core[0]) == bL_core;
                    118: }
                    119:
                    120: /* Returns the hex integer that is after ':' for the FIELD.
                    121:    Returns -1 is returned if there was problem parsing the integer. */
                    122: static unsigned
1.11      mrg       123: parse_field (const std::string &field)
1.3       mrg       124: {
1.11      mrg       125:   const char *rest = strchr (field.c_str (), ':');
                    126:
                    127:   /* The line must be in the format of <name>:<value>, if it's not
                    128:      then we have a weird format.  */
                    129:   if (rest == NULL)
                    130:     return -1;
                    131:
1.3       mrg       132:   char *after;
                    133:   unsigned fint = strtol (rest + 1, &after, 16);
                    134:   if (after == rest + 1)
                    135:     return -1;
                    136:   return fint;
1.1       mrg       137: }
                    138:
1.11      mrg       139: /* Returns the index of the ':' inside the FIELD which must be found
                    140:    after the value of KEY.  Returns string::npos if line does not contain
                    141:    a field.  */
                    142:
                    143: static size_t
                    144: find_field (const std::string &field, const std::string &key)
                    145: {
                    146:   size_t key_pos, sep_pos;
                    147:   key_pos = field.find (key);
                    148:   if (key_pos == std::string::npos)
                    149:     return std::string::npos;
                    150:
                    151:   sep_pos = field.find (":", key_pos + 1);
                    152:   if (sep_pos == std::string::npos)
                    153:     return std::string::npos;
                    154:
                    155:   return sep_pos;
                    156: }
                    157:
                    158: /* Splits and returns a string based on whitespace and return it as
                    159:    part of a set. Empty strings are ignored.  */
                    160:
                    161: static void
                    162: split_words (const std::string &val, std::set<std::string> &result)
                    163: {
                    164:   size_t cur, prev = 0;
                    165:   std::string word;
                    166:   while ((cur = val.find_first_of (" \n", prev)) != std::string::npos)
                    167:     {
                    168:       word = val.substr (prev, cur - prev);
                    169:       /* Skip adding empty words.  */
                    170:       if (!word.empty ())
                    171:        result.insert (word);
                    172:       prev = cur + 1;
                    173:     }
                    174:
                    175:   if (prev != cur)
                    176:     result.insert (val.substr (prev));
                    177: }
                    178:
                    179: /* Read an entire line from F until '\n' or EOF.  */
                    180:
                    181: static std::string
                    182: readline (FILE *f)
                    183: {
                    184:   char *buf = NULL;
                    185:   int size = 0;
                    186:   int last = 0;
                    187:   const int buf_size = 128;
                    188:
                    189:   if (feof (f))
                    190:     return std::string ();
                    191:
                    192:   do
                    193:     {
                    194:       size += buf_size;
                    195:       buf = (char*) xrealloc (buf, size);
                    196:       gcc_assert (buf);
                    197:       /* If fgets fails it returns NULL, but if it reaches EOF
                    198:         with 0 characters read it also returns EOF.  However
                    199:         the condition on the loop would have broken out of the
                    200:         loop in that case,  and if we are in the first iteration
                    201:         then the empty string is the correct thing to return.  */
                    202:       if (!fgets (buf + last, buf_size, f))
                    203:        return std::string ();
                    204:       /* If we're not at the end of the line then override the
                    205:         \0 added by fgets.  */
                    206:       last = strnlen (buf, size) - 1;
                    207:     }
                    208:   while (!feof (f) && buf[last] != '\n');
                    209:
                    210:   std::string result (buf);
                    211:   free (buf);
                    212:   return result;
                    213: }
                    214:
1.3       mrg       215: /*  Return true iff ARR contains CORE, in either of the two elements. */
1.1       mrg       216:
                    217: static bool
1.3       mrg       218: contains_core_p (unsigned *arr, unsigned core)
1.1       mrg       219: {
1.3       mrg       220:   if (arr[0] != INVALID_CORE)
1.1       mrg       221:     {
1.3       mrg       222:       if (arr[0] == core)
                    223:         return true;
1.1       mrg       224:
1.3       mrg       225:       if (arr[1] != INVALID_CORE)
                    226:         return arr[1] == core;
1.1       mrg       227:     }
                    228:
                    229:   return false;
                    230: }
                    231:
                    232: /* This will be called by the spec parser in gcc.c when it sees
                    233:    a %:local_cpu_detect(args) construct.  Currently it will be called
                    234:    with either "arch", "cpu" or "tune" as argument depending on if
                    235:    -march=native, -mcpu=native or -mtune=native is to be substituted.
                    236:
                    237:    It returns a string containing new command line parameters to be
                    238:    put at the place of the above two options, depending on what CPU
                    239:    this is executed.  E.g. "-march=armv8-a" on a Cortex-A57 for
                    240:    -march=native.  If the routine can't detect a known processor,
                    241:    the -march or -mtune option is discarded.
                    242:
                    243:    For -mtune and -mcpu arguments it attempts to detect the CPU or
                    244:    a big.LITTLE system.
                    245:    ARGC and ARGV are set depending on the actual arguments given
                    246:    in the spec.  */
                    247:
1.2       mrg       248: #ifdef __NetBSD__
                    249: /* The NetBSD/arm64 platform does not export linux-style cpuinfo,
                    250:    but the data is available via a sysctl(3) interface.  */
                    251: #include <sys/param.h>
                    252: #include <sys/sysctl.h>
                    253: #include <aarch64/armreg.h>
1.4       mrg       254: #endif
1.2       mrg       255:
                    256: const char *
                    257: host_detect_local_cpu (int argc, const char **argv)
                    258: {
                    259:   const char *res = NULL;
                    260:   static const int num_exts = ARRAY_SIZE (aarch64_extensions);
1.10      rin       261:   FILE *f = NULL;
1.2       mrg       262:   bool arch = false;
                    263:   bool tune = false;
                    264:   bool cpu = false;
1.1       mrg       265:   unsigned int i = 0;
1.10      rin       266:   unsigned char imp = INVALID_IMP;
1.3       mrg       267:   unsigned int cores[2] = { INVALID_CORE, INVALID_CORE };
1.1       mrg       268:   unsigned int n_cores = 0;
1.3       mrg       269:   unsigned int variants[2] = { ALL_VARIANTS, ALL_VARIANTS };
                    270:   unsigned int n_variants = 0;
1.1       mrg       271:   bool processed_exts = false;
1.11      mrg       272:   uint64_t extension_flags = 0;
                    273:   uint64_t default_flags = 0;
                    274:   std::string buf;
                    275:   size_t sep_pos = -1;
                    276:   char *fcpu_info;
1.4       mrg       277:
1.1       mrg       278:   gcc_assert (argc);
                    279:
                    280:   if (!argv[0])
                    281:     goto not_found;
                    282:
                    283:   /* Are we processing -march, mtune or mcpu?  */
                    284:   arch = strcmp (argv[0], "arch") == 0;
                    285:   if (!arch)
                    286:     tune = strcmp (argv[0], "tune") == 0;
                    287:
                    288:   if (!arch && !tune)
                    289:     cpu = strcmp (argv[0], "cpu") == 0;
                    290:
                    291:   if (!arch && !tune && !cpu)
                    292:     goto not_found;
                    293:
1.7       mrg       294: #ifndef __NetBSD__
1.11      mrg       295:   fcpu_info = getenv ("GCC_CPUINFO");
                    296:   if (fcpu_info)
                    297:     f = fopen (fcpu_info, "r");
                    298:   else
                    299:     f = fopen ("/proc/cpuinfo", "r");
1.1       mrg       300:
                    301:   if (f == NULL)
                    302:     goto not_found;
                    303:
                    304:   /* Look through /proc/cpuinfo to determine the implementer
                    305:      and then the part number that identifies a particular core.  */
1.11      mrg       306:   while (!(buf = readline (f)).empty ())
1.1       mrg       307:     {
1.11      mrg       308:       if (find_field (buf, "implementer") != std::string::npos)
1.1       mrg       309:        {
1.3       mrg       310:          unsigned cimp = parse_field (buf);
                    311:          if (cimp == INVALID_IMP)
                    312:            goto not_found;
                    313:
                    314:          if (imp == INVALID_IMP)
                    315:            imp = cimp;
                    316:          /* FIXME: BIG.little implementers are always equal. */
                    317:          else if (imp != cimp)
                    318:            goto not_found;
                    319:        }
1.11      mrg       320:       else if (find_field (buf, "variant") != std::string::npos)
1.3       mrg       321:        {
                    322:          unsigned cvariant = parse_field (buf);
                    323:          if (!contains_core_p (variants, cvariant))
                    324:            {
                    325:               if (n_variants == 2)
                    326:                 goto not_found;
1.1       mrg       327:
1.3       mrg       328:               variants[n_variants++] = cvariant;
                    329:            }
                    330:           continue;
                    331:         }
1.11      mrg       332:       else if (find_field (buf, "part") != std::string::npos)
1.1       mrg       333:        {
1.3       mrg       334:          unsigned ccore = parse_field (buf);
                    335:          if (!contains_core_p (cores, ccore))
                    336:            {
                    337:              if (n_cores == 2)
                    338:                goto not_found;
1.1       mrg       339:
1.3       mrg       340:              cores[n_cores++] = ccore;
                    341:            }
1.1       mrg       342:          continue;
                    343:        }
1.11      mrg       344:       else if (!tune && !processed_exts
                    345:               && (sep_pos = find_field (buf, "Features")) != std::string::npos)
1.1       mrg       346:        {
1.11      mrg       347:          /* First create the list of features in the buffer.  */
                    348:          std::set<std::string> features;
                    349:          /* Drop everything till the :.  */
                    350:          buf = buf.substr (sep_pos + 1);
                    351:          split_words (buf, features);
                    352:
1.1       mrg       353:          for (i = 0; i < num_exts; i++)
                    354:            {
1.11      mrg       355:              const std::string val (aarch64_extensions[i].feat_string);
1.6       mrg       356:
                    357:              /* If the feature contains no HWCAPS string then ignore it for the
                    358:                 auto detection.  */
1.11      mrg       359:              if (val.empty ())
1.6       mrg       360:                continue;
                    361:
1.1       mrg       362:              bool enabled = true;
                    363:
                    364:              /* This may be a multi-token feature string.  We need
1.6       mrg       365:                 to match all parts, which could be in any order.  */
1.11      mrg       366:              std::set<std::string> tokens;
                    367:              split_words (val, tokens);
                    368:              std::set<std::string>::iterator it;
                    369:
                    370:              /* Iterate till the first feature isn't found or all of them
                    371:                 are found.  */
                    372:              for (it = tokens.begin (); enabled && it != tokens.end (); ++it)
                    373:                enabled = enabled && features.count (*it);
1.1       mrg       374:
                    375:              if (enabled)
                    376:                extension_flags |= aarch64_extensions[i].flag;
                    377:              else
                    378:                extension_flags &= ~(aarch64_extensions[i].flag);
                    379:            }
                    380:
                    381:          processed_exts = true;
                    382:        }
                    383:     }
                    384:
                    385:   fclose (f);
                    386:   f = NULL;
1.4       mrg       387: #else
                    388:   unsigned int curcpu;
                    389:   size_t len;
                    390:   char impl_buf[8];
                    391:   int mib[2], ncpu;
                    392:
                    393:   mib[0] = CTL_HW;
                    394:   mib[1] = HW_NCPU;
                    395:   len = sizeof(ncpu);
                    396:   if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1)
                    397:     goto not_found;
                    398:
                    399:   for (curcpu = 0; curcpu < ncpu; curcpu++)
                    400:     {
                    401:       char path[128];
                    402:       struct aarch64_sysctl_cpu_id id;
                    403:
                    404:       len = sizeof id;
                    405:       snprintf(path, sizeof path, "machdep.cpu%d.cpu_id", curcpu);
                    406:       if (sysctlbyname(path, &id, &len, NULL, 0) != 0)
                    407:         goto not_found;
                    408:
                    409:       unsigned cimp = __SHIFTOUT(id.ac_midr, MIDR_EL1_IMPL);
                    410:       if (cimp == INVALID_IMP)
                    411:         goto not_found;
                    412:
                    413:       if (imp == INVALID_IMP)
                    414:         imp = cimp;
                    415:        /* FIXME: BIG.little implementers are always equal. */
                    416:       else if (imp != cimp)
                    417:         goto not_found;
                    418:
                    419:       unsigned cvariant = __SHIFTOUT(id.ac_midr, MIDR_EL1_VARIANT);
                    420:       if (!contains_core_p (variants, cvariant))
                    421:         {
                    422:           if (n_variants == 2)
                    423:             goto not_found;
                    424:
                    425:           variants[n_variants++] = cvariant;
                    426:        }
                    427:
                    428:       unsigned ccore = __SHIFTOUT(id.ac_midr, MIDR_EL1_PARTNUM);
                    429:       if (!contains_core_p (cores, ccore))
                    430:        {
                    431:          if (n_cores == 2)
                    432:            goto not_found;
                    433:
                    434:          cores[n_cores++] = ccore;
                    435:        }
                    436:
                    437:       if (!tune && !processed_exts)
                    438:         {
1.7       mrg       439:           std::string exts;
                    440:
                    441:          /* These are all the extensions from aarch64-option-extensions.def.  */
                    442:           if (__SHIFTOUT(id.ac_aa64pfr0, ID_AA64PFR0_EL1_FP) == ID_AA64PFR0_EL1_FP_IMPL)
                    443:            {
                    444:              exts += "fp ";
                    445:            }
                    446:           if (__SHIFTOUT(id.ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD) == ID_AA64PFR0_EL1_ADV_SIMD_IMPL)
                    447:            {
                    448:              exts += "asimd ";
                    449:            }
1.8       mrg       450: #ifdef ID_AA64ISAR0_EL1_RDM
1.7       mrg       451:           if (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_RDM) == ID_AA64ISAR0_EL1_RDM_SQRDML)
                    452:            {
                    453:              exts += "asimdrdm ";
                    454:            }
                    455:           if (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_DP) == ID_AA64ISAR0_EL1_DP_UDOT)
                    456:            {
                    457:              exts += "asimddp ";
                    458:            }
                    459:           if (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_FHM) == ID_AA64ISAR0_EL1_FHM_FMLAL)
                    460:            {
                    461:              exts += "asimdfml ";
                    462:            }
1.8       mrg       463: #endif
1.7       mrg       464:           if (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_AES) == ID_AA64ISAR0_EL1_AES_AES)
                    465:            {
                    466:              exts += "aes ";
                    467:            }
                    468:           if (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_AES) == ID_AA64ISAR0_EL1_AES_PMUL)
                    469:            {
                    470:              exts += "aes pmull ";
                    471:            }
                    472:           if (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_CRC32) == ID_AA64ISAR0_EL1_CRC32_CRC32X)
                    473:            {
                    474:              exts += "crc32 ";
                    475:            }
1.8       mrg       476: #ifdef ID_AA64ISAR0_EL1_ATOMIC
1.7       mrg       477:           if (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_ATOMIC) == ID_AA64ISAR0_EL1_ATOMIC_SWP)
                    478:            {
                    479:              exts += "atomics ";
                    480:            }
1.8       mrg       481: #endif
1.7       mrg       482:           if ((__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_SHA1) & ID_AA64ISAR0_EL1_SHA1_SHA1CPMHSU) != 0)
                    483:            {
                    484:              exts += "sha1 ";
                    485:            }
                    486:           if ((__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_SHA2) & ID_AA64ISAR0_EL1_SHA2_SHA256HSU) != 0)
                    487:            {
                    488:              exts += "sha2 ";
                    489:            }
1.8       mrg       490: #ifdef ID_AA64ISAR0_EL1_SHA2_SHA512HSU
1.7       mrg       491:           if ((__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_SHA2) & ID_AA64ISAR0_EL1_SHA2_SHA512HSU) != 0)
                    492:            {
                    493:              exts += "sha512 ";
                    494:            }
                    495:           if ((__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_SHA3) & ID_AA64ISAR0_EL1_SHA3_EOR3) != 0)
                    496:            {
                    497:              exts += "sha3 ";
                    498:            }
                    499:           if (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_SM3) == ID_AA64ISAR0_EL1_SM3_SM3)
                    500:            {
                    501:              exts += "sm3 ";
                    502:            }
                    503:           if (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_SM4) == ID_AA64ISAR0_EL1_SM4_SM4)
                    504:            {
                    505:              exts += "sm4 ";
                    506:            }
                    507:           if (__SHIFTOUT(id.ac_aa64pfr0, ID_AA64PFR0_EL1_SVE) == ID_AA64PFR0_EL1_SVE_IMPL)
                    508:            {
                    509:              exts += "sve ";
                    510:            }
                    511:           if (__SHIFTOUT(id.ac_aa64isar1, ID_AA64ISAR1_EL1_LRCPC) == ID_AA64ISAR1_EL1_LRCPC_PR)
                    512:            {
                    513:              exts += "lrcpc ";
                    514:            }
1.8       mrg       515: #endif
1.7       mrg       516:
1.4       mrg       517:           for (i = 0; i < num_exts; i++)
                    518:             {
1.7       mrg       519:              const char *p = aarch64_extensions[i].feat_string;
                    520:
                    521:              /* If the feature contains no HWCAPS string then ignore it for the
                    522:                 auto detection.  */
                    523:              if (*p == '\0')
                    524:                continue;
1.4       mrg       525:
1.7       mrg       526:              bool enabled = true;
                    527:
                    528:              /* This may be a multi-token feature string.  We need
                    529:                 to match all parts, which could be in any order.  */
1.12    ! mrg       530:              size_t len = strlen (exts.c_str());
1.7       mrg       531:              do
1.4       mrg       532:                {
1.7       mrg       533:                  const char *end = strchr (p, ' ');
                    534:                  if (end == NULL)
                    535:                    end = strchr (p, '\0');
1.12    ! mrg       536:                  if (memmem (exts.c_str(), len, p, end - p) == NULL)
1.7       mrg       537:                    {
                    538:                      /* Failed to match this token.  Turn off the
                    539:                         features we'd otherwise enable.  */
                    540:                      enabled = false;
                    541:                      break;
                    542:                    }
                    543:                  if (*end == '\0')
                    544:                    break;
                    545:                  p = end + 1;
1.4       mrg       546:                }
1.7       mrg       547:              while (1);
1.4       mrg       548:
                    549:               if (enabled)
                    550:                 extension_flags |= aarch64_extensions[i].flag;
                    551:               else
                    552:                 extension_flags &= ~(aarch64_extensions[i].flag);
                    553:             }
                    554:
                    555:           processed_exts = true;
                    556:        }
                    557:     }
                    558:   /* End of NetBSD specific section.  */
                    559: #endif
1.1       mrg       560:
                    561:   /* Weird cpuinfo format that we don't know how to handle.  */
1.3       mrg       562:   if (n_cores == 0
                    563:       || n_cores > 2
                    564:       || (n_cores == 1 && n_variants != 1)
                    565:       || imp == INVALID_IMP)
1.1       mrg       566:     goto not_found;
                    567:
1.3       mrg       568:   /* Simple case, one core type or just looking for the arch. */
                    569:   if (n_cores == 1 || arch)
                    570:     {
                    571:       /* Search for one of the cores in the list. */
                    572:       for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
                    573:        if (aarch64_cpu_data[i].implementer_id == imp
                    574:             && cores[0] == aarch64_cpu_data[i].part_no
                    575:             && (aarch64_cpu_data[i].variant == ALL_VARIANTS
                    576:                 || variants[0] == aarch64_cpu_data[i].variant))
                    577:          break;
                    578:       if (aarch64_cpu_data[i].name == NULL)
                    579:         goto not_found;
1.1       mrg       580:
1.3       mrg       581:       if (arch)
                    582:        {
                    583:          const char *arch_id = aarch64_cpu_data[i].arch;
                    584:          aarch64_arch_driver_info* arch_info = get_arch_from_id (arch_id);
1.1       mrg       585:
1.3       mrg       586:          /* We got some arch indentifier that's not in aarch64-arches.def?  */
                    587:          if (!arch_info)
                    588:            goto not_found;
1.1       mrg       589:
1.3       mrg       590:          res = concat ("-march=", arch_info->name, NULL);
                    591:          default_flags = arch_info->flags;
                    592:        }
                    593:       else
                    594:        {
                    595:          default_flags = aarch64_cpu_data[i].flags;
                    596:          res = concat ("-m",
                    597:                        cpu ? "cpu" : "tune", "=",
                    598:                        aarch64_cpu_data[i].name,
                    599:                        NULL);
                    600:        }
1.1       mrg       601:     }
                    602:   /* We have big.LITTLE.  */
1.3       mrg       603:   else
1.1       mrg       604:     {
                    605:       for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
                    606:        {
1.3       mrg       607:          if (aarch64_cpu_data[i].implementer_id == imp
                    608:              && valid_bL_core_p (cores, aarch64_cpu_data[i].part_no))
1.1       mrg       609:            {
                    610:              res = concat ("-m",
                    611:                            cpu ? "cpu" : "tune", "=",
                    612:                            aarch64_cpu_data[i].name,
                    613:                            NULL);
                    614:              default_flags = aarch64_cpu_data[i].flags;
                    615:              break;
                    616:            }
                    617:        }
                    618:       if (!res)
                    619:        goto not_found;
                    620:     }
                    621:
                    622:   if (tune)
                    623:     return res;
                    624:
1.6       mrg       625:   {
                    626:     std::string extension
                    627:       = aarch64_get_extension_string_for_isa_flags (extension_flags,
                    628:                                                    default_flags);
                    629:     res = concat (res, extension.c_str (), NULL);
                    630:   }
1.1       mrg       631:
                    632:   return res;
                    633:
                    634: not_found:
                    635:   {
                    636:    /* If detection fails we ignore the option.
1.6       mrg       637:       Clean up and return NULL.  */
1.1       mrg       638:
                    639:     if (f)
                    640:       fclose (f);
                    641:
1.6       mrg       642:     return NULL;
1.1       mrg       643:   }
                    644: }
1.4       mrg       645:

CVSweb <webmaster@jp.NetBSD.org>