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