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