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