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