PageRenderTime 111ms CodeModel.GetById 2ms app.highlight 101ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Support/Triple.cpp

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