Add hsail and amdil64 to Triple
[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 parseArch(StringRef ArchName) {
226   return StringSwitch<Triple::ArchType>(ArchName)
227     .Cases("i386", "i486", "i586", "i686", Triple::x86)
228     // FIXME: Do we need to support these?
229     .Cases("i786", "i886", "i986", Triple::x86)
230     .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
231     .Case("powerpc", Triple::ppc)
232     .Cases("powerpc64", "ppu", Triple::ppc64)
233     .Case("powerpc64le", Triple::ppc64le)
234     .Case("aarch64", Triple::aarch64)
235     .Case("aarch64_be", Triple::aarch64_be)
236     .Case("arm64", Triple::aarch64)
237     .Cases("arm", "xscale", Triple::arm)
238     // FIXME: It would be good to replace these with explicit names for all the
239     // various suffixes supported.
240     .StartsWith("armv", Triple::arm)
241     .Case("armeb", Triple::armeb)
242     .StartsWith("armebv", Triple::armeb)
243     .Case("thumb", Triple::thumb)
244     .StartsWith("thumbv", Triple::thumb)
245     .Case("thumbeb", Triple::thumbeb)
246     .StartsWith("thumbebv", Triple::thumbeb)
247     .Case("msp430", Triple::msp430)
248     .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
249     .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
250     .Cases("mips64", "mips64eb", Triple::mips64)
251     .Case("mips64el", Triple::mips64el)
252     .Case("r600", Triple::r600)
253     .Case("hexagon", Triple::hexagon)
254     .Case("s390x", Triple::systemz)
255     .Case("sparc", Triple::sparc)
256     .Cases("sparcv9", "sparc64", Triple::sparcv9)
257     .Case("tce", Triple::tce)
258     .Case("xcore", Triple::xcore)
259     .Case("nvptx", Triple::nvptx)
260     .Case("nvptx64", Triple::nvptx64)
261     .Case("le32", Triple::le32)
262     .Case("le64", Triple::le64)
263     .Case("amdil", Triple::amdil)
264     .Case("amdil64", Triple::amdil64)
265     .Case("hsail", Triple::hsail)
266     .Case("hsail64", Triple::hsail64)
267     .Case("spir", Triple::spir)
268     .Case("spir64", Triple::spir64)
269     .StartsWith("kalimba", Triple::kalimba)
270     .Default(Triple::UnknownArch);
271 }
272
273 static Triple::VendorType parseVendor(StringRef VendorName) {
274   return StringSwitch<Triple::VendorType>(VendorName)
275     .Case("apple", Triple::Apple)
276     .Case("pc", Triple::PC)
277     .Case("scei", Triple::SCEI)
278     .Case("bgp", Triple::BGP)
279     .Case("bgq", Triple::BGQ)
280     .Case("fsl", Triple::Freescale)
281     .Case("ibm", Triple::IBM)
282     .Case("img", Triple::ImaginationTechnologies)
283     .Case("mti", Triple::MipsTechnologies)
284     .Case("nvidia", Triple::NVIDIA)
285     .Case("csr", Triple::CSR)
286     .Default(Triple::UnknownVendor);
287 }
288
289 static Triple::OSType parseOS(StringRef OSName) {
290   return StringSwitch<Triple::OSType>(OSName)
291     .StartsWith("darwin", Triple::Darwin)
292     .StartsWith("dragonfly", Triple::DragonFly)
293     .StartsWith("freebsd", Triple::FreeBSD)
294     .StartsWith("ios", Triple::IOS)
295     .StartsWith("kfreebsd", Triple::KFreeBSD)
296     .StartsWith("linux", Triple::Linux)
297     .StartsWith("lv2", Triple::Lv2)
298     .StartsWith("macosx", Triple::MacOSX)
299     .StartsWith("netbsd", Triple::NetBSD)
300     .StartsWith("openbsd", Triple::OpenBSD)
301     .StartsWith("solaris", Triple::Solaris)
302     .StartsWith("win32", Triple::Win32)
303     .StartsWith("windows", Triple::Win32)
304     .StartsWith("haiku", Triple::Haiku)
305     .StartsWith("minix", Triple::Minix)
306     .StartsWith("rtems", Triple::RTEMS)
307     .StartsWith("nacl", Triple::NaCl)
308     .StartsWith("cnk", Triple::CNK)
309     .StartsWith("bitrig", Triple::Bitrig)
310     .StartsWith("aix", Triple::AIX)
311     .StartsWith("cuda", Triple::CUDA)
312     .StartsWith("nvcl", Triple::NVCL)
313     .Default(Triple::UnknownOS);
314 }
315
316 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
317   return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
318     .StartsWith("eabihf", Triple::EABIHF)
319     .StartsWith("eabi", Triple::EABI)
320     .StartsWith("gnueabihf", Triple::GNUEABIHF)
321     .StartsWith("gnueabi", Triple::GNUEABI)
322     .StartsWith("gnux32", Triple::GNUX32)
323     .StartsWith("code16", Triple::CODE16)
324     .StartsWith("gnu", Triple::GNU)
325     .StartsWith("android", Triple::Android)
326     .StartsWith("msvc", Triple::MSVC)
327     .StartsWith("itanium", Triple::Itanium)
328     .StartsWith("cygnus", Triple::Cygnus)
329     .Default(Triple::UnknownEnvironment);
330 }
331
332 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
333   return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
334     .EndsWith("coff", Triple::COFF)
335     .EndsWith("elf", Triple::ELF)
336     .EndsWith("macho", Triple::MachO)
337     .Default(Triple::UnknownObjectFormat);
338 }
339
340 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
341   return StringSwitch<Triple::SubArchType>(SubArchName)
342     .EndsWith("v8", Triple::ARMSubArch_v8)
343     .EndsWith("v8a", Triple::ARMSubArch_v8)
344     .EndsWith("v7", Triple::ARMSubArch_v7)
345     .EndsWith("v7a", Triple::ARMSubArch_v7)
346     .EndsWith("v7em", Triple::ARMSubArch_v7em)
347     .EndsWith("v7l", Triple::ARMSubArch_v7)
348     .EndsWith("v7m", Triple::ARMSubArch_v7m)
349     .EndsWith("v7r", Triple::ARMSubArch_v7)
350     .EndsWith("v7s", Triple::ARMSubArch_v7s)
351     .EndsWith("v6", Triple::ARMSubArch_v6)
352     .EndsWith("v6m", Triple::ARMSubArch_v6m)
353     .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
354     .EndsWith("v5", Triple::ARMSubArch_v5)
355     .EndsWith("v5e", Triple::ARMSubArch_v5)
356     .EndsWith("v5t", Triple::ARMSubArch_v5)
357     .EndsWith("v5te", Triple::ARMSubArch_v5te)
358     .EndsWith("v4t", Triple::ARMSubArch_v4t)
359     .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
360     .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
361     .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
362     .Default(Triple::NoSubArch);
363 }
364
365 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
366   switch (Kind) {
367   case Triple::UnknownObjectFormat: return "";
368   case Triple::COFF: return "coff";
369   case Triple::ELF: return "elf";
370   case Triple::MachO: return "macho";
371   }
372   llvm_unreachable("unknown object format type");
373 }
374
375 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
376   if (T.isOSDarwin())
377     return Triple::MachO;
378   else if (T.isOSWindows())
379     return Triple::COFF;
380   return Triple::ELF;
381 }
382
383 /// \brief Construct a triple from the string representation provided.
384 ///
385 /// This stores the string representation and parses the various pieces into
386 /// enum members.
387 Triple::Triple(const Twine &Str)
388     : Data(Str.str()),
389       Arch(parseArch(getArchName())),
390       SubArch(parseSubArch(getArchName())),
391       Vendor(parseVendor(getVendorName())),
392       OS(parseOS(getOSName())),
393       Environment(parseEnvironment(getEnvironmentName())),
394       ObjectFormat(parseFormat(getEnvironmentName())) {
395   if (ObjectFormat == Triple::UnknownObjectFormat)
396     ObjectFormat = getDefaultFormat(*this);
397 }
398
399 /// \brief Construct a triple from string representations of the architecture,
400 /// vendor, and OS.
401 ///
402 /// This joins each argument into a canonical string representation and parses
403 /// them into enum members. It leaves the environment unknown and omits it from
404 /// the string representation.
405 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
406     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
407       Arch(parseArch(ArchStr.str())),
408       SubArch(parseSubArch(ArchStr.str())),
409       Vendor(parseVendor(VendorStr.str())),
410       OS(parseOS(OSStr.str())),
411       Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
412   ObjectFormat = getDefaultFormat(*this);
413 }
414
415 /// \brief Construct a triple from string representations of the architecture,
416 /// vendor, OS, and environment.
417 ///
418 /// This joins each argument into a canonical string representation and parses
419 /// them into enum members.
420 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
421                const Twine &EnvironmentStr)
422     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
423             EnvironmentStr).str()),
424       Arch(parseArch(ArchStr.str())),
425       SubArch(parseSubArch(ArchStr.str())),
426       Vendor(parseVendor(VendorStr.str())),
427       OS(parseOS(OSStr.str())),
428       Environment(parseEnvironment(EnvironmentStr.str())),
429       ObjectFormat(parseFormat(EnvironmentStr.str())) {
430   if (ObjectFormat == Triple::UnknownObjectFormat)
431     ObjectFormat = getDefaultFormat(*this);
432 }
433
434 std::string Triple::normalize(StringRef Str) {
435   bool IsMinGW32 = false;
436   bool IsCygwin = false;
437
438   // Parse into components.
439   SmallVector<StringRef, 4> Components;
440   Str.split(Components, "-");
441
442   // If the first component corresponds to a known architecture, preferentially
443   // use it for the architecture.  If the second component corresponds to a
444   // known vendor, preferentially use it for the vendor, etc.  This avoids silly
445   // component movement when a component parses as (eg) both a valid arch and a
446   // valid os.
447   ArchType Arch = UnknownArch;
448   if (Components.size() > 0)
449     Arch = parseArch(Components[0]);
450   VendorType Vendor = UnknownVendor;
451   if (Components.size() > 1)
452     Vendor = parseVendor(Components[1]);
453   OSType OS = UnknownOS;
454   if (Components.size() > 2) {
455     OS = parseOS(Components[2]);
456     IsCygwin = Components[2].startswith("cygwin");
457     IsMinGW32 = Components[2].startswith("mingw");
458   }
459   EnvironmentType Environment = UnknownEnvironment;
460   if (Components.size() > 3)
461     Environment = parseEnvironment(Components[3]);
462   ObjectFormatType ObjectFormat = UnknownObjectFormat;
463   if (Components.size() > 4)
464     ObjectFormat = parseFormat(Components[4]);
465
466   // Note which components are already in their final position.  These will not
467   // be moved.
468   bool Found[4];
469   Found[0] = Arch != UnknownArch;
470   Found[1] = Vendor != UnknownVendor;
471   Found[2] = OS != UnknownOS;
472   Found[3] = Environment != UnknownEnvironment;
473
474   // If they are not there already, permute the components into their canonical
475   // positions by seeing if they parse as a valid architecture, and if so moving
476   // the component to the architecture position etc.
477   for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
478     if (Found[Pos])
479       continue; // Already in the canonical position.
480
481     for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
482       // Do not reparse any components that already matched.
483       if (Idx < array_lengthof(Found) && Found[Idx])
484         continue;
485
486       // Does this component parse as valid for the target position?
487       bool Valid = false;
488       StringRef Comp = Components[Idx];
489       switch (Pos) {
490       default: llvm_unreachable("unexpected component type!");
491       case 0:
492         Arch = parseArch(Comp);
493         Valid = Arch != UnknownArch;
494         break;
495       case 1:
496         Vendor = parseVendor(Comp);
497         Valid = Vendor != UnknownVendor;
498         break;
499       case 2:
500         OS = parseOS(Comp);
501         IsCygwin = Comp.startswith("cygwin");
502         IsMinGW32 = Comp.startswith("mingw");
503         Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
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 (IsMinGW32) {
584     Components.resize(4);
585     Components[2] = "windows";
586     Components[3] = "gnu";
587   } else if (IsCygwin) {
588     Components.resize(4);
589     Components[2] = "windows";
590     Components[3] = "cygnus";
591   }
592   if (IsMinGW32 || IsCygwin ||
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() == aarch64) ? 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   setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
764                       getObjectFormatTypeName(Kind)).str());
765 }
766
767 void Triple::setArchName(StringRef Str) {
768   // Work around a miscompilation bug for Twines in gcc 4.0.3.
769   SmallString<64> Triple;
770   Triple += Str;
771   Triple += "-";
772   Triple += getVendorName();
773   Triple += "-";
774   Triple += getOSAndEnvironmentName();
775   setTriple(Triple.str());
776 }
777
778 void Triple::setVendorName(StringRef Str) {
779   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
780 }
781
782 void Triple::setOSName(StringRef Str) {
783   if (hasEnvironment())
784     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
785               "-" + getEnvironmentName());
786   else
787     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
788 }
789
790 void Triple::setEnvironmentName(StringRef Str) {
791   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
792             "-" + Str);
793 }
794
795 void Triple::setOSAndEnvironmentName(StringRef Str) {
796   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
797 }
798
799 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
800   switch (Arch) {
801   case llvm::Triple::UnknownArch:
802     return 0;
803
804   case llvm::Triple::msp430:
805     return 16;
806
807   case llvm::Triple::arm:
808   case llvm::Triple::armeb:
809   case llvm::Triple::hexagon:
810   case llvm::Triple::le32:
811   case llvm::Triple::mips:
812   case llvm::Triple::mipsel:
813   case llvm::Triple::nvptx:
814   case llvm::Triple::ppc:
815   case llvm::Triple::r600:
816   case llvm::Triple::sparc:
817   case llvm::Triple::tce:
818   case llvm::Triple::thumb:
819   case llvm::Triple::thumbeb:
820   case llvm::Triple::x86:
821   case llvm::Triple::xcore:
822   case llvm::Triple::amdil:
823   case llvm::Triple::hsail:
824   case llvm::Triple::spir:
825   case llvm::Triple::kalimba:
826     return 32;
827
828   case llvm::Triple::aarch64:
829   case llvm::Triple::aarch64_be:
830   case llvm::Triple::le64:
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::amdil64:
840   case llvm::Triple::hsail64:
841   case llvm::Triple::spir64:
842     return 64;
843   }
844   llvm_unreachable("Invalid architecture value");
845 }
846
847 bool Triple::isArch64Bit() const {
848   return getArchPointerBitWidth(getArch()) == 64;
849 }
850
851 bool Triple::isArch32Bit() const {
852   return getArchPointerBitWidth(getArch()) == 32;
853 }
854
855 bool Triple::isArch16Bit() const {
856   return getArchPointerBitWidth(getArch()) == 16;
857 }
858
859 Triple Triple::get32BitArchVariant() const {
860   Triple T(*this);
861   switch (getArch()) {
862   case Triple::UnknownArch:
863   case Triple::aarch64:
864   case Triple::aarch64_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::hsail:
873   case Triple::spir:
874   case Triple::arm:
875   case Triple::armeb:
876   case Triple::hexagon:
877   case Triple::kalimba:
878   case Triple::le32:
879   case Triple::mips:
880   case Triple::mipsel:
881   case Triple::nvptx:
882   case Triple::ppc:
883   case Triple::r600:
884   case Triple::sparc:
885   case Triple::tce:
886   case Triple::thumb:
887   case Triple::thumbeb:
888   case Triple::x86:
889   case Triple::xcore:
890     // Already 32-bit.
891     break;
892
893   case Triple::le64:      T.setArch(Triple::le32);    break;
894   case Triple::mips64:    T.setArch(Triple::mips);    break;
895   case Triple::mips64el:  T.setArch(Triple::mipsel);  break;
896   case Triple::nvptx64:   T.setArch(Triple::nvptx);   break;
897   case Triple::ppc64:     T.setArch(Triple::ppc);     break;
898   case Triple::sparcv9:   T.setArch(Triple::sparc);   break;
899   case Triple::x86_64:    T.setArch(Triple::x86);     break;
900   case Triple::amdil64:   T.setArch(Triple::amdil);   break;
901   case Triple::hsail64:   T.setArch(Triple::hsail);   break;
902   case Triple::spir64:    T.setArch(Triple::spir);    break;
903   }
904   return T;
905 }
906
907 Triple Triple::get64BitArchVariant() const {
908   Triple T(*this);
909   switch (getArch()) {
910   case Triple::UnknownArch:
911   case Triple::arm:
912   case Triple::armeb:
913   case Triple::hexagon:
914   case Triple::kalimba:
915   case Triple::msp430:
916   case Triple::r600:
917   case Triple::tce:
918   case Triple::thumb:
919   case Triple::thumbeb:
920   case Triple::xcore:
921     T.setArch(UnknownArch);
922     break;
923
924   case Triple::aarch64:
925   case Triple::aarch64_be:
926   case Triple::le64:
927   case Triple::amdil64:
928   case Triple::hsail64:
929   case Triple::spir64:
930   case Triple::mips64:
931   case Triple::mips64el:
932   case Triple::nvptx64:
933   case Triple::ppc64:
934   case Triple::ppc64le:
935   case Triple::sparcv9:
936   case Triple::systemz:
937   case Triple::x86_64:
938     // Already 64-bit.
939     break;
940
941   case Triple::le32:    T.setArch(Triple::le64);      break;
942   case Triple::mips:    T.setArch(Triple::mips64);    break;
943   case Triple::mipsel:  T.setArch(Triple::mips64el);  break;
944   case Triple::nvptx:   T.setArch(Triple::nvptx64);   break;
945   case Triple::ppc:     T.setArch(Triple::ppc64);     break;
946   case Triple::sparc:   T.setArch(Triple::sparcv9);   break;
947   case Triple::x86:     T.setArch(Triple::x86_64);    break;
948   case Triple::amdil:   T.setArch(Triple::amdil64);   break;
949   case Triple::hsail:   T.setArch(Triple::hsail64);   break;
950   case Triple::spir:    T.setArch(Triple::spir64);    break;
951   }
952   return T;
953 }
954
955 // FIXME: tblgen this.
956 const char *Triple::getARMCPUForArch(StringRef MArch) const {
957   if (MArch.empty())
958     MArch = getArchName();
959
960   switch (getOS()) {
961   case llvm::Triple::FreeBSD:
962   case llvm::Triple::NetBSD:
963     if (MArch == "armv6")
964       return "arm1176jzf-s";
965     break;
966   case llvm::Triple::Win32:
967     // FIXME: this is invalid for WindowsCE
968     return "cortex-a9";
969   default:
970     break;
971   }
972
973   const char *result = nullptr;
974   size_t offset = StringRef::npos;
975   if (MArch.startswith("arm"))
976     offset = 3;
977   if (MArch.startswith("thumb"))
978     offset = 5;
979   if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
980     offset += 2;
981   if (offset != StringRef::npos)
982     result = llvm::StringSwitch<const char *>(MArch.substr(offset))
983       .Cases("v2", "v2a", "arm2")
984       .Case("v3", "arm6")
985       .Case("v3m", "arm7m")
986       .Case("v4", "strongarm")
987       .Case("v4t", "arm7tdmi")
988       .Cases("v5", "v5t", "arm10tdmi")
989       .Cases("v5e", "v5te", "arm1022e")
990       .Case("v5tej", "arm926ej-s")
991       .Cases("v6", "v6k", "arm1136jf-s")
992       .Case("v6j", "arm1136j-s")
993       .Cases("v6z", "v6zk", "arm1176jzf-s")
994       .Case("v6t2", "arm1156t2-s")
995       .Cases("v6m", "v6-m", "cortex-m0")
996       .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
997       .Cases("v7s", "v7-s", "swift")
998       .Cases("v7r", "v7-r", "cortex-r4")
999       .Cases("v7m", "v7-m", "cortex-m3")
1000       .Cases("v7em", "v7e-m", "cortex-m4")
1001       .Cases("v8", "v8a", "v8-a", "cortex-a53")
1002       .Default(nullptr);
1003   else
1004     result = llvm::StringSwitch<const char *>(MArch)
1005       .Case("ep9312", "ep9312")
1006       .Case("iwmmxt", "iwmmxt")
1007       .Case("xscale", "xscale")
1008       .Default(nullptr);
1009
1010   if (result)
1011     return result;
1012
1013   // If all else failed, return the most base CPU with thumb interworking
1014   // supported by LLVM.
1015   // FIXME: Should warn once that we're falling back.
1016   switch (getOS()) {
1017   case llvm::Triple::NetBSD:
1018     switch (getEnvironment()) {
1019     case llvm::Triple::GNUEABIHF:
1020     case llvm::Triple::GNUEABI:
1021     case llvm::Triple::EABIHF:
1022     case llvm::Triple::EABI:
1023       return "arm926ej-s";
1024     default:
1025       return "strongarm";
1026     }
1027   default:
1028     switch (getEnvironment()) {
1029     case llvm::Triple::EABIHF:
1030     case llvm::Triple::GNUEABIHF:
1031       return "arm1176jzf-s";
1032     default:
1033       return "arm7tdmi";
1034     }
1035   }
1036 }