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

source code of llvm/lib/TargetParser/Triple.cpp