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