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