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