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