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