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