Switch a bunch of manual if-chains to use StringSwitch. Clean them up in
[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 InvalidArch: return "<invalid>";
21   case UnknownArch: return "unknown";
22
23   case arm:     return "arm";
24   case cellspu: return "cellspu";
25   case hexagon: return "hexagon";
26   case mips:    return "mips";
27   case mipsel:  return "mipsel";
28   case mips64:  return "mips64";
29   case mips64el:return "mips64el";
30   case msp430:  return "msp430";
31   case ppc64:   return "powerpc64";
32   case ppc:     return "powerpc";
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 ptx32:   return "ptx32";
42   case ptx64:   return "ptx64";
43   case le32:    return "le32";
44   case amdil:   return "amdil";
45   }
46
47   llvm_unreachable("Invalid ArchType!");
48 }
49
50 const char *Triple::getArchTypePrefix(ArchType Kind) {
51   switch (Kind) {
52   default:
53     return 0;
54
55   case arm:
56   case thumb:   return "arm";
57
58   case cellspu: return "spu";
59
60   case ppc64:
61   case ppc:     return "ppc";
62
63   case mblaze:  return "mblaze";
64
65   case hexagon:   return "hexagon";
66
67   case sparcv9:
68   case sparc:   return "sparc";
69
70   case x86:
71   case x86_64:  return "x86";
72
73   case xcore:   return "xcore";
74
75   case ptx32:   return "ptx";
76   case ptx64:   return "ptx";
77   case le32:    return "le32";
78   case amdil:   return "amdil";
79   }
80 }
81
82 const char *Triple::getVendorTypeName(VendorType Kind) {
83   switch (Kind) {
84   case UnknownVendor: return "unknown";
85
86   case Apple: return "apple";
87   case PC: return "pc";
88   case SCEI: return "scei";
89   }
90
91   llvm_unreachable("Invalid VendorType!");
92 }
93
94 const char *Triple::getOSTypeName(OSType Kind) {
95   switch (Kind) {
96   case UnknownOS: return "unknown";
97
98   case AuroraUX: return "auroraux";
99   case Cygwin: return "cygwin";
100   case Darwin: return "darwin";
101   case DragonFly: return "dragonfly";
102   case FreeBSD: return "freebsd";
103   case IOS: return "ios";
104   case KFreeBSD: return "kfreebsd";
105   case Linux: return "linux";
106   case Lv2: return "lv2";
107   case MacOSX: return "macosx";
108   case MinGW32: return "mingw32";
109   case NetBSD: return "netbsd";
110   case OpenBSD: return "openbsd";
111   case Psp: return "psp";
112   case Solaris: return "solaris";
113   case Win32: return "win32";
114   case Haiku: return "haiku";
115   case Minix: return "minix";
116   case RTEMS: return "rtems";
117   case NativeClient: return "nacl";
118   }
119
120   llvm_unreachable("Invalid OSType");
121 }
122
123 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
124   switch (Kind) {
125   case UnknownEnvironment: return "unknown";
126   case GNU: return "gnu";
127   case GNUEABIHF: return "gnueabihf";
128   case GNUEABI: return "gnueabi";
129   case EABI: return "eabi";
130   case MachO: return "macho";
131   case ANDROIDEABI: return "androideabi";
132   }
133
134   llvm_unreachable("Invalid EnvironmentType!");
135 }
136
137 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
138   return StringSwitch<Triple::ArchType>(Name)
139     .Case("arm", arm)
140     .Case("cellspu", cellspu)
141     .Case("mips", mips)
142     .Case("mipsel", mipsel)
143     .Case("mips64", mips64)
144     .Case("mips64el", mips64el)
145     .Case("msp430", msp430)
146     .Case("ppc64", ppc64)
147     .Case("ppc32", ppc)
148     .Case("ppc", ppc)
149     .Case("mblaze", mblaze)
150     .Case("hexagon", hexagon)
151     .Case("sparc", sparc)
152     .Case("sparcv9", sparcv9)
153     .Case("tce", tce)
154     .Case("thumb", thumb)
155     .Case("x86", x86)
156     .Case("x86-64", x86_64)
157     .Case("xcore", xcore)
158     .Case("ptx32", ptx32)
159     .Case("ptx64", ptx64)
160     .Case("le32", le32)
161     .Case("amdil", amdil)
162     .Default(UnknownArch);
163 }
164
165 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
166   // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
167   // archs which Darwin doesn't use.
168
169   // The matching this routine does is fairly pointless, since it is neither the
170   // complete architecture list, nor a reasonable subset. The problem is that
171   // historically the driver driver accepts this and also ties its -march=
172   // handling to the architecture name, so we need to be careful before removing
173   // support for it.
174
175   // This code must be kept in sync with Clang's Darwin specific argument
176   // translation.
177
178   return StringSwitch<ArchType>(Str)
179     .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", Triple::ppc)
180     .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", Triple::ppc)
181     .Case("ppc64", Triple::ppc64)
182     .Cases("i386", "i486", "i486SX", "i586", "i686", Triple::x86)
183     .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
184            Triple::x86)
185     .Case("x86_64", Triple::x86_64)
186     // This is derived from the driver driver.
187     .Cases("arm", "armv4t", "armv5", "armv6", Triple::arm)
188     .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", Triple::arm)
189     .Case("ptx32", Triple::ptx32)
190     .Case("ptx64", Triple::ptx64)
191     .Case("amdil", Triple::amdil)
192     .Default(Triple::UnknownArch);
193 }
194
195 // Returns architecture name that is understood by the target assembler.
196 const char *Triple::getArchNameForAssembler() {
197   if (!isOSDarwin() && getVendor() != Triple::Apple)
198     return NULL;
199
200   return StringSwitch<const char*>(getArchName())
201     .Case("i386", "i386")
202     .Case("x86_64", "x86_64")
203     .Case("powerpc", "ppc")
204     .Case("powerpc64", "ppc64")
205     .Cases("mblaze", "microblaze", "mblaze")
206     .Case("arm", "arm")
207     .Cases("armv4t", "thumbv4t", "armv4t")
208     .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
209     .Cases("armv6", "thumbv6", "armv6")
210     .Cases("armv7", "thumbv7", "armv7")
211     .Case("ptx32", "ptx32")
212     .Case("ptx64", "ptx64")
213     .Case("le32", "le32")
214     .Case("amdil", "amdil")
215     .Default(NULL);
216 }
217
218 //
219
220 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
221   // Handle some unusual patterns.
222   // FIXME: It would be good to replace these with explicit names for all the
223   // various suffixes supported.
224   if (ArchName.startswith("armv")) return arm;
225   if (ArchName.startswith("thumbv")) return thumb;
226
227   return StringSwitch<ArchType>(ArchName)
228     .Cases("i386", "i486", "i586", "i686", x86)
229     .Cases("i786", "i886", "i986", x86) // FIXME: Do we need to support these?
230     .Cases("amd64", "x86_64", x86_64)
231     .Case("powerpc", ppc)
232     .Cases("powerpc64", "ppu", ppc64)
233     .Case("mblaze", mblaze)
234     .Cases("arm", "xscale", arm)
235     .Case("thumb", thumb)
236     .Cases("spu", "cellspu", cellspu)
237     .Case("msp430", msp430)
238     .Cases("mips", "mipseb", "mipsallegrex", mips)
239     .Cases("mipsel", "mipsallegrexel", "psp", mipsel)
240     .Cases("mips64", "mips64eb", mips64)
241     .Case("mips64el", mips64el)
242     .Case("hexagon", hexagon)
243     .Case("sparc", sparc)
244     .Case("sparcv9", sparcv9)
245     .Case("tce", tce)
246     .Case("xcore", xcore)
247     .Case("ptx32", ptx32)
248     .Case("ptx64", ptx64)
249     .Case("le32", le32)
250     .Case("amdil", amdil)
251     .Default(UnknownArch);
252 }
253
254 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
255   return StringSwitch<VendorType>(VendorName)
256     .Case("apple", Apple)
257     .Case("pc", PC)
258     .Case("scei", SCEI)
259     .Default(UnknownVendor);
260 }
261
262 Triple::OSType Triple::ParseOS(StringRef OSName) {
263   if (OSName.startswith("auroraux"))
264     return AuroraUX;
265   else if (OSName.startswith("cygwin"))
266     return Cygwin;
267   else if (OSName.startswith("darwin"))
268     return Darwin;
269   else if (OSName.startswith("dragonfly"))
270     return DragonFly;
271   else if (OSName.startswith("freebsd"))
272     return FreeBSD;
273   else if (OSName.startswith("ios"))
274     return IOS;
275   else if (OSName.startswith("kfreebsd"))
276     return KFreeBSD;
277   else if (OSName.startswith("linux"))
278     return Linux;
279   else if (OSName.startswith("lv2"))
280     return Lv2;
281   else if (OSName.startswith("macosx"))
282     return MacOSX;
283   else if (OSName.startswith("mingw32"))
284     return MinGW32;
285   else if (OSName.startswith("netbsd"))
286     return NetBSD;
287   else if (OSName.startswith("openbsd"))
288     return OpenBSD;
289   else if (OSName.startswith("psp"))
290     return Psp;
291   else if (OSName.startswith("solaris"))
292     return Solaris;
293   else if (OSName.startswith("win32"))
294     return Win32;
295   else if (OSName.startswith("haiku"))
296     return Haiku;
297   else if (OSName.startswith("minix"))
298     return Minix;
299   else if (OSName.startswith("rtems"))
300     return RTEMS;
301   else if (OSName.startswith("nacl"))
302     return NativeClient;
303   else
304     return UnknownOS;
305 }
306
307 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
308   if (EnvironmentName.startswith("eabi"))
309     return EABI;
310   else if (EnvironmentName.startswith("gnueabihf"))
311     return GNUEABIHF;
312   else if (EnvironmentName.startswith("gnueabi"))
313     return GNUEABI;
314   else if (EnvironmentName.startswith("gnu"))
315     return GNU;
316   else if (EnvironmentName.startswith("macho"))
317     return MachO;
318   else if (EnvironmentName.startswith("androideabi"))
319     return ANDROIDEABI;
320   else
321     return UnknownEnvironment;
322 }
323
324 void Triple::Parse() const {
325   assert(!isInitialized() && "Invalid parse call.");
326
327   Arch = ParseArch(getArchName());
328   Vendor = ParseVendor(getVendorName());
329   OS = ParseOS(getOSName());
330   Environment = ParseEnvironment(getEnvironmentName());
331
332   assert(isInitialized() && "Failed to initialize!");
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   Data = Str.str();
579   Arch = InvalidArch;
580 }
581
582 void Triple::setArch(ArchType Kind) {
583   setArchName(getArchTypeName(Kind));
584 }
585
586 void Triple::setVendor(VendorType Kind) {
587   setVendorName(getVendorTypeName(Kind));
588 }
589
590 void Triple::setOS(OSType Kind) {
591   setOSName(getOSTypeName(Kind));
592 }
593
594 void Triple::setEnvironment(EnvironmentType Kind) {
595   setEnvironmentName(getEnvironmentTypeName(Kind));
596 }
597
598 void Triple::setArchName(StringRef Str) {
599   // Work around a miscompilation bug for Twines in gcc 4.0.3.
600   SmallString<64> Triple;
601   Triple += Str;
602   Triple += "-";
603   Triple += getVendorName();
604   Triple += "-";
605   Triple += getOSAndEnvironmentName();
606   setTriple(Triple.str());
607 }
608
609 void Triple::setVendorName(StringRef Str) {
610   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
611 }
612
613 void Triple::setOSName(StringRef Str) {
614   if (hasEnvironment())
615     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
616               "-" + getEnvironmentName());
617   else
618     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
619 }
620
621 void Triple::setEnvironmentName(StringRef Str) {
622   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
623             "-" + Str);
624 }
625
626 void Triple::setOSAndEnvironmentName(StringRef Str) {
627   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
628 }
629
630 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
631   switch (Arch) {
632   case llvm::Triple::UnknownArch:
633   case llvm::Triple::InvalidArch:
634     return 0;
635
636   case llvm::Triple::msp430:
637     return 16;
638
639   case llvm::Triple::amdil:
640   case llvm::Triple::arm:
641   case llvm::Triple::cellspu:
642   case llvm::Triple::hexagon:
643   case llvm::Triple::le32:
644   case llvm::Triple::mblaze:
645   case llvm::Triple::mips:
646   case llvm::Triple::mipsel:
647   case llvm::Triple::ppc:
648   case llvm::Triple::ptx32:
649   case llvm::Triple::sparc:
650   case llvm::Triple::tce:
651   case llvm::Triple::thumb:
652   case llvm::Triple::x86:
653   case llvm::Triple::xcore:
654     return 32;
655
656   case llvm::Triple::mips64:
657   case llvm::Triple::mips64el:
658   case llvm::Triple::ppc64:
659   case llvm::Triple::ptx64:
660   case llvm::Triple::sparcv9:
661   case llvm::Triple::x86_64:
662     return 64;
663   }
664   llvm_unreachable("Invalid architecture value");
665 }
666
667 bool Triple::isArch64Bit() const {
668   return getArchPointerBitWidth(getArch()) == 64;
669 }
670
671 bool Triple::isArch32Bit() const {
672   return getArchPointerBitWidth(getArch()) == 32;
673 }
674
675 bool Triple::isArch16Bit() const {
676   return getArchPointerBitWidth(getArch()) == 16;
677 }
678
679 Triple Triple::get32BitArchVariant() const {
680   Triple T(*this);
681   switch (getArch()) {
682   case Triple::UnknownArch:
683   case Triple::InvalidArch:
684   case Triple::msp430:
685     T.setArch(UnknownArch);
686     break;
687
688   case Triple::amdil:
689   case Triple::arm:
690   case Triple::cellspu:
691   case Triple::hexagon:
692   case Triple::le32:
693   case Triple::mblaze:
694   case Triple::mips:
695   case Triple::mipsel:
696   case Triple::ppc:
697   case Triple::ptx32:
698   case Triple::sparc:
699   case Triple::tce:
700   case Triple::thumb:
701   case Triple::x86:
702   case Triple::xcore:
703     // Already 32-bit.
704     break;
705
706   case Triple::mips64:    T.setArch(Triple::mips);    break;
707   case Triple::mips64el:  T.setArch(Triple::mipsel);  break;
708   case Triple::ppc64:     T.setArch(Triple::ppc);   break;
709   case Triple::ptx64:     T.setArch(Triple::ptx32);   break;
710   case Triple::sparcv9:   T.setArch(Triple::sparc);   break;
711   case Triple::x86_64:    T.setArch(Triple::x86);     break;
712   }
713   return T;
714 }
715
716 Triple Triple::get64BitArchVariant() const {
717   Triple T(*this);
718   switch (getArch()) {
719   case Triple::InvalidArch:
720   case Triple::UnknownArch:
721   case Triple::amdil:
722   case Triple::arm:
723   case Triple::cellspu:
724   case Triple::hexagon:
725   case Triple::le32:
726   case Triple::mblaze:
727   case Triple::msp430:
728   case Triple::tce:
729   case Triple::thumb:
730   case Triple::xcore:
731     T.setArch(UnknownArch);
732     break;
733
734   case Triple::mips64:
735   case Triple::mips64el:
736   case Triple::ppc64:
737   case Triple::ptx64:
738   case Triple::sparcv9:
739   case Triple::x86_64:
740     // Already 64-bit.
741     break;
742
743   case Triple::mips:    T.setArch(Triple::mips64);    break;
744   case Triple::mipsel:  T.setArch(Triple::mips64el);  break;
745   case Triple::ppc:     T.setArch(Triple::ppc64);     break;
746   case Triple::ptx32:   T.setArch(Triple::ptx64);     break;
747   case Triple::sparc:   T.setArch(Triple::sparcv9);   break;
748   case Triple::x86:     T.setArch(Triple::x86_64);    break;
749   }
750   return T;
751 }