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