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