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