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