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