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