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