1 //===--- Triple.cpp - Target triple helper class --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/Triple.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/Support/ErrorHandling.h"
18 const char *Triple::getArchTypeName(ArchType Kind) {
20 case UnknownArch: return "unknown";
22 case aarch64: return "aarch64";
23 case aarch64_be: return "aarch64_be";
24 case arm: return "arm";
25 case armeb: return "armeb";
26 case bpf: return "bpf";
27 case hexagon: return "hexagon";
28 case mips: return "mips";
29 case mipsel: return "mipsel";
30 case mips64: return "mips64";
31 case mips64el: return "mips64el";
32 case msp430: return "msp430";
33 case ppc64: return "powerpc64";
34 case ppc64le: return "powerpc64le";
35 case ppc: return "powerpc";
36 case r600: return "r600";
37 case amdgcn: return "amdgcn";
38 case sparc: return "sparc";
39 case sparcv9: return "sparcv9";
40 case systemz: return "s390x";
41 case tce: return "tce";
42 case thumb: return "thumb";
43 case thumbeb: return "thumbeb";
44 case x86: return "i386";
45 case x86_64: return "x86_64";
46 case xcore: return "xcore";
47 case nvptx: return "nvptx";
48 case nvptx64: return "nvptx64";
49 case le32: return "le32";
50 case le64: return "le64";
51 case amdil: return "amdil";
52 case amdil64: return "amdil64";
53 case hsail: return "hsail";
54 case hsail64: return "hsail64";
55 case spir: return "spir";
56 case spir64: return "spir64";
57 case kalimba: return "kalimba";
60 llvm_unreachable("Invalid ArchType!");
63 const char *Triple::getArchTypePrefix(ArchType Kind) {
69 case aarch64_be: return "aarch64";
74 case thumbeb: return "arm";
78 case ppc: return "ppc";
83 case mips64el: return "mips";
85 case hexagon: return "hexagon";
88 case r600: return "amdgpu";
90 case bpf: return "bpf";
93 case sparc: return "sparc";
95 case systemz: return "s390";
98 case x86_64: return "x86";
100 case xcore: return "xcore";
102 case nvptx: return "nvptx";
103 case nvptx64: return "nvptx";
105 case le32: return "le32";
106 case le64: return "le64";
109 case amdil64: return "amdil";
112 case hsail64: return "hsail";
115 case spir64: return "spir";
116 case kalimba: return "kalimba";
120 const char *Triple::getVendorTypeName(VendorType Kind) {
122 case UnknownVendor: return "unknown";
124 case Apple: return "apple";
125 case PC: return "pc";
126 case SCEI: return "scei";
127 case BGP: return "bgp";
128 case BGQ: return "bgq";
129 case Freescale: return "fsl";
130 case IBM: return "ibm";
131 case ImaginationTechnologies: return "img";
132 case MipsTechnologies: return "mti";
133 case NVIDIA: return "nvidia";
134 case CSR: return "csr";
137 llvm_unreachable("Invalid VendorType!");
140 const char *Triple::getOSTypeName(OSType Kind) {
142 case UnknownOS: return "unknown";
144 case CloudABI: return "cloudabi";
145 case Darwin: return "darwin";
146 case DragonFly: return "dragonfly";
147 case FreeBSD: return "freebsd";
148 case IOS: return "ios";
149 case KFreeBSD: return "kfreebsd";
150 case Linux: return "linux";
151 case Lv2: return "lv2";
152 case MacOSX: return "macosx";
153 case NetBSD: return "netbsd";
154 case OpenBSD: return "openbsd";
155 case Solaris: return "solaris";
156 case Win32: return "windows";
157 case Haiku: return "haiku";
158 case Minix: return "minix";
159 case RTEMS: return "rtems";
160 case NaCl: return "nacl";
161 case CNK: return "cnk";
162 case Bitrig: return "bitrig";
163 case AIX: return "aix";
164 case CUDA: return "cuda";
165 case NVCL: return "nvcl";
166 case AMDHSA: return "amdhsa";
167 case PS4: return "ps4";
170 llvm_unreachable("Invalid OSType");
173 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
175 case UnknownEnvironment: return "unknown";
176 case GNU: return "gnu";
177 case GNUEABIHF: return "gnueabihf";
178 case GNUEABI: return "gnueabi";
179 case GNUX32: return "gnux32";
180 case CODE16: return "code16";
181 case EABI: return "eabi";
182 case EABIHF: return "eabihf";
183 case Android: return "android";
184 case MSVC: return "msvc";
185 case Itanium: return "itanium";
186 case Cygnus: return "cygnus";
189 llvm_unreachable("Invalid EnvironmentType!");
192 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
193 return StringSwitch<Triple::ArchType>(Name)
194 .Case("aarch64", aarch64)
195 .Case("aarch64_be", aarch64_be)
196 .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
198 .Case("armeb", armeb)
201 .Case("mipsel", mipsel)
202 .Case("mips64", mips64)
203 .Case("mips64el", mips64el)
204 .Case("msp430", msp430)
205 .Case("ppc64", ppc64)
208 .Case("ppc64le", ppc64le)
210 .Case("amdgcn", amdgcn)
211 .Case("hexagon", hexagon)
212 .Case("sparc", sparc)
213 .Case("sparcv9", sparcv9)
214 .Case("systemz", systemz)
216 .Case("thumb", thumb)
217 .Case("thumbeb", thumbeb)
219 .Case("x86-64", x86_64)
220 .Case("xcore", xcore)
221 .Case("nvptx", nvptx)
222 .Case("nvptx64", nvptx64)
225 .Case("amdil", amdil)
226 .Case("amdil64", amdil64)
227 .Case("hsail", hsail)
228 .Case("hsail64", hsail64)
230 .Case("spir64", spir64)
231 .Case("kalimba", kalimba)
232 .Default(UnknownArch);
235 static Triple::ArchType parseARMArch(StringRef ArchName) {
236 size_t offset = StringRef::npos;
237 Triple::ArchType arch = Triple::UnknownArch;
238 bool isThumb = ArchName.startswith("thumb");
240 if (ArchName.equals("arm"))
242 if (ArchName.equals("armeb"))
243 return Triple::armeb;
244 if (ArchName.equals("thumb"))
245 return Triple::thumb;
246 if (ArchName.equals("thumbeb"))
247 return Triple::thumbeb;
248 if (ArchName.equals("arm64") || ArchName.equals("aarch64"))
249 return Triple::aarch64;
250 if (ArchName.equals("aarch64_be"))
251 return Triple::aarch64_be;
253 if (ArchName.startswith("armv")) {
255 if (ArchName.endswith("eb")) {
256 arch = Triple::armeb;
257 ArchName = ArchName.substr(0, ArchName.size() - 2);
260 } else if (ArchName.startswith("armebv")) {
262 arch = Triple::armeb;
263 } else if (ArchName.startswith("thumbv")) {
265 if (ArchName.endswith("eb")) {
266 arch = Triple::thumbeb;
267 ArchName = ArchName.substr(0, ArchName.size() - 2);
269 arch = Triple::thumb;
270 } else if (ArchName.startswith("thumbebv")) {
272 arch = Triple::thumbeb;
274 return StringSwitch<Triple::ArchType>(ArchName.substr(offset))
275 .Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch)
276 .Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch)
277 .Cases("v4", "v4t", arch)
278 .Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch)
279 .Cases("v6", "v6j", "v6k", "v6m", "v6sm", arch)
280 .Cases("v6t2", "v6z", "v6zk", arch)
281 .Cases("v7", "v7a", "v7em", "v7l", arch)
282 .Cases("v7m", "v7r", "v7s", arch)
283 .Cases("v8", "v8a", arch)
284 .Cases("v8.1", "v8.1a", arch)
285 .Default(Triple::UnknownArch);
288 static Triple::ArchType parseArch(StringRef ArchName) {
289 Triple::ArchType ARMArch(parseARMArch(ArchName));
291 return StringSwitch<Triple::ArchType>(ArchName)
292 .Cases("i386", "i486", "i586", "i686", Triple::x86)
293 // FIXME: Do we need to support these?
294 .Cases("i786", "i886", "i986", Triple::x86)
295 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
296 .Case("powerpc", Triple::ppc)
297 .Cases("powerpc64", "ppu", Triple::ppc64)
298 .Case("powerpc64le", Triple::ppc64le)
299 .Case("xscale", Triple::arm)
300 .Case("xscaleeb", Triple::armeb)
301 .StartsWith("arm", ARMArch)
302 .StartsWith("thumb", ARMArch)
303 .StartsWith("aarch64", ARMArch)
304 .Case("msp430", Triple::msp430)
305 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
306 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
307 .Cases("mips64", "mips64eb", Triple::mips64)
308 .Case("mips64el", Triple::mips64el)
309 .Case("r600", Triple::r600)
310 .Case("amdgcn", Triple::amdgcn)
311 .Case("bpf", Triple::bpf)
312 .Case("hexagon", Triple::hexagon)
313 .Case("s390x", Triple::systemz)
314 .Case("sparc", Triple::sparc)
315 .Cases("sparcv9", "sparc64", Triple::sparcv9)
316 .Case("tce", Triple::tce)
317 .Case("xcore", Triple::xcore)
318 .Case("nvptx", Triple::nvptx)
319 .Case("nvptx64", Triple::nvptx64)
320 .Case("le32", Triple::le32)
321 .Case("le64", Triple::le64)
322 .Case("amdil", Triple::amdil)
323 .Case("amdil64", Triple::amdil64)
324 .Case("hsail", Triple::hsail)
325 .Case("hsail64", Triple::hsail64)
326 .Case("spir", Triple::spir)
327 .Case("spir64", Triple::spir64)
328 .StartsWith("kalimba", Triple::kalimba)
329 .Default(Triple::UnknownArch);
332 static Triple::VendorType parseVendor(StringRef VendorName) {
333 return StringSwitch<Triple::VendorType>(VendorName)
334 .Case("apple", Triple::Apple)
335 .Case("pc", Triple::PC)
336 .Case("scei", Triple::SCEI)
337 .Case("bgp", Triple::BGP)
338 .Case("bgq", Triple::BGQ)
339 .Case("fsl", Triple::Freescale)
340 .Case("ibm", Triple::IBM)
341 .Case("img", Triple::ImaginationTechnologies)
342 .Case("mti", Triple::MipsTechnologies)
343 .Case("nvidia", Triple::NVIDIA)
344 .Case("csr", Triple::CSR)
345 .Default(Triple::UnknownVendor);
348 static Triple::OSType parseOS(StringRef OSName) {
349 return StringSwitch<Triple::OSType>(OSName)
350 .StartsWith("cloudabi", Triple::CloudABI)
351 .StartsWith("darwin", Triple::Darwin)
352 .StartsWith("dragonfly", Triple::DragonFly)
353 .StartsWith("freebsd", Triple::FreeBSD)
354 .StartsWith("ios", Triple::IOS)
355 .StartsWith("kfreebsd", Triple::KFreeBSD)
356 .StartsWith("linux", Triple::Linux)
357 .StartsWith("lv2", Triple::Lv2)
358 .StartsWith("macosx", Triple::MacOSX)
359 .StartsWith("netbsd", Triple::NetBSD)
360 .StartsWith("openbsd", Triple::OpenBSD)
361 .StartsWith("solaris", Triple::Solaris)
362 .StartsWith("win32", Triple::Win32)
363 .StartsWith("windows", Triple::Win32)
364 .StartsWith("haiku", Triple::Haiku)
365 .StartsWith("minix", Triple::Minix)
366 .StartsWith("rtems", Triple::RTEMS)
367 .StartsWith("nacl", Triple::NaCl)
368 .StartsWith("cnk", Triple::CNK)
369 .StartsWith("bitrig", Triple::Bitrig)
370 .StartsWith("aix", Triple::AIX)
371 .StartsWith("cuda", Triple::CUDA)
372 .StartsWith("nvcl", Triple::NVCL)
373 .StartsWith("amdhsa", Triple::AMDHSA)
374 .StartsWith("ps4", Triple::PS4)
375 .Default(Triple::UnknownOS);
378 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
379 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
380 .StartsWith("eabihf", Triple::EABIHF)
381 .StartsWith("eabi", Triple::EABI)
382 .StartsWith("gnueabihf", Triple::GNUEABIHF)
383 .StartsWith("gnueabi", Triple::GNUEABI)
384 .StartsWith("gnux32", Triple::GNUX32)
385 .StartsWith("code16", Triple::CODE16)
386 .StartsWith("gnu", Triple::GNU)
387 .StartsWith("android", Triple::Android)
388 .StartsWith("msvc", Triple::MSVC)
389 .StartsWith("itanium", Triple::Itanium)
390 .StartsWith("cygnus", Triple::Cygnus)
391 .Default(Triple::UnknownEnvironment);
394 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
395 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
396 .EndsWith("coff", Triple::COFF)
397 .EndsWith("elf", Triple::ELF)
398 .EndsWith("macho", Triple::MachO)
399 .Default(Triple::UnknownObjectFormat);
402 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
403 if (SubArchName.endswith("eb"))
404 SubArchName = SubArchName.substr(0, SubArchName.size() - 2);
406 return StringSwitch<Triple::SubArchType>(SubArchName)
407 .EndsWith("v8.1a", Triple::ARMSubArch_v8_1a)
408 .EndsWith("v8", Triple::ARMSubArch_v8)
409 .EndsWith("v8a", Triple::ARMSubArch_v8)
410 .EndsWith("v7", Triple::ARMSubArch_v7)
411 .EndsWith("v7a", Triple::ARMSubArch_v7)
412 .EndsWith("v7em", Triple::ARMSubArch_v7em)
413 .EndsWith("v7l", Triple::ARMSubArch_v7)
414 .EndsWith("v7m", Triple::ARMSubArch_v7m)
415 .EndsWith("v7r", Triple::ARMSubArch_v7)
416 .EndsWith("v7s", Triple::ARMSubArch_v7s)
417 .EndsWith("v6", Triple::ARMSubArch_v6)
418 .EndsWith("v6m", Triple::ARMSubArch_v6m)
419 .EndsWith("v6sm", Triple::ARMSubArch_v6m)
420 .EndsWith("v6k", Triple::ARMSubArch_v6k)
421 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
422 .EndsWith("v5", Triple::ARMSubArch_v5)
423 .EndsWith("v5e", Triple::ARMSubArch_v5)
424 .EndsWith("v5t", Triple::ARMSubArch_v5)
425 .EndsWith("v5te", Triple::ARMSubArch_v5te)
426 .EndsWith("v4t", Triple::ARMSubArch_v4t)
427 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3)
428 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4)
429 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5)
430 .Default(Triple::NoSubArch);
433 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
435 case Triple::UnknownObjectFormat: return "";
436 case Triple::COFF: return "coff";
437 case Triple::ELF: return "elf";
438 case Triple::MachO: return "macho";
440 llvm_unreachable("unknown object format type");
443 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
444 switch (T.getArch()) {
447 case Triple::hexagon:
451 case Triple::mips64el:
455 case Triple::sparcv9:
456 case Triple::systemz:
458 case Triple::ppc64le:
464 return Triple::MachO;
469 return Triple::MachO;
470 else if (T.isOSWindows())
475 /// \brief Construct a triple from the string representation provided.
477 /// This stores the string representation and parses the various pieces into
479 Triple::Triple(const Twine &Str)
481 Arch(parseArch(getArchName())),
482 SubArch(parseSubArch(getArchName())),
483 Vendor(parseVendor(getVendorName())),
484 OS(parseOS(getOSName())),
485 Environment(parseEnvironment(getEnvironmentName())),
486 ObjectFormat(parseFormat(getEnvironmentName())) {
487 if (ObjectFormat == Triple::UnknownObjectFormat)
488 ObjectFormat = getDefaultFormat(*this);
491 /// \brief Construct a triple from string representations of the architecture,
494 /// This joins each argument into a canonical string representation and parses
495 /// them into enum members. It leaves the environment unknown and omits it from
496 /// the string representation.
497 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
498 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
499 Arch(parseArch(ArchStr.str())),
500 SubArch(parseSubArch(ArchStr.str())),
501 Vendor(parseVendor(VendorStr.str())),
502 OS(parseOS(OSStr.str())),
503 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
504 ObjectFormat = getDefaultFormat(*this);
507 /// \brief Construct a triple from string representations of the architecture,
508 /// vendor, OS, and environment.
510 /// This joins each argument into a canonical string representation and parses
511 /// them into enum members.
512 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
513 const Twine &EnvironmentStr)
514 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
515 EnvironmentStr).str()),
516 Arch(parseArch(ArchStr.str())),
517 SubArch(parseSubArch(ArchStr.str())),
518 Vendor(parseVendor(VendorStr.str())),
519 OS(parseOS(OSStr.str())),
520 Environment(parseEnvironment(EnvironmentStr.str())),
521 ObjectFormat(parseFormat(EnvironmentStr.str())) {
522 if (ObjectFormat == Triple::UnknownObjectFormat)
523 ObjectFormat = getDefaultFormat(*this);
526 std::string Triple::normalize(StringRef Str) {
527 bool IsMinGW32 = false;
528 bool IsCygwin = false;
530 // Parse into components.
531 SmallVector<StringRef, 4> Components;
532 Str.split(Components, "-");
534 // If the first component corresponds to a known architecture, preferentially
535 // use it for the architecture. If the second component corresponds to a
536 // known vendor, preferentially use it for the vendor, etc. This avoids silly
537 // component movement when a component parses as (eg) both a valid arch and a
539 ArchType Arch = UnknownArch;
540 if (Components.size() > 0)
541 Arch = parseArch(Components[0]);
542 VendorType Vendor = UnknownVendor;
543 if (Components.size() > 1)
544 Vendor = parseVendor(Components[1]);
545 OSType OS = UnknownOS;
546 if (Components.size() > 2) {
547 OS = parseOS(Components[2]);
548 IsCygwin = Components[2].startswith("cygwin");
549 IsMinGW32 = Components[2].startswith("mingw");
551 EnvironmentType Environment = UnknownEnvironment;
552 if (Components.size() > 3)
553 Environment = parseEnvironment(Components[3]);
554 ObjectFormatType ObjectFormat = UnknownObjectFormat;
555 if (Components.size() > 4)
556 ObjectFormat = parseFormat(Components[4]);
558 // Note which components are already in their final position. These will not
561 Found[0] = Arch != UnknownArch;
562 Found[1] = Vendor != UnknownVendor;
563 Found[2] = OS != UnknownOS;
564 Found[3] = Environment != UnknownEnvironment;
566 // If they are not there already, permute the components into their canonical
567 // positions by seeing if they parse as a valid architecture, and if so moving
568 // the component to the architecture position etc.
569 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
571 continue; // Already in the canonical position.
573 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
574 // Do not reparse any components that already matched.
575 if (Idx < array_lengthof(Found) && Found[Idx])
578 // Does this component parse as valid for the target position?
580 StringRef Comp = Components[Idx];
582 default: llvm_unreachable("unexpected component type!");
584 Arch = parseArch(Comp);
585 Valid = Arch != UnknownArch;
588 Vendor = parseVendor(Comp);
589 Valid = Vendor != UnknownVendor;
593 IsCygwin = Comp.startswith("cygwin");
594 IsMinGW32 = Comp.startswith("mingw");
595 Valid = OS != UnknownOS || IsCygwin || IsMinGW32;
598 Environment = parseEnvironment(Comp);
599 Valid = Environment != UnknownEnvironment;
601 ObjectFormat = parseFormat(Comp);
602 Valid = ObjectFormat != UnknownObjectFormat;
607 continue; // Nope, try the next component.
609 // Move the component to the target position, pushing any non-fixed
610 // components that are in the way to the right. This tends to give
611 // good results in the common cases of a forgotten vendor component
612 // or a wrongly positioned environment.
614 // Insert left, pushing the existing components to the right. For
615 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
616 StringRef CurrentComponent(""); // The empty component.
617 // Replace the component we are moving with an empty component.
618 std::swap(CurrentComponent, Components[Idx]);
619 // Insert the component being moved at Pos, displacing any existing
620 // components to the right.
621 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
622 // Skip over any fixed components.
623 while (i < array_lengthof(Found) && Found[i])
625 // Place the component at the new position, getting the component
626 // that was at this position - it will be moved right.
627 std::swap(CurrentComponent, Components[i]);
629 } else if (Pos > Idx) {
630 // Push right by inserting empty components until the component at Idx
631 // reaches the target position Pos. For example, pc-a -> -pc-a when
632 // moving pc to the second position.
634 // Insert one empty component at Idx.
635 StringRef CurrentComponent(""); // The empty component.
636 for (unsigned i = Idx; i < Components.size();) {
637 // Place the component at the new position, getting the component
638 // that was at this position - it will be moved right.
639 std::swap(CurrentComponent, Components[i]);
640 // If it was placed on top of an empty component then we are done.
641 if (CurrentComponent.empty())
643 // Advance to the next component, skipping any fixed components.
644 while (++i < array_lengthof(Found) && Found[i])
647 // The last component was pushed off the end - append it.
648 if (!CurrentComponent.empty())
649 Components.push_back(CurrentComponent);
651 // Advance Idx to the component's new position.
652 while (++Idx < array_lengthof(Found) && Found[Idx])
654 } while (Idx < Pos); // Add more until the final position is reached.
656 assert(Pos < Components.size() && Components[Pos] == Comp &&
657 "Component moved wrong!");
663 // Special case logic goes here. At this point Arch, Vendor and OS have the
664 // correct values for the computed components.
666 if (OS == Triple::Win32) {
667 Components.resize(4);
668 Components[2] = "windows";
669 if (Environment == UnknownEnvironment) {
670 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
671 Components[3] = "msvc";
673 Components[3] = getObjectFormatTypeName(ObjectFormat);
675 } else if (IsMinGW32) {
676 Components.resize(4);
677 Components[2] = "windows";
678 Components[3] = "gnu";
679 } else if (IsCygwin) {
680 Components.resize(4);
681 Components[2] = "windows";
682 Components[3] = "cygnus";
684 if (IsMinGW32 || IsCygwin ||
685 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
686 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
687 Components.resize(5);
688 Components[4] = getObjectFormatTypeName(ObjectFormat);
692 // Stick the corrected components back together to form the normalized string.
693 std::string Normalized;
694 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
695 if (i) Normalized += '-';
696 Normalized += Components[i];
701 StringRef Triple::getArchName() const {
702 return StringRef(Data).split('-').first; // Isolate first component
705 StringRef Triple::getVendorName() const {
706 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
707 return Tmp.split('-').first; // Isolate second component
710 StringRef Triple::getOSName() const {
711 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
712 Tmp = Tmp.split('-').second; // Strip second component
713 return Tmp.split('-').first; // Isolate third component
716 StringRef Triple::getEnvironmentName() const {
717 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
718 Tmp = Tmp.split('-').second; // Strip second component
719 return Tmp.split('-').second; // Strip third component
722 StringRef Triple::getOSAndEnvironmentName() const {
723 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
724 return Tmp.split('-').second; // Strip second component
727 static unsigned EatNumber(StringRef &Str) {
728 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
732 // Consume the leading digit.
733 Result = Result*10 + (Str[0] - '0');
737 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
742 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
743 unsigned &Micro) const {
744 StringRef OSName = getOSName();
746 // For Android, we care about the Android version rather than the Linux
748 if (getEnvironment() == Android) {
749 OSName = getEnvironmentName().substr(strlen("android"));
750 if (OSName.startswith("eabi"))
751 OSName = OSName.substr(strlen("eabi"));
754 // Assume that the OS portion of the triple starts with the canonical name.
755 StringRef OSTypeName = getOSTypeName(getOS());
756 if (OSName.startswith(OSTypeName))
757 OSName = OSName.substr(OSTypeName.size());
759 // Any unset version defaults to 0.
760 Major = Minor = Micro = 0;
762 // Parse up to three components.
763 unsigned *Components[3] = { &Major, &Minor, &Micro };
764 for (unsigned i = 0; i != 3; ++i) {
765 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
768 // Consume the leading number.
769 *Components[i] = EatNumber(OSName);
771 // Consume the separator, if present.
772 if (OSName.startswith("."))
773 OSName = OSName.substr(1);
777 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
778 unsigned &Micro) const {
779 getOSVersion(Major, Minor, Micro);
782 default: llvm_unreachable("unexpected OS for Darwin triple");
784 // Default to darwin8, i.e., MacOSX 10.4.
787 // Darwin version numbers are skewed from OS X versions.
804 // Ignore the version from the triple. This is only handled because the
805 // the clang driver combines OS X and IOS support into a common Darwin
806 // toolchain that wants to know the OS X version number even when targeting
816 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
817 unsigned &Micro) const {
819 default: llvm_unreachable("unexpected OS for Darwin triple");
822 // Ignore the version from the triple. This is only handled because the
823 // the clang driver combines OS X and IOS support into a common Darwin
824 // toolchain that wants to know the iOS version number even when targeting
831 getOSVersion(Major, Minor, Micro);
832 // Default to 5.0 (or 7.0 for arm64).
834 Major = (getArch() == aarch64) ? 7 : 5;
839 void Triple::setTriple(const Twine &Str) {
843 void Triple::setArch(ArchType Kind) {
844 setArchName(getArchTypeName(Kind));
847 void Triple::setVendor(VendorType Kind) {
848 setVendorName(getVendorTypeName(Kind));
851 void Triple::setOS(OSType Kind) {
852 setOSName(getOSTypeName(Kind));
855 void Triple::setEnvironment(EnvironmentType Kind) {
856 if (ObjectFormat == getDefaultFormat(*this))
857 return setEnvironmentName(getEnvironmentTypeName(Kind));
859 setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
860 getObjectFormatTypeName(ObjectFormat)).str());
863 void Triple::setObjectFormat(ObjectFormatType Kind) {
864 if (Environment == UnknownEnvironment)
865 return setEnvironmentName(getObjectFormatTypeName(Kind));
867 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
868 getObjectFormatTypeName(Kind)).str());
871 void Triple::setArchName(StringRef Str) {
872 // Work around a miscompilation bug for Twines in gcc 4.0.3.
873 SmallString<64> Triple;
876 Triple += getVendorName();
878 Triple += getOSAndEnvironmentName();
882 void Triple::setVendorName(StringRef Str) {
883 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
886 void Triple::setOSName(StringRef Str) {
887 if (hasEnvironment())
888 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
889 "-" + getEnvironmentName());
891 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
894 void Triple::setEnvironmentName(StringRef Str) {
895 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
899 void Triple::setOSAndEnvironmentName(StringRef Str) {
900 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
903 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
905 case llvm::Triple::UnknownArch:
908 case llvm::Triple::msp430:
911 case llvm::Triple::arm:
912 case llvm::Triple::armeb:
913 case llvm::Triple::hexagon:
914 case llvm::Triple::le32:
915 case llvm::Triple::mips:
916 case llvm::Triple::mipsel:
917 case llvm::Triple::nvptx:
918 case llvm::Triple::ppc:
919 case llvm::Triple::r600:
920 case llvm::Triple::sparc:
921 case llvm::Triple::tce:
922 case llvm::Triple::thumb:
923 case llvm::Triple::thumbeb:
924 case llvm::Triple::x86:
925 case llvm::Triple::xcore:
926 case llvm::Triple::amdil:
927 case llvm::Triple::hsail:
928 case llvm::Triple::spir:
929 case llvm::Triple::kalimba:
932 case llvm::Triple::aarch64:
933 case llvm::Triple::aarch64_be:
934 case llvm::Triple::amdgcn:
935 case llvm::Triple::bpf:
936 case llvm::Triple::le64:
937 case llvm::Triple::mips64:
938 case llvm::Triple::mips64el:
939 case llvm::Triple::nvptx64:
940 case llvm::Triple::ppc64:
941 case llvm::Triple::ppc64le:
942 case llvm::Triple::sparcv9:
943 case llvm::Triple::systemz:
944 case llvm::Triple::x86_64:
945 case llvm::Triple::amdil64:
946 case llvm::Triple::hsail64:
947 case llvm::Triple::spir64:
950 llvm_unreachable("Invalid architecture value");
953 bool Triple::isArch64Bit() const {
954 return getArchPointerBitWidth(getArch()) == 64;
957 bool Triple::isArch32Bit() const {
958 return getArchPointerBitWidth(getArch()) == 32;
961 bool Triple::isArch16Bit() const {
962 return getArchPointerBitWidth(getArch()) == 16;
965 Triple Triple::get32BitArchVariant() const {
968 case Triple::UnknownArch:
969 case Triple::aarch64:
970 case Triple::aarch64_be:
974 case Triple::systemz:
975 case Triple::ppc64le:
976 T.setArch(UnknownArch);
984 case Triple::hexagon:
985 case Triple::kalimba:
995 case Triple::thumbeb:
1001 case Triple::le64: T.setArch(Triple::le32); break;
1002 case Triple::mips64: T.setArch(Triple::mips); break;
1003 case Triple::mips64el: T.setArch(Triple::mipsel); break;
1004 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
1005 case Triple::ppc64: T.setArch(Triple::ppc); break;
1006 case Triple::sparcv9: T.setArch(Triple::sparc); break;
1007 case Triple::x86_64: T.setArch(Triple::x86); break;
1008 case Triple::amdil64: T.setArch(Triple::amdil); break;
1009 case Triple::hsail64: T.setArch(Triple::hsail); break;
1010 case Triple::spir64: T.setArch(Triple::spir); break;
1015 Triple Triple::get64BitArchVariant() const {
1017 switch (getArch()) {
1018 case Triple::UnknownArch:
1021 case Triple::hexagon:
1022 case Triple::kalimba:
1023 case Triple::msp430:
1027 case Triple::thumbeb:
1029 T.setArch(UnknownArch);
1032 case Triple::aarch64:
1033 case Triple::aarch64_be:
1036 case Triple::amdil64:
1037 case Triple::amdgcn:
1038 case Triple::hsail64:
1039 case Triple::spir64:
1040 case Triple::mips64:
1041 case Triple::mips64el:
1042 case Triple::nvptx64:
1044 case Triple::ppc64le:
1045 case Triple::sparcv9:
1046 case Triple::systemz:
1047 case Triple::x86_64:
1051 case Triple::le32: T.setArch(Triple::le64); break;
1052 case Triple::mips: T.setArch(Triple::mips64); break;
1053 case Triple::mipsel: T.setArch(Triple::mips64el); break;
1054 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
1055 case Triple::ppc: T.setArch(Triple::ppc64); break;
1056 case Triple::sparc: T.setArch(Triple::sparcv9); break;
1057 case Triple::x86: T.setArch(Triple::x86_64); break;
1058 case Triple::amdil: T.setArch(Triple::amdil64); break;
1059 case Triple::hsail: T.setArch(Triple::hsail64); break;
1060 case Triple::spir: T.setArch(Triple::spir64); break;
1065 // FIXME: tblgen this.
1066 const char *Triple::getARMCPUForArch(StringRef MArch) const {
1068 MArch = getArchName();
1071 case llvm::Triple::FreeBSD:
1072 case llvm::Triple::NetBSD:
1073 if (MArch == "armv6")
1074 return "arm1176jzf-s";
1076 case llvm::Triple::Win32:
1077 // FIXME: this is invalid for WindowsCE
1083 const char *result = nullptr;
1084 size_t offset = StringRef::npos;
1085 if (MArch.startswith("arm"))
1087 if (MArch.startswith("thumb"))
1089 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
1091 if (MArch.endswith("eb"))
1092 MArch = MArch.substr(0, MArch.size() - 2);
1093 if (offset != StringRef::npos)
1094 result = llvm::StringSwitch<const char *>(MArch.substr(offset))
1095 .Cases("v2", "v2a", "arm2")
1097 .Case("v3m", "arm7m")
1098 .Case("v4", "strongarm")
1099 .Case("v4t", "arm7tdmi")
1100 .Cases("v5", "v5t", "arm10tdmi")
1101 .Cases("v5e", "v5te", "arm1022e")
1102 .Case("v5tej", "arm926ej-s")
1103 .Case("v6", "arm1136jf-s")
1104 .Case("v6j", "arm1136j-s")
1105 .Cases("v6k", "v6z", "v6zk", "arm1176jzf-s")
1106 .Case("v6t2", "arm1156t2-s")
1107 .Cases("v6m", "v6-m", "v6sm", "v6s-m", "cortex-m0")
1108 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
1109 .Cases("v7s", "v7-s", "swift")
1110 .Cases("v7r", "v7-r", "cortex-r4")
1111 .Cases("v7m", "v7-m", "cortex-m3")
1112 .Cases("v7em", "v7e-m", "cortex-m4")
1113 .Cases("v8", "v8a", "v8-a", "cortex-a53")
1114 .Cases("v8.1a", "v8.1-a", "generic")
1117 result = llvm::StringSwitch<const char *>(MArch)
1118 .Case("ep9312", "ep9312")
1119 .Case("iwmmxt", "iwmmxt")
1120 .Case("xscale", "xscale")
1126 // If all else failed, return the most base CPU with thumb interworking
1127 // supported by LLVM.
1128 // FIXME: Should warn once that we're falling back.
1130 case llvm::Triple::NetBSD:
1131 switch (getEnvironment()) {
1132 case llvm::Triple::GNUEABIHF:
1133 case llvm::Triple::GNUEABI:
1134 case llvm::Triple::EABIHF:
1135 case llvm::Triple::EABI:
1136 return "arm926ej-s";
1140 case llvm::Triple::NaCl:
1143 switch (getEnvironment()) {
1144 case llvm::Triple::EABIHF:
1145 case llvm::Triple::GNUEABIHF:
1146 return "arm1176jzf-s";