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