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