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