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