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