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