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