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