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