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