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("arm", Triple::arm)
411 .Case("armeb", Triple::armeb)
412 .Case("thumb", Triple::thumb)
413 .Case("thumbeb", Triple::thumbeb)
414 .Case("avr", Triple::avr)
415 .Case("msp430", Triple::msp430)
416 .Cases("mips", "mipseb", "mipsallegrex", "mipsisa32r6",
417 "mipsr6", Triple::mips)
418 .Cases("mipsel", "mipsallegrexel", "mipsisa32r6el", "mipsr6el",
419 Triple::mipsel)
420 .Cases("mips64", "mips64eb", "mipsn32", "mipsisa64r6",
421 "mips64r6", "mipsn32r6", Triple::mips64)
422 .Cases("mips64el", "mipsn32el", "mipsisa64r6el", "mips64r6el",
423 "mipsn32r6el", Triple::mips64el)
424 .Case("r600", Triple::r600)
425 .Case("amdgcn", Triple::amdgcn)
426 .Case("riscv32", Triple::riscv32)
427 .Case("riscv64", Triple::riscv64)
428 .Case("hexagon", Triple::hexagon)
429 .Cases("s390x", "systemz", Triple::systemz)
430 .Case("sparc", Triple::sparc)
431 .Case("sparcel", Triple::sparcel)
432 .Cases("sparcv9", "sparc64", Triple::sparcv9)
433 .Case("tce", Triple::tce)
434 .Case("tcele", Triple::tcele)
435 .Case("xcore", Triple::xcore)
436 .Case("nvptx", Triple::nvptx)
437 .Case("nvptx64", Triple::nvptx64)
438 .Case("le32", Triple::le32)
439 .Case("le64", Triple::le64)
440 .Case("amdil", Triple::amdil)
441 .Case("amdil64", Triple::amdil64)
442 .Case("hsail", Triple::hsail)
443 .Case("hsail64", Triple::hsail64)
444 .Case("spir", Triple::spir)
445 .Case("spir64", Triple::spir64)
446 .StartsWith("kalimba", Triple::kalimba)
447 .Case("lanai", Triple::lanai)
448 .Case("renderscript32", Triple::renderscript32)
449 .Case("renderscript64", Triple::renderscript64)
450 .Case("shave", Triple::shave)
451 .Case("ve", Triple::ve)
452 .Case("wasm32", Triple::wasm32)
453 .Case("wasm64", Triple::wasm64)
454 .Case("csky", Triple::csky)
455 .Default(Triple::UnknownArch);
456
457 // Some architectures require special parsing logic just to compute the
458 // ArchType result.
459 if (AT == Triple::UnknownArch) {
460 if (ArchName.startswith("arm") || ArchName.startswith("thumb") ||
461 ArchName.startswith("aarch64"))
462 return parseARMArch(ArchName);
463 if (ArchName.startswith("bpf"))
464 return parseBPFArch(ArchName);
465 }
466
467 return AT;
468 }
469
parseVendor(StringRef VendorName)470 static Triple::VendorType parseVendor(StringRef VendorName) {
471 return StringSwitch<Triple::VendorType>(VendorName)
472 .Case("apple", Triple::Apple)
473 .Case("pc", Triple::PC)
474 .Case("scei", Triple::SCEI)
475 .Case("fsl", Triple::Freescale)
476 .Case("ibm", Triple::IBM)
477 .Case("img", Triple::ImaginationTechnologies)
478 .Case("mti", Triple::MipsTechnologies)
479 .Case("nvidia", Triple::NVIDIA)
480 .Case("csr", Triple::CSR)
481 .Case("myriad", Triple::Myriad)
482 .Case("amd", Triple::AMD)
483 .Case("mesa", Triple::Mesa)
484 .Case("suse", Triple::SUSE)
485 .Case("oe", Triple::OpenEmbedded)
486 .Default(Triple::UnknownVendor);
487 }
488
parseOS(StringRef OSName)489 static Triple::OSType parseOS(StringRef OSName) {
490 return StringSwitch<Triple::OSType>(OSName)
491 .StartsWith("ananas", Triple::Ananas)
492 .StartsWith("cloudabi", Triple::CloudABI)
493 .StartsWith("darwin", Triple::Darwin)
494 .StartsWith("dragonfly", Triple::DragonFly)
495 .StartsWith("freebsd", Triple::FreeBSD)
496 .StartsWith("fuchsia", Triple::Fuchsia)
497 .StartsWith("ios", Triple::IOS)
498 .StartsWith("kfreebsd", Triple::KFreeBSD)
499 .StartsWith("linux", Triple::Linux)
500 .StartsWith("lv2", Triple::Lv2)
501 .StartsWith("macos", Triple::MacOSX)
502 .StartsWith("netbsd", Triple::NetBSD)
503 .StartsWith("openbsd", Triple::OpenBSD)
504 .StartsWith("solaris", Triple::Solaris)
505 .StartsWith("win32", Triple::Win32)
506 .StartsWith("windows", Triple::Win32)
507 .StartsWith("zos", Triple::ZOS)
508 .StartsWith("haiku", Triple::Haiku)
509 .StartsWith("minix", Triple::Minix)
510 .StartsWith("rtems", Triple::RTEMS)
511 .StartsWith("nacl", Triple::NaCl)
512 .StartsWith("aix", Triple::AIX)
513 .StartsWith("cuda", Triple::CUDA)
514 .StartsWith("nvcl", Triple::NVCL)
515 .StartsWith("amdhsa", Triple::AMDHSA)
516 .StartsWith("ps4", Triple::PS4)
517 .StartsWith("elfiamcu", Triple::ELFIAMCU)
518 .StartsWith("tvos", Triple::TvOS)
519 .StartsWith("watchos", Triple::WatchOS)
520 .StartsWith("mesa3d", Triple::Mesa3D)
521 .StartsWith("contiki", Triple::Contiki)
522 .StartsWith("amdpal", Triple::AMDPAL)
523 .StartsWith("hermit", Triple::HermitCore)
524 .StartsWith("hurd", Triple::Hurd)
525 .StartsWith("wasi", Triple::WASI)
526 .StartsWith("emscripten", Triple::Emscripten)
527 .Default(Triple::UnknownOS);
528 }
529
parseEnvironment(StringRef EnvironmentName)530 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
531 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
532 .StartsWith("eabihf", Triple::EABIHF)
533 .StartsWith("eabi", Triple::EABI)
534 .StartsWith("gnuabin32", Triple::GNUABIN32)
535 .StartsWith("gnuabi64", Triple::GNUABI64)
536 .StartsWith("gnueabihf", Triple::GNUEABIHF)
537 .StartsWith("gnueabi", Triple::GNUEABI)
538 .StartsWith("gnux32", Triple::GNUX32)
539 .StartsWith("code16", Triple::CODE16)
540 .StartsWith("gnu", Triple::GNU)
541 .StartsWith("android", Triple::Android)
542 .StartsWith("musleabihf", Triple::MuslEABIHF)
543 .StartsWith("musleabi", Triple::MuslEABI)
544 .StartsWith("musl", Triple::Musl)
545 .StartsWith("msvc", Triple::MSVC)
546 .StartsWith("itanium", Triple::Itanium)
547 .StartsWith("cygnus", Triple::Cygnus)
548 .StartsWith("coreclr", Triple::CoreCLR)
549 .StartsWith("simulator", Triple::Simulator)
550 .StartsWith("macabi", Triple::MacABI)
551 .Default(Triple::UnknownEnvironment);
552 }
553
parseFormat(StringRef EnvironmentName)554 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
555 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
556 // "xcoff" must come before "coff" because of the order-dependendent
557 // pattern matching.
558 .EndsWith("xcoff", Triple::XCOFF)
559 .EndsWith("coff", Triple::COFF)
560 .EndsWith("elf", Triple::ELF)
561 .EndsWith("goff", Triple::GOFF)
562 .EndsWith("macho", Triple::MachO)
563 .EndsWith("wasm", Triple::Wasm)
564 .Default(Triple::UnknownObjectFormat);
565 }
566
parseSubArch(StringRef SubArchName)567 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
568 if (SubArchName.startswith("mips") &&
569 (SubArchName.endswith("r6el") || SubArchName.endswith("r6")))
570 return Triple::MipsSubArch_r6;
571
572 if (SubArchName == "powerpcspe")
573 return Triple::PPCSubArch_spe;
574
575 StringRef ARMSubArch = ARM::getCanonicalArchName(SubArchName);
576
577 // For now, this is the small part. Early return.
578 if (ARMSubArch.empty())
579 return StringSwitch<Triple::SubArchType>(SubArchName)
580 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
581 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
582 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
583 .Default(Triple::NoSubArch);
584
585 // ARM sub arch.
586 switch(ARM::parseArch(ARMSubArch)) {
587 case ARM::ArchKind::ARMV4:
588 return Triple::NoSubArch;
589 case ARM::ArchKind::ARMV4T:
590 return Triple::ARMSubArch_v4t;
591 case ARM::ArchKind::ARMV5T:
592 return Triple::ARMSubArch_v5;
593 case ARM::ArchKind::ARMV5TE:
594 case ARM::ArchKind::IWMMXT:
595 case ARM::ArchKind::IWMMXT2:
596 case ARM::ArchKind::XSCALE:
597 case ARM::ArchKind::ARMV5TEJ:
598 return Triple::ARMSubArch_v5te;
599 case ARM::ArchKind::ARMV6:
600 return Triple::ARMSubArch_v6;
601 case ARM::ArchKind::ARMV6K:
602 case ARM::ArchKind::ARMV6KZ:
603 return Triple::ARMSubArch_v6k;
604 case ARM::ArchKind::ARMV6T2:
605 return Triple::ARMSubArch_v6t2;
606 case ARM::ArchKind::ARMV6M:
607 return Triple::ARMSubArch_v6m;
608 case ARM::ArchKind::ARMV7A:
609 case ARM::ArchKind::ARMV7R:
610 return Triple::ARMSubArch_v7;
611 case ARM::ArchKind::ARMV7VE:
612 return Triple::ARMSubArch_v7ve;
613 case ARM::ArchKind::ARMV7K:
614 return Triple::ARMSubArch_v7k;
615 case ARM::ArchKind::ARMV7M:
616 return Triple::ARMSubArch_v7m;
617 case ARM::ArchKind::ARMV7S:
618 return Triple::ARMSubArch_v7s;
619 case ARM::ArchKind::ARMV7EM:
620 return Triple::ARMSubArch_v7em;
621 case ARM::ArchKind::ARMV8A:
622 return Triple::ARMSubArch_v8;
623 case ARM::ArchKind::ARMV8_1A:
624 return Triple::ARMSubArch_v8_1a;
625 case ARM::ArchKind::ARMV8_2A:
626 return Triple::ARMSubArch_v8_2a;
627 case ARM::ArchKind::ARMV8_3A:
628 return Triple::ARMSubArch_v8_3a;
629 case ARM::ArchKind::ARMV8_4A:
630 return Triple::ARMSubArch_v8_4a;
631 case ARM::ArchKind::ARMV8_5A:
632 return Triple::ARMSubArch_v8_5a;
633 case ARM::ArchKind::ARMV8_6A:
634 return Triple::ARMSubArch_v8_6a;
635 case ARM::ArchKind::ARMV8R:
636 return Triple::ARMSubArch_v8r;
637 case ARM::ArchKind::ARMV8MBaseline:
638 return Triple::ARMSubArch_v8m_baseline;
639 case ARM::ArchKind::ARMV8MMainline:
640 return Triple::ARMSubArch_v8m_mainline;
641 case ARM::ArchKind::ARMV8_1MMainline:
642 return Triple::ARMSubArch_v8_1m_mainline;
643 default:
644 return Triple::NoSubArch;
645 }
646 }
647
getObjectFormatTypeName(Triple::ObjectFormatType Kind)648 static StringRef getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
649 switch (Kind) {
650 case Triple::UnknownObjectFormat: return "";
651 case Triple::COFF: return "coff";
652 case Triple::ELF: return "elf";
653 case Triple::GOFF: return "goff";
654 case Triple::MachO: return "macho";
655 case Triple::Wasm: return "wasm";
656 case Triple::XCOFF: return "xcoff";
657 }
658 llvm_unreachable("unknown object format type");
659 }
660
getDefaultFormat(const Triple & T)661 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
662 switch (T.getArch()) {
663 case Triple::UnknownArch:
664 case Triple::aarch64:
665 case Triple::aarch64_32:
666 case Triple::arm:
667 case Triple::thumb:
668 case Triple::x86:
669 case Triple::x86_64:
670 if (T.isOSDarwin())
671 return Triple::MachO;
672 else if (T.isOSWindows())
673 return Triple::COFF;
674 return Triple::ELF;
675
676 case Triple::aarch64_be:
677 case Triple::amdgcn:
678 case Triple::amdil64:
679 case Triple::amdil:
680 case Triple::arc:
681 case Triple::armeb:
682 case Triple::avr:
683 case Triple::bpfeb:
684 case Triple::bpfel:
685 case Triple::csky:
686 case Triple::hexagon:
687 case Triple::hsail64:
688 case Triple::hsail:
689 case Triple::kalimba:
690 case Triple::lanai:
691 case Triple::le32:
692 case Triple::le64:
693 case Triple::mips64:
694 case Triple::mips64el:
695 case Triple::mips:
696 case Triple::mipsel:
697 case Triple::msp430:
698 case Triple::nvptx64:
699 case Triple::nvptx:
700 case Triple::ppc64le:
701 case Triple::r600:
702 case Triple::renderscript32:
703 case Triple::renderscript64:
704 case Triple::riscv32:
705 case Triple::riscv64:
706 case Triple::shave:
707 case Triple::sparc:
708 case Triple::sparcel:
709 case Triple::sparcv9:
710 case Triple::spir64:
711 case Triple::spir:
712 case Triple::tce:
713 case Triple::tcele:
714 case Triple::thumbeb:
715 case Triple::ve:
716 case Triple::xcore:
717 return Triple::ELF;
718
719 case Triple::ppc64:
720 case Triple::ppc:
721 if (T.isOSAIX())
722 return Triple::XCOFF;
723 return Triple::ELF;
724
725 case Triple::systemz:
726 if (T.isOSzOS())
727 return Triple::GOFF;
728 return Triple::ELF;
729
730 case Triple::wasm32:
731 case Triple::wasm64:
732 return Triple::Wasm;
733 }
734 llvm_unreachable("unknown architecture");
735 }
736
737 /// Construct a triple from the string representation provided.
738 ///
739 /// This stores the string representation and parses the various pieces into
740 /// enum members.
Triple(const Twine & Str)741 Triple::Triple(const Twine &Str)
742 : Data(Str.str()), Arch(UnknownArch), SubArch(NoSubArch),
743 Vendor(UnknownVendor), OS(UnknownOS), Environment(UnknownEnvironment),
744 ObjectFormat(UnknownObjectFormat) {
745 // Do minimal parsing by hand here.
746 SmallVector<StringRef, 4> Components;
747 StringRef(Data).split(Components, '-', /*MaxSplit*/ 3);
748 if (Components.size() > 0) {
749 Arch = parseArch(Components[0]);
750 SubArch = parseSubArch(Components[0]);
751 if (Components.size() > 1) {
752 Vendor = parseVendor(Components[1]);
753 if (Components.size() > 2) {
754 OS = parseOS(Components[2]);
755 if (Components.size() > 3) {
756 Environment = parseEnvironment(Components[3]);
757 ObjectFormat = parseFormat(Components[3]);
758 }
759 }
760 } else {
761 Environment =
762 StringSwitch<Triple::EnvironmentType>(Components[0])
763 .StartsWith("mipsn32", Triple::GNUABIN32)
764 .StartsWith("mips64", Triple::GNUABI64)
765 .StartsWith("mipsisa64", Triple::GNUABI64)
766 .StartsWith("mipsisa32", Triple::GNU)
767 .Cases("mips", "mipsel", "mipsr6", "mipsr6el", Triple::GNU)
768 .Default(UnknownEnvironment);
769 }
770 }
771 if (ObjectFormat == UnknownObjectFormat)
772 ObjectFormat = getDefaultFormat(*this);
773 }
774
775 /// Construct a triple from string representations of the architecture,
776 /// vendor, and OS.
777 ///
778 /// This joins each argument into a canonical string representation and parses
779 /// them into enum members. It leaves the environment unknown and omits it from
780 /// the string representation.
Triple(const Twine & ArchStr,const Twine & VendorStr,const Twine & OSStr)781 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
782 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
783 Arch(parseArch(ArchStr.str())),
784 SubArch(parseSubArch(ArchStr.str())),
785 Vendor(parseVendor(VendorStr.str())),
786 OS(parseOS(OSStr.str())),
787 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
788 ObjectFormat = getDefaultFormat(*this);
789 }
790
791 /// Construct a triple from string representations of the architecture,
792 /// vendor, OS, and environment.
793 ///
794 /// This joins each argument into a canonical string representation and parses
795 /// them into enum members.
Triple(const Twine & ArchStr,const Twine & VendorStr,const Twine & OSStr,const Twine & EnvironmentStr)796 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
797 const Twine &EnvironmentStr)
798 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
799 EnvironmentStr).str()),
800 Arch(parseArch(ArchStr.str())),
801 SubArch(parseSubArch(ArchStr.str())),
802 Vendor(parseVendor(VendorStr.str())),
803 OS(parseOS(OSStr.str())),
804 Environment(parseEnvironment(EnvironmentStr.str())),
805 ObjectFormat(parseFormat(EnvironmentStr.str())) {
806 if (ObjectFormat == Triple::UnknownObjectFormat)
807 ObjectFormat = getDefaultFormat(*this);
808 }
809
normalize(StringRef Str)810 std::string Triple::normalize(StringRef Str) {
811 bool IsMinGW32 = false;
812 bool IsCygwin = false;
813
814 // Parse into components.
815 SmallVector<StringRef, 4> Components;
816 Str.split(Components, '-');
817
818 // If the first component corresponds to a known architecture, preferentially
819 // use it for the architecture. If the second component corresponds to a
820 // known vendor, preferentially use it for the vendor, etc. This avoids silly
821 // component movement when a component parses as (eg) both a valid arch and a
822 // valid os.
823 ArchType Arch = UnknownArch;
824 if (Components.size() > 0)
825 Arch = parseArch(Components[0]);
826 VendorType Vendor = UnknownVendor;
827 if (Components.size() > 1)
828 Vendor = parseVendor(Components[1]);
829 OSType OS = UnknownOS;
830 if (Components.size() > 2) {
831 OS = parseOS(Components[2]);
832 IsCygwin = Components[2].startswith("cygwin");
833 IsMinGW32 = Components[2].startswith("mingw");
834 }
835 EnvironmentType Environment = UnknownEnvironment;
836 if (Components.size() > 3)
837 Environment = parseEnvironment(Components[3]);
838 ObjectFormatType ObjectFormat = UnknownObjectFormat;
839 if (Components.size() > 4)
840 ObjectFormat = parseFormat(Components[4]);
841
842 // Note which components are already in their final position. These will not
843 // be moved.
844 bool Found[4];
845 Found[0] = Arch != UnknownArch;
846 Found[1] = Vendor != UnknownVendor;
847 Found[2] = OS != UnknownOS;
848 Found[3] = Environment != UnknownEnvironment;
849
850 // If they are not there already, permute the components into their canonical
851 // positions by seeing if they parse as a valid architecture, and if so moving
852 // the component to the architecture position etc.
853 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
854 if (Found[Pos])
855 continue; // Already in the canonical position.
856
857 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
858 // Do not reparse any components that already matched.
859 if (Idx < array_lengthof(Found) && Found[Idx])
860 continue;
861
862 // Does this component parse as valid for the target position?
863 bool Valid = false;
864 StringRef Comp = Components[Idx];
865 switch (Pos) {
866 default: llvm_unreachable("unexpected component type!");
867 case 0:
868 Arch = parseArch(Comp);
869 Valid = Arch != UnknownArch;
870 break;
871 case 1:
872 Vendor = parseVendor(Comp);
873 Valid = Vendor != UnknownVendor;
874 break;
875 case 2:
876 OS = parseOS(Comp);
877 IsCygwin = Comp.startswith("cygwin");
878 IsMinGW32 = Comp.startswith("mingw");
879 Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
880 break;
881 case 3:
882 Environment = parseEnvironment(Comp);
883 Valid = Environment != UnknownEnvironment;
884 if (!Valid) {
885 ObjectFormat = parseFormat(Comp);
886 Valid = ObjectFormat != UnknownObjectFormat;
887 }
888 break;
889 }
890 if (!Valid)
891 continue; // Nope, try the next component.
892
893 // Move the component to the target position, pushing any non-fixed
894 // components that are in the way to the right. This tends to give
895 // good results in the common cases of a forgotten vendor component
896 // or a wrongly positioned environment.
897 if (Pos < Idx) {
898 // Insert left, pushing the existing components to the right. For
899 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
900 StringRef CurrentComponent(""); // The empty component.
901 // Replace the component we are moving with an empty component.
902 std::swap(CurrentComponent, Components[Idx]);
903 // Insert the component being moved at Pos, displacing any existing
904 // components to the right.
905 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
906 // Skip over any fixed components.
907 while (i < array_lengthof(Found) && Found[i])
908 ++i;
909 // Place the component at the new position, getting the component
910 // that was at this position - it will be moved right.
911 std::swap(CurrentComponent, Components[i]);
912 }
913 } else if (Pos > Idx) {
914 // Push right by inserting empty components until the component at Idx
915 // reaches the target position Pos. For example, pc-a -> -pc-a when
916 // moving pc to the second position.
917 do {
918 // Insert one empty component at Idx.
919 StringRef CurrentComponent(""); // The empty component.
920 for (unsigned i = Idx; i < Components.size();) {
921 // Place the component at the new position, getting the component
922 // that was at this position - it will be moved right.
923 std::swap(CurrentComponent, Components[i]);
924 // If it was placed on top of an empty component then we are done.
925 if (CurrentComponent.empty())
926 break;
927 // Advance to the next component, skipping any fixed components.
928 while (++i < array_lengthof(Found) && Found[i])
929 ;
930 }
931 // The last component was pushed off the end - append it.
932 if (!CurrentComponent.empty())
933 Components.push_back(CurrentComponent);
934
935 // Advance Idx to the component's new position.
936 while (++Idx < array_lengthof(Found) && Found[Idx])
937 ;
938 } while (Idx < Pos); // Add more until the final position is reached.
939 }
940 assert(Pos < Components.size() && Components[Pos] == Comp &&
941 "Component moved wrong!");
942 Found[Pos] = true;
943 break;
944 }
945 }
946
947 // Replace empty components with "unknown" value.
948 for (unsigned i = 0, e = Components.size(); i < e; ++i) {
949 if (Components[i].empty())
950 Components[i] = "unknown";
951 }
952
953 // Special case logic goes here. At this point Arch, Vendor and OS have the
954 // correct values for the computed components.
955 std::string NormalizedEnvironment;
956 if (Environment == Triple::Android && Components[3].startswith("androideabi")) {
957 StringRef AndroidVersion = Components[3].drop_front(strlen("androideabi"));
958 if (AndroidVersion.empty()) {
959 Components[3] = "android";
960 } else {
961 NormalizedEnvironment = Twine("android", AndroidVersion).str();
962 Components[3] = NormalizedEnvironment;
963 }
964 }
965
966 // SUSE uses "gnueabi" to mean "gnueabihf"
967 if (Vendor == Triple::SUSE && Environment == llvm::Triple::GNUEABI)
968 Components[3] = "gnueabihf";
969
970 if (OS == Triple::Win32) {
971 Components.resize(4);
972 Components[2] = "windows";
973 if (Environment == UnknownEnvironment) {
974 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
975 Components[3] = "msvc";
976 else
977 Components[3] = getObjectFormatTypeName(ObjectFormat);
978 }
979 } else if (IsMinGW32) {
980 Components.resize(4);
981 Components[2] = "windows";
982 Components[3] = "gnu";
983 } else if (IsCygwin) {
984 Components.resize(4);
985 Components[2] = "windows";
986 Components[3] = "cygnus";
987 }
988 if (IsMinGW32 || IsCygwin ||
989 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
990 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
991 Components.resize(5);
992 Components[4] = getObjectFormatTypeName(ObjectFormat);
993 }
994 }
995
996 // Stick the corrected components back together to form the normalized string.
997 return join(Components, "-");
998 }
999
getArchName() const1000 StringRef Triple::getArchName() const {
1001 return StringRef(Data).split('-').first; // Isolate first component
1002 }
1003
getVendorName() const1004 StringRef Triple::getVendorName() const {
1005 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1006 return Tmp.split('-').first; // Isolate second component
1007 }
1008
getOSName() const1009 StringRef Triple::getOSName() const {
1010 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1011 Tmp = Tmp.split('-').second; // Strip second component
1012 return Tmp.split('-').first; // Isolate third component
1013 }
1014
getEnvironmentName() const1015 StringRef Triple::getEnvironmentName() const {
1016 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1017 Tmp = Tmp.split('-').second; // Strip second component
1018 return Tmp.split('-').second; // Strip third component
1019 }
1020
getOSAndEnvironmentName() const1021 StringRef Triple::getOSAndEnvironmentName() const {
1022 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
1023 return Tmp.split('-').second; // Strip second component
1024 }
1025
EatNumber(StringRef & Str)1026 static unsigned EatNumber(StringRef &Str) {
1027 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
1028 unsigned Result = 0;
1029
1030 do {
1031 // Consume the leading digit.
1032 Result = Result*10 + (Str[0] - '0');
1033
1034 // Eat the digit.
1035 Str = Str.substr(1);
1036 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
1037
1038 return Result;
1039 }
1040
parseVersionFromName(StringRef Name,unsigned & Major,unsigned & Minor,unsigned & Micro)1041 static void parseVersionFromName(StringRef Name, unsigned &Major,
1042 unsigned &Minor, unsigned &Micro) {
1043 // Any unset version defaults to 0.
1044 Major = Minor = Micro = 0;
1045
1046 // Parse up to three components.
1047 unsigned *Components[3] = {&Major, &Minor, &Micro};
1048 for (unsigned i = 0; i != 3; ++i) {
1049 if (Name.empty() || Name[0] < '0' || Name[0] > '9')
1050 break;
1051
1052 // Consume the leading number.
1053 *Components[i] = EatNumber(Name);
1054
1055 // Consume the separator, if present.
1056 if (Name.startswith("."))
1057 Name = Name.substr(1);
1058 }
1059 }
1060
getEnvironmentVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const1061 void Triple::getEnvironmentVersion(unsigned &Major, unsigned &Minor,
1062 unsigned &Micro) const {
1063 StringRef EnvironmentName = getEnvironmentName();
1064 StringRef EnvironmentTypeName = getEnvironmentTypeName(getEnvironment());
1065 if (EnvironmentName.startswith(EnvironmentTypeName))
1066 EnvironmentName = EnvironmentName.substr(EnvironmentTypeName.size());
1067
1068 parseVersionFromName(EnvironmentName, Major, Minor, Micro);
1069 }
1070
getOSVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const1071 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
1072 unsigned &Micro) const {
1073 StringRef OSName = getOSName();
1074 // Assume that the OS portion of the triple starts with the canonical name.
1075 StringRef OSTypeName = getOSTypeName(getOS());
1076 if (OSName.startswith(OSTypeName))
1077 OSName = OSName.substr(OSTypeName.size());
1078 else if (getOS() == MacOSX)
1079 OSName.consume_front("macos");
1080
1081 parseVersionFromName(OSName, Major, Minor, Micro);
1082 }
1083
getMacOSXVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const1084 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
1085 unsigned &Micro) const {
1086 getOSVersion(Major, Minor, Micro);
1087
1088 switch (getOS()) {
1089 default: llvm_unreachable("unexpected OS for Darwin triple");
1090 case Darwin:
1091 // Default to darwin8, i.e., MacOSX 10.4.
1092 if (Major == 0)
1093 Major = 8;
1094 // Darwin version numbers are skewed from OS X versions.
1095 if (Major < 4)
1096 return false;
1097 if (Major <= 19) {
1098 Micro = 0;
1099 Minor = Major - 4;
1100 Major = 10;
1101 } else {
1102 Micro = 0;
1103 Minor = 0;
1104 // darwin20+ corresponds to macOS 11+.
1105 Major = 11 + Major - 20;
1106 }
1107 break;
1108 case MacOSX:
1109 // Default to 10.4.
1110 if (Major == 0) {
1111 Major = 10;
1112 Minor = 4;
1113 } else if (Major < 10)
1114 return false;
1115 break;
1116 case IOS:
1117 case TvOS:
1118 case WatchOS:
1119 // Ignore the version from the triple. This is only handled because the
1120 // the clang driver combines OS X and IOS support into a common Darwin
1121 // toolchain that wants to know the OS X version number even when targeting
1122 // IOS.
1123 Major = 10;
1124 Minor = 4;
1125 Micro = 0;
1126 break;
1127 }
1128 return true;
1129 }
1130
getiOSVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const1131 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
1132 unsigned &Micro) const {
1133 switch (getOS()) {
1134 default: llvm_unreachable("unexpected OS for Darwin triple");
1135 case Darwin:
1136 case MacOSX:
1137 // Ignore the version from the triple. This is only handled because the
1138 // the clang driver combines OS X and IOS support into a common Darwin
1139 // toolchain that wants to know the iOS version number even when targeting
1140 // OS X.
1141 Major = 5;
1142 Minor = 0;
1143 Micro = 0;
1144 break;
1145 case IOS:
1146 case TvOS:
1147 getOSVersion(Major, Minor, Micro);
1148 // Default to 5.0 (or 7.0 for arm64).
1149 if (Major == 0)
1150 Major = (getArch() == aarch64) ? 7 : 5;
1151 break;
1152 case WatchOS:
1153 llvm_unreachable("conflicting triple info");
1154 }
1155 }
1156
getWatchOSVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const1157 void Triple::getWatchOSVersion(unsigned &Major, unsigned &Minor,
1158 unsigned &Micro) const {
1159 switch (getOS()) {
1160 default: llvm_unreachable("unexpected OS for Darwin triple");
1161 case Darwin:
1162 case MacOSX:
1163 // Ignore the version from the triple. This is only handled because the
1164 // the clang driver combines OS X and IOS support into a common Darwin
1165 // toolchain that wants to know the iOS version number even when targeting
1166 // OS X.
1167 Major = 2;
1168 Minor = 0;
1169 Micro = 0;
1170 break;
1171 case WatchOS:
1172 getOSVersion(Major, Minor, Micro);
1173 if (Major == 0)
1174 Major = 2;
1175 break;
1176 case IOS:
1177 llvm_unreachable("conflicting triple info");
1178 }
1179 }
1180
setTriple(const Twine & Str)1181 void Triple::setTriple(const Twine &Str) {
1182 *this = Triple(Str);
1183 }
1184
setArch(ArchType Kind)1185 void Triple::setArch(ArchType Kind) {
1186 setArchName(getArchTypeName(Kind));
1187 }
1188
setVendor(VendorType Kind)1189 void Triple::setVendor(VendorType Kind) {
1190 setVendorName(getVendorTypeName(Kind));
1191 }
1192
setOS(OSType Kind)1193 void Triple::setOS(OSType Kind) {
1194 setOSName(getOSTypeName(Kind));
1195 }
1196
setEnvironment(EnvironmentType Kind)1197 void Triple::setEnvironment(EnvironmentType Kind) {
1198 if (ObjectFormat == getDefaultFormat(*this))
1199 return setEnvironmentName(getEnvironmentTypeName(Kind));
1200
1201 setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
1202 getObjectFormatTypeName(ObjectFormat)).str());
1203 }
1204
setObjectFormat(ObjectFormatType Kind)1205 void Triple::setObjectFormat(ObjectFormatType Kind) {
1206 if (Environment == UnknownEnvironment)
1207 return setEnvironmentName(getObjectFormatTypeName(Kind));
1208
1209 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
1210 getObjectFormatTypeName(Kind)).str());
1211 }
1212
setArchName(StringRef Str)1213 void Triple::setArchName(StringRef Str) {
1214 // Work around a miscompilation bug for Twines in gcc 4.0.3.
1215 SmallString<64> Triple;
1216 Triple += Str;
1217 Triple += "-";
1218 Triple += getVendorName();
1219 Triple += "-";
1220 Triple += getOSAndEnvironmentName();
1221 setTriple(Triple);
1222 }
1223
setVendorName(StringRef Str)1224 void Triple::setVendorName(StringRef Str) {
1225 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
1226 }
1227
setOSName(StringRef Str)1228 void Triple::setOSName(StringRef Str) {
1229 if (hasEnvironment())
1230 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
1231 "-" + getEnvironmentName());
1232 else
1233 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
1234 }
1235
setEnvironmentName(StringRef Str)1236 void Triple::setEnvironmentName(StringRef Str) {
1237 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
1238 "-" + Str);
1239 }
1240
setOSAndEnvironmentName(StringRef Str)1241 void Triple::setOSAndEnvironmentName(StringRef Str) {
1242 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
1243 }
1244
getArchPointerBitWidth(llvm::Triple::ArchType Arch)1245 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
1246 switch (Arch) {
1247 case llvm::Triple::UnknownArch:
1248 return 0;
1249
1250 case llvm::Triple::avr:
1251 case llvm::Triple::msp430:
1252 return 16;
1253
1254 case llvm::Triple::aarch64_32:
1255 case llvm::Triple::amdil:
1256 case llvm::Triple::arc:
1257 case llvm::Triple::arm:
1258 case llvm::Triple::armeb:
1259 case llvm::Triple::csky:
1260 case llvm::Triple::hexagon:
1261 case llvm::Triple::hsail:
1262 case llvm::Triple::kalimba:
1263 case llvm::Triple::lanai:
1264 case llvm::Triple::le32:
1265 case llvm::Triple::mips:
1266 case llvm::Triple::mipsel:
1267 case llvm::Triple::nvptx:
1268 case llvm::Triple::ppc:
1269 case llvm::Triple::r600:
1270 case llvm::Triple::renderscript32:
1271 case llvm::Triple::riscv32:
1272 case llvm::Triple::shave:
1273 case llvm::Triple::sparc:
1274 case llvm::Triple::sparcel:
1275 case llvm::Triple::spir:
1276 case llvm::Triple::tce:
1277 case llvm::Triple::tcele:
1278 case llvm::Triple::thumb:
1279 case llvm::Triple::thumbeb:
1280 case llvm::Triple::wasm32:
1281 case llvm::Triple::x86:
1282 case llvm::Triple::xcore:
1283 return 32;
1284
1285 case llvm::Triple::aarch64:
1286 case llvm::Triple::aarch64_be:
1287 case llvm::Triple::amdgcn:
1288 case llvm::Triple::amdil64:
1289 case llvm::Triple::bpfeb:
1290 case llvm::Triple::bpfel:
1291 case llvm::Triple::hsail64:
1292 case llvm::Triple::le64:
1293 case llvm::Triple::mips64:
1294 case llvm::Triple::mips64el:
1295 case llvm::Triple::nvptx64:
1296 case llvm::Triple::ppc64:
1297 case llvm::Triple::ppc64le:
1298 case llvm::Triple::renderscript64:
1299 case llvm::Triple::riscv64:
1300 case llvm::Triple::sparcv9:
1301 case llvm::Triple::spir64:
1302 case llvm::Triple::systemz:
1303 case llvm::Triple::ve:
1304 case llvm::Triple::wasm64:
1305 case llvm::Triple::x86_64:
1306 return 64;
1307 }
1308 llvm_unreachable("Invalid architecture value");
1309 }
1310
isArch64Bit() const1311 bool Triple::isArch64Bit() const {
1312 return getArchPointerBitWidth(getArch()) == 64;
1313 }
1314
isArch32Bit() const1315 bool Triple::isArch32Bit() const {
1316 return getArchPointerBitWidth(getArch()) == 32;
1317 }
1318
isArch16Bit() const1319 bool Triple::isArch16Bit() const {
1320 return getArchPointerBitWidth(getArch()) == 16;
1321 }
1322
get32BitArchVariant() const1323 Triple Triple::get32BitArchVariant() const {
1324 Triple T(*this);
1325 switch (getArch()) {
1326 case Triple::UnknownArch:
1327 case Triple::amdgcn:
1328 case Triple::avr:
1329 case Triple::bpfeb:
1330 case Triple::bpfel:
1331 case Triple::msp430:
1332 case Triple::ppc64le:
1333 case Triple::systemz:
1334 case Triple::ve:
1335 T.setArch(UnknownArch);
1336 break;
1337
1338 case Triple::aarch64_32:
1339 case Triple::amdil:
1340 case Triple::arc:
1341 case Triple::arm:
1342 case Triple::armeb:
1343 case Triple::csky:
1344 case Triple::hexagon:
1345 case Triple::hsail:
1346 case Triple::kalimba:
1347 case Triple::lanai:
1348 case Triple::le32:
1349 case Triple::mips:
1350 case Triple::mipsel:
1351 case Triple::nvptx:
1352 case Triple::ppc:
1353 case Triple::r600:
1354 case Triple::renderscript32:
1355 case Triple::riscv32:
1356 case Triple::shave:
1357 case Triple::sparc:
1358 case Triple::sparcel:
1359 case Triple::spir:
1360 case Triple::tce:
1361 case Triple::tcele:
1362 case Triple::thumb:
1363 case Triple::thumbeb:
1364 case Triple::wasm32:
1365 case Triple::x86:
1366 case Triple::xcore:
1367 // Already 32-bit.
1368 break;
1369
1370 case Triple::aarch64: T.setArch(Triple::arm); break;
1371 case Triple::aarch64_be: T.setArch(Triple::armeb); break;
1372 case Triple::amdil64: T.setArch(Triple::amdil); break;
1373 case Triple::hsail64: T.setArch(Triple::hsail); break;
1374 case Triple::le64: T.setArch(Triple::le32); break;
1375 case Triple::mips64: T.setArch(Triple::mips); break;
1376 case Triple::mips64el: T.setArch(Triple::mipsel); break;
1377 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
1378 case Triple::ppc64: T.setArch(Triple::ppc); break;
1379 case Triple::renderscript64: T.setArch(Triple::renderscript32); break;
1380 case Triple::riscv64: T.setArch(Triple::riscv32); break;
1381 case Triple::sparcv9: T.setArch(Triple::sparc); break;
1382 case Triple::spir64: T.setArch(Triple::spir); break;
1383 case Triple::wasm64: T.setArch(Triple::wasm32); break;
1384 case Triple::x86_64: T.setArch(Triple::x86); break;
1385 }
1386 return T;
1387 }
1388
get64BitArchVariant() const1389 Triple Triple::get64BitArchVariant() const {
1390 Triple T(*this);
1391 switch (getArch()) {
1392 case Triple::UnknownArch:
1393 case Triple::arc:
1394 case Triple::avr:
1395 case Triple::csky:
1396 case Triple::hexagon:
1397 case Triple::kalimba:
1398 case Triple::lanai:
1399 case Triple::msp430:
1400 case Triple::r600:
1401 case Triple::shave:
1402 case Triple::sparcel:
1403 case Triple::tce:
1404 case Triple::tcele:
1405 case Triple::xcore:
1406 T.setArch(UnknownArch);
1407 break;
1408
1409 case Triple::aarch64:
1410 case Triple::aarch64_be:
1411 case Triple::amdgcn:
1412 case Triple::amdil64:
1413 case Triple::bpfeb:
1414 case Triple::bpfel:
1415 case Triple::hsail64:
1416 case Triple::le64:
1417 case Triple::mips64:
1418 case Triple::mips64el:
1419 case Triple::nvptx64:
1420 case Triple::ppc64:
1421 case Triple::ppc64le:
1422 case Triple::renderscript64:
1423 case Triple::riscv64:
1424 case Triple::sparcv9:
1425 case Triple::spir64:
1426 case Triple::systemz:
1427 case Triple::ve:
1428 case Triple::wasm64:
1429 case Triple::x86_64:
1430 // Already 64-bit.
1431 break;
1432
1433 case Triple::aarch64_32: T.setArch(Triple::aarch64); break;
1434 case Triple::amdil: T.setArch(Triple::amdil64); break;
1435 case Triple::arm: T.setArch(Triple::aarch64); break;
1436 case Triple::armeb: T.setArch(Triple::aarch64_be); break;
1437 case Triple::hsail: T.setArch(Triple::hsail64); break;
1438 case Triple::le32: T.setArch(Triple::le64); break;
1439 case Triple::mips: T.setArch(Triple::mips64); break;
1440 case Triple::mipsel: T.setArch(Triple::mips64el); break;
1441 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
1442 case Triple::ppc: T.setArch(Triple::ppc64); break;
1443 case Triple::renderscript32: T.setArch(Triple::renderscript64); break;
1444 case Triple::riscv32: T.setArch(Triple::riscv64); break;
1445 case Triple::sparc: T.setArch(Triple::sparcv9); break;
1446 case Triple::spir: T.setArch(Triple::spir64); break;
1447 case Triple::thumb: T.setArch(Triple::aarch64); break;
1448 case Triple::thumbeb: T.setArch(Triple::aarch64_be); break;
1449 case Triple::wasm32: T.setArch(Triple::wasm64); break;
1450 case Triple::x86: T.setArch(Triple::x86_64); break;
1451 }
1452 return T;
1453 }
1454
getBigEndianArchVariant() const1455 Triple Triple::getBigEndianArchVariant() const {
1456 Triple T(*this);
1457 // Already big endian.
1458 if (!isLittleEndian())
1459 return T;
1460 switch (getArch()) {
1461 case Triple::UnknownArch:
1462 case Triple::amdgcn:
1463 case Triple::amdil64:
1464 case Triple::amdil:
1465 case Triple::avr:
1466 case Triple::hexagon:
1467 case Triple::hsail64:
1468 case Triple::hsail:
1469 case Triple::kalimba:
1470 case Triple::le32:
1471 case Triple::le64:
1472 case Triple::msp430:
1473 case Triple::nvptx64:
1474 case Triple::nvptx:
1475 case Triple::r600:
1476 case Triple::renderscript32:
1477 case Triple::renderscript64:
1478 case Triple::riscv32:
1479 case Triple::riscv64:
1480 case Triple::shave:
1481 case Triple::spir64:
1482 case Triple::spir:
1483 case Triple::wasm32:
1484 case Triple::wasm64:
1485 case Triple::x86:
1486 case Triple::x86_64:
1487 case Triple::xcore:
1488 case Triple::ve:
1489 case Triple::csky:
1490
1491 // ARM is intentionally unsupported here, changing the architecture would
1492 // drop any arch suffixes.
1493 case Triple::arm:
1494 case Triple::thumb:
1495 T.setArch(UnknownArch);
1496 break;
1497
1498 case Triple::aarch64: T.setArch(Triple::aarch64_be); break;
1499 case Triple::bpfel: T.setArch(Triple::bpfeb); break;
1500 case Triple::mips64el:T.setArch(Triple::mips64); break;
1501 case Triple::mipsel: T.setArch(Triple::mips); break;
1502 case Triple::ppc64le: T.setArch(Triple::ppc64); break;
1503 case Triple::sparcel: T.setArch(Triple::sparc); break;
1504 case Triple::tcele: T.setArch(Triple::tce); break;
1505 default:
1506 llvm_unreachable("getBigEndianArchVariant: unknown triple.");
1507 }
1508 return T;
1509 }
1510
getLittleEndianArchVariant() const1511 Triple Triple::getLittleEndianArchVariant() const {
1512 Triple T(*this);
1513 if (isLittleEndian())
1514 return T;
1515
1516 switch (getArch()) {
1517 case Triple::UnknownArch:
1518 case Triple::lanai:
1519 case Triple::ppc:
1520 case Triple::sparcv9:
1521 case Triple::systemz:
1522
1523 // ARM is intentionally unsupported here, changing the architecture would
1524 // drop any arch suffixes.
1525 case Triple::armeb:
1526 case Triple::thumbeb:
1527 T.setArch(UnknownArch);
1528 break;
1529
1530 case Triple::aarch64_be: T.setArch(Triple::aarch64); break;
1531 case Triple::bpfeb: T.setArch(Triple::bpfel); break;
1532 case Triple::mips64: T.setArch(Triple::mips64el); break;
1533 case Triple::mips: T.setArch(Triple::mipsel); break;
1534 case Triple::ppc64: T.setArch(Triple::ppc64le); break;
1535 case Triple::sparc: T.setArch(Triple::sparcel); break;
1536 case Triple::tce: T.setArch(Triple::tcele); break;
1537 default:
1538 llvm_unreachable("getLittleEndianArchVariant: unknown triple.");
1539 }
1540 return T;
1541 }
1542
isLittleEndian() const1543 bool Triple::isLittleEndian() const {
1544 switch (getArch()) {
1545 case Triple::aarch64:
1546 case Triple::aarch64_32:
1547 case Triple::amdgcn:
1548 case Triple::amdil64:
1549 case Triple::amdil:
1550 case Triple::arm:
1551 case Triple::avr:
1552 case Triple::bpfel:
1553 case Triple::csky:
1554 case Triple::hexagon:
1555 case Triple::hsail64:
1556 case Triple::hsail:
1557 case Triple::kalimba:
1558 case Triple::le32:
1559 case Triple::le64:
1560 case Triple::mips64el:
1561 case Triple::mipsel:
1562 case Triple::msp430:
1563 case Triple::nvptx64:
1564 case Triple::nvptx:
1565 case Triple::ppc64le:
1566 case Triple::r600:
1567 case Triple::renderscript32:
1568 case Triple::renderscript64:
1569 case Triple::riscv32:
1570 case Triple::riscv64:
1571 case Triple::shave:
1572 case Triple::sparcel:
1573 case Triple::spir64:
1574 case Triple::spir:
1575 case Triple::tcele:
1576 case Triple::thumb:
1577 case Triple::ve:
1578 case Triple::wasm32:
1579 case Triple::wasm64:
1580 case Triple::x86:
1581 case Triple::x86_64:
1582 case Triple::xcore:
1583 return true;
1584 default:
1585 return false;
1586 }
1587 }
1588
isCompatibleWith(const Triple & Other) const1589 bool Triple::isCompatibleWith(const Triple &Other) const {
1590 // ARM and Thumb triples are compatible, if subarch, vendor and OS match.
1591 if ((getArch() == Triple::thumb && Other.getArch() == Triple::arm) ||
1592 (getArch() == Triple::arm && Other.getArch() == Triple::thumb) ||
1593 (getArch() == Triple::thumbeb && Other.getArch() == Triple::armeb) ||
1594 (getArch() == Triple::armeb && Other.getArch() == Triple::thumbeb)) {
1595 if (getVendor() == Triple::Apple)
1596 return getSubArch() == Other.getSubArch() &&
1597 getVendor() == Other.getVendor() && getOS() == Other.getOS();
1598 else
1599 return getSubArch() == Other.getSubArch() &&
1600 getVendor() == Other.getVendor() && getOS() == Other.getOS() &&
1601 getEnvironment() == Other.getEnvironment() &&
1602 getObjectFormat() == Other.getObjectFormat();
1603 }
1604
1605 // If vendor is apple, ignore the version number.
1606 if (getVendor() == Triple::Apple)
1607 return getArch() == Other.getArch() && getSubArch() == Other.getSubArch() &&
1608 getVendor() == Other.getVendor() && getOS() == Other.getOS();
1609
1610 return *this == Other;
1611 }
1612
merge(const Triple & Other) const1613 std::string Triple::merge(const Triple &Other) const {
1614 // If vendor is apple, pick the triple with the larger version number.
1615 if (getVendor() == Triple::Apple)
1616 if (Other.isOSVersionLT(*this))
1617 return str();
1618
1619 return Other.str();
1620 }
1621
isMacOSXVersionLT(unsigned Major,unsigned Minor,unsigned Micro) const1622 bool Triple::isMacOSXVersionLT(unsigned Major, unsigned Minor,
1623 unsigned Micro) const {
1624 assert(isMacOSX() && "Not an OS X triple!");
1625
1626 // If this is OS X, expect a sane version number.
1627 if (getOS() == Triple::MacOSX)
1628 return isOSVersionLT(Major, Minor, Micro);
1629
1630 // Otherwise, compare to the "Darwin" number.
1631 if (Major == 10) {
1632 return isOSVersionLT(Minor + 4, Micro, 0);
1633 } else {
1634 assert(Major >= 11 && "Unexpected major version");
1635 return isOSVersionLT(Major - 11 + 20, Minor, Micro);
1636 }
1637 }
1638
getMinimumSupportedOSVersion() const1639 VersionTuple Triple::getMinimumSupportedOSVersion() const {
1640 if (getVendor() != Triple::Apple || getArch() != Triple::aarch64)
1641 return VersionTuple();
1642 switch (getOS()) {
1643 case Triple::MacOSX:
1644 // ARM64 slice is supported starting from macOS 11.0+.
1645 return VersionTuple(11, 0, 0);
1646 case Triple::IOS:
1647 // ARM64 slice is supported starting from Mac Catalyst 14 (macOS 11).
1648 // ARM64 simulators are supported for iOS 14+.
1649 if (isMacCatalystEnvironment() || isSimulatorEnvironment())
1650 return VersionTuple(14, 0, 0);
1651 break;
1652 case Triple::TvOS:
1653 // ARM64 simulators are supported for tvOS 14+.
1654 if (isSimulatorEnvironment())
1655 return VersionTuple(14, 0, 0);
1656 break;
1657 case Triple::WatchOS:
1658 // ARM64 simulators are supported for watchOS 7+.
1659 if (isSimulatorEnvironment())
1660 return VersionTuple(7, 0, 0);
1661 break;
1662 default:
1663 break;
1664 }
1665 return VersionTuple();
1666 }
1667
getARMCPUForArch(StringRef MArch) const1668 StringRef Triple::getARMCPUForArch(StringRef MArch) const {
1669 if (MArch.empty())
1670 MArch = getArchName();
1671 MArch = ARM::getCanonicalArchName(MArch);
1672
1673 // Some defaults are forced.
1674 switch (getOS()) {
1675 case llvm::Triple::FreeBSD:
1676 case llvm::Triple::NetBSD:
1677 if (!MArch.empty() && MArch == "v6")
1678 return "arm1176jzf-s";
1679 break;
1680 case llvm::Triple::Win32:
1681 // FIXME: this is invalid for WindowsCE
1682 return "cortex-a9";
1683 case llvm::Triple::IOS:
1684 case llvm::Triple::MacOSX:
1685 case llvm::Triple::TvOS:
1686 case llvm::Triple::WatchOS:
1687 if (MArch == "v7k")
1688 return "cortex-a7";
1689 break;
1690 default:
1691 break;
1692 }
1693
1694 if (MArch.empty())
1695 return StringRef();
1696
1697 StringRef CPU = ARM::getDefaultCPU(MArch);
1698 if (!CPU.empty() && !CPU.equals("invalid"))
1699 return CPU;
1700
1701 // If no specific architecture version is requested, return the minimum CPU
1702 // required by the OS and environment.
1703 switch (getOS()) {
1704 case llvm::Triple::NetBSD:
1705 switch (getEnvironment()) {
1706 case llvm::Triple::EABI:
1707 case llvm::Triple::EABIHF:
1708 case llvm::Triple::GNUEABI:
1709 case llvm::Triple::GNUEABIHF:
1710 return "arm926ej-s";
1711 default:
1712 return "strongarm";
1713 }
1714 case llvm::Triple::NaCl:
1715 case llvm::Triple::OpenBSD:
1716 return "cortex-a8";
1717 default:
1718 switch (getEnvironment()) {
1719 case llvm::Triple::EABIHF:
1720 case llvm::Triple::GNUEABIHF:
1721 case llvm::Triple::MuslEABIHF:
1722 return "arm1176jzf-s";
1723 default:
1724 return "arm7tdmi";
1725 }
1726 }
1727
1728 llvm_unreachable("invalid arch name");
1729 }
1730
getCanonicalVersionForOS(OSType OSKind,const VersionTuple & Version)1731 VersionTuple Triple::getCanonicalVersionForOS(OSType OSKind,
1732 const VersionTuple &Version) {
1733 switch (OSKind) {
1734 case MacOSX:
1735 // macOS 10.16 is canonicalized to macOS 11.
1736 if (Version == VersionTuple(10, 16))
1737 return VersionTuple(11, 0);
1738 LLVM_FALLTHROUGH;
1739 default:
1740 return Version;
1741 }
1742 }
1743