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