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