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