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