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