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