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