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