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