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