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