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/SmallString.h"
12#include "llvm/ADT/StringSwitch.h"
13#include "llvm/ADT/STLExtras.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 arm:     return "arm";
23  case cellspu: return "cellspu";
24  case hexagon: return "hexagon";
25  case mips:    return "mips";
26  case mipsel:  return "mipsel";
27  case mips64:  return "mips64";
28  case mips64el:return "mips64el";
29  case msp430:  return "msp430";
30  case ppc64:   return "powerpc64";
31  case ppc:     return "powerpc";
32  case r600:    return "r600";
33  case sparc:   return "sparc";
34  case sparcv9: return "sparcv9";
35  case tce:     return "tce";
36  case thumb:   return "thumb";
37  case x86:     return "i386";
38  case x86_64:  return "x86_64";
39  case xcore:   return "xcore";
40  case mblaze:  return "mblaze";
41  case nvptx:   return "nvptx";
42  case nvptx64: return "nvptx64";
43  case le32:    return "le32";
44  case amdil:   return "amdil";
45  }
46
47  llvm_unreachable("Invalid ArchType!");
48}
49
50const char *Triple::getArchTypePrefix(ArchType Kind) {
51  switch (Kind) {
52  default:
53    return 0;
54
55  case arm:
56  case thumb:   return "arm";
57
58  case cellspu: return "spu";
59
60  case ppc64:
61  case ppc:     return "ppc";
62
63  case mblaze:  return "mblaze";
64
65  case mips:
66  case mipsel:
67  case mips64:
68  case mips64el:return "mips";
69
70  case hexagon: return "hexagon";
71
72  case r600:    return "r600";
73
74  case sparcv9:
75  case sparc:   return "sparc";
76
77  case x86:
78  case x86_64:  return "x86";
79
80  case xcore:   return "xcore";
81
82  case nvptx:   return "nvptx";
83  case nvptx64: return "nvptx";
84  case le32:    return "le32";
85  case amdil:   return "amdil";
86  }
87}
88
89const char *Triple::getVendorTypeName(VendorType Kind) {
90  switch (Kind) {
91  case UnknownVendor: return "unknown";
92
93  case Apple: return "apple";
94  case PC: return "pc";
95  case SCEI: return "scei";
96  case BGP: return "bgp";
97  case BGQ: return "bgq";
98  case Freescale: return "fsl";
99  }
100
101  llvm_unreachable("Invalid VendorType!");
102}
103
104const char *Triple::getOSTypeName(OSType Kind) {
105  switch (Kind) {
106  case UnknownOS: return "unknown";
107
108  case AuroraUX: return "auroraux";
109  case Cygwin: return "cygwin";
110  case Darwin: return "darwin";
111  case DragonFly: return "dragonfly";
112  case FreeBSD: return "freebsd";
113  case IOS: return "ios";
114  case KFreeBSD: return "kfreebsd";
115  case Linux: return "linux";
116  case Lv2: return "lv2";
117  case MacOSX: return "macosx";
118  case MinGW32: return "mingw32";
119  case NetBSD: return "netbsd";
120  case OpenBSD: return "openbsd";
121  case Solaris: return "solaris";
122  case Win32: return "win32";
123  case Haiku: return "haiku";
124  case Minix: return "minix";
125  case RTEMS: return "rtems";
126  case NativeClient: return "nacl";
127  case CNK: return "cnk";
128  case Bitrig: return "bitrig";
129  }
130
131  llvm_unreachable("Invalid OSType");
132}
133
134const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
135  switch (Kind) {
136  case UnknownEnvironment: return "unknown";
137  case GNU: return "gnu";
138  case GNUEABIHF: return "gnueabihf";
139  case GNUEABI: return "gnueabi";
140  case EABI: return "eabi";
141  case MachO: return "macho";
142  case Android: return "android";
143  }
144
145  llvm_unreachable("Invalid EnvironmentType!");
146}
147
148Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
149  return StringSwitch<Triple::ArchType>(Name)
150    .Case("arm", arm)
151    .Case("cellspu", cellspu)
152    .Case("mips", mips)
153    .Case("mipsel", mipsel)
154    .Case("mips64", mips64)
155    .Case("mips64el", mips64el)
156    .Case("msp430", msp430)
157    .Case("ppc64", ppc64)
158    .Case("ppc32", ppc)
159    .Case("ppc", ppc)
160    .Case("mblaze", mblaze)
161    .Case("r600", r600)
162    .Case("hexagon", hexagon)
163    .Case("sparc", sparc)
164    .Case("sparcv9", sparcv9)
165    .Case("tce", tce)
166    .Case("thumb", thumb)
167    .Case("x86", x86)
168    .Case("x86-64", x86_64)
169    .Case("xcore", xcore)
170    .Case("nvptx", nvptx)
171    .Case("nvptx64", nvptx64)
172    .Case("le32", le32)
173    .Case("amdil", amdil)
174    .Default(UnknownArch);
175}
176
177Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
178  // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
179  // archs which Darwin doesn't use.
180
181  // The matching this routine does is fairly pointless, since it is neither the
182  // complete architecture list, nor a reasonable subset. The problem is that
183  // historically the driver driver accepts this and also ties its -march=
184  // handling to the architecture name, so we need to be careful before removing
185  // support for it.
186
187  // This code must be kept in sync with Clang's Darwin specific argument
188  // translation.
189
190  return StringSwitch<ArchType>(Str)
191    .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", Triple::ppc)
192    .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", Triple::ppc)
193    .Case("ppc64", Triple::ppc64)
194    .Cases("i386", "i486", "i486SX", "i586", "i686", Triple::x86)
195    .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
196           Triple::x86)
197    .Case("x86_64", Triple::x86_64)
198    // This is derived from the driver driver.
199    .Cases("arm", "armv4t", "armv5", "armv6", Triple::arm)
200    .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", Triple::arm)
201    .Case("r600", Triple::r600)
202    .Case("nvptx", Triple::nvptx)
203    .Case("nvptx64", Triple::nvptx64)
204    .Case("amdil", Triple::amdil)
205    .Default(Triple::UnknownArch);
206}
207
208// Returns architecture name that is understood by the target assembler.
209const char *Triple::getArchNameForAssembler() {
210  if (!isOSDarwin() && getVendor() != Triple::Apple)
211    return NULL;
212
213  return StringSwitch<const char*>(getArchName())
214    .Case("i386", "i386")
215    .Case("x86_64", "x86_64")
216    .Case("powerpc", "ppc")
217    .Case("powerpc64", "ppc64")
218    .Cases("mblaze", "microblaze", "mblaze")
219    .Case("arm", "arm")
220    .Cases("armv4t", "thumbv4t", "armv4t")
221    .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
222    .Cases("armv6", "thumbv6", "armv6")
223    .Cases("armv7", "thumbv7", "armv7")
224    .Case("r600", "r600")
225    .Case("nvptx", "nvptx")
226    .Case("nvptx64", "nvptx64")
227    .Case("le32", "le32")
228    .Case("amdil", "amdil")
229    .Default(NULL);
230}
231
232static Triple::ArchType parseArch(StringRef ArchName) {
233  return StringSwitch<Triple::ArchType>(ArchName)
234    .Cases("i386", "i486", "i586", "i686", Triple::x86)
235    // FIXME: Do we need to support these?
236    .Cases("i786", "i886", "i986", Triple::x86)
237    .Cases("amd64", "x86_64", Triple::x86_64)
238    .Case("powerpc", Triple::ppc)
239    .Cases("powerpc64", "ppu", Triple::ppc64)
240    .Case("mblaze", Triple::mblaze)
241    .Cases("arm", "xscale", Triple::arm)
242    // FIXME: It would be good to replace these with explicit names for all the
243    // various suffixes supported.
244    .StartsWith("armv", Triple::arm)
245    .Case("thumb", Triple::thumb)
246    .StartsWith("thumbv", Triple::thumb)
247    .Cases("spu", "cellspu", Triple::cellspu)
248    .Case("msp430", Triple::msp430)
249    .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
250    .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
251    .Cases("mips64", "mips64eb", Triple::mips64)
252    .Case("mips64el", Triple::mips64el)
253    .Case("r600", Triple::r600)
254    .Case("hexagon", Triple::hexagon)
255    .Case("sparc", Triple::sparc)
256    .Case("sparcv9", 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("amdil", Triple::amdil)
263    .Default(Triple::UnknownArch);
264}
265
266static Triple::VendorType parseVendor(StringRef VendorName) {
267  return StringSwitch<Triple::VendorType>(VendorName)
268    .Case("apple", Triple::Apple)
269    .Case("pc", Triple::PC)
270    .Case("scei", Triple::SCEI)
271    .Case("bgp", Triple::BGP)
272    .Case("bgq", Triple::BGQ)
273    .Case("fsl", Triple::Freescale)
274    .Default(Triple::UnknownVendor);
275}
276
277static Triple::OSType parseOS(StringRef OSName) {
278  return StringSwitch<Triple::OSType>(OSName)
279    .StartsWith("auroraux", Triple::AuroraUX)
280    .StartsWith("cygwin", Triple::Cygwin)
281    .StartsWith("darwin", Triple::Darwin)
282    .StartsWith("dragonfly", Triple::DragonFly)
283    .StartsWith("freebsd", Triple::FreeBSD)
284    .StartsWith("ios", Triple::IOS)
285    .StartsWith("kfreebsd", Triple::KFreeBSD)
286    .StartsWith("linux", Triple::Linux)
287    .StartsWith("lv2", Triple::Lv2)
288    .StartsWith("macosx", Triple::MacOSX)
289    .StartsWith("mingw32", Triple::MinGW32)
290    .StartsWith("netbsd", Triple::NetBSD)
291    .StartsWith("openbsd", Triple::OpenBSD)
292    .StartsWith("solaris", Triple::Solaris)
293    .StartsWith("win32", Triple::Win32)
294    .StartsWith("haiku", Triple::Haiku)
295    .StartsWith("minix", Triple::Minix)
296    .StartsWith("rtems", Triple::RTEMS)
297    .StartsWith("nacl", Triple::NativeClient)
298    .StartsWith("cnk", Triple::CNK)
299    .StartsWith("bitrig", Triple::Bitrig)
300    .Default(Triple::UnknownOS);
301}
302
303static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
304  return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
305    .StartsWith("eabi", Triple::EABI)
306    .StartsWith("gnueabihf", Triple::GNUEABIHF)
307    .StartsWith("gnueabi", Triple::GNUEABI)
308    .StartsWith("gnu", Triple::GNU)
309    .StartsWith("macho", Triple::MachO)
310    .StartsWith("android", Triple::Android)
311    .Default(Triple::UnknownEnvironment);
312}
313
314/// \brief Construct a triple from the string representation provided.
315///
316/// This stores the string representation and parses the various pieces into
317/// enum members.
318Triple::Triple(const Twine &Str)
319    : Data(Str.str()),
320      Arch(parseArch(getArchName())),
321      Vendor(parseVendor(getVendorName())),
322      OS(parseOS(getOSName())),
323      Environment(parseEnvironment(getEnvironmentName())) {
324}
325
326/// \brief Construct a triple from string representations of the architecture,
327/// vendor, and OS.
328///
329/// This joins each argument into a canonical string representation and parses
330/// them into enum members. It leaves the environment unknown and omits it from
331/// the string representation.
332Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
333    : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
334      Arch(parseArch(ArchStr.str())),
335      Vendor(parseVendor(VendorStr.str())),
336      OS(parseOS(OSStr.str())),
337      Environment() {
338}
339
340/// \brief Construct a triple from string representations of the architecture,
341/// vendor, OS, and environment.
342///
343/// This joins each argument into a canonical string representation and parses
344/// them into enum members.
345Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
346               const Twine &EnvironmentStr)
347    : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
348            EnvironmentStr).str()),
349      Arch(parseArch(ArchStr.str())),
350      Vendor(parseVendor(VendorStr.str())),
351      OS(parseOS(OSStr.str())),
352      Environment(parseEnvironment(EnvironmentStr.str())) {
353}
354
355std::string Triple::normalize(StringRef Str) {
356  // Parse into components.
357  SmallVector<StringRef, 4> Components;
358  Str.split(Components, "-");
359
360  // If the first component corresponds to a known architecture, preferentially
361  // use it for the architecture.  If the second component corresponds to a
362  // known vendor, preferentially use it for the vendor, etc.  This avoids silly
363  // component movement when a component parses as (eg) both a valid arch and a
364  // valid os.
365  ArchType Arch = UnknownArch;
366  if (Components.size() > 0)
367    Arch = parseArch(Components[0]);
368  VendorType Vendor = UnknownVendor;
369  if (Components.size() > 1)
370    Vendor = parseVendor(Components[1]);
371  OSType OS = UnknownOS;
372  if (Components.size() > 2)
373    OS = parseOS(Components[2]);
374  EnvironmentType Environment = UnknownEnvironment;
375  if (Components.size() > 3)
376    Environment = parseEnvironment(Components[3]);
377
378  // Note which components are already in their final position.  These will not
379  // be moved.
380  bool Found[4];
381  Found[0] = Arch != UnknownArch;
382  Found[1] = Vendor != UnknownVendor;
383  Found[2] = OS != UnknownOS;
384  Found[3] = Environment != UnknownEnvironment;
385
386  // If they are not there already, permute the components into their canonical
387  // positions by seeing if they parse as a valid architecture, and if so moving
388  // the component to the architecture position etc.
389  for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
390    if (Found[Pos])
391      continue; // Already in the canonical position.
392
393    for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
394      // Do not reparse any components that already matched.
395      if (Idx < array_lengthof(Found) && Found[Idx])
396        continue;
397
398      // Does this component parse as valid for the target position?
399      bool Valid = false;
400      StringRef Comp = Components[Idx];
401      switch (Pos) {
402      default: llvm_unreachable("unexpected component type!");
403      case 0:
404        Arch = parseArch(Comp);
405        Valid = Arch != UnknownArch;
406        break;
407      case 1:
408        Vendor = parseVendor(Comp);
409        Valid = Vendor != UnknownVendor;
410        break;
411      case 2:
412        OS = parseOS(Comp);
413        Valid = OS != UnknownOS;
414        break;
415      case 3:
416        Environment = parseEnvironment(Comp);
417        Valid = Environment != UnknownEnvironment;
418        break;
419      }
420      if (!Valid)
421        continue; // Nope, try the next component.
422
423      // Move the component to the target position, pushing any non-fixed
424      // components that are in the way to the right.  This tends to give
425      // good results in the common cases of a forgotten vendor component
426      // or a wrongly positioned environment.
427      if (Pos < Idx) {
428        // Insert left, pushing the existing components to the right.  For
429        // example, a-b-i386 -> i386-a-b when moving i386 to the front.
430        StringRef CurrentComponent(""); // The empty component.
431        // Replace the component we are moving with an empty component.
432        std::swap(CurrentComponent, Components[Idx]);
433        // Insert the component being moved at Pos, displacing any existing
434        // components to the right.
435        for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
436          // Skip over any fixed components.
437          while (i < array_lengthof(Found) && Found[i])
438            ++i;
439          // Place the component at the new position, getting the component
440          // that was at this position - it will be moved right.
441          std::swap(CurrentComponent, Components[i]);
442        }
443      } else if (Pos > Idx) {
444        // Push right by inserting empty components until the component at Idx
445        // reaches the target position Pos.  For example, pc-a -> -pc-a when
446        // moving pc to the second position.
447        do {
448          // Insert one empty component at Idx.
449          StringRef CurrentComponent(""); // The empty component.
450          for (unsigned i = Idx; i < Components.size();) {
451            // Place the component at the new position, getting the component
452            // that was at this position - it will be moved right.
453            std::swap(CurrentComponent, Components[i]);
454            // If it was placed on top of an empty component then we are done.
455            if (CurrentComponent.empty())
456              break;
457            // Advance to the next component, skipping any fixed components.
458            while (++i < array_lengthof(Found) && Found[i])
459              ;
460          }
461          // The last component was pushed off the end - append it.
462          if (!CurrentComponent.empty())
463            Components.push_back(CurrentComponent);
464
465          // Advance Idx to the component's new position.
466          while (++Idx < array_lengthof(Found) && Found[Idx])
467            ;
468        } while (Idx < Pos); // Add more until the final position is reached.
469      }
470      assert(Pos < Components.size() && Components[Pos] == Comp &&
471             "Component moved wrong!");
472      Found[Pos] = true;
473      break;
474    }
475  }
476
477  // Special case logic goes here.  At this point Arch, Vendor and OS have the
478  // correct values for the computed components.
479
480  // Stick the corrected components back together to form the normalized string.
481  std::string Normalized;
482  for (unsigned i = 0, e = Components.size(); i != e; ++i) {
483    if (i) Normalized += '-';
484    Normalized += Components[i];
485  }
486  return Normalized;
487}
488
489StringRef Triple::getArchName() const {
490  return StringRef(Data).split('-').first;           // Isolate first component
491}
492
493StringRef Triple::getVendorName() const {
494  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
495  return Tmp.split('-').first;                       // Isolate second component
496}
497
498StringRef Triple::getOSName() const {
499  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
500  Tmp = Tmp.split('-').second;                       // Strip second component
501  return Tmp.split('-').first;                       // Isolate third component
502}
503
504StringRef Triple::getEnvironmentName() const {
505  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
506  Tmp = Tmp.split('-').second;                       // Strip second component
507  return Tmp.split('-').second;                      // Strip third component
508}
509
510StringRef Triple::getOSAndEnvironmentName() const {
511  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
512  return Tmp.split('-').second;                      // Strip second component
513}
514
515static unsigned EatNumber(StringRef &Str) {
516  assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
517  unsigned Result = 0;
518
519  do {
520    // Consume the leading digit.
521    Result = Result*10 + (Str[0] - '0');
522
523    // Eat the digit.
524    Str = Str.substr(1);
525  } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
526
527  return Result;
528}
529
530void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
531                          unsigned &Micro) const {
532  StringRef OSName = getOSName();
533
534  // Assume that the OS portion of the triple starts with the canonical name.
535  StringRef OSTypeName = getOSTypeName(getOS());
536  if (OSName.startswith(OSTypeName))
537    OSName = OSName.substr(OSTypeName.size());
538
539  // Any unset version defaults to 0.
540  Major = Minor = Micro = 0;
541
542  // Parse up to three components.
543  unsigned *Components[3] = { &Major, &Minor, &Micro };
544  for (unsigned i = 0; i != 3; ++i) {
545    if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
546      break;
547
548    // Consume the leading number.
549    *Components[i] = EatNumber(OSName);
550
551    // Consume the separator, if present.
552    if (OSName.startswith("."))
553      OSName = OSName.substr(1);
554  }
555}
556
557bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
558                              unsigned &Micro) const {
559  getOSVersion(Major, Minor, Micro);
560
561  switch (getOS()) {
562  default: llvm_unreachable("unexpected OS for Darwin triple");
563  case Darwin:
564    // Default to darwin8, i.e., MacOSX 10.4.
565    if (Major == 0)
566      Major = 8;
567    // Darwin version numbers are skewed from OS X versions.
568    if (Major < 4)
569      return false;
570    Micro = 0;
571    Minor = Major - 4;
572    Major = 10;
573    break;
574  case MacOSX:
575    // Default to 10.4.
576    if (Major == 0) {
577      Major = 10;
578      Minor = 4;
579    }
580    if (Major != 10)
581      return false;
582    break;
583  case IOS:
584    // Ignore the version from the triple.  This is only handled because the
585    // the clang driver combines OS X and IOS support into a common Darwin
586    // toolchain that wants to know the OS X version number even when targeting
587    // IOS.
588    Major = 10;
589    Minor = 4;
590    Micro = 0;
591    break;
592  }
593  return true;
594}
595
596void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
597                           unsigned &Micro) const {
598  switch (getOS()) {
599  default: llvm_unreachable("unexpected OS for Darwin triple");
600  case Darwin:
601  case MacOSX:
602    // Ignore the version from the triple.  This is only handled because the
603    // the clang driver combines OS X and IOS support into a common Darwin
604    // toolchain that wants to know the iOS version number even when targeting
605    // OS X.
606    Major = 3;
607    Minor = 0;
608    Micro = 0;
609    break;
610  case IOS:
611    getOSVersion(Major, Minor, Micro);
612    // Default to 3.0.
613    if (Major == 0)
614      Major = 3;
615    break;
616  }
617}
618
619void Triple::setTriple(const Twine &Str) {
620  *this = Triple(Str);
621}
622
623void Triple::setArch(ArchType Kind) {
624  setArchName(getArchTypeName(Kind));
625}
626
627void Triple::setVendor(VendorType Kind) {
628  setVendorName(getVendorTypeName(Kind));
629}
630
631void Triple::setOS(OSType Kind) {
632  setOSName(getOSTypeName(Kind));
633}
634
635void Triple::setEnvironment(EnvironmentType Kind) {
636  setEnvironmentName(getEnvironmentTypeName(Kind));
637}
638
639void Triple::setArchName(StringRef Str) {
640  // Work around a miscompilation bug for Twines in gcc 4.0.3.
641  SmallString<64> Triple;
642  Triple += Str;
643  Triple += "-";
644  Triple += getVendorName();
645  Triple += "-";
646  Triple += getOSAndEnvironmentName();
647  setTriple(Triple.str());
648}
649
650void Triple::setVendorName(StringRef Str) {
651  setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
652}
653
654void Triple::setOSName(StringRef Str) {
655  if (hasEnvironment())
656    setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
657              "-" + getEnvironmentName());
658  else
659    setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
660}
661
662void Triple::setEnvironmentName(StringRef Str) {
663  setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
664            "-" + Str);
665}
666
667void Triple::setOSAndEnvironmentName(StringRef Str) {
668  setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
669}
670
671static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
672  switch (Arch) {
673  case llvm::Triple::UnknownArch:
674    return 0;
675
676  case llvm::Triple::msp430:
677    return 16;
678
679  case llvm::Triple::amdil:
680  case llvm::Triple::arm:
681  case llvm::Triple::cellspu:
682  case llvm::Triple::hexagon:
683  case llvm::Triple::le32:
684  case llvm::Triple::mblaze:
685  case llvm::Triple::mips:
686  case llvm::Triple::mipsel:
687  case llvm::Triple::nvptx:
688  case llvm::Triple::ppc:
689  case llvm::Triple::r600:
690  case llvm::Triple::sparc:
691  case llvm::Triple::tce:
692  case llvm::Triple::thumb:
693  case llvm::Triple::x86:
694  case llvm::Triple::xcore:
695    return 32;
696
697  case llvm::Triple::mips64:
698  case llvm::Triple::mips64el:
699  case llvm::Triple::nvptx64:
700  case llvm::Triple::ppc64:
701  case llvm::Triple::sparcv9:
702  case llvm::Triple::x86_64:
703    return 64;
704  }
705  llvm_unreachable("Invalid architecture value");
706}
707
708bool Triple::isArch64Bit() const {
709  return getArchPointerBitWidth(getArch()) == 64;
710}
711
712bool Triple::isArch32Bit() const {
713  return getArchPointerBitWidth(getArch()) == 32;
714}
715
716bool Triple::isArch16Bit() const {
717  return getArchPointerBitWidth(getArch()) == 16;
718}
719
720Triple Triple::get32BitArchVariant() const {
721  Triple T(*this);
722  switch (getArch()) {
723  case Triple::UnknownArch:
724  case Triple::msp430:
725    T.setArch(UnknownArch);
726    break;
727
728  case Triple::amdil:
729  case Triple::arm:
730  case Triple::cellspu:
731  case Triple::hexagon:
732  case Triple::le32:
733  case Triple::mblaze:
734  case Triple::mips:
735  case Triple::mipsel:
736  case Triple::nvptx:
737  case Triple::ppc:
738  case Triple::r600:
739  case Triple::sparc:
740  case Triple::tce:
741  case Triple::thumb:
742  case Triple::x86:
743  case Triple::xcore:
744    // Already 32-bit.
745    break;
746
747  case Triple::mips64:    T.setArch(Triple::mips);    break;
748  case Triple::mips64el:  T.setArch(Triple::mipsel);  break;
749  case Triple::nvptx64:   T.setArch(Triple::nvptx);   break;
750  case Triple::ppc64:     T.setArch(Triple::ppc);   break;
751  case Triple::sparcv9:   T.setArch(Triple::sparc);   break;
752  case Triple::x86_64:    T.setArch(Triple::x86);     break;
753  }
754  return T;
755}
756
757Triple Triple::get64BitArchVariant() const {
758  Triple T(*this);
759  switch (getArch()) {
760  case Triple::UnknownArch:
761  case Triple::amdil:
762  case Triple::arm:
763  case Triple::cellspu:
764  case Triple::hexagon:
765  case Triple::le32:
766  case Triple::mblaze:
767  case Triple::msp430:
768  case Triple::r600:
769  case Triple::tce:
770  case Triple::thumb:
771  case Triple::xcore:
772    T.setArch(UnknownArch);
773    break;
774
775  case Triple::mips64:
776  case Triple::mips64el:
777  case Triple::nvptx64:
778  case Triple::ppc64:
779  case Triple::sparcv9:
780  case Triple::x86_64:
781    // Already 64-bit.
782    break;
783
784  case Triple::mips:    T.setArch(Triple::mips64);    break;
785  case Triple::mipsel:  T.setArch(Triple::mips64el);  break;
786  case Triple::nvptx:   T.setArch(Triple::nvptx64);   break;
787  case Triple::ppc:     T.setArch(Triple::ppc64);     break;
788  case Triple::sparc:   T.setArch(Triple::sparcv9);   break;
789  case Triple::x86:     T.setArch(Triple::x86_64);    break;
790  }
791  return T;
792}
793