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 hexagon: return "hexagon";
27 case mips: return "mips";
28 case mipsel: return "mipsel";
29 case mips64: return "mips64";
30 case mips64el: return "mips64el";
31 case msp430: return "msp430";
32 case ppc64: return "powerpc64";
33 case ppc64le: return "powerpc64le";
34 case ppc: return "powerpc";
35 case r600: return "r600";
36 case sparc: return "sparc";
37 case sparcv9: return "sparcv9";
38 case systemz: return "s390x";
39 case tce: return "tce";
40 case thumb: return "thumb";
41 case thumbeb: return "thumbeb";
42 case x86: return "i386";
43 case x86_64: return "x86_64";
44 case xcore: return "xcore";
45 case nvptx: return "nvptx";
46 case nvptx64: return "nvptx64";
47 case le32: return "le32";
48 case amdil: return "amdil";
49 case spir: return "spir";
50 case spir64: return "spir64";
51 case kalimba: return "kalimba";
54 llvm_unreachable("Invalid ArchType!");
57 const char *Triple::getArchTypePrefix(ArchType Kind) {
63 case aarch64_be: return "aarch64";
68 case thumbeb: return "arm";
72 case ppc: return "ppc";
77 case mips64el: return "mips";
79 case hexagon: return "hexagon";
81 case r600: return "r600";
84 case sparc: return "sparc";
86 case systemz: return "systemz";
89 case x86_64: return "x86";
91 case xcore: return "xcore";
93 case nvptx: return "nvptx";
94 case nvptx64: return "nvptx";
96 case le32: return "le32";
97 case amdil: return "amdil";
98 case spir: return "spir";
99 case spir64: return "spir";
100 case kalimba: return "kalimba";
104 const char *Triple::getVendorTypeName(VendorType Kind) {
106 case UnknownVendor: return "unknown";
108 case Apple: return "apple";
109 case PC: return "pc";
110 case SCEI: return "scei";
111 case BGP: return "bgp";
112 case BGQ: return "bgq";
113 case Freescale: return "fsl";
114 case IBM: return "ibm";
115 case ImaginationTechnologies: return "img";
116 case MipsTechnologies: return "mti";
117 case NVIDIA: return "nvidia";
118 case CSR: return "csr";
121 llvm_unreachable("Invalid VendorType!");
124 const char *Triple::getOSTypeName(OSType Kind) {
126 case UnknownOS: return "unknown";
128 case AuroraUX: return "auroraux";
129 case Cygwin: return "cygwin";
130 case Darwin: return "darwin";
131 case DragonFly: return "dragonfly";
132 case FreeBSD: return "freebsd";
133 case IOS: return "ios";
134 case KFreeBSD: return "kfreebsd";
135 case Linux: return "linux";
136 case Lv2: return "lv2";
137 case MacOSX: return "macosx";
138 case MinGW32: return "mingw32";
139 case NetBSD: return "netbsd";
140 case OpenBSD: return "openbsd";
141 case Solaris: return "solaris";
142 case Win32: return "windows";
143 case Haiku: return "haiku";
144 case Minix: return "minix";
145 case RTEMS: return "rtems";
146 case NaCl: return "nacl";
147 case CNK: return "cnk";
148 case Bitrig: return "bitrig";
149 case AIX: return "aix";
150 case CUDA: return "cuda";
151 case NVCL: return "nvcl";
154 llvm_unreachable("Invalid OSType");
157 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
159 case UnknownEnvironment: return "unknown";
160 case GNU: return "gnu";
161 case GNUEABIHF: return "gnueabihf";
162 case GNUEABI: return "gnueabi";
163 case GNUX32: return "gnux32";
164 case CODE16: return "code16";
165 case EABI: return "eabi";
166 case EABIHF: return "eabihf";
167 case Android: return "android";
168 case MSVC: return "msvc";
169 case Itanium: return "itanium";
170 case Cygnus: return "cygnus";
173 llvm_unreachable("Invalid EnvironmentType!");
176 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
177 return StringSwitch<Triple::ArchType>(Name)
178 .Case("aarch64", aarch64)
179 .Case("aarch64_be", aarch64_be)
180 .Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
182 .Case("armeb", armeb)
184 .Case("mipsel", mipsel)
185 .Case("mips64", mips64)
186 .Case("mips64el", mips64el)
187 .Case("msp430", msp430)
188 .Case("ppc64", ppc64)
191 .Case("ppc64le", ppc64le)
193 .Case("hexagon", hexagon)
194 .Case("sparc", sparc)
195 .Case("sparcv9", sparcv9)
196 .Case("systemz", systemz)
198 .Case("thumb", thumb)
199 .Case("thumbeb", thumbeb)
201 .Case("x86-64", x86_64)
202 .Case("xcore", xcore)
203 .Case("nvptx", nvptx)
204 .Case("nvptx64", nvptx64)
206 .Case("amdil", amdil)
208 .Case("spir64", spir64)
209 .Case("kalimba", kalimba)
210 .Default(UnknownArch);
213 // Returns architecture name that is understood by the target assembler.
214 const char *Triple::getArchNameForAssembler() {
215 if (!isOSDarwin() && getVendor() != Triple::Apple)
218 return StringSwitch<const char*>(getArchName())
219 .Case("i386", "i386")
220 .Case("x86_64", "x86_64")
221 .Case("powerpc", "ppc")
222 .Case("powerpc64", "ppc64")
223 .Case("powerpc64le", "ppc64le")
225 .Cases("armv4t", "thumbv4t", "armv4t")
226 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
227 .Cases("armv6", "thumbv6", "armv6")
228 .Cases("armv7", "thumbv7", "armv7")
229 .Case("armeb", "armeb")
230 .Case("arm64", "arm64")
231 .Case("r600", "r600")
232 .Case("nvptx", "nvptx")
233 .Case("nvptx64", "nvptx64")
234 .Case("le32", "le32")
235 .Case("amdil", "amdil")
236 .Case("spir", "spir")
237 .Case("spir64", "spir64")
241 static Triple::ArchType parseArch(StringRef ArchName) {
242 return StringSwitch<Triple::ArchType>(ArchName)
243 .Cases("i386", "i486", "i586", "i686", Triple::x86)
244 // FIXME: Do we need to support these?
245 .Cases("i786", "i886", "i986", Triple::x86)
246 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
247 .Case("powerpc", Triple::ppc)
248 .Cases("powerpc64", "ppu", Triple::ppc64)
249 .Case("powerpc64le", Triple::ppc64le)
250 .Case("aarch64", Triple::aarch64)
251 .Case("aarch64_be", Triple::aarch64_be)
252 .Case("arm64", Triple::aarch64)
253 .Cases("arm", "xscale", Triple::arm)
254 // FIXME: It would be good to replace these with explicit names for all the
255 // various suffixes supported.
256 .StartsWith("armv", Triple::arm)
257 .Case("armeb", Triple::armeb)
258 .StartsWith("armebv", Triple::armeb)
259 .Case("thumb", Triple::thumb)
260 .StartsWith("thumbv", Triple::thumb)
261 .Case("thumbeb", Triple::thumbeb)
262 .StartsWith("thumbebv", Triple::thumbeb)
263 .Case("msp430", Triple::msp430)
264 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
265 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
266 .Cases("mips64", "mips64eb", Triple::mips64)
267 .Case("mips64el", Triple::mips64el)
268 .Case("r600", Triple::r600)
269 .Case("hexagon", Triple::hexagon)
270 .Case("s390x", Triple::systemz)
271 .Case("sparc", Triple::sparc)
272 .Cases("sparcv9", "sparc64", Triple::sparcv9)
273 .Case("tce", Triple::tce)
274 .Case("xcore", Triple::xcore)
275 .Case("nvptx", Triple::nvptx)
276 .Case("nvptx64", Triple::nvptx64)
277 .Case("le32", Triple::le32)
278 .Case("amdil", Triple::amdil)
279 .Case("spir", Triple::spir)
280 .Case("spir64", Triple::spir64)
281 .Case("kalimba", Triple::kalimba)
282 .Default(Triple::UnknownArch);
285 static Triple::VendorType parseVendor(StringRef VendorName) {
286 return StringSwitch<Triple::VendorType>(VendorName)
287 .Case("apple", Triple::Apple)
288 .Case("pc", Triple::PC)
289 .Case("scei", Triple::SCEI)
290 .Case("bgp", Triple::BGP)
291 .Case("bgq", Triple::BGQ)
292 .Case("fsl", Triple::Freescale)
293 .Case("ibm", Triple::IBM)
294 .Case("img", Triple::ImaginationTechnologies)
295 .Case("mti", Triple::MipsTechnologies)
296 .Case("nvidia", Triple::NVIDIA)
297 .Case("csr", Triple::CSR)
298 .Default(Triple::UnknownVendor);
301 static Triple::OSType parseOS(StringRef OSName) {
302 return StringSwitch<Triple::OSType>(OSName)
303 .StartsWith("auroraux", Triple::AuroraUX)
304 .StartsWith("cygwin", Triple::Cygwin)
305 .StartsWith("darwin", Triple::Darwin)
306 .StartsWith("dragonfly", Triple::DragonFly)
307 .StartsWith("freebsd", Triple::FreeBSD)
308 .StartsWith("ios", Triple::IOS)
309 .StartsWith("kfreebsd", Triple::KFreeBSD)
310 .StartsWith("linux", Triple::Linux)
311 .StartsWith("lv2", Triple::Lv2)
312 .StartsWith("macosx", Triple::MacOSX)
313 .StartsWith("mingw32", Triple::MinGW32)
314 .StartsWith("netbsd", Triple::NetBSD)
315 .StartsWith("openbsd", Triple::OpenBSD)
316 .StartsWith("solaris", Triple::Solaris)
317 .StartsWith("win32", Triple::Win32)
318 .StartsWith("windows", Triple::Win32)
319 .StartsWith("haiku", Triple::Haiku)
320 .StartsWith("minix", Triple::Minix)
321 .StartsWith("rtems", Triple::RTEMS)
322 .StartsWith("nacl", Triple::NaCl)
323 .StartsWith("cnk", Triple::CNK)
324 .StartsWith("bitrig", Triple::Bitrig)
325 .StartsWith("aix", Triple::AIX)
326 .StartsWith("cuda", Triple::CUDA)
327 .StartsWith("nvcl", Triple::NVCL)
328 .Default(Triple::UnknownOS);
331 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
332 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
333 .StartsWith("eabihf", Triple::EABIHF)
334 .StartsWith("eabi", Triple::EABI)
335 .StartsWith("gnueabihf", Triple::GNUEABIHF)
336 .StartsWith("gnueabi", Triple::GNUEABI)
337 .StartsWith("gnux32", Triple::GNUX32)
338 .StartsWith("code16", Triple::CODE16)
339 .StartsWith("gnu", Triple::GNU)
340 .StartsWith("android", Triple::Android)
341 .StartsWith("msvc", Triple::MSVC)
342 .StartsWith("itanium", Triple::Itanium)
343 .StartsWith("cygnus", Triple::Cygnus)
344 .Default(Triple::UnknownEnvironment);
347 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
348 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
349 .EndsWith("coff", Triple::COFF)
350 .EndsWith("elf", Triple::ELF)
351 .EndsWith("macho", Triple::MachO)
352 .Default(Triple::UnknownObjectFormat);
355 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
356 return StringSwitch<Triple::SubArchType>(SubArchName)
357 .EndsWith("v8", Triple::ARMSubArch_v8)
358 .EndsWith("v8a", Triple::ARMSubArch_v8)
359 .EndsWith("v7", Triple::ARMSubArch_v7)
360 .EndsWith("v7a", Triple::ARMSubArch_v7)
361 .EndsWith("v7em", Triple::ARMSubArch_v7em)
362 .EndsWith("v7l", Triple::ARMSubArch_v7)
363 .EndsWith("v7m", Triple::ARMSubArch_v7m)
364 .EndsWith("v7r", Triple::ARMSubArch_v7)
365 .EndsWith("v7s", Triple::ARMSubArch_v7s)
366 .EndsWith("v6", Triple::ARMSubArch_v6)
367 .EndsWith("v6m", Triple::ARMSubArch_v6m)
368 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
369 .EndsWith("v5", Triple::ARMSubArch_v5)
370 .EndsWith("v5e", Triple::ARMSubArch_v5)
371 .EndsWith("v5t", Triple::ARMSubArch_v5)
372 .EndsWith("v5te", Triple::ARMSubArch_v5te)
373 .EndsWith("v4t", Triple::ARMSubArch_v4t)
374 .Default(Triple::NoSubArch);
377 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
379 case Triple::UnknownObjectFormat: return "";
380 case Triple::COFF: return "coff";
381 case Triple::ELF: return "elf";
382 case Triple::MachO: return "macho";
384 llvm_unreachable("unknown object format type");
387 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
389 return Triple::MachO;
390 else if (T.isOSWindows())
395 /// \brief Construct a triple from the string representation provided.
397 /// This stores the string representation and parses the various pieces into
399 Triple::Triple(const Twine &Str)
401 Arch(parseArch(getArchName())),
402 SubArch(parseSubArch(getArchName())),
403 Vendor(parseVendor(getVendorName())),
404 OS(parseOS(getOSName())),
405 Environment(parseEnvironment(getEnvironmentName())),
406 ObjectFormat(parseFormat(getEnvironmentName())) {
407 if (ObjectFormat == Triple::UnknownObjectFormat)
408 ObjectFormat = getDefaultFormat(*this);
411 /// \brief Construct a triple from string representations of the architecture,
414 /// This joins each argument into a canonical string representation and parses
415 /// them into enum members. It leaves the environment unknown and omits it from
416 /// the string representation.
417 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
418 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
419 Arch(parseArch(ArchStr.str())),
420 SubArch(parseSubArch(ArchStr.str())),
421 Vendor(parseVendor(VendorStr.str())),
422 OS(parseOS(OSStr.str())),
423 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
424 ObjectFormat = getDefaultFormat(*this);
427 /// \brief Construct a triple from string representations of the architecture,
428 /// vendor, OS, and environment.
430 /// This joins each argument into a canonical string representation and parses
431 /// them into enum members.
432 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
433 const Twine &EnvironmentStr)
434 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
435 EnvironmentStr).str()),
436 Arch(parseArch(ArchStr.str())),
437 SubArch(parseSubArch(ArchStr.str())),
438 Vendor(parseVendor(VendorStr.str())),
439 OS(parseOS(OSStr.str())),
440 Environment(parseEnvironment(EnvironmentStr.str())),
441 ObjectFormat(parseFormat(EnvironmentStr.str())) {
442 if (ObjectFormat == Triple::UnknownObjectFormat)
443 ObjectFormat = getDefaultFormat(*this);
446 std::string Triple::normalize(StringRef Str) {
447 // Parse into components.
448 SmallVector<StringRef, 4> Components;
449 Str.split(Components, "-");
451 // If the first component corresponds to a known architecture, preferentially
452 // use it for the architecture. If the second component corresponds to a
453 // known vendor, preferentially use it for the vendor, etc. This avoids silly
454 // component movement when a component parses as (eg) both a valid arch and a
456 ArchType Arch = UnknownArch;
457 if (Components.size() > 0)
458 Arch = parseArch(Components[0]);
459 VendorType Vendor = UnknownVendor;
460 if (Components.size() > 1)
461 Vendor = parseVendor(Components[1]);
462 OSType OS = UnknownOS;
463 if (Components.size() > 2)
464 OS = parseOS(Components[2]);
465 EnvironmentType Environment = UnknownEnvironment;
466 if (Components.size() > 3)
467 Environment = parseEnvironment(Components[3]);
468 ObjectFormatType ObjectFormat = UnknownObjectFormat;
469 if (Components.size() > 4)
470 ObjectFormat = parseFormat(Components[4]);
472 // Note which components are already in their final position. These will not
475 Found[0] = Arch != UnknownArch;
476 Found[1] = Vendor != UnknownVendor;
477 Found[2] = OS != UnknownOS;
478 Found[3] = Environment != UnknownEnvironment;
480 // If they are not there already, permute the components into their canonical
481 // positions by seeing if they parse as a valid architecture, and if so moving
482 // the component to the architecture position etc.
483 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
485 continue; // Already in the canonical position.
487 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
488 // Do not reparse any components that already matched.
489 if (Idx < array_lengthof(Found) && Found[Idx])
492 // Does this component parse as valid for the target position?
494 StringRef Comp = Components[Idx];
496 default: llvm_unreachable("unexpected component type!");
498 Arch = parseArch(Comp);
499 Valid = Arch != UnknownArch;
502 Vendor = parseVendor(Comp);
503 Valid = Vendor != UnknownVendor;
507 Valid = OS != UnknownOS;
510 Environment = parseEnvironment(Comp);
511 Valid = Environment != UnknownEnvironment;
513 ObjectFormat = parseFormat(Comp);
514 Valid = ObjectFormat != UnknownObjectFormat;
519 continue; // Nope, try the next component.
521 // Move the component to the target position, pushing any non-fixed
522 // components that are in the way to the right. This tends to give
523 // good results in the common cases of a forgotten vendor component
524 // or a wrongly positioned environment.
526 // Insert left, pushing the existing components to the right. For
527 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
528 StringRef CurrentComponent(""); // The empty component.
529 // Replace the component we are moving with an empty component.
530 std::swap(CurrentComponent, Components[Idx]);
531 // Insert the component being moved at Pos, displacing any existing
532 // components to the right.
533 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
534 // Skip over any fixed components.
535 while (i < array_lengthof(Found) && Found[i])
537 // Place the component at the new position, getting the component
538 // that was at this position - it will be moved right.
539 std::swap(CurrentComponent, Components[i]);
541 } else if (Pos > Idx) {
542 // Push right by inserting empty components until the component at Idx
543 // reaches the target position Pos. For example, pc-a -> -pc-a when
544 // moving pc to the second position.
546 // Insert one empty component at Idx.
547 StringRef CurrentComponent(""); // The empty component.
548 for (unsigned i = Idx; i < Components.size();) {
549 // Place the component at the new position, getting the component
550 // that was at this position - it will be moved right.
551 std::swap(CurrentComponent, Components[i]);
552 // If it was placed on top of an empty component then we are done.
553 if (CurrentComponent.empty())
555 // Advance to the next component, skipping any fixed components.
556 while (++i < array_lengthof(Found) && Found[i])
559 // The last component was pushed off the end - append it.
560 if (!CurrentComponent.empty())
561 Components.push_back(CurrentComponent);
563 // Advance Idx to the component's new position.
564 while (++Idx < array_lengthof(Found) && Found[Idx])
566 } while (Idx < Pos); // Add more until the final position is reached.
568 assert(Pos < Components.size() && Components[Pos] == Comp &&
569 "Component moved wrong!");
575 // Special case logic goes here. At this point Arch, Vendor and OS have the
576 // correct values for the computed components.
578 if (OS == Triple::Win32) {
579 Components.resize(4);
580 Components[2] = "windows";
581 if (Environment == UnknownEnvironment) {
582 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
583 Components[3] = "msvc";
585 Components[3] = getObjectFormatTypeName(ObjectFormat);
587 } else if (OS == Triple::MinGW32) {
588 Components.resize(4);
589 Components[2] = "windows";
590 Components[3] = "gnu";
591 } else if (OS == Triple::Cygwin) {
592 Components.resize(4);
593 Components[2] = "windows";
594 Components[3] = "cygnus";
596 if (OS == Triple::MinGW32 || OS == Triple::Cygwin ||
597 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
598 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
599 Components.resize(5);
600 Components[4] = getObjectFormatTypeName(ObjectFormat);
604 // Stick the corrected components back together to form the normalized string.
605 std::string Normalized;
606 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
607 if (i) Normalized += '-';
608 Normalized += Components[i];
613 StringRef Triple::getArchName() const {
614 return StringRef(Data).split('-').first; // Isolate first component
617 StringRef Triple::getVendorName() const {
618 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
619 return Tmp.split('-').first; // Isolate second component
622 StringRef Triple::getOSName() const {
623 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
624 Tmp = Tmp.split('-').second; // Strip second component
625 return Tmp.split('-').first; // Isolate third component
628 StringRef Triple::getEnvironmentName() const {
629 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
630 Tmp = Tmp.split('-').second; // Strip second component
631 return Tmp.split('-').second; // Strip third component
634 StringRef Triple::getOSAndEnvironmentName() const {
635 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
636 return Tmp.split('-').second; // Strip second component
639 static unsigned EatNumber(StringRef &Str) {
640 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
644 // Consume the leading digit.
645 Result = Result*10 + (Str[0] - '0');
649 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
654 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
655 unsigned &Micro) const {
656 StringRef OSName = getOSName();
658 // Assume that the OS portion of the triple starts with the canonical name.
659 StringRef OSTypeName = getOSTypeName(getOS());
660 if (OSName.startswith(OSTypeName))
661 OSName = OSName.substr(OSTypeName.size());
663 // Any unset version defaults to 0.
664 Major = Minor = Micro = 0;
666 // Parse up to three components.
667 unsigned *Components[3] = { &Major, &Minor, &Micro };
668 for (unsigned i = 0; i != 3; ++i) {
669 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
672 // Consume the leading number.
673 *Components[i] = EatNumber(OSName);
675 // Consume the separator, if present.
676 if (OSName.startswith("."))
677 OSName = OSName.substr(1);
681 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
682 unsigned &Micro) const {
683 getOSVersion(Major, Minor, Micro);
686 default: llvm_unreachable("unexpected OS for Darwin triple");
688 // Default to darwin8, i.e., MacOSX 10.4.
691 // Darwin version numbers are skewed from OS X versions.
708 // Ignore the version from the triple. This is only handled because the
709 // the clang driver combines OS X and IOS support into a common Darwin
710 // toolchain that wants to know the OS X version number even when targeting
720 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
721 unsigned &Micro) const {
723 default: llvm_unreachable("unexpected OS for Darwin triple");
726 // Ignore the version from the triple. This is only handled because the
727 // the clang driver combines OS X and IOS support into a common Darwin
728 // toolchain that wants to know the iOS version number even when targeting
735 getOSVersion(Major, Minor, Micro);
736 // Default to 5.0 (or 7.0 for arm64).
738 Major = (getArch() == aarch64) ? 7 : 5;
743 void Triple::setTriple(const Twine &Str) {
747 void Triple::setArch(ArchType Kind) {
748 setArchName(getArchTypeName(Kind));
751 void Triple::setVendor(VendorType Kind) {
752 setVendorName(getVendorTypeName(Kind));
755 void Triple::setOS(OSType Kind) {
756 setOSName(getOSTypeName(Kind));
759 void Triple::setEnvironment(EnvironmentType Kind) {
760 setEnvironmentName(getEnvironmentTypeName(Kind));
763 void Triple::setObjectFormat(ObjectFormatType Kind) {
764 if (Environment == UnknownEnvironment)
765 return setEnvironmentName(getObjectFormatTypeName(Kind));
767 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
768 getObjectFormatTypeName(Kind)).str());
771 void Triple::setArchName(StringRef Str) {
772 // Work around a miscompilation bug for Twines in gcc 4.0.3.
773 SmallString<64> Triple;
776 Triple += getVendorName();
778 Triple += getOSAndEnvironmentName();
779 setTriple(Triple.str());
782 void Triple::setVendorName(StringRef Str) {
783 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
786 void Triple::setOSName(StringRef Str) {
787 if (hasEnvironment())
788 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
789 "-" + getEnvironmentName());
791 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
794 void Triple::setEnvironmentName(StringRef Str) {
795 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
799 void Triple::setOSAndEnvironmentName(StringRef Str) {
800 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
803 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
805 case llvm::Triple::UnknownArch:
808 case llvm::Triple::msp430:
811 case llvm::Triple::amdil:
812 case llvm::Triple::arm:
813 case llvm::Triple::armeb:
814 case llvm::Triple::hexagon:
815 case llvm::Triple::le32:
816 case llvm::Triple::mips:
817 case llvm::Triple::mipsel:
818 case llvm::Triple::nvptx:
819 case llvm::Triple::ppc:
820 case llvm::Triple::r600:
821 case llvm::Triple::sparc:
822 case llvm::Triple::tce:
823 case llvm::Triple::thumb:
824 case llvm::Triple::thumbeb:
825 case llvm::Triple::x86:
826 case llvm::Triple::xcore:
827 case llvm::Triple::spir:
828 case llvm::Triple::kalimba:
831 case llvm::Triple::aarch64:
832 case llvm::Triple::aarch64_be:
833 case llvm::Triple::mips64:
834 case llvm::Triple::mips64el:
835 case llvm::Triple::nvptx64:
836 case llvm::Triple::ppc64:
837 case llvm::Triple::ppc64le:
838 case llvm::Triple::sparcv9:
839 case llvm::Triple::systemz:
840 case llvm::Triple::x86_64:
841 case llvm::Triple::spir64:
844 llvm_unreachable("Invalid architecture value");
847 bool Triple::isArch64Bit() const {
848 return getArchPointerBitWidth(getArch()) == 64;
851 bool Triple::isArch32Bit() const {
852 return getArchPointerBitWidth(getArch()) == 32;
855 bool Triple::isArch16Bit() const {
856 return getArchPointerBitWidth(getArch()) == 16;
859 Triple Triple::get32BitArchVariant() const {
862 case Triple::UnknownArch:
863 case Triple::aarch64:
864 case Triple::aarch64_be:
866 case Triple::systemz:
867 case Triple::ppc64le:
868 T.setArch(UnknownArch);
875 case Triple::hexagon:
876 case Triple::kalimba:
886 case Triple::thumbeb:
892 case Triple::mips64: T.setArch(Triple::mips); break;
893 case Triple::mips64el: T.setArch(Triple::mipsel); break;
894 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
895 case Triple::ppc64: T.setArch(Triple::ppc); break;
896 case Triple::sparcv9: T.setArch(Triple::sparc); break;
897 case Triple::x86_64: T.setArch(Triple::x86); break;
898 case Triple::spir64: T.setArch(Triple::spir); break;
903 Triple Triple::get64BitArchVariant() const {
906 case Triple::UnknownArch:
910 case Triple::hexagon:
911 case Triple::kalimba:
917 case Triple::thumbeb:
919 T.setArch(UnknownArch);
922 case Triple::aarch64:
923 case Triple::aarch64_be:
926 case Triple::mips64el:
927 case Triple::nvptx64:
929 case Triple::ppc64le:
930 case Triple::sparcv9:
931 case Triple::systemz:
936 case Triple::mips: T.setArch(Triple::mips64); break;
937 case Triple::mipsel: T.setArch(Triple::mips64el); break;
938 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
939 case Triple::ppc: T.setArch(Triple::ppc64); break;
940 case Triple::sparc: T.setArch(Triple::sparcv9); break;
941 case Triple::x86: T.setArch(Triple::x86_64); break;
942 case Triple::spir: T.setArch(Triple::spir64); break;
947 // FIXME: tblgen this.
948 const char *Triple::getARMCPUForArch(StringRef MArch) const {
950 MArch = getArchName();
953 case llvm::Triple::NetBSD:
954 if (MArch == "armv6")
955 return "arm1176jzf-s";
957 case llvm::Triple::Win32:
958 // FIXME: this is invalid for WindowsCE
964 const char *result = nullptr;
965 size_t offset = StringRef::npos;
966 if (MArch.startswith("arm"))
968 if (MArch.startswith("thumb"))
970 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
972 if (offset != StringRef::npos)
973 result = llvm::StringSwitch<const char *>(MArch.substr(offset))
974 .Cases("v2", "v2a", "arm2")
976 .Case("v3m", "arm7m")
977 .Case("v4", "strongarm")
978 .Case("v4t", "arm7tdmi")
979 .Cases("v5", "v5t", "arm10tdmi")
980 .Cases("v5e", "v5te", "arm1022e")
981 .Case("v5tej", "arm926ej-s")
982 .Cases("v6", "v6k", "arm1136jf-s")
983 .Case("v6j", "arm1136j-s")
984 .Cases("v6z", "v6zk", "arm1176jzf-s")
985 .Case("v6t2", "arm1156t2-s")
986 .Cases("v6m", "v6-m", "cortex-m0")
987 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
988 .Cases("v7s", "v7-s", "swift")
989 .Cases("v7r", "v7-r", "cortex-r4")
990 .Cases("v7m", "v7-m", "cortex-m3")
991 .Cases("v7em", "v7e-m", "cortex-m4")
992 .Cases("v8", "v8a", "v8-a", "cortex-a53")
995 result = llvm::StringSwitch<const char *>(MArch)
996 .Case("ep9312", "ep9312")
997 .Case("iwmmxt", "iwmmxt")
998 .Case("xscale", "xscale")
1004 // If all else failed, return the most base CPU with thumb interworking
1005 // supported by LLVM.
1006 // FIXME: Should warn once that we're falling back.
1008 case llvm::Triple::NetBSD:
1009 switch (getEnvironment()) {
1010 case llvm::Triple::GNUEABIHF:
1011 case llvm::Triple::GNUEABI:
1012 case llvm::Triple::EABIHF:
1013 case llvm::Triple::EABI:
1014 return "arm926ej-s";
1019 switch (getEnvironment()) {
1020 case llvm::Triple::EABIHF:
1021 case llvm::Triple::GNUEABIHF:
1022 return "arm1176jzf-s";