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