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