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