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 "llvm/Support/TargetParser.h"
16 #include "llvm/Support/Host.h"
17 #include <cstring>
18 using namespace llvm;
19 
20 const char *Triple::getArchTypeName(ArchType Kind) {
21   switch (Kind) {
22   case UnknownArch: return "unknown";
23 
24   case aarch64:     return "aarch64";
25   case aarch64_be:  return "aarch64_be";
26   case arm:         return "arm";
27   case armeb:       return "armeb";
28   case avr:         return "avr";
29   case bpfel:       return "bpfel";
30   case bpfeb:       return "bpfeb";
31   case hexagon:     return "hexagon";
32   case mips:        return "mips";
33   case mipsel:      return "mipsel";
34   case mips64:      return "mips64";
35   case mips64el:    return "mips64el";
36   case msp430:      return "msp430";
37   case ppc64:       return "powerpc64";
38   case ppc64le:     return "powerpc64le";
39   case ppc:         return "powerpc";
40   case r600:        return "r600";
41   case amdgcn:      return "amdgcn";
42   case sparc:       return "sparc";
43   case sparcv9:     return "sparcv9";
44   case sparcel:     return "sparcel";
45   case systemz:     return "s390x";
46   case tce:         return "tce";
47   case thumb:       return "thumb";
48   case thumbeb:     return "thumbeb";
49   case x86:         return "i386";
50   case x86_64:      return "x86_64";
51   case xcore:       return "xcore";
52   case nvptx:       return "nvptx";
53   case nvptx64:     return "nvptx64";
54   case le32:        return "le32";
55   case le64:        return "le64";
56   case amdil:       return "amdil";
57   case amdil64:     return "amdil64";
58   case hsail:       return "hsail";
59   case hsail64:     return "hsail64";
60   case spir:        return "spir";
61   case spir64:      return "spir64";
62   case kalimba:     return "kalimba";
63   case lanai:       return "lanai";
64   case shave:       return "shave";
65   case wasm32:      return "wasm32";
66   case wasm64:      return "wasm64";
67   }
68 
69   llvm_unreachable("Invalid ArchType!");
70 }
71 
72 const char *Triple::getArchTypePrefix(ArchType Kind) {
73   switch (Kind) {
74   default:
75     return nullptr;
76 
77   case aarch64:
78   case aarch64_be:  return "aarch64";
79 
80   case arm:
81   case armeb:
82   case thumb:
83   case thumbeb:     return "arm";
84 
85   case avr:         return "avr";
86 
87   case ppc64:
88   case ppc64le:
89   case ppc:         return "ppc";
90 
91   case mips:
92   case mipsel:
93   case mips64:
94   case mips64el:    return "mips";
95 
96   case hexagon:     return "hexagon";
97 
98   case amdgcn:      return "amdgcn";
99   case r600:        return "r600";
100 
101   case bpfel:
102   case bpfeb:       return "bpf";
103 
104   case sparcv9:
105   case sparcel:
106   case sparc:       return "sparc";
107 
108   case systemz:     return "s390";
109 
110   case x86:
111   case x86_64:      return "x86";
112 
113   case xcore:       return "xcore";
114 
115   case nvptx:       return "nvptx";
116   case nvptx64:     return "nvptx";
117 
118   case le32:        return "le32";
119   case le64:        return "le64";
120 
121   case amdil:
122   case amdil64:     return "amdil";
123 
124   case hsail:
125   case hsail64:     return "hsail";
126 
127   case spir:
128   case spir64:      return "spir";
129   case kalimba:     return "kalimba";
130   case lanai:       return "lanai";
131   case shave:       return "shave";
132   case wasm32:
133   case wasm64:      return "wasm";
134   }
135 }
136 
137 const char *Triple::getVendorTypeName(VendorType Kind) {
138   switch (Kind) {
139   case UnknownVendor: return "unknown";
140 
141   case Apple: return "apple";
142   case PC: return "pc";
143   case SCEI: return "scei";
144   case BGP: return "bgp";
145   case BGQ: return "bgq";
146   case Freescale: return "fsl";
147   case IBM: return "ibm";
148   case ImaginationTechnologies: return "img";
149   case MipsTechnologies: return "mti";
150   case NVIDIA: return "nvidia";
151   case CSR: return "csr";
152   case Myriad: return "myriad";
153   case AMD: return "amd";
154   case Mesa: return "mesa";
155   }
156 
157   llvm_unreachable("Invalid VendorType!");
158 }
159 
160 const char *Triple::getOSTypeName(OSType Kind) {
161   switch (Kind) {
162   case UnknownOS: return "unknown";
163 
164   case CloudABI: return "cloudabi";
165   case Darwin: return "darwin";
166   case DragonFly: return "dragonfly";
167   case FreeBSD: return "freebsd";
168   case IOS: return "ios";
169   case KFreeBSD: return "kfreebsd";
170   case Linux: return "linux";
171   case Lv2: return "lv2";
172   case MacOSX: return "macosx";
173   case NetBSD: return "netbsd";
174   case OpenBSD: return "openbsd";
175   case Solaris: return "solaris";
176   case Win32: return "windows";
177   case Haiku: return "haiku";
178   case Minix: return "minix";
179   case RTEMS: return "rtems";
180   case NaCl: return "nacl";
181   case CNK: return "cnk";
182   case Bitrig: return "bitrig";
183   case AIX: return "aix";
184   case CUDA: return "cuda";
185   case NVCL: return "nvcl";
186   case AMDHSA: return "amdhsa";
187   case PS4: return "ps4";
188   case ELFIAMCU: return "elfiamcu";
189   case TvOS: return "tvos";
190   case WatchOS: return "watchos";
191   case Mesa3D: return "mesa3d";
192   }
193 
194   llvm_unreachable("Invalid OSType");
195 }
196 
197 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
198   switch (Kind) {
199   case UnknownEnvironment: return "unknown";
200   case GNU: return "gnu";
201   case GNUEABIHF: return "gnueabihf";
202   case GNUEABI: return "gnueabi";
203   case GNUX32: return "gnux32";
204   case CODE16: return "code16";
205   case EABI: return "eabi";
206   case EABIHF: return "eabihf";
207   case Android: return "android";
208   case MSVC: return "msvc";
209   case Itanium: return "itanium";
210   case Cygnus: return "cygnus";
211   case AMDOpenCL: return "amdopencl";
212   case CoreCLR: return "coreclr";
213   }
214 
215   llvm_unreachable("Invalid EnvironmentType!");
216 }
217 
218 static Triple::ArchType parseBPFArch(StringRef ArchName) {
219   if (ArchName.equals("bpf")) {
220     if (sys::IsLittleEndianHost)
221       return Triple::bpfel;
222     else
223       return Triple::bpfeb;
224   } else if (ArchName.equals("bpf_be") || ArchName.equals("bpfeb")) {
225     return Triple::bpfeb;
226   } else if (ArchName.equals("bpf_le") || ArchName.equals("bpfel")) {
227     return Triple::bpfel;
228   } else {
229     return Triple::UnknownArch;
230   }
231 }
232 
233 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
234   Triple::ArchType BPFArch(parseBPFArch(Name));
235   return StringSwitch<Triple::ArchType>(Name)
236     .Case("aarch64", aarch64)
237     .Case("aarch64_be", aarch64_be)
238     .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
239     .Case("arm", arm)
240     .Case("armeb", armeb)
241     .Case("avr", avr)
242     .StartsWith("bpf", BPFArch)
243     .Case("mips", mips)
244     .Case("mipsel", mipsel)
245     .Case("mips64", mips64)
246     .Case("mips64el", mips64el)
247     .Case("msp430", msp430)
248     .Case("ppc64", ppc64)
249     .Case("ppc32", ppc)
250     .Case("ppc", ppc)
251     .Case("ppc64le", ppc64le)
252     .Case("r600", r600)
253     .Case("amdgcn", amdgcn)
254     .Case("hexagon", hexagon)
255     .Case("sparc", sparc)
256     .Case("sparcel", sparcel)
257     .Case("sparcv9", sparcv9)
258     .Case("systemz", systemz)
259     .Case("tce", tce)
260     .Case("thumb", thumb)
261     .Case("thumbeb", thumbeb)
262     .Case("x86", x86)
263     .Case("x86-64", x86_64)
264     .Case("xcore", xcore)
265     .Case("nvptx", nvptx)
266     .Case("nvptx64", nvptx64)
267     .Case("le32", le32)
268     .Case("le64", le64)
269     .Case("amdil", amdil)
270     .Case("amdil64", amdil64)
271     .Case("hsail", hsail)
272     .Case("hsail64", hsail64)
273     .Case("spir", spir)
274     .Case("spir64", spir64)
275     .Case("kalimba", kalimba)
276     .Case("lanai", lanai)
277     .Case("shave", shave)
278     .Case("wasm32", wasm32)
279     .Case("wasm64", wasm64)
280     .Default(UnknownArch);
281 }
282 
283 static Triple::ArchType parseARMArch(StringRef ArchName) {
284   unsigned ISA = ARM::parseArchISA(ArchName);
285   unsigned ENDIAN = ARM::parseArchEndian(ArchName);
286 
287   Triple::ArchType arch = Triple::UnknownArch;
288   switch (ENDIAN) {
289   case ARM::EK_LITTLE: {
290     switch (ISA) {
291     case ARM::IK_ARM:
292       arch = Triple::arm;
293       break;
294     case ARM::IK_THUMB:
295       arch = Triple::thumb;
296       break;
297     case ARM::IK_AARCH64:
298       arch = Triple::aarch64;
299       break;
300     }
301     break;
302   }
303   case ARM::EK_BIG: {
304     switch (ISA) {
305     case ARM::IK_ARM:
306       arch = Triple::armeb;
307       break;
308     case ARM::IK_THUMB:
309       arch = Triple::thumbeb;
310       break;
311     case ARM::IK_AARCH64:
312       arch = Triple::aarch64_be;
313       break;
314     }
315     break;
316   }
317   }
318 
319   ArchName = ARM::getCanonicalArchName(ArchName);
320   if (ArchName.empty())
321     return Triple::UnknownArch;
322 
323   // Thumb only exists in v4+
324   if (ISA == ARM::IK_THUMB &&
325       (ArchName.startswith("v2") || ArchName.startswith("v3")))
326     return Triple::UnknownArch;
327 
328   // Thumb only for v6m
329   unsigned Profile = ARM::parseArchProfile(ArchName);
330   unsigned Version = ARM::parseArchVersion(ArchName);
331   if (Profile == ARM::PK_M && Version == 6) {
332     if (ENDIAN == ARM::EK_BIG)
333       return Triple::thumbeb;
334     else
335       return Triple::thumb;
336   }
337 
338   return arch;
339 }
340 
341 static Triple::ArchType parseArch(StringRef ArchName) {
342   auto AT = StringSwitch<Triple::ArchType>(ArchName)
343     .Cases("i386", "i486", "i586", "i686", Triple::x86)
344     // FIXME: Do we need to support these?
345     .Cases("i786", "i886", "i986", Triple::x86)
346     .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
347     .Cases("powerpc", "ppc32", Triple::ppc)
348     .Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
349     .Cases("powerpc64le", "ppc64le", Triple::ppc64le)
350     .Case("xscale", Triple::arm)
351     .Case("xscaleeb", Triple::armeb)
352     .Case("aarch64", Triple::aarch64)
353     .Case("aarch64_be", Triple::aarch64_be)
354     .Case("arm64", Triple::aarch64)
355     .Case("arm", Triple::arm)
356     .Case("armeb", Triple::armeb)
357     .Case("thumb", Triple::thumb)
358     .Case("thumbeb", Triple::thumbeb)
359     .Case("avr", Triple::avr)
360     .Case("msp430", Triple::msp430)
361     .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
362     .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
363     .Cases("mips64", "mips64eb", Triple::mips64)
364     .Case("mips64el", Triple::mips64el)
365     .Case("r600", Triple::r600)
366     .Case("amdgcn", Triple::amdgcn)
367     .Case("hexagon", Triple::hexagon)
368     .Cases("s390x", "systemz", Triple::systemz)
369     .Case("sparc", Triple::sparc)
370     .Case("sparcel", Triple::sparcel)
371     .Cases("sparcv9", "sparc64", Triple::sparcv9)
372     .Case("tce", Triple::tce)
373     .Case("xcore", Triple::xcore)
374     .Case("nvptx", Triple::nvptx)
375     .Case("nvptx64", Triple::nvptx64)
376     .Case("le32", Triple::le32)
377     .Case("le64", Triple::le64)
378     .Case("amdil", Triple::amdil)
379     .Case("amdil64", Triple::amdil64)
380     .Case("hsail", Triple::hsail)
381     .Case("hsail64", Triple::hsail64)
382     .Case("spir", Triple::spir)
383     .Case("spir64", Triple::spir64)
384     .StartsWith("kalimba", Triple::kalimba)
385     .Case("lanai", Triple::lanai)
386     .Case("shave", Triple::shave)
387     .Case("wasm32", Triple::wasm32)
388     .Case("wasm64", Triple::wasm64)
389     .Default(Triple::UnknownArch);
390 
391   // Some architectures require special parsing logic just to compute the
392   // ArchType result.
393   if (AT == Triple::UnknownArch) {
394     if (ArchName.startswith("arm") || ArchName.startswith("thumb") ||
395         ArchName.startswith("aarch64"))
396       return parseARMArch(ArchName);
397     if (ArchName.startswith("bpf"))
398       return parseBPFArch(ArchName);
399   }
400 
401   return AT;
402 }
403 
404 static Triple::VendorType parseVendor(StringRef VendorName) {
405   return StringSwitch<Triple::VendorType>(VendorName)
406     .Case("apple", Triple::Apple)
407     .Case("pc", Triple::PC)
408     .Case("scei", Triple::SCEI)
409     .Case("bgp", Triple::BGP)
410     .Case("bgq", Triple::BGQ)
411     .Case("fsl", Triple::Freescale)
412     .Case("ibm", Triple::IBM)
413     .Case("img", Triple::ImaginationTechnologies)
414     .Case("mti", Triple::MipsTechnologies)
415     .Case("nvidia", Triple::NVIDIA)
416     .Case("csr", Triple::CSR)
417     .Case("myriad", Triple::Myriad)
418     .Case("amd", Triple::AMD)
419     .Case("mesa", Triple::Mesa)
420     .Default(Triple::UnknownVendor);
421 }
422 
423 static Triple::OSType parseOS(StringRef OSName) {
424   return StringSwitch<Triple::OSType>(OSName)
425     .StartsWith("cloudabi", Triple::CloudABI)
426     .StartsWith("darwin", Triple::Darwin)
427     .StartsWith("dragonfly", Triple::DragonFly)
428     .StartsWith("freebsd", Triple::FreeBSD)
429     .StartsWith("ios", Triple::IOS)
430     .StartsWith("kfreebsd", Triple::KFreeBSD)
431     .StartsWith("linux", Triple::Linux)
432     .StartsWith("lv2", Triple::Lv2)
433     .StartsWith("macosx", Triple::MacOSX)
434     .StartsWith("netbsd", Triple::NetBSD)
435     .StartsWith("openbsd", Triple::OpenBSD)
436     .StartsWith("solaris", Triple::Solaris)
437     .StartsWith("win32", Triple::Win32)
438     .StartsWith("windows", Triple::Win32)
439     .StartsWith("haiku", Triple::Haiku)
440     .StartsWith("minix", Triple::Minix)
441     .StartsWith("rtems", Triple::RTEMS)
442     .StartsWith("nacl", Triple::NaCl)
443     .StartsWith("cnk", Triple::CNK)
444     .StartsWith("bitrig", Triple::Bitrig)
445     .StartsWith("aix", Triple::AIX)
446     .StartsWith("cuda", Triple::CUDA)
447     .StartsWith("nvcl", Triple::NVCL)
448     .StartsWith("amdhsa", Triple::AMDHSA)
449     .StartsWith("ps4", Triple::PS4)
450     .StartsWith("elfiamcu", Triple::ELFIAMCU)
451     .StartsWith("tvos", Triple::TvOS)
452     .StartsWith("watchos", Triple::WatchOS)
453     .StartsWith("mesa3d", Triple::Mesa3D)
454     .Default(Triple::UnknownOS);
455 }
456 
457 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
458   return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
459     .StartsWith("eabihf", Triple::EABIHF)
460     .StartsWith("eabi", Triple::EABI)
461     .StartsWith("gnueabihf", Triple::GNUEABIHF)
462     .StartsWith("gnueabi", Triple::GNUEABI)
463     .StartsWith("gnux32", Triple::GNUX32)
464     .StartsWith("code16", Triple::CODE16)
465     .StartsWith("gnu", Triple::GNU)
466     .StartsWith("android", Triple::Android)
467     .StartsWith("msvc", Triple::MSVC)
468     .StartsWith("itanium", Triple::Itanium)
469     .StartsWith("cygnus", Triple::Cygnus)
470     .StartsWith("amdopencl", Triple::AMDOpenCL)
471     .StartsWith("coreclr", Triple::CoreCLR)
472     .Default(Triple::UnknownEnvironment);
473 }
474 
475 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
476   return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
477     .EndsWith("coff", Triple::COFF)
478     .EndsWith("elf", Triple::ELF)
479     .EndsWith("macho", Triple::MachO)
480     .Default(Triple::UnknownObjectFormat);
481 }
482 
483 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
484   StringRef ARMSubArch = ARM::getCanonicalArchName(SubArchName);
485 
486   // For now, this is the small part. Early return.
487   if (ARMSubArch.empty())
488     return StringSwitch<Triple::SubArchType>(SubArchName)
489       .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
490       .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
491       .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
492       .Default(Triple::NoSubArch);
493 
494   // ARM sub arch.
495   switch(ARM::parseArch(ARMSubArch)) {
496   case ARM::AK_ARMV4:
497     return Triple::NoSubArch;
498   case ARM::AK_ARMV4T:
499     return Triple::ARMSubArch_v4t;
500   case ARM::AK_ARMV5T:
501     return Triple::ARMSubArch_v5;
502   case ARM::AK_ARMV5TE:
503   case ARM::AK_IWMMXT:
504   case ARM::AK_IWMMXT2:
505   case ARM::AK_XSCALE:
506   case ARM::AK_ARMV5TEJ:
507     return Triple::ARMSubArch_v5te;
508   case ARM::AK_ARMV6:
509     return Triple::ARMSubArch_v6;
510   case ARM::AK_ARMV6K:
511   case ARM::AK_ARMV6KZ:
512     return Triple::ARMSubArch_v6k;
513   case ARM::AK_ARMV6T2:
514     return Triple::ARMSubArch_v6t2;
515   case ARM::AK_ARMV6M:
516     return Triple::ARMSubArch_v6m;
517   case ARM::AK_ARMV7A:
518   case ARM::AK_ARMV7R:
519     return Triple::ARMSubArch_v7;
520   case ARM::AK_ARMV7K:
521     return Triple::ARMSubArch_v7k;
522   case ARM::AK_ARMV7M:
523     return Triple::ARMSubArch_v7m;
524   case ARM::AK_ARMV7S:
525     return Triple::ARMSubArch_v7s;
526   case ARM::AK_ARMV7EM:
527     return Triple::ARMSubArch_v7em;
528   case ARM::AK_ARMV8A:
529     return Triple::ARMSubArch_v8;
530   case ARM::AK_ARMV8_1A:
531     return Triple::ARMSubArch_v8_1a;
532   case ARM::AK_ARMV8_2A:
533     return Triple::ARMSubArch_v8_2a;
534   case ARM::AK_ARMV8MBaseline:
535     return Triple::ARMSubArch_v8m_baseline;
536   case ARM::AK_ARMV8MMainline:
537     return Triple::ARMSubArch_v8m_mainline;
538   default:
539     return Triple::NoSubArch;
540   }
541 }
542 
543 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
544   switch (Kind) {
545   case Triple::UnknownObjectFormat: return "";
546   case Triple::COFF: return "coff";
547   case Triple::ELF: return "elf";
548   case Triple::MachO: return "macho";
549   }
550   llvm_unreachable("unknown object format type");
551 }
552 
553 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
554   switch (T.getArch()) {
555   case Triple::UnknownArch:
556   case Triple::aarch64:
557   case Triple::arm:
558   case Triple::thumb:
559   case Triple::x86:
560   case Triple::x86_64:
561     if (T.isOSDarwin())
562       return Triple::MachO;
563     else if (T.isOSWindows())
564       return Triple::COFF;
565     return Triple::ELF;
566 
567   case Triple::aarch64_be:
568   case Triple::amdgcn:
569   case Triple::amdil:
570   case Triple::amdil64:
571   case Triple::armeb:
572   case Triple::avr:
573   case Triple::bpfeb:
574   case Triple::bpfel:
575   case Triple::hexagon:
576   case Triple::lanai:
577   case Triple::hsail:
578   case Triple::hsail64:
579   case Triple::kalimba:
580   case Triple::le32:
581   case Triple::le64:
582   case Triple::mips:
583   case Triple::mips64:
584   case Triple::mips64el:
585   case Triple::mipsel:
586   case Triple::msp430:
587   case Triple::nvptx:
588   case Triple::nvptx64:
589   case Triple::ppc64le:
590   case Triple::r600:
591   case Triple::shave:
592   case Triple::sparc:
593   case Triple::sparcel:
594   case Triple::sparcv9:
595   case Triple::spir:
596   case Triple::spir64:
597   case Triple::systemz:
598   case Triple::tce:
599   case Triple::thumbeb:
600   case Triple::wasm32:
601   case Triple::wasm64:
602   case Triple::xcore:
603     return Triple::ELF;
604 
605   case Triple::ppc:
606   case Triple::ppc64:
607     if (T.isOSDarwin())
608       return Triple::MachO;
609     return Triple::ELF;
610   }
611   llvm_unreachable("unknown architecture");
612 }
613 
614 /// \brief Construct a triple from the string representation provided.
615 ///
616 /// This stores the string representation and parses the various pieces into
617 /// enum members.
618 Triple::Triple(const Twine &Str)
619     : Data(Str.str()), Arch(UnknownArch), SubArch(NoSubArch),
620       Vendor(UnknownVendor), OS(UnknownOS), Environment(UnknownEnvironment),
621       ObjectFormat(UnknownObjectFormat) {
622   // Do minimal parsing by hand here.
623   SmallVector<StringRef, 4> Components;
624   StringRef(Data).split(Components, '-', /*MaxSplit*/ 3);
625   if (Components.size() > 0) {
626     Arch = parseArch(Components[0]);
627     SubArch = parseSubArch(Components[0]);
628     if (Components.size() > 1) {
629       Vendor = parseVendor(Components[1]);
630       if (Components.size() > 2) {
631         OS = parseOS(Components[2]);
632         if (Components.size() > 3) {
633           Environment = parseEnvironment(Components[3]);
634           ObjectFormat = parseFormat(Components[3]);
635         }
636       }
637     }
638   }
639   if (ObjectFormat == UnknownObjectFormat)
640     ObjectFormat = getDefaultFormat(*this);
641 }
642 
643 /// \brief Construct a triple from string representations of the architecture,
644 /// vendor, and OS.
645 ///
646 /// This joins each argument into a canonical string representation and parses
647 /// them into enum members. It leaves the environment unknown and omits it from
648 /// the string representation.
649 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
650     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
651       Arch(parseArch(ArchStr.str())),
652       SubArch(parseSubArch(ArchStr.str())),
653       Vendor(parseVendor(VendorStr.str())),
654       OS(parseOS(OSStr.str())),
655       Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
656   ObjectFormat = getDefaultFormat(*this);
657 }
658 
659 /// \brief Construct a triple from string representations of the architecture,
660 /// vendor, OS, and environment.
661 ///
662 /// This joins each argument into a canonical string representation and parses
663 /// them into enum members.
664 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
665                const Twine &EnvironmentStr)
666     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
667             EnvironmentStr).str()),
668       Arch(parseArch(ArchStr.str())),
669       SubArch(parseSubArch(ArchStr.str())),
670       Vendor(parseVendor(VendorStr.str())),
671       OS(parseOS(OSStr.str())),
672       Environment(parseEnvironment(EnvironmentStr.str())),
673       ObjectFormat(parseFormat(EnvironmentStr.str())) {
674   if (ObjectFormat == Triple::UnknownObjectFormat)
675     ObjectFormat = getDefaultFormat(*this);
676 }
677 
678 std::string Triple::normalize(StringRef Str) {
679   bool IsMinGW32 = false;
680   bool IsCygwin = false;
681 
682   // Parse into components.
683   SmallVector<StringRef, 4> Components;
684   Str.split(Components, '-');
685 
686   // If the first component corresponds to a known architecture, preferentially
687   // use it for the architecture.  If the second component corresponds to a
688   // known vendor, preferentially use it for the vendor, etc.  This avoids silly
689   // component movement when a component parses as (eg) both a valid arch and a
690   // valid os.
691   ArchType Arch = UnknownArch;
692   if (Components.size() > 0)
693     Arch = parseArch(Components[0]);
694   VendorType Vendor = UnknownVendor;
695   if (Components.size() > 1)
696     Vendor = parseVendor(Components[1]);
697   OSType OS = UnknownOS;
698   if (Components.size() > 2) {
699     OS = parseOS(Components[2]);
700     IsCygwin = Components[2].startswith("cygwin");
701     IsMinGW32 = Components[2].startswith("mingw");
702   }
703   EnvironmentType Environment = UnknownEnvironment;
704   if (Components.size() > 3)
705     Environment = parseEnvironment(Components[3]);
706   ObjectFormatType ObjectFormat = UnknownObjectFormat;
707   if (Components.size() > 4)
708     ObjectFormat = parseFormat(Components[4]);
709 
710   // Note which components are already in their final position.  These will not
711   // be moved.
712   bool Found[4];
713   Found[0] = Arch != UnknownArch;
714   Found[1] = Vendor != UnknownVendor;
715   Found[2] = OS != UnknownOS;
716   Found[3] = Environment != UnknownEnvironment;
717 
718   // If they are not there already, permute the components into their canonical
719   // positions by seeing if they parse as a valid architecture, and if so moving
720   // the component to the architecture position etc.
721   for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
722     if (Found[Pos])
723       continue; // Already in the canonical position.
724 
725     for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
726       // Do not reparse any components that already matched.
727       if (Idx < array_lengthof(Found) && Found[Idx])
728         continue;
729 
730       // Does this component parse as valid for the target position?
731       bool Valid = false;
732       StringRef Comp = Components[Idx];
733       switch (Pos) {
734       default: llvm_unreachable("unexpected component type!");
735       case 0:
736         Arch = parseArch(Comp);
737         Valid = Arch != UnknownArch;
738         break;
739       case 1:
740         Vendor = parseVendor(Comp);
741         Valid = Vendor != UnknownVendor;
742         break;
743       case 2:
744         OS = parseOS(Comp);
745         IsCygwin = Comp.startswith("cygwin");
746         IsMinGW32 = Comp.startswith("mingw");
747         Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
748         break;
749       case 3:
750         Environment = parseEnvironment(Comp);
751         Valid = Environment != UnknownEnvironment;
752         if (!Valid) {
753           ObjectFormat = parseFormat(Comp);
754           Valid = ObjectFormat != UnknownObjectFormat;
755         }
756         break;
757       }
758       if (!Valid)
759         continue; // Nope, try the next component.
760 
761       // Move the component to the target position, pushing any non-fixed
762       // components that are in the way to the right.  This tends to give
763       // good results in the common cases of a forgotten vendor component
764       // or a wrongly positioned environment.
765       if (Pos < Idx) {
766         // Insert left, pushing the existing components to the right.  For
767         // example, a-b-i386 -> i386-a-b when moving i386 to the front.
768         StringRef CurrentComponent(""); // The empty component.
769         // Replace the component we are moving with an empty component.
770         std::swap(CurrentComponent, Components[Idx]);
771         // Insert the component being moved at Pos, displacing any existing
772         // components to the right.
773         for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
774           // Skip over any fixed components.
775           while (i < array_lengthof(Found) && Found[i])
776             ++i;
777           // Place the component at the new position, getting the component
778           // that was at this position - it will be moved right.
779           std::swap(CurrentComponent, Components[i]);
780         }
781       } else if (Pos > Idx) {
782         // Push right by inserting empty components until the component at Idx
783         // reaches the target position Pos.  For example, pc-a -> -pc-a when
784         // moving pc to the second position.
785         do {
786           // Insert one empty component at Idx.
787           StringRef CurrentComponent(""); // The empty component.
788           for (unsigned i = Idx; i < Components.size();) {
789             // Place the component at the new position, getting the component
790             // that was at this position - it will be moved right.
791             std::swap(CurrentComponent, Components[i]);
792             // If it was placed on top of an empty component then we are done.
793             if (CurrentComponent.empty())
794               break;
795             // Advance to the next component, skipping any fixed components.
796             while (++i < array_lengthof(Found) && Found[i])
797               ;
798           }
799           // The last component was pushed off the end - append it.
800           if (!CurrentComponent.empty())
801             Components.push_back(CurrentComponent);
802 
803           // Advance Idx to the component's new position.
804           while (++Idx < array_lengthof(Found) && Found[Idx])
805             ;
806         } while (Idx < Pos); // Add more until the final position is reached.
807       }
808       assert(Pos < Components.size() && Components[Pos] == Comp &&
809              "Component moved wrong!");
810       Found[Pos] = true;
811       break;
812     }
813   }
814 
815   // Special case logic goes here.  At this point Arch, Vendor and OS have the
816   // correct values for the computed components.
817   std::string NormalizedEnvironment;
818   if (Environment == Triple::Android && Components[3].startswith("androideabi")) {
819     StringRef AndroidVersion = Components[3].drop_front(strlen("androideabi"));
820     if (AndroidVersion.empty()) {
821       Components[3] = "android";
822     } else {
823       NormalizedEnvironment = Twine("android", AndroidVersion).str();
824       Components[3] = NormalizedEnvironment;
825     }
826   }
827 
828   if (OS == Triple::Win32) {
829     Components.resize(4);
830     Components[2] = "windows";
831     if (Environment == UnknownEnvironment) {
832       if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
833         Components[3] = "msvc";
834       else
835         Components[3] = getObjectFormatTypeName(ObjectFormat);
836     }
837   } else if (IsMinGW32) {
838     Components.resize(4);
839     Components[2] = "windows";
840     Components[3] = "gnu";
841   } else if (IsCygwin) {
842     Components.resize(4);
843     Components[2] = "windows";
844     Components[3] = "cygnus";
845   }
846   if (IsMinGW32 || IsCygwin ||
847       (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
848     if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
849       Components.resize(5);
850       Components[4] = getObjectFormatTypeName(ObjectFormat);
851     }
852   }
853 
854   // Stick the corrected components back together to form the normalized string.
855   std::string Normalized;
856   for (unsigned i = 0, e = Components.size(); i != e; ++i) {
857     if (i) Normalized += '-';
858     Normalized += Components[i];
859   }
860   return Normalized;
861 }
862 
863 StringRef Triple::getArchName() const {
864   return StringRef(Data).split('-').first;           // Isolate first component
865 }
866 
867 StringRef Triple::getVendorName() const {
868   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
869   return Tmp.split('-').first;                       // Isolate second component
870 }
871 
872 StringRef Triple::getOSName() const {
873   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
874   Tmp = Tmp.split('-').second;                       // Strip second component
875   return Tmp.split('-').first;                       // Isolate third component
876 }
877 
878 StringRef Triple::getEnvironmentName() const {
879   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
880   Tmp = Tmp.split('-').second;                       // Strip second component
881   return Tmp.split('-').second;                      // Strip third component
882 }
883 
884 StringRef Triple::getOSAndEnvironmentName() const {
885   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
886   return Tmp.split('-').second;                      // Strip second component
887 }
888 
889 static unsigned EatNumber(StringRef &Str) {
890   assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
891   unsigned Result = 0;
892 
893   do {
894     // Consume the leading digit.
895     Result = Result*10 + (Str[0] - '0');
896 
897     // Eat the digit.
898     Str = Str.substr(1);
899   } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
900 
901   return Result;
902 }
903 
904 static void parseVersionFromName(StringRef Name, unsigned &Major,
905                                  unsigned &Minor, unsigned &Micro) {
906   // Any unset version defaults to 0.
907   Major = Minor = Micro = 0;
908 
909   // Parse up to three components.
910   unsigned *Components[3] = {&Major, &Minor, &Micro};
911   for (unsigned i = 0; i != 3; ++i) {
912     if (Name.empty() || Name[0] < '0' || Name[0] > '9')
913       break;
914 
915     // Consume the leading number.
916     *Components[i] = EatNumber(Name);
917 
918     // Consume the separator, if present.
919     if (Name.startswith("."))
920       Name = Name.substr(1);
921   }
922 }
923 
924 void Triple::getEnvironmentVersion(unsigned &Major, unsigned &Minor,
925                                    unsigned &Micro) const {
926   StringRef EnvironmentName = getEnvironmentName();
927   StringRef EnvironmentTypeName = getEnvironmentTypeName(getEnvironment());
928   if (EnvironmentName.startswith(EnvironmentTypeName))
929     EnvironmentName = EnvironmentName.substr(EnvironmentTypeName.size());
930 
931   parseVersionFromName(EnvironmentName, Major, Minor, Micro);
932 }
933 
934 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
935                           unsigned &Micro) const {
936   StringRef OSName = getOSName();
937   // Assume that the OS portion of the triple starts with the canonical name.
938   StringRef OSTypeName = getOSTypeName(getOS());
939   if (OSName.startswith(OSTypeName))
940     OSName = OSName.substr(OSTypeName.size());
941 
942   parseVersionFromName(OSName, Major, Minor, Micro);
943 }
944 
945 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
946                               unsigned &Micro) const {
947   getOSVersion(Major, Minor, Micro);
948 
949   switch (getOS()) {
950   default: llvm_unreachable("unexpected OS for Darwin triple");
951   case Darwin:
952     // Default to darwin8, i.e., MacOSX 10.4.
953     if (Major == 0)
954       Major = 8;
955     // Darwin version numbers are skewed from OS X versions.
956     if (Major < 4)
957       return false;
958     Micro = 0;
959     Minor = Major - 4;
960     Major = 10;
961     break;
962   case MacOSX:
963     // Default to 10.4.
964     if (Major == 0) {
965       Major = 10;
966       Minor = 4;
967     }
968     if (Major != 10)
969       return false;
970     break;
971   case IOS:
972   case TvOS:
973   case WatchOS:
974     // Ignore the version from the triple.  This is only handled because the
975     // the clang driver combines OS X and IOS support into a common Darwin
976     // toolchain that wants to know the OS X version number even when targeting
977     // IOS.
978     Major = 10;
979     Minor = 4;
980     Micro = 0;
981     break;
982   }
983   return true;
984 }
985 
986 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
987                            unsigned &Micro) const {
988   switch (getOS()) {
989   default: llvm_unreachable("unexpected OS for Darwin triple");
990   case Darwin:
991   case MacOSX:
992     // Ignore the version from the triple.  This is only handled because the
993     // the clang driver combines OS X and IOS support into a common Darwin
994     // toolchain that wants to know the iOS version number even when targeting
995     // OS X.
996     Major = 5;
997     Minor = 0;
998     Micro = 0;
999     break;
1000   case IOS:
1001   case TvOS:
1002     getOSVersion(Major, Minor, Micro);
1003     // Default to 5.0 (or 7.0 for arm64).
1004     if (Major == 0)
1005       Major = (getArch() == aarch64) ? 7 : 5;
1006     break;
1007   case WatchOS:
1008     llvm_unreachable("conflicting triple info");
1009   }
1010 }
1011 
1012 void Triple::getWatchOSVersion(unsigned &Major, unsigned &Minor,
1013                                unsigned &Micro) const {
1014   switch (getOS()) {
1015   default: llvm_unreachable("unexpected OS for Darwin triple");
1016   case Darwin:
1017   case MacOSX:
1018     // Ignore the version from the triple.  This is only handled because the
1019     // the clang driver combines OS X and IOS support into a common Darwin
1020     // toolchain that wants to know the iOS version number even when targeting
1021     // OS X.
1022     Major = 2;
1023     Minor = 0;
1024     Micro = 0;
1025     break;
1026   case WatchOS:
1027     getOSVersion(Major, Minor, Micro);
1028     if (Major == 0)
1029       Major = 2;
1030     break;
1031   case IOS:
1032     llvm_unreachable("conflicting triple info");
1033   }
1034 }
1035 
1036 void Triple::setTriple(const Twine &Str) {
1037   *this = Triple(Str);
1038 }
1039 
1040 void Triple::setArch(ArchType Kind) {
1041   setArchName(getArchTypeName(Kind));
1042 }
1043 
1044 void Triple::setVendor(VendorType Kind) {
1045   setVendorName(getVendorTypeName(Kind));
1046 }
1047 
1048 void Triple::setOS(OSType Kind) {
1049   setOSName(getOSTypeName(Kind));
1050 }
1051 
1052 void Triple::setEnvironment(EnvironmentType Kind) {
1053   if (ObjectFormat == getDefaultFormat(*this))
1054     return setEnvironmentName(getEnvironmentTypeName(Kind));
1055 
1056   setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
1057                       getObjectFormatTypeName(ObjectFormat)).str());
1058 }
1059 
1060 void Triple::setObjectFormat(ObjectFormatType Kind) {
1061   if (Environment == UnknownEnvironment)
1062     return setEnvironmentName(getObjectFormatTypeName(Kind));
1063 
1064   setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
1065                       getObjectFormatTypeName(Kind)).str());
1066 }
1067 
1068 void Triple::setArchName(StringRef Str) {
1069   // Work around a miscompilation bug for Twines in gcc 4.0.3.
1070   SmallString<64> Triple;
1071   Triple += Str;
1072   Triple += "-";
1073   Triple += getVendorName();
1074   Triple += "-";
1075   Triple += getOSAndEnvironmentName();
1076   setTriple(Triple);
1077 }
1078 
1079 void Triple::setVendorName(StringRef Str) {
1080   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
1081 }
1082 
1083 void Triple::setOSName(StringRef Str) {
1084   if (hasEnvironment())
1085     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
1086               "-" + getEnvironmentName());
1087   else
1088     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
1089 }
1090 
1091 void Triple::setEnvironmentName(StringRef Str) {
1092   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
1093             "-" + Str);
1094 }
1095 
1096 void Triple::setOSAndEnvironmentName(StringRef Str) {
1097   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
1098 }
1099 
1100 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
1101   switch (Arch) {
1102   case llvm::Triple::UnknownArch:
1103     return 0;
1104 
1105   case llvm::Triple::avr:
1106   case llvm::Triple::msp430:
1107     return 16;
1108 
1109   case llvm::Triple::arm:
1110   case llvm::Triple::armeb:
1111   case llvm::Triple::hexagon:
1112   case llvm::Triple::le32:
1113   case llvm::Triple::mips:
1114   case llvm::Triple::mipsel:
1115   case llvm::Triple::nvptx:
1116   case llvm::Triple::ppc:
1117   case llvm::Triple::r600:
1118   case llvm::Triple::sparc:
1119   case llvm::Triple::sparcel:
1120   case llvm::Triple::tce:
1121   case llvm::Triple::thumb:
1122   case llvm::Triple::thumbeb:
1123   case llvm::Triple::x86:
1124   case llvm::Triple::xcore:
1125   case llvm::Triple::amdil:
1126   case llvm::Triple::hsail:
1127   case llvm::Triple::spir:
1128   case llvm::Triple::kalimba:
1129   case llvm::Triple::lanai:
1130   case llvm::Triple::shave:
1131   case llvm::Triple::wasm32:
1132     return 32;
1133 
1134   case llvm::Triple::aarch64:
1135   case llvm::Triple::aarch64_be:
1136   case llvm::Triple::amdgcn:
1137   case llvm::Triple::bpfel:
1138   case llvm::Triple::bpfeb:
1139   case llvm::Triple::le64:
1140   case llvm::Triple::mips64:
1141   case llvm::Triple::mips64el:
1142   case llvm::Triple::nvptx64:
1143   case llvm::Triple::ppc64:
1144   case llvm::Triple::ppc64le:
1145   case llvm::Triple::sparcv9:
1146   case llvm::Triple::systemz:
1147   case llvm::Triple::x86_64:
1148   case llvm::Triple::amdil64:
1149   case llvm::Triple::hsail64:
1150   case llvm::Triple::spir64:
1151   case llvm::Triple::wasm64:
1152     return 64;
1153   }
1154   llvm_unreachable("Invalid architecture value");
1155 }
1156 
1157 bool Triple::isArch64Bit() const {
1158   return getArchPointerBitWidth(getArch()) == 64;
1159 }
1160 
1161 bool Triple::isArch32Bit() const {
1162   return getArchPointerBitWidth(getArch()) == 32;
1163 }
1164 
1165 bool Triple::isArch16Bit() const {
1166   return getArchPointerBitWidth(getArch()) == 16;
1167 }
1168 
1169 Triple Triple::get32BitArchVariant() const {
1170   Triple T(*this);
1171   switch (getArch()) {
1172   case Triple::UnknownArch:
1173   case Triple::amdgcn:
1174   case Triple::avr:
1175   case Triple::bpfel:
1176   case Triple::bpfeb:
1177   case Triple::msp430:
1178   case Triple::systemz:
1179   case Triple::ppc64le:
1180     T.setArch(UnknownArch);
1181     break;
1182 
1183   case Triple::amdil:
1184   case Triple::hsail:
1185   case Triple::spir:
1186   case Triple::arm:
1187   case Triple::armeb:
1188   case Triple::hexagon:
1189   case Triple::kalimba:
1190   case Triple::le32:
1191   case Triple::mips:
1192   case Triple::mipsel:
1193   case Triple::nvptx:
1194   case Triple::ppc:
1195   case Triple::r600:
1196   case Triple::sparc:
1197   case Triple::sparcel:
1198   case Triple::tce:
1199   case Triple::thumb:
1200   case Triple::thumbeb:
1201   case Triple::x86:
1202   case Triple::xcore:
1203   case Triple::lanai:
1204   case Triple::shave:
1205   case Triple::wasm32:
1206     // Already 32-bit.
1207     break;
1208 
1209   case Triple::aarch64:    T.setArch(Triple::arm);     break;
1210   case Triple::aarch64_be: T.setArch(Triple::armeb);   break;
1211   case Triple::le64:       T.setArch(Triple::le32);    break;
1212   case Triple::mips64:     T.setArch(Triple::mips);    break;
1213   case Triple::mips64el:   T.setArch(Triple::mipsel);  break;
1214   case Triple::nvptx64:    T.setArch(Triple::nvptx);   break;
1215   case Triple::ppc64:      T.setArch(Triple::ppc);     break;
1216   case Triple::sparcv9:    T.setArch(Triple::sparc);   break;
1217   case Triple::x86_64:     T.setArch(Triple::x86);     break;
1218   case Triple::amdil64:    T.setArch(Triple::amdil);   break;
1219   case Triple::hsail64:    T.setArch(Triple::hsail);   break;
1220   case Triple::spir64:     T.setArch(Triple::spir);    break;
1221   case Triple::wasm64:     T.setArch(Triple::wasm32);  break;
1222   }
1223   return T;
1224 }
1225 
1226 Triple Triple::get64BitArchVariant() const {
1227   Triple T(*this);
1228   switch (getArch()) {
1229   case Triple::UnknownArch:
1230   case Triple::avr:
1231   case Triple::hexagon:
1232   case Triple::kalimba:
1233   case Triple::lanai:
1234   case Triple::msp430:
1235   case Triple::r600:
1236   case Triple::tce:
1237   case Triple::xcore:
1238   case Triple::sparcel:
1239   case Triple::shave:
1240     T.setArch(UnknownArch);
1241     break;
1242 
1243   case Triple::aarch64:
1244   case Triple::aarch64_be:
1245   case Triple::bpfel:
1246   case Triple::bpfeb:
1247   case Triple::le64:
1248   case Triple::amdil64:
1249   case Triple::amdgcn:
1250   case Triple::hsail64:
1251   case Triple::spir64:
1252   case Triple::mips64:
1253   case Triple::mips64el:
1254   case Triple::nvptx64:
1255   case Triple::ppc64:
1256   case Triple::ppc64le:
1257   case Triple::sparcv9:
1258   case Triple::systemz:
1259   case Triple::x86_64:
1260   case Triple::wasm64:
1261     // Already 64-bit.
1262     break;
1263 
1264   case Triple::arm:     T.setArch(Triple::aarch64);    break;
1265   case Triple::armeb:   T.setArch(Triple::aarch64_be); break;
1266   case Triple::le32:    T.setArch(Triple::le64);       break;
1267   case Triple::mips:    T.setArch(Triple::mips64);     break;
1268   case Triple::mipsel:  T.setArch(Triple::mips64el);   break;
1269   case Triple::nvptx:   T.setArch(Triple::nvptx64);    break;
1270   case Triple::ppc:     T.setArch(Triple::ppc64);      break;
1271   case Triple::sparc:   T.setArch(Triple::sparcv9);    break;
1272   case Triple::x86:     T.setArch(Triple::x86_64);     break;
1273   case Triple::amdil:   T.setArch(Triple::amdil64);    break;
1274   case Triple::hsail:   T.setArch(Triple::hsail64);    break;
1275   case Triple::spir:    T.setArch(Triple::spir64);     break;
1276   case Triple::thumb:   T.setArch(Triple::aarch64);    break;
1277   case Triple::thumbeb: T.setArch(Triple::aarch64_be); break;
1278   case Triple::wasm32:  T.setArch(Triple::wasm64);     break;
1279   }
1280   return T;
1281 }
1282 
1283 Triple Triple::getBigEndianArchVariant() const {
1284   Triple T(*this);
1285   switch (getArch()) {
1286   case Triple::UnknownArch:
1287   case Triple::amdgcn:
1288   case Triple::amdil64:
1289   case Triple::amdil:
1290   case Triple::avr:
1291   case Triple::hexagon:
1292   case Triple::hsail64:
1293   case Triple::hsail:
1294   case Triple::kalimba:
1295   case Triple::le32:
1296   case Triple::le64:
1297   case Triple::msp430:
1298   case Triple::nvptx64:
1299   case Triple::nvptx:
1300   case Triple::r600:
1301   case Triple::shave:
1302   case Triple::spir64:
1303   case Triple::spir:
1304   case Triple::wasm32:
1305   case Triple::wasm64:
1306   case Triple::x86:
1307   case Triple::x86_64:
1308   case Triple::xcore:
1309 
1310   // ARM is intentionally unsupported here, changing the architecture would
1311   // drop any arch suffixes.
1312   case Triple::arm:
1313   case Triple::thumb:
1314     T.setArch(UnknownArch);
1315     break;
1316 
1317   case Triple::aarch64_be:
1318   case Triple::armeb:
1319   case Triple::bpfeb:
1320   case Triple::lanai:
1321   case Triple::mips64:
1322   case Triple::mips:
1323   case Triple::ppc64:
1324   case Triple::ppc:
1325   case Triple::sparc:
1326   case Triple::sparcv9:
1327   case Triple::systemz:
1328   case Triple::tce:
1329   case Triple::thumbeb:
1330     // Already big endian.
1331     break;
1332 
1333   case Triple::aarch64: T.setArch(Triple::aarch64_be); break;
1334   case Triple::bpfel:   T.setArch(Triple::bpfeb);      break;
1335   case Triple::mips64el:T.setArch(Triple::mips64);     break;
1336   case Triple::mipsel:  T.setArch(Triple::mips);       break;
1337   case Triple::ppc64le: T.setArch(Triple::ppc64);      break;
1338   case Triple::sparcel: T.setArch(Triple::sparc);      break;
1339   }
1340   return T;
1341 }
1342 
1343 Triple Triple::getLittleEndianArchVariant() const {
1344   Triple T(*this);
1345   switch (getArch()) {
1346   case Triple::UnknownArch:
1347   case Triple::lanai:
1348   case Triple::ppc:
1349   case Triple::sparcv9:
1350   case Triple::systemz:
1351   case Triple::tce:
1352 
1353   // ARM is intentionally unsupported here, changing the architecture would
1354   // drop any arch suffixes.
1355   case Triple::armeb:
1356   case Triple::thumbeb:
1357     T.setArch(UnknownArch);
1358     break;
1359 
1360   case Triple::aarch64:
1361   case Triple::amdgcn:
1362   case Triple::amdil64:
1363   case Triple::amdil:
1364   case Triple::arm:
1365   case Triple::avr:
1366   case Triple::bpfel:
1367   case Triple::hexagon:
1368   case Triple::hsail64:
1369   case Triple::hsail:
1370   case Triple::kalimba:
1371   case Triple::le32:
1372   case Triple::le64:
1373   case Triple::mips64el:
1374   case Triple::mipsel:
1375   case Triple::msp430:
1376   case Triple::nvptx64:
1377   case Triple::nvptx:
1378   case Triple::ppc64le:
1379   case Triple::r600:
1380   case Triple::shave:
1381   case Triple::sparcel:
1382   case Triple::spir64:
1383   case Triple::spir:
1384   case Triple::thumb:
1385   case Triple::wasm32:
1386   case Triple::wasm64:
1387   case Triple::x86:
1388   case Triple::x86_64:
1389   case Triple::xcore:
1390     // Already little endian.
1391     break;
1392 
1393   case Triple::aarch64_be: T.setArch(Triple::aarch64);  break;
1394   case Triple::bpfeb:      T.setArch(Triple::bpfel);    break;
1395   case Triple::mips64:     T.setArch(Triple::mips64el); break;
1396   case Triple::mips:       T.setArch(Triple::mipsel);   break;
1397   case Triple::ppc64:      T.setArch(Triple::ppc64le);  break;
1398   case Triple::sparc:      T.setArch(Triple::sparcel);  break;
1399   }
1400   return T;
1401 }
1402 
1403 StringRef Triple::getARMCPUForArch(StringRef MArch) const {
1404   if (MArch.empty())
1405     MArch = getArchName();
1406   MArch = ARM::getCanonicalArchName(MArch);
1407 
1408   // Some defaults are forced.
1409   switch (getOS()) {
1410   case llvm::Triple::FreeBSD:
1411   case llvm::Triple::NetBSD:
1412     if (!MArch.empty() && MArch == "v6")
1413       return "arm1176jzf-s";
1414     break;
1415   case llvm::Triple::Win32:
1416     // FIXME: this is invalid for WindowsCE
1417     return "cortex-a9";
1418   case llvm::Triple::MacOSX:
1419   case llvm::Triple::IOS:
1420   case llvm::Triple::WatchOS:
1421   case llvm::Triple::TvOS:
1422     if (MArch == "v7k")
1423       return "cortex-a7";
1424     break;
1425   default:
1426     break;
1427   }
1428 
1429   if (MArch.empty())
1430     return StringRef();
1431 
1432   StringRef CPU = ARM::getDefaultCPU(MArch);
1433   if (!CPU.empty())
1434     return CPU;
1435 
1436   // If no specific architecture version is requested, return the minimum CPU
1437   // required by the OS and environment.
1438   switch (getOS()) {
1439   case llvm::Triple::NetBSD:
1440     switch (getEnvironment()) {
1441     case llvm::Triple::GNUEABIHF:
1442     case llvm::Triple::GNUEABI:
1443     case llvm::Triple::EABIHF:
1444     case llvm::Triple::EABI:
1445       return "arm926ej-s";
1446     default:
1447       return "strongarm";
1448     }
1449   case llvm::Triple::NaCl:
1450     return "cortex-a8";
1451   default:
1452     switch (getEnvironment()) {
1453     case llvm::Triple::EABIHF:
1454     case llvm::Triple::GNUEABIHF:
1455       return "arm1176jzf-s";
1456     default:
1457       return "arm7tdmi";
1458     }
1459   }
1460 
1461   llvm_unreachable("invalid arch name");
1462 }
1463