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