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