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>
16using namespace llvm;
17
18const 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
63const 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
120const 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
140const 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
173const 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
192Triple::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
235static 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
288static 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
332static 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
348static 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
378static 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
394static 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
402static 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
433static 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
443static 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.
479Triple::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.
497Triple::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.
512Triple::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
526std::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
701StringRef Triple::getArchName() const {
702  return StringRef(Data).split('-').first;           // Isolate first component
703}
704
705StringRef Triple::getVendorName() const {
706  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
707  return Tmp.split('-').first;                       // Isolate second component
708}
709
710StringRef 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
716StringRef 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
722StringRef Triple::getOSAndEnvironmentName() const {
723  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
724  return Tmp.split('-').second;                      // Strip second component
725}
726
727static 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
742void 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
777bool 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
816void 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
839void Triple::setTriple(const Twine &Str) {
840  *this = Triple(Str);
841}
842
843void Triple::setArch(ArchType Kind) {
844  setArchName(getArchTypeName(Kind));
845}
846
847void Triple::setVendor(VendorType Kind) {
848  setVendorName(getVendorTypeName(Kind));
849}
850
851void Triple::setOS(OSType Kind) {
852  setOSName(getOSTypeName(Kind));
853}
854
855void 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
863void 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
871void 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
882void Triple::setVendorName(StringRef Str) {
883  setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
884}
885
886void Triple::setOSName(StringRef Str) {
887  if (hasEnvironment())
888    setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
889              "-" + getEnvironmentName());
890  else
891    setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
892}
893
894void Triple::setEnvironmentName(StringRef Str) {
895  setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
896            "-" + Str);
897}
898
899void Triple::setOSAndEnvironmentName(StringRef Str) {
900  setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
901}
902
903static 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
953bool Triple::isArch64Bit() const {
954  return getArchPointerBitWidth(getArch()) == 64;
955}
956
957bool Triple::isArch32Bit() const {
958  return getArchPointerBitWidth(getArch()) == 32;
959}
960
961bool Triple::isArch16Bit() const {
962  return getArchPointerBitWidth(getArch()) == 16;
963}
964
965Triple 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
1015Triple 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.
1066const 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")
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}
1152