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