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