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