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