PageRenderTime 4ms CodeModel.GetById 6ms app.highlight 113ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/Support/Triple.cpp

https://github.com/Zoxc/llvm
C++ | 1036 lines | 845 code | 100 blank | 91 comment | 129 complexity | 187deeb55e6a2fe2c0c256d3e6ca5418 MD5 | raw file
   1//===--- Triple.cpp - Target triple helper class --------------------------===//
   2//
   3//                     The LLVM Compiler Infrastructure
   4//
   5// This file is distributed under the University of Illinois Open Source
   6// License. See LICENSE.TXT for details.
   7//
   8//===----------------------------------------------------------------------===//
   9
  10#include "llvm/ADT/Triple.h"
  11#include "llvm/ADT/STLExtras.h"
  12#include "llvm/ADT/SmallString.h"
  13#include "llvm/ADT/StringSwitch.h"
  14#include "llvm/Support/ErrorHandling.h"
  15#include <cstring>
  16using namespace llvm;
  17
  18const char *Triple::getArchTypeName(ArchType Kind) {
  19  switch (Kind) {
  20  case UnknownArch: return "unknown";
  21
  22  case aarch64:     return "aarch64";
  23  case aarch64_be:  return "aarch64_be";
  24  case arm:         return "arm";
  25  case armeb:       return "armeb";
  26  case hexagon:     return "hexagon";
  27  case mips:        return "mips";
  28  case mipsel:      return "mipsel";
  29  case mips64:      return "mips64";
  30  case mips64el:    return "mips64el";
  31  case msp430:      return "msp430";
  32  case ppc64:       return "powerpc64";
  33  case ppc64le:     return "powerpc64le";
  34  case ppc:         return "powerpc";
  35  case r600:        return "r600";
  36  case sparc:       return "sparc";
  37  case sparcv9:     return "sparcv9";
  38  case systemz:     return "s390x";
  39  case tce:         return "tce";
  40  case thumb:       return "thumb";
  41  case thumbeb:     return "thumbeb";
  42  case x86:         return "i386";
  43  case x86_64:      return "x86_64";
  44  case xcore:       return "xcore";
  45  case nvptx:       return "nvptx";
  46  case nvptx64:     return "nvptx64";
  47  case le32:        return "le32";
  48  case le64:        return "le64";
  49  case amdil:       return "amdil";
  50  case amdil64:     return "amdil64";
  51  case hsail:       return "hsail";
  52  case hsail64:     return "hsail64";
  53  case spir:        return "spir";
  54  case spir64:      return "spir64";
  55  case kalimba:     return "kalimba";
  56  }
  57
  58  llvm_unreachable("Invalid ArchType!");
  59}
  60
  61const char *Triple::getArchTypePrefix(ArchType Kind) {
  62  switch (Kind) {
  63  default:
  64    return nullptr;
  65
  66  case aarch64:
  67  case aarch64_be:  return "aarch64";
  68
  69  case arm:
  70  case armeb:
  71  case thumb:
  72  case thumbeb:     return "arm";
  73
  74  case ppc64:
  75  case ppc64le:
  76  case ppc:         return "ppc";
  77
  78  case mips:
  79  case mipsel:
  80  case mips64:
  81  case mips64el:    return "mips";
  82
  83  case hexagon:     return "hexagon";
  84
  85  case r600:        return "r600";
  86
  87  case sparcv9:
  88  case sparc:       return "sparc";
  89
  90  case systemz:     return "systemz";
  91
  92  case x86:
  93  case x86_64:      return "x86";
  94
  95  case xcore:       return "xcore";
  96
  97  case nvptx:       return "nvptx";
  98  case nvptx64:     return "nvptx";
  99
 100  case le32:        return "le32";
 101  case le64:        return "le64";
 102
 103  case amdil:
 104  case amdil64:     return "amdil";
 105
 106  case hsail:
 107  case hsail64:     return "hsail";
 108
 109  case spir:
 110  case spir64:      return "spir";
 111  case kalimba:     return "kalimba";
 112  }
 113}
 114
 115const char *Triple::getVendorTypeName(VendorType Kind) {
 116  switch (Kind) {
 117  case UnknownVendor: return "unknown";
 118
 119  case Apple: return "apple";
 120  case PC: return "pc";
 121  case SCEI: return "scei";
 122  case BGP: return "bgp";
 123  case BGQ: return "bgq";
 124  case Freescale: return "fsl";
 125  case IBM: return "ibm";
 126  case ImaginationTechnologies: return "img";
 127  case MipsTechnologies: return "mti";
 128  case NVIDIA: return "nvidia";
 129  case CSR: return "csr";
 130  }
 131
 132  llvm_unreachable("Invalid VendorType!");
 133}
 134
 135const char *Triple::getOSTypeName(OSType Kind) {
 136  switch (Kind) {
 137  case UnknownOS: return "unknown";
 138
 139  case Darwin: return "darwin";
 140  case DragonFly: return "dragonfly";
 141  case FreeBSD: return "freebsd";
 142  case IOS: return "ios";
 143  case KFreeBSD: return "kfreebsd";
 144  case Linux: return "linux";
 145  case Lv2: return "lv2";
 146  case MacOSX: return "macosx";
 147  case NetBSD: return "netbsd";
 148  case OpenBSD: return "openbsd";
 149  case Solaris: return "solaris";
 150  case Win32: return "windows";
 151  case Haiku: return "haiku";
 152  case Minix: return "minix";
 153  case RTEMS: return "rtems";
 154  case NaCl: return "nacl";
 155  case CNK: return "cnk";
 156  case Bitrig: return "bitrig";
 157  case AIX: return "aix";
 158  case CUDA: return "cuda";
 159  case NVCL: return "nvcl";
 160  }
 161
 162  llvm_unreachable("Invalid OSType");
 163}
 164
 165const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
 166  switch (Kind) {
 167  case UnknownEnvironment: return "unknown";
 168  case GNU: return "gnu";
 169  case GNUEABIHF: return "gnueabihf";
 170  case GNUEABI: return "gnueabi";
 171  case GNUX32: return "gnux32";
 172  case CODE16: return "code16";
 173  case EABI: return "eabi";
 174  case EABIHF: return "eabihf";
 175  case Android: return "android";
 176  case MSVC: return "msvc";
 177  case Itanium: return "itanium";
 178  case Cygnus: return "cygnus";
 179  }
 180
 181  llvm_unreachable("Invalid EnvironmentType!");
 182}
 183
 184Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
 185  return StringSwitch<Triple::ArchType>(Name)
 186    .Case("aarch64", aarch64)
 187    .Case("aarch64_be", aarch64_be)
 188    .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
 189    .Case("arm", arm)
 190    .Case("armeb", armeb)
 191    .Case("mips", mips)
 192    .Case("mipsel", mipsel)
 193    .Case("mips64", mips64)
 194    .Case("mips64el", mips64el)
 195    .Case("msp430", msp430)
 196    .Case("ppc64", ppc64)
 197    .Case("ppc32", ppc)
 198    .Case("ppc", ppc)
 199    .Case("ppc64le", ppc64le)
 200    .Case("r600", r600)
 201    .Case("hexagon", hexagon)
 202    .Case("sparc", sparc)
 203    .Case("sparcv9", sparcv9)
 204    .Case("systemz", systemz)
 205    .Case("tce", tce)
 206    .Case("thumb", thumb)
 207    .Case("thumbeb", thumbeb)
 208    .Case("x86", x86)
 209    .Case("x86-64", x86_64)
 210    .Case("xcore", xcore)
 211    .Case("nvptx", nvptx)
 212    .Case("nvptx64", nvptx64)
 213    .Case("le32", le32)
 214    .Case("le64", le64)
 215    .Case("amdil", amdil)
 216    .Case("amdil64", amdil64)
 217    .Case("hsail", hsail)
 218    .Case("hsail64", hsail64)
 219    .Case("spir", spir)
 220    .Case("spir64", spir64)
 221    .Case("kalimba", kalimba)
 222    .Default(UnknownArch);
 223}
 224
 225static Triple::ArchType parseArch(StringRef ArchName) {
 226  return StringSwitch<Triple::ArchType>(ArchName)
 227    .Cases("i386", "i486", "i586", "i686", Triple::x86)
 228    // FIXME: Do we need to support these?
 229    .Cases("i786", "i886", "i986", Triple::x86)
 230    .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
 231    .Case("powerpc", Triple::ppc)
 232    .Cases("powerpc64", "ppu", Triple::ppc64)
 233    .Case("powerpc64le", Triple::ppc64le)
 234    .Case("aarch64", Triple::aarch64)
 235    .Case("aarch64_be", Triple::aarch64_be)
 236    .Case("arm64", Triple::aarch64)
 237    .Cases("arm", "xscale", Triple::arm)
 238    // FIXME: It would be good to replace these with explicit names for all the
 239    // various suffixes supported.
 240    .StartsWith("armv", Triple::arm)
 241    .Case("armeb", Triple::armeb)
 242    .StartsWith("armebv", Triple::armeb)
 243    .Case("thumb", Triple::thumb)
 244    .StartsWith("thumbv", Triple::thumb)
 245    .Case("thumbeb", Triple::thumbeb)
 246    .StartsWith("thumbebv", Triple::thumbeb)
 247    .Case("msp430", Triple::msp430)
 248    .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
 249    .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
 250    .Cases("mips64", "mips64eb", Triple::mips64)
 251    .Case("mips64el", Triple::mips64el)
 252    .Case("r600", Triple::r600)
 253    .Case("hexagon", Triple::hexagon)
 254    .Case("s390x", Triple::systemz)
 255    .Case("sparc", Triple::sparc)
 256    .Cases("sparcv9", "sparc64", Triple::sparcv9)
 257    .Case("tce", Triple::tce)
 258    .Case("xcore", Triple::xcore)
 259    .Case("nvptx", Triple::nvptx)
 260    .Case("nvptx64", Triple::nvptx64)
 261    .Case("le32", Triple::le32)
 262    .Case("le64", Triple::le64)
 263    .Case("amdil", Triple::amdil)
 264    .Case("amdil64", Triple::amdil64)
 265    .Case("hsail", Triple::hsail)
 266    .Case("hsail64", Triple::hsail64)
 267    .Case("spir", Triple::spir)
 268    .Case("spir64", Triple::spir64)
 269    .StartsWith("kalimba", Triple::kalimba)
 270    .Default(Triple::UnknownArch);
 271}
 272
 273static Triple::VendorType parseVendor(StringRef VendorName) {
 274  return StringSwitch<Triple::VendorType>(VendorName)
 275    .Case("apple", Triple::Apple)
 276    .Case("pc", Triple::PC)
 277    .Case("scei", Triple::SCEI)
 278    .Case("bgp", Triple::BGP)
 279    .Case("bgq", Triple::BGQ)
 280    .Case("fsl", Triple::Freescale)
 281    .Case("ibm", Triple::IBM)
 282    .Case("img", Triple::ImaginationTechnologies)
 283    .Case("mti", Triple::MipsTechnologies)
 284    .Case("nvidia", Triple::NVIDIA)
 285    .Case("csr", Triple::CSR)
 286    .Default(Triple::UnknownVendor);
 287}
 288
 289static Triple::OSType parseOS(StringRef OSName) {
 290  return StringSwitch<Triple::OSType>(OSName)
 291    .StartsWith("darwin", Triple::Darwin)
 292    .StartsWith("dragonfly", Triple::DragonFly)
 293    .StartsWith("freebsd", Triple::FreeBSD)
 294    .StartsWith("ios", Triple::IOS)
 295    .StartsWith("kfreebsd", Triple::KFreeBSD)
 296    .StartsWith("linux", Triple::Linux)
 297    .StartsWith("lv2", Triple::Lv2)
 298    .StartsWith("macosx", Triple::MacOSX)
 299    .StartsWith("netbsd", Triple::NetBSD)
 300    .StartsWith("openbsd", Triple::OpenBSD)
 301    .StartsWith("solaris", Triple::Solaris)
 302    .StartsWith("win32", Triple::Win32)
 303    .StartsWith("windows", Triple::Win32)
 304    .StartsWith("haiku", Triple::Haiku)
 305    .StartsWith("minix", Triple::Minix)
 306    .StartsWith("rtems", Triple::RTEMS)
 307    .StartsWith("nacl", Triple::NaCl)
 308    .StartsWith("cnk", Triple::CNK)
 309    .StartsWith("bitrig", Triple::Bitrig)
 310    .StartsWith("aix", Triple::AIX)
 311    .StartsWith("cuda", Triple::CUDA)
 312    .StartsWith("nvcl", Triple::NVCL)
 313    .Default(Triple::UnknownOS);
 314}
 315
 316static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
 317  return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
 318    .StartsWith("eabihf", Triple::EABIHF)
 319    .StartsWith("eabi", Triple::EABI)
 320    .StartsWith("gnueabihf", Triple::GNUEABIHF)
 321    .StartsWith("gnueabi", Triple::GNUEABI)
 322    .StartsWith("gnux32", Triple::GNUX32)
 323    .StartsWith("code16", Triple::CODE16)
 324    .StartsWith("gnu", Triple::GNU)
 325    .StartsWith("android", Triple::Android)
 326    .StartsWith("msvc", Triple::MSVC)
 327    .StartsWith("itanium", Triple::Itanium)
 328    .StartsWith("cygnus", Triple::Cygnus)
 329    .Default(Triple::UnknownEnvironment);
 330}
 331
 332static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
 333  return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
 334    .EndsWith("coff", Triple::COFF)
 335    .EndsWith("elf", Triple::ELF)
 336    .EndsWith("macho", Triple::MachO)
 337    .Default(Triple::UnknownObjectFormat);
 338}
 339
 340static Triple::SubArchType parseSubArch(StringRef SubArchName) {
 341  return StringSwitch<Triple::SubArchType>(SubArchName)
 342    .EndsWith("v8", Triple::ARMSubArch_v8)
 343    .EndsWith("v8a", Triple::ARMSubArch_v8)
 344    .EndsWith("v7", Triple::ARMSubArch_v7)
 345    .EndsWith("v7a", Triple::ARMSubArch_v7)
 346    .EndsWith("v7em", Triple::ARMSubArch_v7em)
 347    .EndsWith("v7l", Triple::ARMSubArch_v7)
 348    .EndsWith("v7m", Triple::ARMSubArch_v7m)
 349    .EndsWith("v7r", Triple::ARMSubArch_v7)
 350    .EndsWith("v7s", Triple::ARMSubArch_v7s)
 351    .EndsWith("v6", Triple::ARMSubArch_v6)
 352    .EndsWith("v6m", Triple::ARMSubArch_v6m)
 353    .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
 354    .EndsWith("v5", Triple::ARMSubArch_v5)
 355    .EndsWith("v5e", Triple::ARMSubArch_v5)
 356    .EndsWith("v5t", Triple::ARMSubArch_v5)
 357    .EndsWith("v5te", Triple::ARMSubArch_v5te)
 358    .EndsWith("v4t", Triple::ARMSubArch_v4t)
 359    .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
 360    .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
 361    .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
 362    .Default(Triple::NoSubArch);
 363}
 364
 365static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
 366  switch (Kind) {
 367  case Triple::UnknownObjectFormat: return "";
 368  case Triple::COFF: return "coff";
 369  case Triple::ELF: return "elf";
 370  case Triple::MachO: return "macho";
 371  }
 372  llvm_unreachable("unknown object format type");
 373}
 374
 375static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
 376  if (T.isOSDarwin())
 377    return Triple::MachO;
 378  else if (T.isOSWindows())
 379    return Triple::COFF;
 380  return Triple::ELF;
 381}
 382
 383/// \brief Construct a triple from the string representation provided.
 384///
 385/// This stores the string representation and parses the various pieces into
 386/// enum members.
 387Triple::Triple(const Twine &Str)
 388    : Data(Str.str()),
 389      Arch(parseArch(getArchName())),
 390      SubArch(parseSubArch(getArchName())),
 391      Vendor(parseVendor(getVendorName())),
 392      OS(parseOS(getOSName())),
 393      Environment(parseEnvironment(getEnvironmentName())),
 394      ObjectFormat(parseFormat(getEnvironmentName())) {
 395  if (ObjectFormat == Triple::UnknownObjectFormat)
 396    ObjectFormat = getDefaultFormat(*this);
 397}
 398
 399/// \brief Construct a triple from string representations of the architecture,
 400/// vendor, and OS.
 401///
 402/// This joins each argument into a canonical string representation and parses
 403/// them into enum members. It leaves the environment unknown and omits it from
 404/// the string representation.
 405Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
 406    : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
 407      Arch(parseArch(ArchStr.str())),
 408      SubArch(parseSubArch(ArchStr.str())),
 409      Vendor(parseVendor(VendorStr.str())),
 410      OS(parseOS(OSStr.str())),
 411      Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
 412  ObjectFormat = getDefaultFormat(*this);
 413}
 414
 415/// \brief Construct a triple from string representations of the architecture,
 416/// vendor, OS, and environment.
 417///
 418/// This joins each argument into a canonical string representation and parses
 419/// them into enum members.
 420Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
 421               const Twine &EnvironmentStr)
 422    : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
 423            EnvironmentStr).str()),
 424      Arch(parseArch(ArchStr.str())),
 425      SubArch(parseSubArch(ArchStr.str())),
 426      Vendor(parseVendor(VendorStr.str())),
 427      OS(parseOS(OSStr.str())),
 428      Environment(parseEnvironment(EnvironmentStr.str())),
 429      ObjectFormat(parseFormat(EnvironmentStr.str())) {
 430  if (ObjectFormat == Triple::UnknownObjectFormat)
 431    ObjectFormat = getDefaultFormat(*this);
 432}
 433
 434std::string Triple::normalize(StringRef Str) {
 435  bool IsMinGW32 = false;
 436  bool IsCygwin = false;
 437
 438  // Parse into components.
 439  SmallVector<StringRef, 4> Components;
 440  Str.split(Components, "-");
 441
 442  // If the first component corresponds to a known architecture, preferentially
 443  // use it for the architecture.  If the second component corresponds to a
 444  // known vendor, preferentially use it for the vendor, etc.  This avoids silly
 445  // component movement when a component parses as (eg) both a valid arch and a
 446  // valid os.
 447  ArchType Arch = UnknownArch;
 448  if (Components.size() > 0)
 449    Arch = parseArch(Components[0]);
 450  VendorType Vendor = UnknownVendor;
 451  if (Components.size() > 1)
 452    Vendor = parseVendor(Components[1]);
 453  OSType OS = UnknownOS;
 454  if (Components.size() > 2) {
 455    OS = parseOS(Components[2]);
 456    IsCygwin = Components[2].startswith("cygwin");
 457    IsMinGW32 = Components[2].startswith("mingw");
 458  }
 459  EnvironmentType Environment = UnknownEnvironment;
 460  if (Components.size() > 3)
 461    Environment = parseEnvironment(Components[3]);
 462  ObjectFormatType ObjectFormat = UnknownObjectFormat;
 463  if (Components.size() > 4)
 464    ObjectFormat = parseFormat(Components[4]);
 465
 466  // Note which components are already in their final position.  These will not
 467  // be moved.
 468  bool Found[4];
 469  Found[0] = Arch != UnknownArch;
 470  Found[1] = Vendor != UnknownVendor;
 471  Found[2] = OS != UnknownOS;
 472  Found[3] = Environment != UnknownEnvironment;
 473
 474  // If they are not there already, permute the components into their canonical
 475  // positions by seeing if they parse as a valid architecture, and if so moving
 476  // the component to the architecture position etc.
 477  for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
 478    if (Found[Pos])
 479      continue; // Already in the canonical position.
 480
 481    for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
 482      // Do not reparse any components that already matched.
 483      if (Idx < array_lengthof(Found) && Found[Idx])
 484        continue;
 485
 486      // Does this component parse as valid for the target position?
 487      bool Valid = false;
 488      StringRef Comp = Components[Idx];
 489      switch (Pos) {
 490      default: llvm_unreachable("unexpected component type!");
 491      case 0:
 492        Arch = parseArch(Comp);
 493        Valid = Arch != UnknownArch;
 494        break;
 495      case 1:
 496        Vendor = parseVendor(Comp);
 497        Valid = Vendor != UnknownVendor;
 498        break;
 499      case 2:
 500        OS = parseOS(Comp);
 501        IsCygwin = Comp.startswith("cygwin");
 502        IsMinGW32 = Comp.startswith("mingw");
 503        Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
 504        break;
 505      case 3:
 506        Environment = parseEnvironment(Comp);
 507        Valid = Environment != UnknownEnvironment;
 508        if (!Valid) {
 509          ObjectFormat = parseFormat(Comp);
 510          Valid = ObjectFormat != UnknownObjectFormat;
 511        }
 512        break;
 513      }
 514      if (!Valid)
 515        continue; // Nope, try the next component.
 516
 517      // Move the component to the target position, pushing any non-fixed
 518      // components that are in the way to the right.  This tends to give
 519      // good results in the common cases of a forgotten vendor component
 520      // or a wrongly positioned environment.
 521      if (Pos < Idx) {
 522        // Insert left, pushing the existing components to the right.  For
 523        // example, a-b-i386 -> i386-a-b when moving i386 to the front.
 524        StringRef CurrentComponent(""); // The empty component.
 525        // Replace the component we are moving with an empty component.
 526        std::swap(CurrentComponent, Components[Idx]);
 527        // Insert the component being moved at Pos, displacing any existing
 528        // components to the right.
 529        for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
 530          // Skip over any fixed components.
 531          while (i < array_lengthof(Found) && Found[i])
 532            ++i;
 533          // Place the component at the new position, getting the component
 534          // that was at this position - it will be moved right.
 535          std::swap(CurrentComponent, Components[i]);
 536        }
 537      } else if (Pos > Idx) {
 538        // Push right by inserting empty components until the component at Idx
 539        // reaches the target position Pos.  For example, pc-a -> -pc-a when
 540        // moving pc to the second position.
 541        do {
 542          // Insert one empty component at Idx.
 543          StringRef CurrentComponent(""); // The empty component.
 544          for (unsigned i = Idx; i < Components.size();) {
 545            // Place the component at the new position, getting the component
 546            // that was at this position - it will be moved right.
 547            std::swap(CurrentComponent, Components[i]);
 548            // If it was placed on top of an empty component then we are done.
 549            if (CurrentComponent.empty())
 550              break;
 551            // Advance to the next component, skipping any fixed components.
 552            while (++i < array_lengthof(Found) && Found[i])
 553              ;
 554          }
 555          // The last component was pushed off the end - append it.
 556          if (!CurrentComponent.empty())
 557            Components.push_back(CurrentComponent);
 558
 559          // Advance Idx to the component's new position.
 560          while (++Idx < array_lengthof(Found) && Found[Idx])
 561            ;
 562        } while (Idx < Pos); // Add more until the final position is reached.
 563      }
 564      assert(Pos < Components.size() && Components[Pos] == Comp &&
 565             "Component moved wrong!");
 566      Found[Pos] = true;
 567      break;
 568    }
 569  }
 570
 571  // Special case logic goes here.  At this point Arch, Vendor and OS have the
 572  // correct values for the computed components.
 573
 574  if (OS == Triple::Win32) {
 575    Components.resize(4);
 576    Components[2] = "windows";
 577    if (Environment == UnknownEnvironment) {
 578      if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
 579        Components[3] = "msvc";
 580      else
 581        Components[3] = getObjectFormatTypeName(ObjectFormat);
 582    }
 583  } else if (IsMinGW32) {
 584    Components.resize(4);
 585    Components[2] = "windows";
 586    Components[3] = "gnu";
 587  } else if (IsCygwin) {
 588    Components.resize(4);
 589    Components[2] = "windows";
 590    Components[3] = "cygnus";
 591  }
 592  if (IsMinGW32 || IsCygwin ||
 593      (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
 594    if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
 595      Components.resize(5);
 596      Components[4] = getObjectFormatTypeName(ObjectFormat);
 597    }
 598  }
 599
 600  // Stick the corrected components back together to form the normalized string.
 601  std::string Normalized;
 602  for (unsigned i = 0, e = Components.size(); i != e; ++i) {
 603    if (i) Normalized += '-';
 604    Normalized += Components[i];
 605  }
 606  return Normalized;
 607}
 608
 609StringRef Triple::getArchName() const {
 610  return StringRef(Data).split('-').first;           // Isolate first component
 611}
 612
 613StringRef Triple::getVendorName() const {
 614  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
 615  return Tmp.split('-').first;                       // Isolate second component
 616}
 617
 618StringRef Triple::getOSName() const {
 619  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
 620  Tmp = Tmp.split('-').second;                       // Strip second component
 621  return Tmp.split('-').first;                       // Isolate third component
 622}
 623
 624StringRef Triple::getEnvironmentName() const {
 625  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
 626  Tmp = Tmp.split('-').second;                       // Strip second component
 627  return Tmp.split('-').second;                      // Strip third component
 628}
 629
 630StringRef Triple::getOSAndEnvironmentName() const {
 631  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
 632  return Tmp.split('-').second;                      // Strip second component
 633}
 634
 635static unsigned EatNumber(StringRef &Str) {
 636  assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
 637  unsigned Result = 0;
 638
 639  do {
 640    // Consume the leading digit.
 641    Result = Result*10 + (Str[0] - '0');
 642
 643    // Eat the digit.
 644    Str = Str.substr(1);
 645  } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
 646
 647  return Result;
 648}
 649
 650void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
 651                          unsigned &Micro) const {
 652  StringRef OSName = getOSName();
 653
 654  // Assume that the OS portion of the triple starts with the canonical name.
 655  StringRef OSTypeName = getOSTypeName(getOS());
 656  if (OSName.startswith(OSTypeName))
 657    OSName = OSName.substr(OSTypeName.size());
 658
 659  // Any unset version defaults to 0.
 660  Major = Minor = Micro = 0;
 661
 662  // Parse up to three components.
 663  unsigned *Components[3] = { &Major, &Minor, &Micro };
 664  for (unsigned i = 0; i != 3; ++i) {
 665    if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
 666      break;
 667
 668    // Consume the leading number.
 669    *Components[i] = EatNumber(OSName);
 670
 671    // Consume the separator, if present.
 672    if (OSName.startswith("."))
 673      OSName = OSName.substr(1);
 674  }
 675}
 676
 677bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
 678                              unsigned &Micro) const {
 679  getOSVersion(Major, Minor, Micro);
 680
 681  switch (getOS()) {
 682  default: llvm_unreachable("unexpected OS for Darwin triple");
 683  case Darwin:
 684    // Default to darwin8, i.e., MacOSX 10.4.
 685    if (Major == 0)
 686      Major = 8;
 687    // Darwin version numbers are skewed from OS X versions.
 688    if (Major < 4)
 689      return false;
 690    Micro = 0;
 691    Minor = Major - 4;
 692    Major = 10;
 693    break;
 694  case MacOSX:
 695    // Default to 10.4.
 696    if (Major == 0) {
 697      Major = 10;
 698      Minor = 4;
 699    }
 700    if (Major != 10)
 701      return false;
 702    break;
 703  case IOS:
 704    // Ignore the version from the triple.  This is only handled because the
 705    // the clang driver combines OS X and IOS support into a common Darwin
 706    // toolchain that wants to know the OS X version number even when targeting
 707    // IOS.
 708    Major = 10;
 709    Minor = 4;
 710    Micro = 0;
 711    break;
 712  }
 713  return true;
 714}
 715
 716void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
 717                           unsigned &Micro) const {
 718  switch (getOS()) {
 719  default: llvm_unreachable("unexpected OS for Darwin triple");
 720  case Darwin:
 721  case MacOSX:
 722    // Ignore the version from the triple.  This is only handled because the
 723    // the clang driver combines OS X and IOS support into a common Darwin
 724    // toolchain that wants to know the iOS version number even when targeting
 725    // OS X.
 726    Major = 5;
 727    Minor = 0;
 728    Micro = 0;
 729    break;
 730  case IOS:
 731    getOSVersion(Major, Minor, Micro);
 732    // Default to 5.0 (or 7.0 for arm64).
 733    if (Major == 0)
 734      Major = (getArch() == aarch64) ? 7 : 5;
 735    break;
 736  }
 737}
 738
 739void Triple::setTriple(const Twine &Str) {
 740  *this = Triple(Str);
 741}
 742
 743void Triple::setArch(ArchType Kind) {
 744  setArchName(getArchTypeName(Kind));
 745}
 746
 747void Triple::setVendor(VendorType Kind) {
 748  setVendorName(getVendorTypeName(Kind));
 749}
 750
 751void Triple::setOS(OSType Kind) {
 752  setOSName(getOSTypeName(Kind));
 753}
 754
 755void Triple::setEnvironment(EnvironmentType Kind) {
 756  setEnvironmentName(getEnvironmentTypeName(Kind));
 757}
 758
 759void Triple::setObjectFormat(ObjectFormatType Kind) {
 760  if (Environment == UnknownEnvironment)
 761    return setEnvironmentName(getObjectFormatTypeName(Kind));
 762
 763  setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
 764                      getObjectFormatTypeName(Kind)).str());
 765}
 766
 767void Triple::setArchName(StringRef Str) {
 768  // Work around a miscompilation bug for Twines in gcc 4.0.3.
 769  SmallString<64> Triple;
 770  Triple += Str;
 771  Triple += "-";
 772  Triple += getVendorName();
 773  Triple += "-";
 774  Triple += getOSAndEnvironmentName();
 775  setTriple(Triple.str());
 776}
 777
 778void Triple::setVendorName(StringRef Str) {
 779  setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
 780}
 781
 782void Triple::setOSName(StringRef Str) {
 783  if (hasEnvironment())
 784    setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
 785              "-" + getEnvironmentName());
 786  else
 787    setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
 788}
 789
 790void Triple::setEnvironmentName(StringRef Str) {
 791  setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
 792            "-" + Str);
 793}
 794
 795void Triple::setOSAndEnvironmentName(StringRef Str) {
 796  setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
 797}
 798
 799static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
 800  switch (Arch) {
 801  case llvm::Triple::UnknownArch:
 802    return 0;
 803
 804  case llvm::Triple::msp430:
 805    return 16;
 806
 807  case llvm::Triple::arm:
 808  case llvm::Triple::armeb:
 809  case llvm::Triple::hexagon:
 810  case llvm::Triple::le32:
 811  case llvm::Triple::mips:
 812  case llvm::Triple::mipsel:
 813  case llvm::Triple::nvptx:
 814  case llvm::Triple::ppc:
 815  case llvm::Triple::r600:
 816  case llvm::Triple::sparc:
 817  case llvm::Triple::tce:
 818  case llvm::Triple::thumb:
 819  case llvm::Triple::thumbeb:
 820  case llvm::Triple::x86:
 821  case llvm::Triple::xcore:
 822  case llvm::Triple::amdil:
 823  case llvm::Triple::hsail:
 824  case llvm::Triple::spir:
 825  case llvm::Triple::kalimba:
 826    return 32;
 827
 828  case llvm::Triple::aarch64:
 829  case llvm::Triple::aarch64_be:
 830  case llvm::Triple::le64:
 831  case llvm::Triple::mips64:
 832  case llvm::Triple::mips64el:
 833  case llvm::Triple::nvptx64:
 834  case llvm::Triple::ppc64:
 835  case llvm::Triple::ppc64le:
 836  case llvm::Triple::sparcv9:
 837  case llvm::Triple::systemz:
 838  case llvm::Triple::x86_64:
 839  case llvm::Triple::amdil64:
 840  case llvm::Triple::hsail64:
 841  case llvm::Triple::spir64:
 842    return 64;
 843  }
 844  llvm_unreachable("Invalid architecture value");
 845}
 846
 847bool Triple::isArch64Bit() const {
 848  return getArchPointerBitWidth(getArch()) == 64;
 849}
 850
 851bool Triple::isArch32Bit() const {
 852  return getArchPointerBitWidth(getArch()) == 32;
 853}
 854
 855bool Triple::isArch16Bit() const {
 856  return getArchPointerBitWidth(getArch()) == 16;
 857}
 858
 859Triple Triple::get32BitArchVariant() const {
 860  Triple T(*this);
 861  switch (getArch()) {
 862  case Triple::UnknownArch:
 863  case Triple::aarch64:
 864  case Triple::aarch64_be:
 865  case Triple::msp430:
 866  case Triple::systemz:
 867  case Triple::ppc64le:
 868    T.setArch(UnknownArch);
 869    break;
 870
 871  case Triple::amdil:
 872  case Triple::hsail:
 873  case Triple::spir:
 874  case Triple::arm:
 875  case Triple::armeb:
 876  case Triple::hexagon:
 877  case Triple::kalimba:
 878  case Triple::le32:
 879  case Triple::mips:
 880  case Triple::mipsel:
 881  case Triple::nvptx:
 882  case Triple::ppc:
 883  case Triple::r600:
 884  case Triple::sparc:
 885  case Triple::tce:
 886  case Triple::thumb:
 887  case Triple::thumbeb:
 888  case Triple::x86:
 889  case Triple::xcore:
 890    // Already 32-bit.
 891    break;
 892
 893  case Triple::le64:      T.setArch(Triple::le32);    break;
 894  case Triple::mips64:    T.setArch(Triple::mips);    break;
 895  case Triple::mips64el:  T.setArch(Triple::mipsel);  break;
 896  case Triple::nvptx64:   T.setArch(Triple::nvptx);   break;
 897  case Triple::ppc64:     T.setArch(Triple::ppc);     break;
 898  case Triple::sparcv9:   T.setArch(Triple::sparc);   break;
 899  case Triple::x86_64:    T.setArch(Triple::x86);     break;
 900  case Triple::amdil64:   T.setArch(Triple::amdil);   break;
 901  case Triple::hsail64:   T.setArch(Triple::hsail);   break;
 902  case Triple::spir64:    T.setArch(Triple::spir);    break;
 903  }
 904  return T;
 905}
 906
 907Triple Triple::get64BitArchVariant() const {
 908  Triple T(*this);
 909  switch (getArch()) {
 910  case Triple::UnknownArch:
 911  case Triple::arm:
 912  case Triple::armeb:
 913  case Triple::hexagon:
 914  case Triple::kalimba:
 915  case Triple::msp430:
 916  case Triple::r600:
 917  case Triple::tce:
 918  case Triple::thumb:
 919  case Triple::thumbeb:
 920  case Triple::xcore:
 921    T.setArch(UnknownArch);
 922    break;
 923
 924  case Triple::aarch64:
 925  case Triple::aarch64_be:
 926  case Triple::le64:
 927  case Triple::amdil64:
 928  case Triple::hsail64:
 929  case Triple::spir64:
 930  case Triple::mips64:
 931  case Triple::mips64el:
 932  case Triple::nvptx64:
 933  case Triple::ppc64:
 934  case Triple::ppc64le:
 935  case Triple::sparcv9:
 936  case Triple::systemz:
 937  case Triple::x86_64:
 938    // Already 64-bit.
 939    break;
 940
 941  case Triple::le32:    T.setArch(Triple::le64);      break;
 942  case Triple::mips:    T.setArch(Triple::mips64);    break;
 943  case Triple::mipsel:  T.setArch(Triple::mips64el);  break;
 944  case Triple::nvptx:   T.setArch(Triple::nvptx64);   break;
 945  case Triple::ppc:     T.setArch(Triple::ppc64);     break;
 946  case Triple::sparc:   T.setArch(Triple::sparcv9);   break;
 947  case Triple::x86:     T.setArch(Triple::x86_64);    break;
 948  case Triple::amdil:   T.setArch(Triple::amdil64);   break;
 949  case Triple::hsail:   T.setArch(Triple::hsail64);   break;
 950  case Triple::spir:    T.setArch(Triple::spir64);    break;
 951  }
 952  return T;
 953}
 954
 955// FIXME: tblgen this.
 956const char *Triple::getARMCPUForArch(StringRef MArch) const {
 957  if (MArch.empty())
 958    MArch = getArchName();
 959
 960  switch (getOS()) {
 961  case llvm::Triple::FreeBSD:
 962  case llvm::Triple::NetBSD:
 963    if (MArch == "armv6")
 964      return "arm1176jzf-s";
 965    break;
 966  case llvm::Triple::Win32:
 967    // FIXME: this is invalid for WindowsCE
 968    return "cortex-a9";
 969  default:
 970    break;
 971  }
 972
 973  const char *result = nullptr;
 974  size_t offset = StringRef::npos;
 975  if (MArch.startswith("arm"))
 976    offset = 3;
 977  if (MArch.startswith("thumb"))
 978    offset = 5;
 979  if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
 980    offset += 2;
 981  if (offset != StringRef::npos)
 982    result = llvm::StringSwitch<const char *>(MArch.substr(offset))
 983      .Cases("v2", "v2a", "arm2")
 984      .Case("v3", "arm6")
 985      .Case("v3m", "arm7m")
 986      .Case("v4", "strongarm")
 987      .Case("v4t", "arm7tdmi")
 988      .Cases("v5", "v5t", "arm10tdmi")
 989      .Cases("v5e", "v5te", "arm1022e")
 990      .Case("v5tej", "arm926ej-s")
 991      .Cases("v6", "v6k", "arm1136jf-s")
 992      .Case("v6j", "arm1136j-s")
 993      .Cases("v6z", "v6zk", "arm1176jzf-s")
 994      .Case("v6t2", "arm1156t2-s")
 995      .Cases("v6m", "v6-m", "cortex-m0")
 996      .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
 997      .Cases("v7s", "v7-s", "swift")
 998      .Cases("v7r", "v7-r", "cortex-r4")
 999      .Cases("v7m", "v7-m", "cortex-m3")
1000      .Cases("v7em", "v7e-m", "cortex-m4")
1001      .Cases("v8", "v8a", "v8-a", "cortex-a53")
1002      .Default(nullptr);
1003  else
1004    result = llvm::StringSwitch<const char *>(MArch)
1005      .Case("ep9312", "ep9312")
1006      .Case("iwmmxt", "iwmmxt")
1007      .Case("xscale", "xscale")
1008      .Default(nullptr);
1009
1010  if (result)
1011    return result;
1012
1013  // If all else failed, return the most base CPU with thumb interworking
1014  // supported by LLVM.
1015  // FIXME: Should warn once that we're falling back.
1016  switch (getOS()) {
1017  case llvm::Triple::NetBSD:
1018    switch (getEnvironment()) {
1019    case llvm::Triple::GNUEABIHF:
1020    case llvm::Triple::GNUEABI:
1021    case llvm::Triple::EABIHF:
1022    case llvm::Triple::EABI:
1023      return "arm926ej-s";
1024    default:
1025      return "strongarm";
1026    }
1027  default:
1028    switch (getEnvironment()) {
1029    case llvm::Triple::EABIHF:
1030    case llvm::Triple::GNUEABIHF:
1031      return "arm1176jzf-s";
1032    default:
1033      return "arm7tdmi";
1034    }
1035  }
1036}