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