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