1193323Sed//===--- Triple.cpp - Target triple helper class --------------------------===//
2193323Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193323Sed//
7193323Sed//===----------------------------------------------------------------------===//
8193323Sed
9193323Sed#include "llvm/ADT/Triple.h"
10249423Sdim#include "llvm/ADT/STLExtras.h"
11198090Srdivacky#include "llvm/ADT/SmallString.h"
12234353Sdim#include "llvm/ADT/StringSwitch.h"
13234353Sdim#include "llvm/Support/ErrorHandling.h"
14321369Sdim#include "llvm/Support/Host.h"
15288943Sdim#include "llvm/Support/TargetParser.h"
16193323Sed#include <cstring>
17193323Sedusing namespace llvm;
18193323Sed
19314564SdimStringRef Triple::getArchTypeName(ArchType Kind) {
20193323Sed  switch (Kind) {
21309124Sdim  case UnknownArch:    return "unknown";
22218893Sdim
23309124Sdim  case aarch64:        return "aarch64";
24360784Sdim  case aarch64_32:     return "aarch64_32";
25309124Sdim  case aarch64_be:     return "aarch64_be";
26360784Sdim  case amdgcn:         return "amdgcn";
27360784Sdim  case amdil64:        return "amdil64";
28360784Sdim  case amdil:          return "amdil";
29360784Sdim  case arc:            return "arc";
30309124Sdim  case arm:            return "arm";
31309124Sdim  case armeb:          return "armeb";
32309124Sdim  case avr:            return "avr";
33360784Sdim  case bpfeb:          return "bpfeb";
34309124Sdim  case bpfel:          return "bpfel";
35309124Sdim  case hexagon:        return "hexagon";
36360784Sdim  case hsail64:        return "hsail64";
37360784Sdim  case hsail:          return "hsail";
38360784Sdim  case kalimba:        return "kalimba";
39360784Sdim  case lanai:          return "lanai";
40360784Sdim  case le32:           return "le32";
41360784Sdim  case le64:           return "le64";
42360784Sdim  case mips64:         return "mips64";
43360784Sdim  case mips64el:       return "mips64el";
44309124Sdim  case mips:           return "mips";
45309124Sdim  case mipsel:         return "mipsel";
46309124Sdim  case msp430:         return "msp430";
47360784Sdim  case nvptx64:        return "nvptx64";
48360784Sdim  case nvptx:          return "nvptx";
49309124Sdim  case ppc64:          return "powerpc64";
50309124Sdim  case ppc64le:        return "powerpc64le";
51309124Sdim  case ppc:            return "powerpc";
52309124Sdim  case r600:           return "r600";
53360784Sdim  case renderscript32: return "renderscript32";
54360784Sdim  case renderscript64: return "renderscript64";
55314564Sdim  case riscv32:        return "riscv32";
56314564Sdim  case riscv64:        return "riscv64";
57360784Sdim  case shave:          return "shave";
58309124Sdim  case sparc:          return "sparc";
59360784Sdim  case sparcel:        return "sparcel";
60309124Sdim  case sparcv9:        return "sparcv9";
61360784Sdim  case spir64:         return "spir64";
62360784Sdim  case spir:           return "spir";
63309124Sdim  case systemz:        return "s390x";
64309124Sdim  case tce:            return "tce";
65314564Sdim  case tcele:          return "tcele";
66309124Sdim  case thumb:          return "thumb";
67309124Sdim  case thumbeb:        return "thumbeb";
68360784Sdim  case ve:             return "ve";
69360784Sdim  case wasm32:         return "wasm32";
70360784Sdim  case wasm64:         return "wasm64";
71309124Sdim  case x86:            return "i386";
72309124Sdim  case x86_64:         return "x86_64";
73309124Sdim  case xcore:          return "xcore";
74193323Sed  }
75193323Sed
76234353Sdim  llvm_unreachable("Invalid ArchType!");
77193323Sed}
78193323Sed
79314564SdimStringRef Triple::getArchTypePrefix(ArchType Kind) {
80198090Srdivacky  switch (Kind) {
81198090Srdivacky  default:
82314564Sdim    return StringRef();
83198090Srdivacky
84276479Sdim  case aarch64:
85353358Sdim  case aarch64_be:
86353358Sdim  case aarch64_32:  return "aarch64";
87249423Sdim
88327952Sdim  case arc:         return "arc";
89327952Sdim
90198090Srdivacky  case arm:
91276479Sdim  case armeb:
92276479Sdim  case thumb:
93276479Sdim  case thumbeb:     return "arm";
94198090Srdivacky
95296417Sdim  case avr:         return "avr";
96296417Sdim
97198090Srdivacky  case ppc64:
98261991Sdim  case ppc64le:
99276479Sdim  case ppc:         return "ppc";
100198090Srdivacky
101239462Sdim  case mips:
102239462Sdim  case mipsel:
103239462Sdim  case mips64:
104276479Sdim  case mips64el:    return "mips";
105234353Sdim
106276479Sdim  case hexagon:     return "hexagon";
107239462Sdim
108309124Sdim  case amdgcn:      return "amdgcn";
109309124Sdim  case r600:        return "r600";
110234353Sdim
111288943Sdim  case bpfel:
112288943Sdim  case bpfeb:       return "bpf";
113288943Sdim
114203954Srdivacky  case sparcv9:
115288943Sdim  case sparcel:
116276479Sdim  case sparc:       return "sparc";
117198090Srdivacky
118288943Sdim  case systemz:     return "s390";
119251662Sdim
120198090Srdivacky  case x86:
121276479Sdim  case x86_64:      return "x86";
122218893Sdim
123276479Sdim  case xcore:       return "xcore";
124218893Sdim
125309124Sdim  // NVPTX intrinsics are namespaced under nvvm.
126309124Sdim  case nvptx:       return "nvvm";
127309124Sdim  case nvptx64:     return "nvvm";
128276479Sdim
129276479Sdim  case le32:        return "le32";
130280031Sdim  case le64:        return "le64";
131280031Sdim
132280031Sdim  case amdil:
133280031Sdim  case amdil64:     return "amdil";
134280031Sdim
135280031Sdim  case hsail:
136280031Sdim  case hsail64:     return "hsail";
137280031Sdim
138280031Sdim  case spir:
139276479Sdim  case spir64:      return "spir";
140276479Sdim  case kalimba:     return "kalimba";
141309124Sdim  case lanai:       return "lanai";
142288943Sdim  case shave:       return "shave";
143296417Sdim  case wasm32:
144296417Sdim  case wasm64:      return "wasm";
145314564Sdim
146314564Sdim  case riscv32:
147314564Sdim  case riscv64:     return "riscv";
148360784Sdim
149360784Sdim  case ve:          return "ve";
150198090Srdivacky  }
151198090Srdivacky}
152198090Srdivacky
153314564SdimStringRef Triple::getVendorTypeName(VendorType Kind) {
154193323Sed  switch (Kind) {
155193323Sed  case UnknownVendor: return "unknown";
156193323Sed
157360784Sdim  case AMD: return "amd";
158193323Sed  case Apple: return "apple";
159234353Sdim  case BGP: return "bgp";
160234353Sdim  case BGQ: return "bgq";
161360784Sdim  case CSR: return "csr";
162243830Sdim  case Freescale: return "fsl";
163243830Sdim  case IBM: return "ibm";
164276479Sdim  case ImaginationTechnologies: return "img";
165360784Sdim  case Mesa: return "mesa";
166276479Sdim  case MipsTechnologies: return "mti";
167360784Sdim  case Myriad: return "myriad";
168261991Sdim  case NVIDIA: return "nvidia";
169360784Sdim  case OpenEmbedded: return "oe";
170360784Sdim  case PC: return "pc";
171360784Sdim  case SCEI: return "scei";
172321369Sdim  case SUSE: return "suse";
173193323Sed  }
174193323Sed
175234353Sdim  llvm_unreachable("Invalid VendorType!");
176193323Sed}
177193323Sed
178314564SdimStringRef Triple::getOSTypeName(OSType Kind) {
179193323Sed  switch (Kind) {
180193323Sed  case UnknownOS: return "unknown";
181193323Sed
182360784Sdim  case AIX: return "aix";
183360784Sdim  case AMDHSA: return "amdhsa";
184360784Sdim  case AMDPAL: return "amdpal";
185321369Sdim  case Ananas: return "ananas";
186360784Sdim  case CNK: return "cnk";
187360784Sdim  case CUDA: return "cuda";
188288943Sdim  case CloudABI: return "cloudabi";
189360784Sdim  case Contiki: return "contiki";
190193323Sed  case Darwin: return "darwin";
191193323Sed  case DragonFly: return "dragonfly";
192360784Sdim  case ELFIAMCU: return "elfiamcu";
193360784Sdim  case Emscripten: return "emscripten";
194193323Sed  case FreeBSD: return "freebsd";
195314564Sdim  case Fuchsia: return "fuchsia";
196360784Sdim  case Haiku: return "haiku";
197360784Sdim  case HermitCore: return "hermit";
198360784Sdim  case Hurd: return "hurd";
199221345Sdim  case IOS: return "ios";
200226633Sdim  case KFreeBSD: return "kfreebsd";
201193323Sed  case Linux: return "linux";
202199989Srdivacky  case Lv2: return "lv2";
203221345Sdim  case MacOSX: return "macosx";
204360784Sdim  case Mesa3D: return "mesa3d";
205360784Sdim  case Minix: return "minix";
206360784Sdim  case NVCL: return "nvcl";
207360784Sdim  case NaCl: return "nacl";
208198090Srdivacky  case NetBSD: return "netbsd";
209195340Sed  case OpenBSD: return "openbsd";
210360784Sdim  case PS4: return "ps4";
211360784Sdim  case RTEMS: return "rtems";
212198090Srdivacky  case Solaris: return "solaris";
213296417Sdim  case TvOS: return "tvos";
214360784Sdim  case WASI: return "wasi";
215296417Sdim  case WatchOS: return "watchos";
216360784Sdim  case Win32: return "windows";
217193323Sed  }
218193323Sed
219234353Sdim  llvm_unreachable("Invalid OSType");
220193323Sed}
221193323Sed
222314564SdimStringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) {
223218893Sdim  switch (Kind) {
224218893Sdim  case UnknownEnvironment: return "unknown";
225360784Sdim  case Android: return "android";
226360784Sdim  case CODE16: return "code16";
227360784Sdim  case CoreCLR: return "coreclr";
228360784Sdim  case Cygnus: return "cygnus";
229360784Sdim  case EABI: return "eabi";
230360784Sdim  case EABIHF: return "eabihf";
231218893Sdim  case GNU: return "gnu";
232360784Sdim  case GNUABI64: return "gnuabi64";
233327952Sdim  case GNUABIN32: return "gnuabin32";
234360784Sdim  case GNUEABI: return "gnueabi";
235234353Sdim  case GNUEABIHF: return "gnueabihf";
236249423Sdim  case GNUX32: return "gnux32";
237360784Sdim  case Itanium: return "itanium";
238360784Sdim  case MSVC: return "msvc";
239360784Sdim  case MacABI: return "macabi";
240309124Sdim  case Musl: return "musl";
241309124Sdim  case MuslEABI: return "musleabi";
242309124Sdim  case MuslEABIHF: return "musleabihf";
243327952Sdim  case Simulator: return "simulator";
244218893Sdim  }
245218893Sdim
246234353Sdim  llvm_unreachable("Invalid EnvironmentType!");
247218893Sdim}
248218893Sdim
249288943Sdimstatic Triple::ArchType parseBPFArch(StringRef ArchName) {
250288943Sdim  if (ArchName.equals("bpf")) {
251288943Sdim    if (sys::IsLittleEndianHost)
252288943Sdim      return Triple::bpfel;
253288943Sdim    else
254288943Sdim      return Triple::bpfeb;
255288943Sdim  } else if (ArchName.equals("bpf_be") || ArchName.equals("bpfeb")) {
256288943Sdim    return Triple::bpfeb;
257288943Sdim  } else if (ArchName.equals("bpf_le") || ArchName.equals("bpfel")) {
258288943Sdim    return Triple::bpfel;
259288943Sdim  } else {
260288943Sdim    return Triple::UnknownArch;
261288943Sdim  }
262288943Sdim}
263288943Sdim
264199481SrdivackyTriple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
265288943Sdim  Triple::ArchType BPFArch(parseBPFArch(Name));
266234353Sdim  return StringSwitch<Triple::ArchType>(Name)
267249423Sdim    .Case("aarch64", aarch64)
268276479Sdim    .Case("aarch64_be", aarch64_be)
269353358Sdim    .Case("aarch64_32", aarch64_32)
270327952Sdim    .Case("arc", arc)
271280031Sdim    .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
272353358Sdim    .Case("arm64_32", aarch64_32)
273234353Sdim    .Case("arm", arm)
274276479Sdim    .Case("armeb", armeb)
275296417Sdim    .Case("avr", avr)
276288943Sdim    .StartsWith("bpf", BPFArch)
277234353Sdim    .Case("mips", mips)
278234353Sdim    .Case("mipsel", mipsel)
279234353Sdim    .Case("mips64", mips64)
280234353Sdim    .Case("mips64el", mips64el)
281234353Sdim    .Case("msp430", msp430)
282234353Sdim    .Case("ppc64", ppc64)
283234353Sdim    .Case("ppc32", ppc)
284234353Sdim    .Case("ppc", ppc)
285261991Sdim    .Case("ppc64le", ppc64le)
286234353Sdim    .Case("r600", r600)
287280031Sdim    .Case("amdgcn", amdgcn)
288314564Sdim    .Case("riscv32", riscv32)
289314564Sdim    .Case("riscv64", riscv64)
290234353Sdim    .Case("hexagon", hexagon)
291234353Sdim    .Case("sparc", sparc)
292288943Sdim    .Case("sparcel", sparcel)
293234353Sdim    .Case("sparcv9", sparcv9)
294251662Sdim    .Case("systemz", systemz)
295234353Sdim    .Case("tce", tce)
296314564Sdim    .Case("tcele", tcele)
297234353Sdim    .Case("thumb", thumb)
298276479Sdim    .Case("thumbeb", thumbeb)
299234353Sdim    .Case("x86", x86)
300234353Sdim    .Case("x86-64", x86_64)
301234353Sdim    .Case("xcore", xcore)
302239462Sdim    .Case("nvptx", nvptx)
303239462Sdim    .Case("nvptx64", nvptx64)
304234353Sdim    .Case("le32", le32)
305280031Sdim    .Case("le64", le64)
306234353Sdim    .Case("amdil", amdil)
307280031Sdim    .Case("amdil64", amdil64)
308280031Sdim    .Case("hsail", hsail)
309280031Sdim    .Case("hsail64", hsail64)
310243830Sdim    .Case("spir", spir)
311243830Sdim    .Case("spir64", spir64)
312276479Sdim    .Case("kalimba", kalimba)
313309124Sdim    .Case("lanai", lanai)
314288943Sdim    .Case("shave", shave)
315288943Sdim    .Case("wasm32", wasm32)
316288943Sdim    .Case("wasm64", wasm64)
317309124Sdim    .Case("renderscript32", renderscript32)
318309124Sdim    .Case("renderscript64", renderscript64)
319360784Sdim    .Case("ve", ve)
320234353Sdim    .Default(UnknownArch);
321198090Srdivacky}
322198090Srdivacky
323280031Sdimstatic Triple::ArchType parseARMArch(StringRef ArchName) {
324327952Sdim  ARM::ISAKind ISA = ARM::parseArchISA(ArchName);
325327952Sdim  ARM::EndianKind ENDIAN = ARM::parseArchEndian(ArchName);
326288943Sdim
327280031Sdim  Triple::ArchType arch = Triple::UnknownArch;
328288943Sdim  switch (ENDIAN) {
329327952Sdim  case ARM::EndianKind::LITTLE: {
330288943Sdim    switch (ISA) {
331327952Sdim    case ARM::ISAKind::ARM:
332280031Sdim      arch = Triple::arm;
333288943Sdim      break;
334327952Sdim    case ARM::ISAKind::THUMB:
335280031Sdim      arch = Triple::thumb;
336288943Sdim      break;
337327952Sdim    case ARM::ISAKind::AARCH64:
338288943Sdim      arch = Triple::aarch64;
339288943Sdim      break;
340327952Sdim    case ARM::ISAKind::INVALID:
341327952Sdim      break;
342288943Sdim    }
343288943Sdim    break;
344280031Sdim  }
345327952Sdim  case ARM::EndianKind::BIG: {
346288943Sdim    switch (ISA) {
347327952Sdim    case ARM::ISAKind::ARM:
348288943Sdim      arch = Triple::armeb;
349288943Sdim      break;
350327952Sdim    case ARM::ISAKind::THUMB:
351288943Sdim      arch = Triple::thumbeb;
352288943Sdim      break;
353327952Sdim    case ARM::ISAKind::AARCH64:
354288943Sdim      arch = Triple::aarch64_be;
355288943Sdim      break;
356327952Sdim    case ARM::ISAKind::INVALID:
357327952Sdim      break;
358288943Sdim    }
359288943Sdim    break;
360288943Sdim  }
361327952Sdim  case ARM::EndianKind::INVALID: {
362327952Sdim    break;
363288943Sdim  }
364327952Sdim  }
365288943Sdim
366296417Sdim  ArchName = ARM::getCanonicalArchName(ArchName);
367288943Sdim  if (ArchName.empty())
368288943Sdim    return Triple::UnknownArch;
369288943Sdim
370288943Sdim  // Thumb only exists in v4+
371327952Sdim  if (ISA == ARM::ISAKind::THUMB &&
372288943Sdim      (ArchName.startswith("v2") || ArchName.startswith("v3")))
373288943Sdim    return Triple::UnknownArch;
374288943Sdim
375288943Sdim  // Thumb only for v6m
376327952Sdim  ARM::ProfileKind Profile = ARM::parseArchProfile(ArchName);
377296417Sdim  unsigned Version = ARM::parseArchVersion(ArchName);
378327952Sdim  if (Profile == ARM::ProfileKind::M && Version == 6) {
379327952Sdim    if (ENDIAN == ARM::EndianKind::BIG)
380288943Sdim      return Triple::thumbeb;
381288943Sdim    else
382288943Sdim      return Triple::thumb;
383288943Sdim  }
384288943Sdim
385288943Sdim  return arch;
386199481Srdivacky}
387199481Srdivacky
388234353Sdimstatic Triple::ArchType parseArch(StringRef ArchName) {
389296417Sdim  auto AT = StringSwitch<Triple::ArchType>(ArchName)
390234353Sdim    .Cases("i386", "i486", "i586", "i686", Triple::x86)
391234353Sdim    // FIXME: Do we need to support these?
392234353Sdim    .Cases("i786", "i886", "i986", Triple::x86)
393261991Sdim    .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
394360661Sdim    .Cases("powerpc", "powerpcspe", "ppc", "ppc32", Triple::ppc)
395296417Sdim    .Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
396296417Sdim    .Cases("powerpc64le", "ppc64le", Triple::ppc64le)
397280031Sdim    .Case("xscale", Triple::arm)
398280031Sdim    .Case("xscaleeb", Triple::armeb)
399296417Sdim    .Case("aarch64", Triple::aarch64)
400296417Sdim    .Case("aarch64_be", Triple::aarch64_be)
401353358Sdim    .Case("aarch64_32", Triple::aarch64_32)
402327952Sdim    .Case("arc", Triple::arc)
403296417Sdim    .Case("arm64", Triple::aarch64)
404353358Sdim    .Case("arm64_32", Triple::aarch64_32)
405296417Sdim    .Case("arm", Triple::arm)
406296417Sdim    .Case("armeb", Triple::armeb)
407296417Sdim    .Case("thumb", Triple::thumb)
408296417Sdim    .Case("thumbeb", Triple::thumbeb)
409296417Sdim    .Case("avr", Triple::avr)
410234353Sdim    .Case("msp430", Triple::msp430)
411344779Sdim    .Cases("mips", "mipseb", "mipsallegrex", "mipsisa32r6",
412344779Sdim           "mipsr6", Triple::mips)
413344779Sdim    .Cases("mipsel", "mipsallegrexel", "mipsisa32r6el", "mipsr6el",
414344779Sdim           Triple::mipsel)
415344779Sdim    .Cases("mips64", "mips64eb", "mipsn32", "mipsisa64r6",
416344779Sdim           "mips64r6", "mipsn32r6", Triple::mips64)
417344779Sdim    .Cases("mips64el", "mipsn32el", "mipsisa64r6el", "mips64r6el",
418344779Sdim           "mipsn32r6el", Triple::mips64el)
419234353Sdim    .Case("r600", Triple::r600)
420280031Sdim    .Case("amdgcn", Triple::amdgcn)
421314564Sdim    .Case("riscv32", Triple::riscv32)
422314564Sdim    .Case("riscv64", Triple::riscv64)
423234353Sdim    .Case("hexagon", Triple::hexagon)
424296417Sdim    .Cases("s390x", "systemz", Triple::systemz)
425234353Sdim    .Case("sparc", Triple::sparc)
426288943Sdim    .Case("sparcel", Triple::sparcel)
427261991Sdim    .Cases("sparcv9", "sparc64", Triple::sparcv9)
428234353Sdim    .Case("tce", Triple::tce)
429314564Sdim    .Case("tcele", Triple::tcele)
430234353Sdim    .Case("xcore", Triple::xcore)
431239462Sdim    .Case("nvptx", Triple::nvptx)
432239462Sdim    .Case("nvptx64", Triple::nvptx64)
433234353Sdim    .Case("le32", Triple::le32)
434280031Sdim    .Case("le64", Triple::le64)
435234353Sdim    .Case("amdil", Triple::amdil)
436280031Sdim    .Case("amdil64", Triple::amdil64)
437280031Sdim    .Case("hsail", Triple::hsail)
438280031Sdim    .Case("hsail64", Triple::hsail64)
439243830Sdim    .Case("spir", Triple::spir)
440243830Sdim    .Case("spir64", Triple::spir64)
441280031Sdim    .StartsWith("kalimba", Triple::kalimba)
442309124Sdim    .Case("lanai", Triple::lanai)
443360784Sdim    .Case("renderscript32", Triple::renderscript32)
444360784Sdim    .Case("renderscript64", Triple::renderscript64)
445288943Sdim    .Case("shave", Triple::shave)
446360784Sdim    .Case("ve", Triple::ve)
447288943Sdim    .Case("wasm32", Triple::wasm32)
448288943Sdim    .Case("wasm64", Triple::wasm64)
449234353Sdim    .Default(Triple::UnknownArch);
450296417Sdim
451296417Sdim  // Some architectures require special parsing logic just to compute the
452296417Sdim  // ArchType result.
453296417Sdim  if (AT == Triple::UnknownArch) {
454296417Sdim    if (ArchName.startswith("arm") || ArchName.startswith("thumb") ||
455296417Sdim        ArchName.startswith("aarch64"))
456296417Sdim      return parseARMArch(ArchName);
457296417Sdim    if (ArchName.startswith("bpf"))
458296417Sdim      return parseBPFArch(ArchName);
459296417Sdim  }
460296417Sdim
461296417Sdim  return AT;
462234353Sdim}
463193323Sed
464234353Sdimstatic Triple::VendorType parseVendor(StringRef VendorName) {
465234353Sdim  return StringSwitch<Triple::VendorType>(VendorName)
466234353Sdim    .Case("apple", Triple::Apple)
467234353Sdim    .Case("pc", Triple::PC)
468234353Sdim    .Case("scei", Triple::SCEI)
469234353Sdim    .Case("bgp", Triple::BGP)
470234353Sdim    .Case("bgq", Triple::BGQ)
471243830Sdim    .Case("fsl", Triple::Freescale)
472243830Sdim    .Case("ibm", Triple::IBM)
473276479Sdim    .Case("img", Triple::ImaginationTechnologies)
474276479Sdim    .Case("mti", Triple::MipsTechnologies)
475261991Sdim    .Case("nvidia", Triple::NVIDIA)
476276479Sdim    .Case("csr", Triple::CSR)
477296417Sdim    .Case("myriad", Triple::Myriad)
478309124Sdim    .Case("amd", Triple::AMD)
479309124Sdim    .Case("mesa", Triple::Mesa)
480321369Sdim    .Case("suse", Triple::SUSE)
481341825Sdim    .Case("oe", Triple::OpenEmbedded)
482234353Sdim    .Default(Triple::UnknownVendor);
483212904Sdim}
484193323Sed
485234353Sdimstatic Triple::OSType parseOS(StringRef OSName) {
486234353Sdim  return StringSwitch<Triple::OSType>(OSName)
487321369Sdim    .StartsWith("ananas", Triple::Ananas)
488288943Sdim    .StartsWith("cloudabi", Triple::CloudABI)
489234353Sdim    .StartsWith("darwin", Triple::Darwin)
490234353Sdim    .StartsWith("dragonfly", Triple::DragonFly)
491234353Sdim    .StartsWith("freebsd", Triple::FreeBSD)
492314564Sdim    .StartsWith("fuchsia", Triple::Fuchsia)
493234353Sdim    .StartsWith("ios", Triple::IOS)
494234353Sdim    .StartsWith("kfreebsd", Triple::KFreeBSD)
495234353Sdim    .StartsWith("linux", Triple::Linux)
496234353Sdim    .StartsWith("lv2", Triple::Lv2)
497321369Sdim    .StartsWith("macos", Triple::MacOSX)
498234353Sdim    .StartsWith("netbsd", Triple::NetBSD)
499234353Sdim    .StartsWith("openbsd", Triple::OpenBSD)
500234353Sdim    .StartsWith("solaris", Triple::Solaris)
501234353Sdim    .StartsWith("win32", Triple::Win32)
502276479Sdim    .StartsWith("windows", Triple::Win32)
503234353Sdim    .StartsWith("haiku", Triple::Haiku)
504234353Sdim    .StartsWith("minix", Triple::Minix)
505234353Sdim    .StartsWith("rtems", Triple::RTEMS)
506249423Sdim    .StartsWith("nacl", Triple::NaCl)
507234353Sdim    .StartsWith("cnk", Triple::CNK)
508243830Sdim    .StartsWith("aix", Triple::AIX)
509261991Sdim    .StartsWith("cuda", Triple::CUDA)
510261991Sdim    .StartsWith("nvcl", Triple::NVCL)
511280031Sdim    .StartsWith("amdhsa", Triple::AMDHSA)
512288943Sdim    .StartsWith("ps4", Triple::PS4)
513296417Sdim    .StartsWith("elfiamcu", Triple::ELFIAMCU)
514296417Sdim    .StartsWith("tvos", Triple::TvOS)
515296417Sdim    .StartsWith("watchos", Triple::WatchOS)
516309124Sdim    .StartsWith("mesa3d", Triple::Mesa3D)
517314564Sdim    .StartsWith("contiki", Triple::Contiki)
518327952Sdim    .StartsWith("amdpal", Triple::AMDPAL)
519344779Sdim    .StartsWith("hermit", Triple::HermitCore)
520344779Sdim    .StartsWith("hurd", Triple::Hurd)
521344779Sdim    .StartsWith("wasi", Triple::WASI)
522353358Sdim    .StartsWith("emscripten", Triple::Emscripten)
523234353Sdim    .Default(Triple::UnknownOS);
524212904Sdim}
525193323Sed
526234353Sdimstatic Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
527234353Sdim  return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
528276479Sdim    .StartsWith("eabihf", Triple::EABIHF)
529234353Sdim    .StartsWith("eabi", Triple::EABI)
530327952Sdim    .StartsWith("gnuabin32", Triple::GNUABIN32)
531309124Sdim    .StartsWith("gnuabi64", Triple::GNUABI64)
532234353Sdim    .StartsWith("gnueabihf", Triple::GNUEABIHF)
533234353Sdim    .StartsWith("gnueabi", Triple::GNUEABI)
534249423Sdim    .StartsWith("gnux32", Triple::GNUX32)
535276479Sdim    .StartsWith("code16", Triple::CODE16)
536234353Sdim    .StartsWith("gnu", Triple::GNU)
537243830Sdim    .StartsWith("android", Triple::Android)
538309124Sdim    .StartsWith("musleabihf", Triple::MuslEABIHF)
539309124Sdim    .StartsWith("musleabi", Triple::MuslEABI)
540309124Sdim    .StartsWith("musl", Triple::Musl)
541276479Sdim    .StartsWith("msvc", Triple::MSVC)
542276479Sdim    .StartsWith("itanium", Triple::Itanium)
543276479Sdim    .StartsWith("cygnus", Triple::Cygnus)
544296417Sdim    .StartsWith("coreclr", Triple::CoreCLR)
545327952Sdim    .StartsWith("simulator", Triple::Simulator)
546353358Sdim    .StartsWith("macabi", Triple::MacABI)
547234353Sdim    .Default(Triple::UnknownEnvironment);
548212904Sdim}
549193323Sed
550276479Sdimstatic Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
551276479Sdim  return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
552353358Sdim    // "xcoff" must come before "coff" because of the order-dependendent
553353358Sdim    // pattern matching.
554353358Sdim    .EndsWith("xcoff", Triple::XCOFF)
555276479Sdim    .EndsWith("coff", Triple::COFF)
556276479Sdim    .EndsWith("elf", Triple::ELF)
557276479Sdim    .EndsWith("macho", Triple::MachO)
558321369Sdim    .EndsWith("wasm", Triple::Wasm)
559276479Sdim    .Default(Triple::UnknownObjectFormat);
560276479Sdim}
561276479Sdim
562276479Sdimstatic Triple::SubArchType parseSubArch(StringRef SubArchName) {
563344779Sdim  if (SubArchName.startswith("mips") &&
564344779Sdim      (SubArchName.endswith("r6el") || SubArchName.endswith("r6")))
565344779Sdim    return Triple::MipsSubArch_r6;
566344779Sdim
567360661Sdim  if (SubArchName == "powerpcspe")
568360661Sdim    return Triple::PPCSubArch_spe;
569360661Sdim
570296417Sdim  StringRef ARMSubArch = ARM::getCanonicalArchName(SubArchName);
571280031Sdim
572288943Sdim  // For now, this is the small part. Early return.
573288943Sdim  if (ARMSubArch.empty())
574288943Sdim    return StringSwitch<Triple::SubArchType>(SubArchName)
575288943Sdim      .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
576288943Sdim      .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
577288943Sdim      .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
578288943Sdim      .Default(Triple::NoSubArch);
579288943Sdim
580288943Sdim  // ARM sub arch.
581296417Sdim  switch(ARM::parseArch(ARMSubArch)) {
582327952Sdim  case ARM::ArchKind::ARMV4:
583288943Sdim    return Triple::NoSubArch;
584327952Sdim  case ARM::ArchKind::ARMV4T:
585288943Sdim    return Triple::ARMSubArch_v4t;
586327952Sdim  case ARM::ArchKind::ARMV5T:
587288943Sdim    return Triple::ARMSubArch_v5;
588327952Sdim  case ARM::ArchKind::ARMV5TE:
589327952Sdim  case ARM::ArchKind::IWMMXT:
590327952Sdim  case ARM::ArchKind::IWMMXT2:
591327952Sdim  case ARM::ArchKind::XSCALE:
592327952Sdim  case ARM::ArchKind::ARMV5TEJ:
593288943Sdim    return Triple::ARMSubArch_v5te;
594327952Sdim  case ARM::ArchKind::ARMV6:
595288943Sdim    return Triple::ARMSubArch_v6;
596327952Sdim  case ARM::ArchKind::ARMV6K:
597327952Sdim  case ARM::ArchKind::ARMV6KZ:
598288943Sdim    return Triple::ARMSubArch_v6k;
599327952Sdim  case ARM::ArchKind::ARMV6T2:
600288943Sdim    return Triple::ARMSubArch_v6t2;
601327952Sdim  case ARM::ArchKind::ARMV6M:
602288943Sdim    return Triple::ARMSubArch_v6m;
603327952Sdim  case ARM::ArchKind::ARMV7A:
604327952Sdim  case ARM::ArchKind::ARMV7R:
605288943Sdim    return Triple::ARMSubArch_v7;
606327952Sdim  case ARM::ArchKind::ARMV7VE:
607321369Sdim    return Triple::ARMSubArch_v7ve;
608327952Sdim  case ARM::ArchKind::ARMV7K:
609296417Sdim    return Triple::ARMSubArch_v7k;
610327952Sdim  case ARM::ArchKind::ARMV7M:
611288943Sdim    return Triple::ARMSubArch_v7m;
612327952Sdim  case ARM::ArchKind::ARMV7S:
613288943Sdim    return Triple::ARMSubArch_v7s;
614327952Sdim  case ARM::ArchKind::ARMV7EM:
615288943Sdim    return Triple::ARMSubArch_v7em;
616327952Sdim  case ARM::ArchKind::ARMV8A:
617288943Sdim    return Triple::ARMSubArch_v8;
618327952Sdim  case ARM::ArchKind::ARMV8_1A:
619288943Sdim    return Triple::ARMSubArch_v8_1a;
620327952Sdim  case ARM::ArchKind::ARMV8_2A:
621296417Sdim    return Triple::ARMSubArch_v8_2a;
622327952Sdim  case ARM::ArchKind::ARMV8_3A:
623327952Sdim    return Triple::ARMSubArch_v8_3a;
624341825Sdim  case ARM::ArchKind::ARMV8_4A:
625341825Sdim    return Triple::ARMSubArch_v8_4a;
626344779Sdim  case ARM::ArchKind::ARMV8_5A:
627344779Sdim    return Triple::ARMSubArch_v8_5a;
628327952Sdim  case ARM::ArchKind::ARMV8R:
629314564Sdim    return Triple::ARMSubArch_v8r;
630327952Sdim  case ARM::ArchKind::ARMV8MBaseline:
631309124Sdim    return Triple::ARMSubArch_v8m_baseline;
632327952Sdim  case ARM::ArchKind::ARMV8MMainline:
633309124Sdim    return Triple::ARMSubArch_v8m_mainline;
634353358Sdim  case ARM::ArchKind::ARMV8_1MMainline:
635353358Sdim    return Triple::ARMSubArch_v8_1m_mainline;
636288943Sdim  default:
637288943Sdim    return Triple::NoSubArch;
638288943Sdim  }
639276479Sdim}
640276479Sdim
641314564Sdimstatic StringRef getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
642276479Sdim  switch (Kind) {
643276479Sdim  case Triple::UnknownObjectFormat: return "";
644360784Sdim  case Triple::COFF:  return "coff";
645360784Sdim  case Triple::ELF:   return "elf";
646276479Sdim  case Triple::MachO: return "macho";
647360784Sdim  case Triple::Wasm:  return "wasm";
648353358Sdim  case Triple::XCOFF: return "xcoff";
649276479Sdim  }
650276479Sdim  llvm_unreachable("unknown object format type");
651276479Sdim}
652276479Sdim
653276479Sdimstatic Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
654288943Sdim  switch (T.getArch()) {
655296417Sdim  case Triple::UnknownArch:
656296417Sdim  case Triple::aarch64:
657353358Sdim  case Triple::aarch64_32:
658296417Sdim  case Triple::arm:
659296417Sdim  case Triple::thumb:
660296417Sdim  case Triple::x86:
661296417Sdim  case Triple::x86_64:
662296417Sdim    if (T.isOSDarwin())
663296417Sdim      return Triple::MachO;
664296417Sdim    else if (T.isOSWindows())
665296417Sdim      return Triple::COFF;
666296417Sdim    return Triple::ELF;
667296417Sdim
668296417Sdim  case Triple::aarch64_be:
669296417Sdim  case Triple::amdgcn:
670360784Sdim  case Triple::amdil64:
671296417Sdim  case Triple::amdil:
672360784Sdim  case Triple::arc:
673296417Sdim  case Triple::armeb:
674296417Sdim  case Triple::avr:
675296417Sdim  case Triple::bpfeb:
676296417Sdim  case Triple::bpfel:
677288943Sdim  case Triple::hexagon:
678360784Sdim  case Triple::hsail64:
679296417Sdim  case Triple::hsail:
680296417Sdim  case Triple::kalimba:
681360784Sdim  case Triple::lanai:
682296417Sdim  case Triple::le32:
683296417Sdim  case Triple::le64:
684288943Sdim  case Triple::mips64:
685288943Sdim  case Triple::mips64el:
686360784Sdim  case Triple::mips:
687296417Sdim  case Triple::mipsel:
688296417Sdim  case Triple::msp430:
689360784Sdim  case Triple::nvptx64:
690296417Sdim  case Triple::nvptx:
691296417Sdim  case Triple::ppc64le:
692288943Sdim  case Triple::r600:
693309124Sdim  case Triple::renderscript32:
694309124Sdim  case Triple::renderscript64:
695314564Sdim  case Triple::riscv32:
696314564Sdim  case Triple::riscv64:
697296417Sdim  case Triple::shave:
698288943Sdim  case Triple::sparc:
699296417Sdim  case Triple::sparcel:
700288943Sdim  case Triple::sparcv9:
701360784Sdim  case Triple::spir64:
702296417Sdim  case Triple::spir:
703288943Sdim  case Triple::systemz:
704296417Sdim  case Triple::tce:
705314564Sdim  case Triple::tcele:
706296417Sdim  case Triple::thumbeb:
707360784Sdim  case Triple::ve:
708288943Sdim  case Triple::xcore:
709288943Sdim    return Triple::ELF;
710288943Sdim
711360784Sdim  case Triple::ppc64:
712288943Sdim  case Triple::ppc:
713288943Sdim    if (T.isOSDarwin())
714288943Sdim      return Triple::MachO;
715353358Sdim    else if (T.isOSAIX())
716353358Sdim      return Triple::XCOFF;
717288943Sdim    return Triple::ELF;
718341825Sdim
719341825Sdim  case Triple::wasm32:
720341825Sdim  case Triple::wasm64:
721341825Sdim    return Triple::Wasm;
722288943Sdim  }
723296417Sdim  llvm_unreachable("unknown architecture");
724276479Sdim}
725276479Sdim
726341825Sdim/// Construct a triple from the string representation provided.
727234353Sdim///
728234353Sdim/// This stores the string representation and parses the various pieces into
729234353Sdim/// enum members.
730234353SdimTriple::Triple(const Twine &Str)
731296417Sdim    : Data(Str.str()), Arch(UnknownArch), SubArch(NoSubArch),
732296417Sdim      Vendor(UnknownVendor), OS(UnknownOS), Environment(UnknownEnvironment),
733296417Sdim      ObjectFormat(UnknownObjectFormat) {
734296417Sdim  // Do minimal parsing by hand here.
735296417Sdim  SmallVector<StringRef, 4> Components;
736296417Sdim  StringRef(Data).split(Components, '-', /*MaxSplit*/ 3);
737296417Sdim  if (Components.size() > 0) {
738296417Sdim    Arch = parseArch(Components[0]);
739296417Sdim    SubArch = parseSubArch(Components[0]);
740296417Sdim    if (Components.size() > 1) {
741296417Sdim      Vendor = parseVendor(Components[1]);
742296417Sdim      if (Components.size() > 2) {
743296417Sdim        OS = parseOS(Components[2]);
744296417Sdim        if (Components.size() > 3) {
745296417Sdim          Environment = parseEnvironment(Components[3]);
746296417Sdim          ObjectFormat = parseFormat(Components[3]);
747296417Sdim        }
748296417Sdim      }
749344779Sdim    } else {
750344779Sdim      Environment =
751344779Sdim          StringSwitch<Triple::EnvironmentType>(Components[0])
752344779Sdim              .StartsWith("mipsn32", Triple::GNUABIN32)
753344779Sdim              .StartsWith("mips64", Triple::GNUABI64)
754344779Sdim              .StartsWith("mipsisa64", Triple::GNUABI64)
755344779Sdim              .StartsWith("mipsisa32", Triple::GNU)
756344779Sdim              .Cases("mips", "mipsel", "mipsr6", "mipsr6el", Triple::GNU)
757344779Sdim              .Default(UnknownEnvironment);
758296417Sdim    }
759296417Sdim  }
760296417Sdim  if (ObjectFormat == UnknownObjectFormat)
761276479Sdim    ObjectFormat = getDefaultFormat(*this);
762218893Sdim}
763218893Sdim
764341825Sdim/// Construct a triple from string representations of the architecture,
765234353Sdim/// vendor, and OS.
766234353Sdim///
767234353Sdim/// This joins each argument into a canonical string representation and parses
768234353Sdim/// them into enum members. It leaves the environment unknown and omits it from
769234353Sdim/// the string representation.
770234353SdimTriple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
771234353Sdim    : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
772234353Sdim      Arch(parseArch(ArchStr.str())),
773276479Sdim      SubArch(parseSubArch(ArchStr.str())),
774234353Sdim      Vendor(parseVendor(VendorStr.str())),
775234353Sdim      OS(parseOS(OSStr.str())),
776276479Sdim      Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
777276479Sdim  ObjectFormat = getDefaultFormat(*this);
778234353Sdim}
779212904Sdim
780341825Sdim/// Construct a triple from string representations of the architecture,
781234353Sdim/// vendor, OS, and environment.
782234353Sdim///
783234353Sdim/// This joins each argument into a canonical string representation and parses
784234353Sdim/// them into enum members.
785234353SdimTriple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
786234353Sdim               const Twine &EnvironmentStr)
787234353Sdim    : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
788234353Sdim            EnvironmentStr).str()),
789234353Sdim      Arch(parseArch(ArchStr.str())),
790276479Sdim      SubArch(parseSubArch(ArchStr.str())),
791234353Sdim      Vendor(parseVendor(VendorStr.str())),
792234353Sdim      OS(parseOS(OSStr.str())),
793276479Sdim      Environment(parseEnvironment(EnvironmentStr.str())),
794276479Sdim      ObjectFormat(parseFormat(EnvironmentStr.str())) {
795276479Sdim  if (ObjectFormat == Triple::UnknownObjectFormat)
796276479Sdim    ObjectFormat = getDefaultFormat(*this);
797193323Sed}
798193323Sed
799212904Sdimstd::string Triple::normalize(StringRef Str) {
800280031Sdim  bool IsMinGW32 = false;
801280031Sdim  bool IsCygwin = false;
802280031Sdim
803212904Sdim  // Parse into components.
804212904Sdim  SmallVector<StringRef, 4> Components;
805296417Sdim  Str.split(Components, '-');
806212904Sdim
807212904Sdim  // If the first component corresponds to a known architecture, preferentially
808212904Sdim  // use it for the architecture.  If the second component corresponds to a
809212904Sdim  // known vendor, preferentially use it for the vendor, etc.  This avoids silly
810212904Sdim  // component movement when a component parses as (eg) both a valid arch and a
811212904Sdim  // valid os.
812212904Sdim  ArchType Arch = UnknownArch;
813212904Sdim  if (Components.size() > 0)
814234353Sdim    Arch = parseArch(Components[0]);
815212904Sdim  VendorType Vendor = UnknownVendor;
816212904Sdim  if (Components.size() > 1)
817234353Sdim    Vendor = parseVendor(Components[1]);
818212904Sdim  OSType OS = UnknownOS;
819280031Sdim  if (Components.size() > 2) {
820234353Sdim    OS = parseOS(Components[2]);
821280031Sdim    IsCygwin = Components[2].startswith("cygwin");
822280031Sdim    IsMinGW32 = Components[2].startswith("mingw");
823280031Sdim  }
824218893Sdim  EnvironmentType Environment = UnknownEnvironment;
825218893Sdim  if (Components.size() > 3)
826234353Sdim    Environment = parseEnvironment(Components[3]);
827276479Sdim  ObjectFormatType ObjectFormat = UnknownObjectFormat;
828276479Sdim  if (Components.size() > 4)
829276479Sdim    ObjectFormat = parseFormat(Components[4]);
830212904Sdim
831212904Sdim  // Note which components are already in their final position.  These will not
832212904Sdim  // be moved.
833218893Sdim  bool Found[4];
834212904Sdim  Found[0] = Arch != UnknownArch;
835212904Sdim  Found[1] = Vendor != UnknownVendor;
836212904Sdim  Found[2] = OS != UnknownOS;
837218893Sdim  Found[3] = Environment != UnknownEnvironment;
838212904Sdim
839212904Sdim  // If they are not there already, permute the components into their canonical
840212904Sdim  // positions by seeing if they parse as a valid architecture, and if so moving
841212904Sdim  // the component to the architecture position etc.
842218893Sdim  for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
843212904Sdim    if (Found[Pos])
844212904Sdim      continue; // Already in the canonical position.
845212904Sdim
846212904Sdim    for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
847212904Sdim      // Do not reparse any components that already matched.
848218893Sdim      if (Idx < array_lengthof(Found) && Found[Idx])
849212904Sdim        continue;
850212904Sdim
851212904Sdim      // Does this component parse as valid for the target position?
852212904Sdim      bool Valid = false;
853212904Sdim      StringRef Comp = Components[Idx];
854212904Sdim      switch (Pos) {
855234353Sdim      default: llvm_unreachable("unexpected component type!");
856212904Sdim      case 0:
857234353Sdim        Arch = parseArch(Comp);
858212904Sdim        Valid = Arch != UnknownArch;
859212904Sdim        break;
860212904Sdim      case 1:
861234353Sdim        Vendor = parseVendor(Comp);
862212904Sdim        Valid = Vendor != UnknownVendor;
863212904Sdim        break;
864212904Sdim      case 2:
865234353Sdim        OS = parseOS(Comp);
866280031Sdim        IsCygwin = Comp.startswith("cygwin");
867280031Sdim        IsMinGW32 = Comp.startswith("mingw");
868280031Sdim        Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
869212904Sdim        break;
870218893Sdim      case 3:
871234353Sdim        Environment = parseEnvironment(Comp);
872218893Sdim        Valid = Environment != UnknownEnvironment;
873276479Sdim        if (!Valid) {
874276479Sdim          ObjectFormat = parseFormat(Comp);
875276479Sdim          Valid = ObjectFormat != UnknownObjectFormat;
876276479Sdim        }
877218893Sdim        break;
878212904Sdim      }
879212904Sdim      if (!Valid)
880212904Sdim        continue; // Nope, try the next component.
881212904Sdim
882212904Sdim      // Move the component to the target position, pushing any non-fixed
883212904Sdim      // components that are in the way to the right.  This tends to give
884212904Sdim      // good results in the common cases of a forgotten vendor component
885212904Sdim      // or a wrongly positioned environment.
886212904Sdim      if (Pos < Idx) {
887212904Sdim        // Insert left, pushing the existing components to the right.  For
888212904Sdim        // example, a-b-i386 -> i386-a-b when moving i386 to the front.
889212904Sdim        StringRef CurrentComponent(""); // The empty component.
890212904Sdim        // Replace the component we are moving with an empty component.
891212904Sdim        std::swap(CurrentComponent, Components[Idx]);
892212904Sdim        // Insert the component being moved at Pos, displacing any existing
893212904Sdim        // components to the right.
894212904Sdim        for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
895212904Sdim          // Skip over any fixed components.
896234353Sdim          while (i < array_lengthof(Found) && Found[i])
897234353Sdim            ++i;
898212904Sdim          // Place the component at the new position, getting the component
899212904Sdim          // that was at this position - it will be moved right.
900212904Sdim          std::swap(CurrentComponent, Components[i]);
901212904Sdim        }
902212904Sdim      } else if (Pos > Idx) {
903212904Sdim        // Push right by inserting empty components until the component at Idx
904212904Sdim        // reaches the target position Pos.  For example, pc-a -> -pc-a when
905212904Sdim        // moving pc to the second position.
906212904Sdim        do {
907212904Sdim          // Insert one empty component at Idx.
908212904Sdim          StringRef CurrentComponent(""); // The empty component.
909218893Sdim          for (unsigned i = Idx; i < Components.size();) {
910212904Sdim            // Place the component at the new position, getting the component
911212904Sdim            // that was at this position - it will be moved right.
912212904Sdim            std::swap(CurrentComponent, Components[i]);
913212904Sdim            // If it was placed on top of an empty component then we are done.
914212904Sdim            if (CurrentComponent.empty())
915212904Sdim              break;
916218893Sdim            // Advance to the next component, skipping any fixed components.
917218893Sdim            while (++i < array_lengthof(Found) && Found[i])
918218893Sdim              ;
919212904Sdim          }
920212904Sdim          // The last component was pushed off the end - append it.
921212904Sdim          if (!CurrentComponent.empty())
922212904Sdim            Components.push_back(CurrentComponent);
923212904Sdim
924212904Sdim          // Advance Idx to the component's new position.
925234353Sdim          while (++Idx < array_lengthof(Found) && Found[Idx])
926234353Sdim            ;
927212904Sdim        } while (Idx < Pos); // Add more until the final position is reached.
928212904Sdim      }
929212904Sdim      assert(Pos < Components.size() && Components[Pos] == Comp &&
930212904Sdim             "Component moved wrong!");
931212904Sdim      Found[Pos] = true;
932212904Sdim      break;
933212904Sdim    }
934212904Sdim  }
935212904Sdim
936344779Sdim  // Replace empty components with "unknown" value.
937344779Sdim  for (unsigned i = 0, e = Components.size(); i < e; ++i) {
938344779Sdim    if (Components[i].empty())
939344779Sdim      Components[i] = "unknown";
940344779Sdim  }
941344779Sdim
942212904Sdim  // Special case logic goes here.  At this point Arch, Vendor and OS have the
943212904Sdim  // correct values for the computed components.
944288943Sdim  std::string NormalizedEnvironment;
945288943Sdim  if (Environment == Triple::Android && Components[3].startswith("androideabi")) {
946288943Sdim    StringRef AndroidVersion = Components[3].drop_front(strlen("androideabi"));
947288943Sdim    if (AndroidVersion.empty()) {
948288943Sdim      Components[3] = "android";
949288943Sdim    } else {
950288943Sdim      NormalizedEnvironment = Twine("android", AndroidVersion).str();
951288943Sdim      Components[3] = NormalizedEnvironment;
952288943Sdim    }
953288943Sdim  }
954212904Sdim
955321369Sdim  // SUSE uses "gnueabi" to mean "gnueabihf"
956321369Sdim  if (Vendor == Triple::SUSE && Environment == llvm::Triple::GNUEABI)
957321369Sdim    Components[3] = "gnueabihf";
958321369Sdim
959276479Sdim  if (OS == Triple::Win32) {
960276479Sdim    Components.resize(4);
961276479Sdim    Components[2] = "windows";
962276479Sdim    if (Environment == UnknownEnvironment) {
963276479Sdim      if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
964276479Sdim        Components[3] = "msvc";
965276479Sdim      else
966276479Sdim        Components[3] = getObjectFormatTypeName(ObjectFormat);
967276479Sdim    }
968280031Sdim  } else if (IsMinGW32) {
969276479Sdim    Components.resize(4);
970276479Sdim    Components[2] = "windows";
971276479Sdim    Components[3] = "gnu";
972280031Sdim  } else if (IsCygwin) {
973276479Sdim    Components.resize(4);
974276479Sdim    Components[2] = "windows";
975276479Sdim    Components[3] = "cygnus";
976276479Sdim  }
977280031Sdim  if (IsMinGW32 || IsCygwin ||
978276479Sdim      (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
979276479Sdim    if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
980276479Sdim      Components.resize(5);
981276479Sdim      Components[4] = getObjectFormatTypeName(ObjectFormat);
982276479Sdim    }
983276479Sdim  }
984276479Sdim
985212904Sdim  // Stick the corrected components back together to form the normalized string.
986212904Sdim  std::string Normalized;
987212904Sdim  for (unsigned i = 0, e = Components.size(); i != e; ++i) {
988212904Sdim    if (i) Normalized += '-';
989212904Sdim    Normalized += Components[i];
990212904Sdim  }
991212904Sdim  return Normalized;
992212904Sdim}
993212904Sdim
994198090SrdivackyStringRef Triple::getArchName() const {
995198090Srdivacky  return StringRef(Data).split('-').first;           // Isolate first component
996193323Sed}
997193323Sed
998198090SrdivackyStringRef Triple::getVendorName() const {
999198090Srdivacky  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1000198090Srdivacky  return Tmp.split('-').first;                       // Isolate second component
1001193323Sed}
1002193323Sed
1003198090SrdivackyStringRef Triple::getOSName() const {
1004198090Srdivacky  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1005198090Srdivacky  Tmp = Tmp.split('-').second;                       // Strip second component
1006198090Srdivacky  return Tmp.split('-').first;                       // Isolate third component
1007193323Sed}
1008193323Sed
1009198090SrdivackyStringRef Triple::getEnvironmentName() const {
1010198090Srdivacky  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1011198090Srdivacky  Tmp = Tmp.split('-').second;                       // Strip second component
1012198090Srdivacky  return Tmp.split('-').second;                      // Strip third component
1013193323Sed}
1014193323Sed
1015198090SrdivackyStringRef Triple::getOSAndEnvironmentName() const {
1016198090Srdivacky  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1017198090Srdivacky  return Tmp.split('-').second;                      // Strip second component
1018193323Sed}
1019193323Sed
1020198090Srdivackystatic unsigned EatNumber(StringRef &Str) {
1021198090Srdivacky  assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
1022221345Sdim  unsigned Result = 0;
1023218893Sdim
1024221345Sdim  do {
1025221345Sdim    // Consume the leading digit.
1026221345Sdim    Result = Result*10 + (Str[0] - '0');
1027218893Sdim
1028198090Srdivacky    // Eat the digit.
1029198090Srdivacky    Str = Str.substr(1);
1030221345Sdim  } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
1031218893Sdim
1032198090Srdivacky  return Result;
1033193323Sed}
1034193323Sed
1035288943Sdimstatic void parseVersionFromName(StringRef Name, unsigned &Major,
1036288943Sdim                                 unsigned &Minor, unsigned &Micro) {
1037221345Sdim  // Any unset version defaults to 0.
1038221345Sdim  Major = Minor = Micro = 0;
1039198090Srdivacky
1040221345Sdim  // Parse up to three components.
1041288943Sdim  unsigned *Components[3] = {&Major, &Minor, &Micro};
1042221345Sdim  for (unsigned i = 0; i != 3; ++i) {
1043288943Sdim    if (Name.empty() || Name[0] < '0' || Name[0] > '9')
1044221345Sdim      break;
1045198090Srdivacky
1046221345Sdim    // Consume the leading number.
1047288943Sdim    *Components[i] = EatNumber(Name);
1048218893Sdim
1049221345Sdim    // Consume the separator, if present.
1050288943Sdim    if (Name.startswith("."))
1051288943Sdim      Name = Name.substr(1);
1052221345Sdim  }
1053193323Sed}
1054193323Sed
1055288943Sdimvoid Triple::getEnvironmentVersion(unsigned &Major, unsigned &Minor,
1056288943Sdim                                   unsigned &Micro) const {
1057288943Sdim  StringRef EnvironmentName = getEnvironmentName();
1058288943Sdim  StringRef EnvironmentTypeName = getEnvironmentTypeName(getEnvironment());
1059288943Sdim  if (EnvironmentName.startswith(EnvironmentTypeName))
1060288943Sdim    EnvironmentName = EnvironmentName.substr(EnvironmentTypeName.size());
1061288943Sdim
1062288943Sdim  parseVersionFromName(EnvironmentName, Major, Minor, Micro);
1063288943Sdim}
1064288943Sdim
1065288943Sdimvoid Triple::getOSVersion(unsigned &Major, unsigned &Minor,
1066288943Sdim                          unsigned &Micro) const {
1067288943Sdim  StringRef OSName = getOSName();
1068288943Sdim  // Assume that the OS portion of the triple starts with the canonical name.
1069288943Sdim  StringRef OSTypeName = getOSTypeName(getOS());
1070288943Sdim  if (OSName.startswith(OSTypeName))
1071288943Sdim    OSName = OSName.substr(OSTypeName.size());
1072321369Sdim  else if (getOS() == MacOSX)
1073321369Sdim    OSName.consume_front("macos");
1074288943Sdim
1075288943Sdim  parseVersionFromName(OSName, Major, Minor, Micro);
1076288943Sdim}
1077288943Sdim
1078234353Sdimbool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
1079234353Sdim                              unsigned &Micro) const {
1080234353Sdim  getOSVersion(Major, Minor, Micro);
1081234353Sdim
1082234353Sdim  switch (getOS()) {
1083234353Sdim  default: llvm_unreachable("unexpected OS for Darwin triple");
1084234353Sdim  case Darwin:
1085234353Sdim    // Default to darwin8, i.e., MacOSX 10.4.
1086234353Sdim    if (Major == 0)
1087234353Sdim      Major = 8;
1088234353Sdim    // Darwin version numbers are skewed from OS X versions.
1089234353Sdim    if (Major < 4)
1090234353Sdim      return false;
1091234353Sdim    Micro = 0;
1092234353Sdim    Minor = Major - 4;
1093234353Sdim    Major = 10;
1094234353Sdim    break;
1095234353Sdim  case MacOSX:
1096234353Sdim    // Default to 10.4.
1097234353Sdim    if (Major == 0) {
1098234353Sdim      Major = 10;
1099234353Sdim      Minor = 4;
1100234353Sdim    }
1101234353Sdim    if (Major != 10)
1102234353Sdim      return false;
1103234353Sdim    break;
1104234353Sdim  case IOS:
1105296417Sdim  case TvOS:
1106296417Sdim  case WatchOS:
1107234353Sdim    // Ignore the version from the triple.  This is only handled because the
1108234353Sdim    // the clang driver combines OS X and IOS support into a common Darwin
1109234353Sdim    // toolchain that wants to know the OS X version number even when targeting
1110234353Sdim    // IOS.
1111234353Sdim    Major = 10;
1112234353Sdim    Minor = 4;
1113234353Sdim    Micro = 0;
1114234353Sdim    break;
1115234353Sdim  }
1116234353Sdim  return true;
1117234353Sdim}
1118234353Sdim
1119239462Sdimvoid Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
1120239462Sdim                           unsigned &Micro) const {
1121239462Sdim  switch (getOS()) {
1122239462Sdim  default: llvm_unreachable("unexpected OS for Darwin triple");
1123239462Sdim  case Darwin:
1124239462Sdim  case MacOSX:
1125239462Sdim    // Ignore the version from the triple.  This is only handled because the
1126239462Sdim    // the clang driver combines OS X and IOS support into a common Darwin
1127239462Sdim    // toolchain that wants to know the iOS version number even when targeting
1128239462Sdim    // OS X.
1129276479Sdim    Major = 5;
1130239462Sdim    Minor = 0;
1131239462Sdim    Micro = 0;
1132239462Sdim    break;
1133239462Sdim  case IOS:
1134296417Sdim  case TvOS:
1135239462Sdim    getOSVersion(Major, Minor, Micro);
1136276479Sdim    // Default to 5.0 (or 7.0 for arm64).
1137239462Sdim    if (Major == 0)
1138280031Sdim      Major = (getArch() == aarch64) ? 7 : 5;
1139239462Sdim    break;
1140296417Sdim  case WatchOS:
1141296417Sdim    llvm_unreachable("conflicting triple info");
1142239462Sdim  }
1143239462Sdim}
1144239462Sdim
1145296417Sdimvoid Triple::getWatchOSVersion(unsigned &Major, unsigned &Minor,
1146296417Sdim                               unsigned &Micro) const {
1147296417Sdim  switch (getOS()) {
1148296417Sdim  default: llvm_unreachable("unexpected OS for Darwin triple");
1149296417Sdim  case Darwin:
1150296417Sdim  case MacOSX:
1151296417Sdim    // Ignore the version from the triple.  This is only handled because the
1152296417Sdim    // the clang driver combines OS X and IOS support into a common Darwin
1153296417Sdim    // toolchain that wants to know the iOS version number even when targeting
1154296417Sdim    // OS X.
1155296417Sdim    Major = 2;
1156296417Sdim    Minor = 0;
1157296417Sdim    Micro = 0;
1158296417Sdim    break;
1159296417Sdim  case WatchOS:
1160296417Sdim    getOSVersion(Major, Minor, Micro);
1161296417Sdim    if (Major == 0)
1162296417Sdim      Major = 2;
1163296417Sdim    break;
1164296417Sdim  case IOS:
1165296417Sdim    llvm_unreachable("conflicting triple info");
1166296417Sdim  }
1167296417Sdim}
1168296417Sdim
1169198090Srdivackyvoid Triple::setTriple(const Twine &Str) {
1170234353Sdim  *this = Triple(Str);
1171193323Sed}
1172193323Sed
1173193323Sedvoid Triple::setArch(ArchType Kind) {
1174193323Sed  setArchName(getArchTypeName(Kind));
1175193323Sed}
1176193323Sed
1177193323Sedvoid Triple::setVendor(VendorType Kind) {
1178193323Sed  setVendorName(getVendorTypeName(Kind));
1179193323Sed}
1180193323Sed
1181193323Sedvoid Triple::setOS(OSType Kind) {
1182193323Sed  setOSName(getOSTypeName(Kind));
1183193323Sed}
1184193323Sed
1185218893Sdimvoid Triple::setEnvironment(EnvironmentType Kind) {
1186288943Sdim  if (ObjectFormat == getDefaultFormat(*this))
1187288943Sdim    return setEnvironmentName(getEnvironmentTypeName(Kind));
1188288943Sdim
1189288943Sdim  setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
1190288943Sdim                      getObjectFormatTypeName(ObjectFormat)).str());
1191218893Sdim}
1192218893Sdim
1193276479Sdimvoid Triple::setObjectFormat(ObjectFormatType Kind) {
1194276479Sdim  if (Environment == UnknownEnvironment)
1195276479Sdim    return setEnvironmentName(getObjectFormatTypeName(Kind));
1196276479Sdim
1197276479Sdim  setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
1198276479Sdim                      getObjectFormatTypeName(Kind)).str());
1199276479Sdim}
1200276479Sdim
1201199481Srdivackyvoid Triple::setArchName(StringRef Str) {
1202198090Srdivacky  // Work around a miscompilation bug for Twines in gcc 4.0.3.
1203198090Srdivacky  SmallString<64> Triple;
1204198090Srdivacky  Triple += Str;
1205198090Srdivacky  Triple += "-";
1206198090Srdivacky  Triple += getVendorName();
1207198090Srdivacky  Triple += "-";
1208198090Srdivacky  Triple += getOSAndEnvironmentName();
1209288943Sdim  setTriple(Triple);
1210193323Sed}
1211193323Sed
1212199481Srdivackyvoid Triple::setVendorName(StringRef Str) {
1213193323Sed  setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
1214193323Sed}
1215193323Sed
1216199481Srdivackyvoid Triple::setOSName(StringRef Str) {
1217193323Sed  if (hasEnvironment())
1218193323Sed    setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
1219193323Sed              "-" + getEnvironmentName());
1220193323Sed  else
1221193323Sed    setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
1222193323Sed}
1223193323Sed
1224199481Srdivackyvoid Triple::setEnvironmentName(StringRef Str) {
1225199481Srdivacky  setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
1226193323Sed            "-" + Str);
1227193323Sed}
1228193323Sed
1229199481Srdivackyvoid Triple::setOSAndEnvironmentName(StringRef Str) {
1230193323Sed  setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
1231193323Sed}
1232234353Sdim
1233234353Sdimstatic unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
1234234353Sdim  switch (Arch) {
1235234353Sdim  case llvm::Triple::UnknownArch:
1236234353Sdim    return 0;
1237234353Sdim
1238296417Sdim  case llvm::Triple::avr:
1239234353Sdim  case llvm::Triple::msp430:
1240234353Sdim    return 16;
1241234353Sdim
1242353358Sdim  case llvm::Triple::aarch64_32:
1243360784Sdim  case llvm::Triple::amdil:
1244327952Sdim  case llvm::Triple::arc:
1245234353Sdim  case llvm::Triple::arm:
1246276479Sdim  case llvm::Triple::armeb:
1247234353Sdim  case llvm::Triple::hexagon:
1248360784Sdim  case llvm::Triple::hsail:
1249360784Sdim  case llvm::Triple::kalimba:
1250360784Sdim  case llvm::Triple::lanai:
1251234353Sdim  case llvm::Triple::le32:
1252234353Sdim  case llvm::Triple::mips:
1253234353Sdim  case llvm::Triple::mipsel:
1254239462Sdim  case llvm::Triple::nvptx:
1255234353Sdim  case llvm::Triple::ppc:
1256234353Sdim  case llvm::Triple::r600:
1257360784Sdim  case llvm::Triple::renderscript32:
1258314564Sdim  case llvm::Triple::riscv32:
1259360784Sdim  case llvm::Triple::shave:
1260234353Sdim  case llvm::Triple::sparc:
1261288943Sdim  case llvm::Triple::sparcel:
1262360784Sdim  case llvm::Triple::spir:
1263234353Sdim  case llvm::Triple::tce:
1264314564Sdim  case llvm::Triple::tcele:
1265234353Sdim  case llvm::Triple::thumb:
1266276479Sdim  case llvm::Triple::thumbeb:
1267360784Sdim  case llvm::Triple::wasm32:
1268234353Sdim  case llvm::Triple::x86:
1269234353Sdim  case llvm::Triple::xcore:
1270234353Sdim    return 32;
1271234353Sdim
1272249423Sdim  case llvm::Triple::aarch64:
1273276479Sdim  case llvm::Triple::aarch64_be:
1274280031Sdim  case llvm::Triple::amdgcn:
1275360784Sdim  case llvm::Triple::amdil64:
1276360784Sdim  case llvm::Triple::bpfeb:
1277288943Sdim  case llvm::Triple::bpfel:
1278360784Sdim  case llvm::Triple::hsail64:
1279280031Sdim  case llvm::Triple::le64:
1280234353Sdim  case llvm::Triple::mips64:
1281234353Sdim  case llvm::Triple::mips64el:
1282239462Sdim  case llvm::Triple::nvptx64:
1283234353Sdim  case llvm::Triple::ppc64:
1284261991Sdim  case llvm::Triple::ppc64le:
1285360784Sdim  case llvm::Triple::renderscript64:
1286314564Sdim  case llvm::Triple::riscv64:
1287234353Sdim  case llvm::Triple::sparcv9:
1288360784Sdim  case llvm::Triple::spir64:
1289251662Sdim  case llvm::Triple::systemz:
1290360784Sdim  case llvm::Triple::ve:
1291360784Sdim  case llvm::Triple::wasm64:
1292234353Sdim  case llvm::Triple::x86_64:
1293234353Sdim    return 64;
1294234353Sdim  }
1295234353Sdim  llvm_unreachable("Invalid architecture value");
1296234353Sdim}
1297234353Sdim
1298234353Sdimbool Triple::isArch64Bit() const {
1299234353Sdim  return getArchPointerBitWidth(getArch()) == 64;
1300234353Sdim}
1301234353Sdim
1302234353Sdimbool Triple::isArch32Bit() const {
1303234353Sdim  return getArchPointerBitWidth(getArch()) == 32;
1304234353Sdim}
1305234353Sdim
1306234353Sdimbool Triple::isArch16Bit() const {
1307234353Sdim  return getArchPointerBitWidth(getArch()) == 16;
1308234353Sdim}
1309234353Sdim
1310234353SdimTriple Triple::get32BitArchVariant() const {
1311234353Sdim  Triple T(*this);
1312234353Sdim  switch (getArch()) {
1313234353Sdim  case Triple::UnknownArch:
1314280031Sdim  case Triple::amdgcn:
1315296417Sdim  case Triple::avr:
1316360784Sdim  case Triple::bpfeb:
1317288943Sdim  case Triple::bpfel:
1318234353Sdim  case Triple::msp430:
1319360784Sdim  case Triple::ppc64le:
1320251662Sdim  case Triple::systemz:
1321360784Sdim  case Triple::ve:
1322234353Sdim    T.setArch(UnknownArch);
1323234353Sdim    break;
1324234353Sdim
1325353358Sdim  case Triple::aarch64_32:
1326234353Sdim  case Triple::amdil:
1327327952Sdim  case Triple::arc:
1328234353Sdim  case Triple::arm:
1329276479Sdim  case Triple::armeb:
1330234353Sdim  case Triple::hexagon:
1331360784Sdim  case Triple::hsail:
1332276479Sdim  case Triple::kalimba:
1333360784Sdim  case Triple::lanai:
1334234353Sdim  case Triple::le32:
1335234353Sdim  case Triple::mips:
1336234353Sdim  case Triple::mipsel:
1337239462Sdim  case Triple::nvptx:
1338234353Sdim  case Triple::ppc:
1339234353Sdim  case Triple::r600:
1340360784Sdim  case Triple::renderscript32:
1341314564Sdim  case Triple::riscv32:
1342360784Sdim  case Triple::shave:
1343234353Sdim  case Triple::sparc:
1344288943Sdim  case Triple::sparcel:
1345360784Sdim  case Triple::spir:
1346234353Sdim  case Triple::tce:
1347314564Sdim  case Triple::tcele:
1348234353Sdim  case Triple::thumb:
1349276479Sdim  case Triple::thumbeb:
1350360784Sdim  case Triple::wasm32:
1351234353Sdim  case Triple::x86:
1352234353Sdim  case Triple::xcore:
1353234353Sdim    // Already 32-bit.
1354234353Sdim    break;
1355234353Sdim
1356309124Sdim  case Triple::aarch64:        T.setArch(Triple::arm);     break;
1357309124Sdim  case Triple::aarch64_be:     T.setArch(Triple::armeb);   break;
1358360784Sdim  case Triple::amdil64:        T.setArch(Triple::amdil);   break;
1359360784Sdim  case Triple::hsail64:        T.setArch(Triple::hsail);   break;
1360309124Sdim  case Triple::le64:           T.setArch(Triple::le32);    break;
1361309124Sdim  case Triple::mips64:         T.setArch(Triple::mips);    break;
1362309124Sdim  case Triple::mips64el:       T.setArch(Triple::mipsel);  break;
1363309124Sdim  case Triple::nvptx64:        T.setArch(Triple::nvptx);   break;
1364309124Sdim  case Triple::ppc64:          T.setArch(Triple::ppc);     break;
1365360784Sdim  case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
1366360784Sdim  case Triple::riscv64:        T.setArch(Triple::riscv32); break;
1367309124Sdim  case Triple::sparcv9:        T.setArch(Triple::sparc);   break;
1368309124Sdim  case Triple::spir64:         T.setArch(Triple::spir);    break;
1369309124Sdim  case Triple::wasm64:         T.setArch(Triple::wasm32);  break;
1370360784Sdim  case Triple::x86_64:         T.setArch(Triple::x86);     break;
1371234353Sdim  }
1372234353Sdim  return T;
1373234353Sdim}
1374234353Sdim
1375234353SdimTriple Triple::get64BitArchVariant() const {
1376234353Sdim  Triple T(*this);
1377234353Sdim  switch (getArch()) {
1378234353Sdim  case Triple::UnknownArch:
1379327952Sdim  case Triple::arc:
1380296417Sdim  case Triple::avr:
1381234353Sdim  case Triple::hexagon:
1382276479Sdim  case Triple::kalimba:
1383309124Sdim  case Triple::lanai:
1384234353Sdim  case Triple::msp430:
1385234353Sdim  case Triple::r600:
1386360784Sdim  case Triple::shave:
1387360784Sdim  case Triple::sparcel:
1388234353Sdim  case Triple::tce:
1389314564Sdim  case Triple::tcele:
1390234353Sdim  case Triple::xcore:
1391234353Sdim    T.setArch(UnknownArch);
1392234353Sdim    break;
1393234353Sdim
1394249423Sdim  case Triple::aarch64:
1395276479Sdim  case Triple::aarch64_be:
1396360784Sdim  case Triple::amdgcn:
1397360784Sdim  case Triple::amdil64:
1398360784Sdim  case Triple::bpfeb:
1399288943Sdim  case Triple::bpfel:
1400360784Sdim  case Triple::hsail64:
1401280031Sdim  case Triple::le64:
1402234353Sdim  case Triple::mips64:
1403234353Sdim  case Triple::mips64el:
1404239462Sdim  case Triple::nvptx64:
1405234353Sdim  case Triple::ppc64:
1406261991Sdim  case Triple::ppc64le:
1407360784Sdim  case Triple::renderscript64:
1408314564Sdim  case Triple::riscv64:
1409234353Sdim  case Triple::sparcv9:
1410360784Sdim  case Triple::spir64:
1411251662Sdim  case Triple::systemz:
1412360784Sdim  case Triple::ve:
1413360784Sdim  case Triple::wasm64:
1414234353Sdim  case Triple::x86_64:
1415234353Sdim    // Already 64-bit.
1416234353Sdim    break;
1417234353Sdim
1418353358Sdim  case Triple::aarch64_32:      T.setArch(Triple::aarch64);    break;
1419360784Sdim  case Triple::amdil:           T.setArch(Triple::amdil64);    break;
1420309124Sdim  case Triple::arm:             T.setArch(Triple::aarch64);    break;
1421309124Sdim  case Triple::armeb:           T.setArch(Triple::aarch64_be); break;
1422360784Sdim  case Triple::hsail:           T.setArch(Triple::hsail64);    break;
1423309124Sdim  case Triple::le32:            T.setArch(Triple::le64);       break;
1424309124Sdim  case Triple::mips:            T.setArch(Triple::mips64);     break;
1425309124Sdim  case Triple::mipsel:          T.setArch(Triple::mips64el);   break;
1426309124Sdim  case Triple::nvptx:           T.setArch(Triple::nvptx64);    break;
1427309124Sdim  case Triple::ppc:             T.setArch(Triple::ppc64);      break;
1428360784Sdim  case Triple::renderscript32:  T.setArch(Triple::renderscript64);     break;
1429360784Sdim  case Triple::riscv32:         T.setArch(Triple::riscv64);    break;
1430309124Sdim  case Triple::sparc:           T.setArch(Triple::sparcv9);    break;
1431309124Sdim  case Triple::spir:            T.setArch(Triple::spir64);     break;
1432309124Sdim  case Triple::thumb:           T.setArch(Triple::aarch64);    break;
1433309124Sdim  case Triple::thumbeb:         T.setArch(Triple::aarch64_be); break;
1434309124Sdim  case Triple::wasm32:          T.setArch(Triple::wasm64);     break;
1435360784Sdim  case Triple::x86:             T.setArch(Triple::x86_64);     break;
1436234353Sdim  }
1437234353Sdim  return T;
1438234353Sdim}
1439276479Sdim
1440288943SdimTriple Triple::getBigEndianArchVariant() const {
1441288943Sdim  Triple T(*this);
1442309124Sdim  // Already big endian.
1443309124Sdim  if (!isLittleEndian())
1444309124Sdim    return T;
1445288943Sdim  switch (getArch()) {
1446288943Sdim  case Triple::UnknownArch:
1447288943Sdim  case Triple::amdgcn:
1448288943Sdim  case Triple::amdil64:
1449288943Sdim  case Triple::amdil:
1450296417Sdim  case Triple::avr:
1451288943Sdim  case Triple::hexagon:
1452288943Sdim  case Triple::hsail64:
1453288943Sdim  case Triple::hsail:
1454288943Sdim  case Triple::kalimba:
1455288943Sdim  case Triple::le32:
1456288943Sdim  case Triple::le64:
1457288943Sdim  case Triple::msp430:
1458288943Sdim  case Triple::nvptx64:
1459288943Sdim  case Triple::nvptx:
1460288943Sdim  case Triple::r600:
1461360784Sdim  case Triple::renderscript32:
1462360784Sdim  case Triple::renderscript64:
1463314564Sdim  case Triple::riscv32:
1464314564Sdim  case Triple::riscv64:
1465288943Sdim  case Triple::shave:
1466288943Sdim  case Triple::spir64:
1467288943Sdim  case Triple::spir:
1468288943Sdim  case Triple::wasm32:
1469288943Sdim  case Triple::wasm64:
1470288943Sdim  case Triple::x86:
1471288943Sdim  case Triple::x86_64:
1472288943Sdim  case Triple::xcore:
1473360784Sdim  case Triple::ve:
1474288943Sdim
1475288943Sdim  // ARM is intentionally unsupported here, changing the architecture would
1476288943Sdim  // drop any arch suffixes.
1477288943Sdim  case Triple::arm:
1478288943Sdim  case Triple::thumb:
1479288943Sdim    T.setArch(UnknownArch);
1480288943Sdim    break;
1481288943Sdim
1482288943Sdim  case Triple::aarch64: T.setArch(Triple::aarch64_be); break;
1483288943Sdim  case Triple::bpfel:   T.setArch(Triple::bpfeb);      break;
1484288943Sdim  case Triple::mips64el:T.setArch(Triple::mips64);     break;
1485288943Sdim  case Triple::mipsel:  T.setArch(Triple::mips);       break;
1486288943Sdim  case Triple::ppc64le: T.setArch(Triple::ppc64);      break;
1487288943Sdim  case Triple::sparcel: T.setArch(Triple::sparc);      break;
1488360784Sdim  case Triple::tcele:   T.setArch(Triple::tce);        break;
1489309124Sdim  default:
1490309124Sdim    llvm_unreachable("getBigEndianArchVariant: unknown triple.");
1491288943Sdim  }
1492288943Sdim  return T;
1493288943Sdim}
1494288943Sdim
1495288943SdimTriple Triple::getLittleEndianArchVariant() const {
1496288943Sdim  Triple T(*this);
1497309124Sdim  if (isLittleEndian())
1498309124Sdim    return T;
1499309124Sdim
1500288943Sdim  switch (getArch()) {
1501288943Sdim  case Triple::UnknownArch:
1502309124Sdim  case Triple::lanai:
1503288943Sdim  case Triple::ppc:
1504288943Sdim  case Triple::sparcv9:
1505288943Sdim  case Triple::systemz:
1506288943Sdim
1507288943Sdim  // ARM is intentionally unsupported here, changing the architecture would
1508288943Sdim  // drop any arch suffixes.
1509288943Sdim  case Triple::armeb:
1510288943Sdim  case Triple::thumbeb:
1511288943Sdim    T.setArch(UnknownArch);
1512288943Sdim    break;
1513288943Sdim
1514309124Sdim  case Triple::aarch64_be: T.setArch(Triple::aarch64);  break;
1515309124Sdim  case Triple::bpfeb:      T.setArch(Triple::bpfel);    break;
1516309124Sdim  case Triple::mips64:     T.setArch(Triple::mips64el); break;
1517309124Sdim  case Triple::mips:       T.setArch(Triple::mipsel);   break;
1518309124Sdim  case Triple::ppc64:      T.setArch(Triple::ppc64le);  break;
1519309124Sdim  case Triple::sparc:      T.setArch(Triple::sparcel);  break;
1520360784Sdim  case Triple::tce:        T.setArch(Triple::tcele);    break;
1521309124Sdim  default:
1522309124Sdim    llvm_unreachable("getLittleEndianArchVariant: unknown triple.");
1523309124Sdim  }
1524309124Sdim  return T;
1525309124Sdim}
1526309124Sdim
1527309124Sdimbool Triple::isLittleEndian() const {
1528309124Sdim  switch (getArch()) {
1529288943Sdim  case Triple::aarch64:
1530353358Sdim  case Triple::aarch64_32:
1531288943Sdim  case Triple::amdgcn:
1532288943Sdim  case Triple::amdil64:
1533288943Sdim  case Triple::amdil:
1534288943Sdim  case Triple::arm:
1535296417Sdim  case Triple::avr:
1536288943Sdim  case Triple::bpfel:
1537288943Sdim  case Triple::hexagon:
1538288943Sdim  case Triple::hsail64:
1539288943Sdim  case Triple::hsail:
1540288943Sdim  case Triple::kalimba:
1541288943Sdim  case Triple::le32:
1542288943Sdim  case Triple::le64:
1543288943Sdim  case Triple::mips64el:
1544288943Sdim  case Triple::mipsel:
1545288943Sdim  case Triple::msp430:
1546288943Sdim  case Triple::nvptx64:
1547288943Sdim  case Triple::nvptx:
1548288943Sdim  case Triple::ppc64le:
1549288943Sdim  case Triple::r600:
1550360784Sdim  case Triple::renderscript32:
1551360784Sdim  case Triple::renderscript64:
1552314564Sdim  case Triple::riscv32:
1553314564Sdim  case Triple::riscv64:
1554288943Sdim  case Triple::shave:
1555288943Sdim  case Triple::sparcel:
1556288943Sdim  case Triple::spir64:
1557288943Sdim  case Triple::spir:
1558360784Sdim  case Triple::tcele:
1559288943Sdim  case Triple::thumb:
1560360784Sdim  case Triple::ve:
1561288943Sdim  case Triple::wasm32:
1562288943Sdim  case Triple::wasm64:
1563288943Sdim  case Triple::x86:
1564288943Sdim  case Triple::x86_64:
1565288943Sdim  case Triple::xcore:
1566309124Sdim    return true;
1567309124Sdim  default:
1568309124Sdim    return false;
1569288943Sdim  }
1570288943Sdim}
1571288943Sdim
1572321369Sdimbool Triple::isCompatibleWith(const Triple &Other) const {
1573321369Sdim  // ARM and Thumb triples are compatible, if subarch, vendor and OS match.
1574321369Sdim  if ((getArch() == Triple::thumb && Other.getArch() == Triple::arm) ||
1575321369Sdim      (getArch() == Triple::arm && Other.getArch() == Triple::thumb) ||
1576321369Sdim      (getArch() == Triple::thumbeb && Other.getArch() == Triple::armeb) ||
1577321369Sdim      (getArch() == Triple::armeb && Other.getArch() == Triple::thumbeb)) {
1578321369Sdim    if (getVendor() == Triple::Apple)
1579321369Sdim      return getSubArch() == Other.getSubArch() &&
1580321369Sdim             getVendor() == Other.getVendor() && getOS() == Other.getOS();
1581321369Sdim    else
1582321369Sdim      return getSubArch() == Other.getSubArch() &&
1583321369Sdim             getVendor() == Other.getVendor() && getOS() == Other.getOS() &&
1584321369Sdim             getEnvironment() == Other.getEnvironment() &&
1585321369Sdim             getObjectFormat() == Other.getObjectFormat();
1586321369Sdim  }
1587321369Sdim
1588321369Sdim  // If vendor is apple, ignore the version number.
1589321369Sdim  if (getVendor() == Triple::Apple)
1590321369Sdim    return getArch() == Other.getArch() && getSubArch() == Other.getSubArch() &&
1591321369Sdim           getVendor() == Other.getVendor() && getOS() == Other.getOS();
1592321369Sdim
1593321369Sdim  return *this == Other;
1594321369Sdim}
1595321369Sdim
1596321369Sdimstd::string Triple::merge(const Triple &Other) const {
1597321369Sdim  // If vendor is apple, pick the triple with the larger version number.
1598321369Sdim  if (getVendor() == Triple::Apple)
1599321369Sdim    if (Other.isOSVersionLT(*this))
1600321369Sdim      return str();
1601321369Sdim
1602321369Sdim  return Other.str();
1603321369Sdim}
1604321369Sdim
1605296417SdimStringRef Triple::getARMCPUForArch(StringRef MArch) const {
1606276479Sdim  if (MArch.empty())
1607276479Sdim    MArch = getArchName();
1608296417Sdim  MArch = ARM::getCanonicalArchName(MArch);
1609276479Sdim
1610288943Sdim  // Some defaults are forced.
1611276479Sdim  switch (getOS()) {
1612276479Sdim  case llvm::Triple::FreeBSD:
1613276479Sdim  case llvm::Triple::NetBSD:
1614288943Sdim    if (!MArch.empty() && MArch == "v6")
1615276479Sdim      return "arm1176jzf-s";
1616276479Sdim    break;
1617276479Sdim  case llvm::Triple::Win32:
1618276479Sdim    // FIXME: this is invalid for WindowsCE
1619276479Sdim    return "cortex-a9";
1620360784Sdim  case llvm::Triple::IOS:
1621296417Sdim  case llvm::Triple::MacOSX:
1622360784Sdim  case llvm::Triple::TvOS:
1623296417Sdim  case llvm::Triple::WatchOS:
1624296417Sdim    if (MArch == "v7k")
1625296417Sdim      return "cortex-a7";
1626296417Sdim    break;
1627276479Sdim  default:
1628276479Sdim    break;
1629276479Sdim  }
1630276479Sdim
1631288943Sdim  if (MArch.empty())
1632296417Sdim    return StringRef();
1633276479Sdim
1634296417Sdim  StringRef CPU = ARM::getDefaultCPU(MArch);
1635327952Sdim  if (!CPU.empty() && !CPU.equals("invalid"))
1636288943Sdim    return CPU;
1637276479Sdim
1638288943Sdim  // If no specific architecture version is requested, return the minimum CPU
1639288943Sdim  // required by the OS and environment.
1640276479Sdim  switch (getOS()) {
1641276479Sdim  case llvm::Triple::NetBSD:
1642276479Sdim    switch (getEnvironment()) {
1643360784Sdim    case llvm::Triple::EABI:
1644360784Sdim    case llvm::Triple::EABIHF:
1645360784Sdim    case llvm::Triple::GNUEABI:
1646276479Sdim    case llvm::Triple::GNUEABIHF:
1647276479Sdim      return "arm926ej-s";
1648276479Sdim    default:
1649276479Sdim      return "strongarm";
1650276479Sdim    }
1651288943Sdim  case llvm::Triple::NaCl:
1652321369Sdim  case llvm::Triple::OpenBSD:
1653288943Sdim    return "cortex-a8";
1654276479Sdim  default:
1655276479Sdim    switch (getEnvironment()) {
1656276479Sdim    case llvm::Triple::EABIHF:
1657276479Sdim    case llvm::Triple::GNUEABIHF:
1658309124Sdim    case llvm::Triple::MuslEABIHF:
1659276479Sdim      return "arm1176jzf-s";
1660276479Sdim    default:
1661276479Sdim      return "arm7tdmi";
1662276479Sdim    }
1663276479Sdim  }
1664288943Sdim
1665288943Sdim  llvm_unreachable("invalid arch name");
1666276479Sdim}
1667