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