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