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