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