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