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