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   case ARM::ArchKind::ARMV8_1MMainline:
629     return Triple::ARMSubArch_v8_1m_mainline;
630   default:
631     return Triple::NoSubArch;
632   }
633 }
634 
635 static StringRef getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
636   switch (Kind) {
637   case Triple::UnknownObjectFormat: return "";
638   case Triple::COFF: return "coff";
639   case Triple::ELF: return "elf";
640   case Triple::MachO: return "macho";
641   case Triple::Wasm: return "wasm";
642   case Triple::XCOFF: return "xcoff";
643   }
644   llvm_unreachable("unknown object format type");
645 }
646 
647 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
648   switch (T.getArch()) {
649   case Triple::UnknownArch:
650   case Triple::aarch64:
651   case Triple::aarch64_32:
652   case Triple::arm:
653   case Triple::thumb:
654   case Triple::x86:
655   case Triple::x86_64:
656     if (T.isOSDarwin())
657       return Triple::MachO;
658     else if (T.isOSWindows())
659       return Triple::COFF;
660     return Triple::ELF;
661 
662   case Triple::aarch64_be:
663   case Triple::arc:
664   case Triple::amdgcn:
665   case Triple::amdil:
666   case Triple::amdil64:
667   case Triple::armeb:
668   case Triple::avr:
669   case Triple::bpfeb:
670   case Triple::bpfel:
671   case Triple::hexagon:
672   case Triple::lanai:
673   case Triple::hsail:
674   case Triple::hsail64:
675   case Triple::kalimba:
676   case Triple::le32:
677   case Triple::le64:
678   case Triple::mips:
679   case Triple::mips64:
680   case Triple::mips64el:
681   case Triple::mipsel:
682   case Triple::msp430:
683   case Triple::nvptx:
684   case Triple::nvptx64:
685   case Triple::ppc64le:
686   case Triple::r600:
687   case Triple::renderscript32:
688   case Triple::renderscript64:
689   case Triple::riscv32:
690   case Triple::riscv64:
691   case Triple::shave:
692   case Triple::sparc:
693   case Triple::sparcel:
694   case Triple::sparcv9:
695   case Triple::spir:
696   case Triple::spir64:
697   case Triple::systemz:
698   case Triple::tce:
699   case Triple::tcele:
700   case Triple::thumbeb:
701   case Triple::xcore:
702     return Triple::ELF;
703 
704   case Triple::ppc:
705   case Triple::ppc64:
706     if (T.isOSDarwin())
707       return Triple::MachO;
708     else if (T.isOSAIX())
709       return Triple::XCOFF;
710     return Triple::ELF;
711 
712   case Triple::wasm32:
713   case Triple::wasm64:
714     return Triple::Wasm;
715   }
716   llvm_unreachable("unknown architecture");
717 }
718 
719 /// Construct a triple from the string representation provided.
720 ///
721 /// This stores the string representation and parses the various pieces into
722 /// enum members.
723 Triple::Triple(const Twine &Str)
724     : Data(Str.str()), Arch(UnknownArch), SubArch(NoSubArch),
725       Vendor(UnknownVendor), OS(UnknownOS), Environment(UnknownEnvironment),
726       ObjectFormat(UnknownObjectFormat) {
727   // Do minimal parsing by hand here.
728   SmallVector<StringRef, 4> Components;
729   StringRef(Data).split(Components, '-', /*MaxSplit*/ 3);
730   if (Components.size() > 0) {
731     Arch = parseArch(Components[0]);
732     SubArch = parseSubArch(Components[0]);
733     if (Components.size() > 1) {
734       Vendor = parseVendor(Components[1]);
735       if (Components.size() > 2) {
736         OS = parseOS(Components[2]);
737         if (Components.size() > 3) {
738           Environment = parseEnvironment(Components[3]);
739           ObjectFormat = parseFormat(Components[3]);
740         }
741       }
742     } else {
743       Environment =
744           StringSwitch<Triple::EnvironmentType>(Components[0])
745               .StartsWith("mipsn32", Triple::GNUABIN32)
746               .StartsWith("mips64", Triple::GNUABI64)
747               .StartsWith("mipsisa64", Triple::GNUABI64)
748               .StartsWith("mipsisa32", Triple::GNU)
749               .Cases("mips", "mipsel", "mipsr6", "mipsr6el", Triple::GNU)
750               .Default(UnknownEnvironment);
751     }
752   }
753   if (ObjectFormat == UnknownObjectFormat)
754     ObjectFormat = getDefaultFormat(*this);
755 }
756 
757 /// Construct a triple from string representations of the architecture,
758 /// vendor, and OS.
759 ///
760 /// This joins each argument into a canonical string representation and parses
761 /// them into enum members. It leaves the environment unknown and omits it from
762 /// the string representation.
763 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
764     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
765       Arch(parseArch(ArchStr.str())),
766       SubArch(parseSubArch(ArchStr.str())),
767       Vendor(parseVendor(VendorStr.str())),
768       OS(parseOS(OSStr.str())),
769       Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
770   ObjectFormat = getDefaultFormat(*this);
771 }
772 
773 /// Construct a triple from string representations of the architecture,
774 /// vendor, OS, and environment.
775 ///
776 /// This joins each argument into a canonical string representation and parses
777 /// them into enum members.
778 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
779                const Twine &EnvironmentStr)
780     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
781             EnvironmentStr).str()),
782       Arch(parseArch(ArchStr.str())),
783       SubArch(parseSubArch(ArchStr.str())),
784       Vendor(parseVendor(VendorStr.str())),
785       OS(parseOS(OSStr.str())),
786       Environment(parseEnvironment(EnvironmentStr.str())),
787       ObjectFormat(parseFormat(EnvironmentStr.str())) {
788   if (ObjectFormat == Triple::UnknownObjectFormat)
789     ObjectFormat = getDefaultFormat(*this);
790 }
791 
792 std::string Triple::normalize(StringRef Str) {
793   bool IsMinGW32 = false;
794   bool IsCygwin = false;
795 
796   // Parse into components.
797   SmallVector<StringRef, 4> Components;
798   Str.split(Components, '-');
799 
800   // If the first component corresponds to a known architecture, preferentially
801   // use it for the architecture.  If the second component corresponds to a
802   // known vendor, preferentially use it for the vendor, etc.  This avoids silly
803   // component movement when a component parses as (eg) both a valid arch and a
804   // valid os.
805   ArchType Arch = UnknownArch;
806   if (Components.size() > 0)
807     Arch = parseArch(Components[0]);
808   VendorType Vendor = UnknownVendor;
809   if (Components.size() > 1)
810     Vendor = parseVendor(Components[1]);
811   OSType OS = UnknownOS;
812   if (Components.size() > 2) {
813     OS = parseOS(Components[2]);
814     IsCygwin = Components[2].startswith("cygwin");
815     IsMinGW32 = Components[2].startswith("mingw");
816   }
817   EnvironmentType Environment = UnknownEnvironment;
818   if (Components.size() > 3)
819     Environment = parseEnvironment(Components[3]);
820   ObjectFormatType ObjectFormat = UnknownObjectFormat;
821   if (Components.size() > 4)
822     ObjectFormat = parseFormat(Components[4]);
823 
824   // Note which components are already in their final position.  These will not
825   // be moved.
826   bool Found[4];
827   Found[0] = Arch != UnknownArch;
828   Found[1] = Vendor != UnknownVendor;
829   Found[2] = OS != UnknownOS;
830   Found[3] = Environment != UnknownEnvironment;
831 
832   // If they are not there already, permute the components into their canonical
833   // positions by seeing if they parse as a valid architecture, and if so moving
834   // the component to the architecture position etc.
835   for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
836     if (Found[Pos])
837       continue; // Already in the canonical position.
838 
839     for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
840       // Do not reparse any components that already matched.
841       if (Idx < array_lengthof(Found) && Found[Idx])
842         continue;
843 
844       // Does this component parse as valid for the target position?
845       bool Valid = false;
846       StringRef Comp = Components[Idx];
847       switch (Pos) {
848       default: llvm_unreachable("unexpected component type!");
849       case 0:
850         Arch = parseArch(Comp);
851         Valid = Arch != UnknownArch;
852         break;
853       case 1:
854         Vendor = parseVendor(Comp);
855         Valid = Vendor != UnknownVendor;
856         break;
857       case 2:
858         OS = parseOS(Comp);
859         IsCygwin = Comp.startswith("cygwin");
860         IsMinGW32 = Comp.startswith("mingw");
861         Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
862         break;
863       case 3:
864         Environment = parseEnvironment(Comp);
865         Valid = Environment != UnknownEnvironment;
866         if (!Valid) {
867           ObjectFormat = parseFormat(Comp);
868           Valid = ObjectFormat != UnknownObjectFormat;
869         }
870         break;
871       }
872       if (!Valid)
873         continue; // Nope, try the next component.
874 
875       // Move the component to the target position, pushing any non-fixed
876       // components that are in the way to the right.  This tends to give
877       // good results in the common cases of a forgotten vendor component
878       // or a wrongly positioned environment.
879       if (Pos < Idx) {
880         // Insert left, pushing the existing components to the right.  For
881         // example, a-b-i386 -> i386-a-b when moving i386 to the front.
882         StringRef CurrentComponent(""); // The empty component.
883         // Replace the component we are moving with an empty component.
884         std::swap(CurrentComponent, Components[Idx]);
885         // Insert the component being moved at Pos, displacing any existing
886         // components to the right.
887         for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
888           // Skip over any fixed components.
889           while (i < array_lengthof(Found) && Found[i])
890             ++i;
891           // Place the component at the new position, getting the component
892           // that was at this position - it will be moved right.
893           std::swap(CurrentComponent, Components[i]);
894         }
895       } else if (Pos > Idx) {
896         // Push right by inserting empty components until the component at Idx
897         // reaches the target position Pos.  For example, pc-a -> -pc-a when
898         // moving pc to the second position.
899         do {
900           // Insert one empty component at Idx.
901           StringRef CurrentComponent(""); // The empty component.
902           for (unsigned i = Idx; i < Components.size();) {
903             // Place the component at the new position, getting the component
904             // that was at this position - it will be moved right.
905             std::swap(CurrentComponent, Components[i]);
906             // If it was placed on top of an empty component then we are done.
907             if (CurrentComponent.empty())
908               break;
909             // Advance to the next component, skipping any fixed components.
910             while (++i < array_lengthof(Found) && Found[i])
911               ;
912           }
913           // The last component was pushed off the end - append it.
914           if (!CurrentComponent.empty())
915             Components.push_back(CurrentComponent);
916 
917           // Advance Idx to the component's new position.
918           while (++Idx < array_lengthof(Found) && Found[Idx])
919             ;
920         } while (Idx < Pos); // Add more until the final position is reached.
921       }
922       assert(Pos < Components.size() && Components[Pos] == Comp &&
923              "Component moved wrong!");
924       Found[Pos] = true;
925       break;
926     }
927   }
928 
929   // Replace empty components with "unknown" value.
930   for (unsigned i = 0, e = Components.size(); i < e; ++i) {
931     if (Components[i].empty())
932       Components[i] = "unknown";
933   }
934 
935   // Special case logic goes here.  At this point Arch, Vendor and OS have the
936   // correct values for the computed components.
937   std::string NormalizedEnvironment;
938   if (Environment == Triple::Android && Components[3].startswith("androideabi")) {
939     StringRef AndroidVersion = Components[3].drop_front(strlen("androideabi"));
940     if (AndroidVersion.empty()) {
941       Components[3] = "android";
942     } else {
943       NormalizedEnvironment = Twine("android", AndroidVersion).str();
944       Components[3] = NormalizedEnvironment;
945     }
946   }
947 
948   // SUSE uses "gnueabi" to mean "gnueabihf"
949   if (Vendor == Triple::SUSE && Environment == llvm::Triple::GNUEABI)
950     Components[3] = "gnueabihf";
951 
952   if (OS == Triple::Win32) {
953     Components.resize(4);
954     Components[2] = "windows";
955     if (Environment == UnknownEnvironment) {
956       if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
957         Components[3] = "msvc";
958       else
959         Components[3] = getObjectFormatTypeName(ObjectFormat);
960     }
961   } else if (IsMinGW32) {
962     Components.resize(4);
963     Components[2] = "windows";
964     Components[3] = "gnu";
965   } else if (IsCygwin) {
966     Components.resize(4);
967     Components[2] = "windows";
968     Components[3] = "cygnus";
969   }
970   if (IsMinGW32 || IsCygwin ||
971       (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
972     if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
973       Components.resize(5);
974       Components[4] = getObjectFormatTypeName(ObjectFormat);
975     }
976   }
977 
978   // Stick the corrected components back together to form the normalized string.
979   std::string Normalized;
980   for (unsigned i = 0, e = Components.size(); i != e; ++i) {
981     if (i) Normalized += '-';
982     Normalized += Components[i];
983   }
984   return Normalized;
985 }
986 
987 StringRef Triple::getArchName() const {
988   return StringRef(Data).split('-').first;           // Isolate first component
989 }
990 
991 StringRef Triple::getVendorName() const {
992   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
993   return Tmp.split('-').first;                       // Isolate second component
994 }
995 
996 StringRef Triple::getOSName() const {
997   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
998   Tmp = Tmp.split('-').second;                       // Strip second component
999   return Tmp.split('-').first;                       // Isolate third component
1000 }
1001 
1002 StringRef Triple::getEnvironmentName() const {
1003   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1004   Tmp = Tmp.split('-').second;                       // Strip second component
1005   return Tmp.split('-').second;                      // Strip third component
1006 }
1007 
1008 StringRef Triple::getOSAndEnvironmentName() const {
1009   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1010   return Tmp.split('-').second;                      // Strip second component
1011 }
1012 
1013 static unsigned EatNumber(StringRef &Str) {
1014   assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
1015   unsigned Result = 0;
1016 
1017   do {
1018     // Consume the leading digit.
1019     Result = Result*10 + (Str[0] - '0');
1020 
1021     // Eat the digit.
1022     Str = Str.substr(1);
1023   } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
1024 
1025   return Result;
1026 }
1027 
1028 static void parseVersionFromName(StringRef Name, unsigned &Major,
1029                                  unsigned &Minor, unsigned &Micro) {
1030   // Any unset version defaults to 0.
1031   Major = Minor = Micro = 0;
1032 
1033   // Parse up to three components.
1034   unsigned *Components[3] = {&Major, &Minor, &Micro};
1035   for (unsigned i = 0; i != 3; ++i) {
1036     if (Name.empty() || Name[0] < '0' || Name[0] > '9')
1037       break;
1038 
1039     // Consume the leading number.
1040     *Components[i] = EatNumber(Name);
1041 
1042     // Consume the separator, if present.
1043     if (Name.startswith("."))
1044       Name = Name.substr(1);
1045   }
1046 }
1047 
1048 void Triple::getEnvironmentVersion(unsigned &Major, unsigned &Minor,
1049                                    unsigned &Micro) const {
1050   StringRef EnvironmentName = getEnvironmentName();
1051   StringRef EnvironmentTypeName = getEnvironmentTypeName(getEnvironment());
1052   if (EnvironmentName.startswith(EnvironmentTypeName))
1053     EnvironmentName = EnvironmentName.substr(EnvironmentTypeName.size());
1054 
1055   parseVersionFromName(EnvironmentName, Major, Minor, Micro);
1056 }
1057 
1058 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
1059                           unsigned &Micro) const {
1060   StringRef OSName = getOSName();
1061   // Assume that the OS portion of the triple starts with the canonical name.
1062   StringRef OSTypeName = getOSTypeName(getOS());
1063   if (OSName.startswith(OSTypeName))
1064     OSName = OSName.substr(OSTypeName.size());
1065   else if (getOS() == MacOSX)
1066     OSName.consume_front("macos");
1067 
1068   parseVersionFromName(OSName, Major, Minor, Micro);
1069 }
1070 
1071 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
1072                               unsigned &Micro) const {
1073   getOSVersion(Major, Minor, Micro);
1074 
1075   switch (getOS()) {
1076   default: llvm_unreachable("unexpected OS for Darwin triple");
1077   case Darwin:
1078     // Default to darwin8, i.e., MacOSX 10.4.
1079     if (Major == 0)
1080       Major = 8;
1081     // Darwin version numbers are skewed from OS X versions.
1082     if (Major < 4)
1083       return false;
1084     Micro = 0;
1085     Minor = Major - 4;
1086     Major = 10;
1087     break;
1088   case MacOSX:
1089     // Default to 10.4.
1090     if (Major == 0) {
1091       Major = 10;
1092       Minor = 4;
1093     }
1094     if (Major != 10)
1095       return false;
1096     break;
1097   case IOS:
1098   case TvOS:
1099   case WatchOS:
1100     // Ignore the version from the triple.  This is only handled because the
1101     // the clang driver combines OS X and IOS support into a common Darwin
1102     // toolchain that wants to know the OS X version number even when targeting
1103     // IOS.
1104     Major = 10;
1105     Minor = 4;
1106     Micro = 0;
1107     break;
1108   }
1109   return true;
1110 }
1111 
1112 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
1113                            unsigned &Micro) const {
1114   switch (getOS()) {
1115   default: llvm_unreachable("unexpected OS for Darwin triple");
1116   case Darwin:
1117   case MacOSX:
1118     // Ignore the version from the triple.  This is only handled because the
1119     // the clang driver combines OS X and IOS support into a common Darwin
1120     // toolchain that wants to know the iOS version number even when targeting
1121     // OS X.
1122     Major = 5;
1123     Minor = 0;
1124     Micro = 0;
1125     break;
1126   case IOS:
1127   case TvOS:
1128     getOSVersion(Major, Minor, Micro);
1129     // Default to 5.0 (or 7.0 for arm64).
1130     if (Major == 0)
1131       Major = (getArch() == aarch64) ? 7 : 5;
1132     break;
1133   case WatchOS:
1134     llvm_unreachable("conflicting triple info");
1135   }
1136 }
1137 
1138 void Triple::getWatchOSVersion(unsigned &Major, unsigned &Minor,
1139                                unsigned &Micro) const {
1140   switch (getOS()) {
1141   default: llvm_unreachable("unexpected OS for Darwin triple");
1142   case Darwin:
1143   case MacOSX:
1144     // Ignore the version from the triple.  This is only handled because the
1145     // the clang driver combines OS X and IOS support into a common Darwin
1146     // toolchain that wants to know the iOS version number even when targeting
1147     // OS X.
1148     Major = 2;
1149     Minor = 0;
1150     Micro = 0;
1151     break;
1152   case WatchOS:
1153     getOSVersion(Major, Minor, Micro);
1154     if (Major == 0)
1155       Major = 2;
1156     break;
1157   case IOS:
1158     llvm_unreachable("conflicting triple info");
1159   }
1160 }
1161 
1162 void Triple::setTriple(const Twine &Str) {
1163   *this = Triple(Str);
1164 }
1165 
1166 void Triple::setArch(ArchType Kind) {
1167   setArchName(getArchTypeName(Kind));
1168 }
1169 
1170 void Triple::setVendor(VendorType Kind) {
1171   setVendorName(getVendorTypeName(Kind));
1172 }
1173 
1174 void Triple::setOS(OSType Kind) {
1175   setOSName(getOSTypeName(Kind));
1176 }
1177 
1178 void Triple::setEnvironment(EnvironmentType Kind) {
1179   if (ObjectFormat == getDefaultFormat(*this))
1180     return setEnvironmentName(getEnvironmentTypeName(Kind));
1181 
1182   setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
1183                       getObjectFormatTypeName(ObjectFormat)).str());
1184 }
1185 
1186 void Triple::setObjectFormat(ObjectFormatType Kind) {
1187   if (Environment == UnknownEnvironment)
1188     return setEnvironmentName(getObjectFormatTypeName(Kind));
1189 
1190   setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
1191                       getObjectFormatTypeName(Kind)).str());
1192 }
1193 
1194 void Triple::setArchName(StringRef Str) {
1195   // Work around a miscompilation bug for Twines in gcc 4.0.3.
1196   SmallString<64> Triple;
1197   Triple += Str;
1198   Triple += "-";
1199   Triple += getVendorName();
1200   Triple += "-";
1201   Triple += getOSAndEnvironmentName();
1202   setTriple(Triple);
1203 }
1204 
1205 void Triple::setVendorName(StringRef Str) {
1206   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
1207 }
1208 
1209 void Triple::setOSName(StringRef Str) {
1210   if (hasEnvironment())
1211     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
1212               "-" + getEnvironmentName());
1213   else
1214     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
1215 }
1216 
1217 void Triple::setEnvironmentName(StringRef Str) {
1218   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
1219             "-" + Str);
1220 }
1221 
1222 void Triple::setOSAndEnvironmentName(StringRef Str) {
1223   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
1224 }
1225 
1226 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
1227   switch (Arch) {
1228   case llvm::Triple::UnknownArch:
1229     return 0;
1230 
1231   case llvm::Triple::avr:
1232   case llvm::Triple::msp430:
1233     return 16;
1234 
1235   case llvm::Triple::aarch64_32:
1236   case llvm::Triple::arc:
1237   case llvm::Triple::arm:
1238   case llvm::Triple::armeb:
1239   case llvm::Triple::hexagon:
1240   case llvm::Triple::le32:
1241   case llvm::Triple::mips:
1242   case llvm::Triple::mipsel:
1243   case llvm::Triple::nvptx:
1244   case llvm::Triple::ppc:
1245   case llvm::Triple::r600:
1246   case llvm::Triple::riscv32:
1247   case llvm::Triple::sparc:
1248   case llvm::Triple::sparcel:
1249   case llvm::Triple::tce:
1250   case llvm::Triple::tcele:
1251   case llvm::Triple::thumb:
1252   case llvm::Triple::thumbeb:
1253   case llvm::Triple::x86:
1254   case llvm::Triple::xcore:
1255   case llvm::Triple::amdil:
1256   case llvm::Triple::hsail:
1257   case llvm::Triple::spir:
1258   case llvm::Triple::kalimba:
1259   case llvm::Triple::lanai:
1260   case llvm::Triple::shave:
1261   case llvm::Triple::wasm32:
1262   case llvm::Triple::renderscript32:
1263     return 32;
1264 
1265   case llvm::Triple::aarch64:
1266   case llvm::Triple::aarch64_be:
1267   case llvm::Triple::amdgcn:
1268   case llvm::Triple::bpfel:
1269   case llvm::Triple::bpfeb:
1270   case llvm::Triple::le64:
1271   case llvm::Triple::mips64:
1272   case llvm::Triple::mips64el:
1273   case llvm::Triple::nvptx64:
1274   case llvm::Triple::ppc64:
1275   case llvm::Triple::ppc64le:
1276   case llvm::Triple::riscv64:
1277   case llvm::Triple::sparcv9:
1278   case llvm::Triple::systemz:
1279   case llvm::Triple::x86_64:
1280   case llvm::Triple::amdil64:
1281   case llvm::Triple::hsail64:
1282   case llvm::Triple::spir64:
1283   case llvm::Triple::wasm64:
1284   case llvm::Triple::renderscript64:
1285     return 64;
1286   }
1287   llvm_unreachable("Invalid architecture value");
1288 }
1289 
1290 bool Triple::isArch64Bit() const {
1291   return getArchPointerBitWidth(getArch()) == 64;
1292 }
1293 
1294 bool Triple::isArch32Bit() const {
1295   return getArchPointerBitWidth(getArch()) == 32;
1296 }
1297 
1298 bool Triple::isArch16Bit() const {
1299   return getArchPointerBitWidth(getArch()) == 16;
1300 }
1301 
1302 Triple Triple::get32BitArchVariant() const {
1303   Triple T(*this);
1304   switch (getArch()) {
1305   case Triple::UnknownArch:
1306   case Triple::amdgcn:
1307   case Triple::avr:
1308   case Triple::bpfel:
1309   case Triple::bpfeb:
1310   case Triple::msp430:
1311   case Triple::systemz:
1312   case Triple::ppc64le:
1313     T.setArch(UnknownArch);
1314     break;
1315 
1316   case Triple::aarch64_32:
1317   case Triple::amdil:
1318   case Triple::hsail:
1319   case Triple::spir:
1320   case Triple::arc:
1321   case Triple::arm:
1322   case Triple::armeb:
1323   case Triple::hexagon:
1324   case Triple::kalimba:
1325   case Triple::le32:
1326   case Triple::mips:
1327   case Triple::mipsel:
1328   case Triple::nvptx:
1329   case Triple::ppc:
1330   case Triple::r600:
1331   case Triple::riscv32:
1332   case Triple::sparc:
1333   case Triple::sparcel:
1334   case Triple::tce:
1335   case Triple::tcele:
1336   case Triple::thumb:
1337   case Triple::thumbeb:
1338   case Triple::x86:
1339   case Triple::xcore:
1340   case Triple::lanai:
1341   case Triple::shave:
1342   case Triple::wasm32:
1343   case Triple::renderscript32:
1344     // Already 32-bit.
1345     break;
1346 
1347   case Triple::aarch64:        T.setArch(Triple::arm);     break;
1348   case Triple::aarch64_be:     T.setArch(Triple::armeb);   break;
1349   case Triple::le64:           T.setArch(Triple::le32);    break;
1350   case Triple::mips64:         T.setArch(Triple::mips);    break;
1351   case Triple::mips64el:       T.setArch(Triple::mipsel);  break;
1352   case Triple::nvptx64:        T.setArch(Triple::nvptx);   break;
1353   case Triple::ppc64:          T.setArch(Triple::ppc);     break;
1354   case Triple::sparcv9:        T.setArch(Triple::sparc);   break;
1355   case Triple::riscv64:        T.setArch(Triple::riscv32); break;
1356   case Triple::x86_64:         T.setArch(Triple::x86);     break;
1357   case Triple::amdil64:        T.setArch(Triple::amdil);   break;
1358   case Triple::hsail64:        T.setArch(Triple::hsail);   break;
1359   case Triple::spir64:         T.setArch(Triple::spir);    break;
1360   case Triple::wasm64:         T.setArch(Triple::wasm32);  break;
1361   case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
1362   }
1363   return T;
1364 }
1365 
1366 Triple Triple::get64BitArchVariant() const {
1367   Triple T(*this);
1368   switch (getArch()) {
1369   case Triple::UnknownArch:
1370   case Triple::arc:
1371   case Triple::avr:
1372   case Triple::hexagon:
1373   case Triple::kalimba:
1374   case Triple::lanai:
1375   case Triple::msp430:
1376   case Triple::r600:
1377   case Triple::tce:
1378   case Triple::tcele:
1379   case Triple::xcore:
1380   case Triple::sparcel:
1381   case Triple::shave:
1382     T.setArch(UnknownArch);
1383     break;
1384 
1385   case Triple::aarch64:
1386   case Triple::aarch64_be:
1387   case Triple::bpfel:
1388   case Triple::bpfeb:
1389   case Triple::le64:
1390   case Triple::amdil64:
1391   case Triple::amdgcn:
1392   case Triple::hsail64:
1393   case Triple::spir64:
1394   case Triple::mips64:
1395   case Triple::mips64el:
1396   case Triple::nvptx64:
1397   case Triple::ppc64:
1398   case Triple::ppc64le:
1399   case Triple::riscv64:
1400   case Triple::sparcv9:
1401   case Triple::systemz:
1402   case Triple::x86_64:
1403   case Triple::wasm64:
1404   case Triple::renderscript64:
1405     // Already 64-bit.
1406     break;
1407 
1408   case Triple::aarch64_32:      T.setArch(Triple::aarch64);    break;
1409   case Triple::arm:             T.setArch(Triple::aarch64);    break;
1410   case Triple::armeb:           T.setArch(Triple::aarch64_be); break;
1411   case Triple::le32:            T.setArch(Triple::le64);       break;
1412   case Triple::mips:            T.setArch(Triple::mips64);     break;
1413   case Triple::mipsel:          T.setArch(Triple::mips64el);   break;
1414   case Triple::nvptx:           T.setArch(Triple::nvptx64);    break;
1415   case Triple::ppc:             T.setArch(Triple::ppc64);      break;
1416   case Triple::sparc:           T.setArch(Triple::sparcv9);    break;
1417   case Triple::riscv32:         T.setArch(Triple::riscv64);    break;
1418   case Triple::x86:             T.setArch(Triple::x86_64);     break;
1419   case Triple::amdil:           T.setArch(Triple::amdil64);    break;
1420   case Triple::hsail:           T.setArch(Triple::hsail64);    break;
1421   case Triple::spir:            T.setArch(Triple::spir64);     break;
1422   case Triple::thumb:           T.setArch(Triple::aarch64);    break;
1423   case Triple::thumbeb:         T.setArch(Triple::aarch64_be); break;
1424   case Triple::wasm32:          T.setArch(Triple::wasm64);     break;
1425   case Triple::renderscript32:  T.setArch(Triple::renderscript64);     break;
1426   }
1427   return T;
1428 }
1429 
1430 Triple Triple::getBigEndianArchVariant() const {
1431   Triple T(*this);
1432   // Already big endian.
1433   if (!isLittleEndian())
1434     return T;
1435   switch (getArch()) {
1436   case Triple::UnknownArch:
1437   case Triple::amdgcn:
1438   case Triple::amdil64:
1439   case Triple::amdil:
1440   case Triple::avr:
1441   case Triple::hexagon:
1442   case Triple::hsail64:
1443   case Triple::hsail:
1444   case Triple::kalimba:
1445   case Triple::le32:
1446   case Triple::le64:
1447   case Triple::msp430:
1448   case Triple::nvptx64:
1449   case Triple::nvptx:
1450   case Triple::r600:
1451   case Triple::riscv32:
1452   case Triple::riscv64:
1453   case Triple::shave:
1454   case Triple::spir64:
1455   case Triple::spir:
1456   case Triple::wasm32:
1457   case Triple::wasm64:
1458   case Triple::x86:
1459   case Triple::x86_64:
1460   case Triple::xcore:
1461   case Triple::renderscript32:
1462   case Triple::renderscript64:
1463 
1464   // ARM is intentionally unsupported here, changing the architecture would
1465   // drop any arch suffixes.
1466   case Triple::arm:
1467   case Triple::thumb:
1468     T.setArch(UnknownArch);
1469     break;
1470 
1471   case Triple::tcele:   T.setArch(Triple::tce);        break;
1472   case Triple::aarch64: T.setArch(Triple::aarch64_be); break;
1473   case Triple::bpfel:   T.setArch(Triple::bpfeb);      break;
1474   case Triple::mips64el:T.setArch(Triple::mips64);     break;
1475   case Triple::mipsel:  T.setArch(Triple::mips);       break;
1476   case Triple::ppc64le: T.setArch(Triple::ppc64);      break;
1477   case Triple::sparcel: T.setArch(Triple::sparc);      break;
1478   default:
1479     llvm_unreachable("getBigEndianArchVariant: unknown triple.");
1480   }
1481   return T;
1482 }
1483 
1484 Triple Triple::getLittleEndianArchVariant() const {
1485   Triple T(*this);
1486   if (isLittleEndian())
1487     return T;
1488 
1489   switch (getArch()) {
1490   case Triple::UnknownArch:
1491   case Triple::lanai:
1492   case Triple::ppc:
1493   case Triple::sparcv9:
1494   case Triple::systemz:
1495 
1496   // ARM is intentionally unsupported here, changing the architecture would
1497   // drop any arch suffixes.
1498   case Triple::armeb:
1499   case Triple::thumbeb:
1500     T.setArch(UnknownArch);
1501     break;
1502 
1503   case Triple::tce:        T.setArch(Triple::tcele);    break;
1504   case Triple::aarch64_be: T.setArch(Triple::aarch64);  break;
1505   case Triple::bpfeb:      T.setArch(Triple::bpfel);    break;
1506   case Triple::mips64:     T.setArch(Triple::mips64el); break;
1507   case Triple::mips:       T.setArch(Triple::mipsel);   break;
1508   case Triple::ppc64:      T.setArch(Triple::ppc64le);  break;
1509   case Triple::sparc:      T.setArch(Triple::sparcel);  break;
1510   default:
1511     llvm_unreachable("getLittleEndianArchVariant: unknown triple.");
1512   }
1513   return T;
1514 }
1515 
1516 bool Triple::isLittleEndian() const {
1517   switch (getArch()) {
1518   case Triple::aarch64:
1519   case Triple::aarch64_32:
1520   case Triple::amdgcn:
1521   case Triple::amdil64:
1522   case Triple::amdil:
1523   case Triple::arm:
1524   case Triple::avr:
1525   case Triple::bpfel:
1526   case Triple::hexagon:
1527   case Triple::hsail64:
1528   case Triple::hsail:
1529   case Triple::kalimba:
1530   case Triple::le32:
1531   case Triple::le64:
1532   case Triple::mips64el:
1533   case Triple::mipsel:
1534   case Triple::msp430:
1535   case Triple::nvptx64:
1536   case Triple::nvptx:
1537   case Triple::ppc64le:
1538   case Triple::r600:
1539   case Triple::riscv32:
1540   case Triple::riscv64:
1541   case Triple::shave:
1542   case Triple::sparcel:
1543   case Triple::spir64:
1544   case Triple::spir:
1545   case Triple::thumb:
1546   case Triple::wasm32:
1547   case Triple::wasm64:
1548   case Triple::x86:
1549   case Triple::x86_64:
1550   case Triple::xcore:
1551   case Triple::tcele:
1552   case Triple::renderscript32:
1553   case Triple::renderscript64:
1554     return true;
1555   default:
1556     return false;
1557   }
1558 }
1559 
1560 bool Triple::isCompatibleWith(const Triple &Other) const {
1561   // ARM and Thumb triples are compatible, if subarch, vendor and OS match.
1562   if ((getArch() == Triple::thumb && Other.getArch() == Triple::arm) ||
1563       (getArch() == Triple::arm && Other.getArch() == Triple::thumb) ||
1564       (getArch() == Triple::thumbeb && Other.getArch() == Triple::armeb) ||
1565       (getArch() == Triple::armeb && Other.getArch() == Triple::thumbeb)) {
1566     if (getVendor() == Triple::Apple)
1567       return getSubArch() == Other.getSubArch() &&
1568              getVendor() == Other.getVendor() && getOS() == Other.getOS();
1569     else
1570       return getSubArch() == Other.getSubArch() &&
1571              getVendor() == Other.getVendor() && getOS() == Other.getOS() &&
1572              getEnvironment() == Other.getEnvironment() &&
1573              getObjectFormat() == Other.getObjectFormat();
1574   }
1575 
1576   // If vendor is apple, ignore the version number.
1577   if (getVendor() == Triple::Apple)
1578     return getArch() == Other.getArch() && getSubArch() == Other.getSubArch() &&
1579            getVendor() == Other.getVendor() && getOS() == Other.getOS();
1580 
1581   return *this == Other;
1582 }
1583 
1584 std::string Triple::merge(const Triple &Other) const {
1585   // If vendor is apple, pick the triple with the larger version number.
1586   if (getVendor() == Triple::Apple)
1587     if (Other.isOSVersionLT(*this))
1588       return str();
1589 
1590   return Other.str();
1591 }
1592 
1593 StringRef Triple::getARMCPUForArch(StringRef MArch) const {
1594   if (MArch.empty())
1595     MArch = getArchName();
1596   MArch = ARM::getCanonicalArchName(MArch);
1597 
1598   // Some defaults are forced.
1599   switch (getOS()) {
1600   case llvm::Triple::FreeBSD:
1601   case llvm::Triple::NetBSD:
1602     if (!MArch.empty() && MArch == "v6")
1603       return "arm1176jzf-s";
1604     break;
1605   case llvm::Triple::Win32:
1606     // FIXME: this is invalid for WindowsCE
1607     return "cortex-a9";
1608   case llvm::Triple::MacOSX:
1609   case llvm::Triple::IOS:
1610   case llvm::Triple::WatchOS:
1611   case llvm::Triple::TvOS:
1612     if (MArch == "v7k")
1613       return "cortex-a7";
1614     break;
1615   default:
1616     break;
1617   }
1618 
1619   if (MArch.empty())
1620     return StringRef();
1621 
1622   StringRef CPU = ARM::getDefaultCPU(MArch);
1623   if (!CPU.empty() && !CPU.equals("invalid"))
1624     return CPU;
1625 
1626   // If no specific architecture version is requested, return the minimum CPU
1627   // required by the OS and environment.
1628   switch (getOS()) {
1629   case llvm::Triple::NetBSD:
1630     switch (getEnvironment()) {
1631     case llvm::Triple::GNUEABIHF:
1632     case llvm::Triple::GNUEABI:
1633     case llvm::Triple::EABIHF:
1634     case llvm::Triple::EABI:
1635       return "arm926ej-s";
1636     default:
1637       return "strongarm";
1638     }
1639   case llvm::Triple::NaCl:
1640   case llvm::Triple::OpenBSD:
1641     return "cortex-a8";
1642   default:
1643     switch (getEnvironment()) {
1644     case llvm::Triple::EABIHF:
1645     case llvm::Triple::GNUEABIHF:
1646     case llvm::Triple::MuslEABIHF:
1647       return "arm1176jzf-s";
1648     default:
1649       return "arm7tdmi";
1650     }
1651   }
1652 
1653   llvm_unreachable("invalid arch name");
1654 }
1655