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