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