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