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