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