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 arm64: return "arm64";
27 case arm64_be: return "arm64_be";
28 case hexagon: return "hexagon";
29 case mips: return "mips";
30 case mipsel: return "mipsel";
31 case mips64: return "mips64";
32 case mips64el: return "mips64el";
33 case msp430: return "msp430";
34 case ppc64: return "powerpc64";
35 case ppc64le: return "powerpc64le";
36 case ppc: return "powerpc";
37 case r600: return "r600";
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 amdil: return "amdil";
51 case spir: return "spir";
52 case spir64: return "spir64";
55 llvm_unreachable("Invalid ArchType!");
58 const char *Triple::getArchTypePrefix(ArchType Kind) {
64 case aarch64_be: return "aarch64";
69 case thumbeb: return "arm";
72 case arm64_be: return "arm64";
76 case ppc: return "ppc";
81 case mips64el: return "mips";
83 case hexagon: return "hexagon";
85 case r600: return "r600";
88 case sparc: return "sparc";
90 case systemz: return "systemz";
93 case x86_64: return "x86";
95 case xcore: return "xcore";
97 case nvptx: return "nvptx";
98 case nvptx64: return "nvptx";
100 case le32: return "le32";
101 case amdil: return "amdil";
102 case spir: return "spir";
103 case spir64: return "spir";
107 const char *Triple::getVendorTypeName(VendorType Kind) {
109 case UnknownVendor: return "unknown";
111 case Apple: return "apple";
112 case PC: return "pc";
113 case SCEI: return "scei";
114 case BGP: return "bgp";
115 case BGQ: return "bgq";
116 case Freescale: return "fsl";
117 case IBM: return "ibm";
118 case NVIDIA: return "nvidia";
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)
181 .Case("armeb", armeb)
182 .Case("arm64", arm64)
183 .Case("arm64_be", arm64_be)
185 .Case("mipsel", mipsel)
186 .Case("mips64", mips64)
187 .Case("mips64el", mips64el)
188 .Case("msp430", msp430)
189 .Case("ppc64", ppc64)
192 .Case("ppc64le", ppc64le)
194 .Case("hexagon", hexagon)
195 .Case("sparc", sparc)
196 .Case("sparcv9", sparcv9)
197 .Case("systemz", systemz)
199 .Case("thumb", thumb)
200 .Case("thumbeb", thumbeb)
202 .Case("x86-64", x86_64)
203 .Case("xcore", xcore)
204 .Case("nvptx", nvptx)
205 .Case("nvptx64", nvptx64)
207 .Case("amdil", amdil)
209 .Case("spir64", spir64)
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("arm64_be", "arm64")
232 .Case("r600", "r600")
233 .Case("nvptx", "nvptx")
234 .Case("nvptx64", "nvptx64")
235 .Case("le32", "le32")
236 .Case("amdil", "amdil")
237 .Case("spir", "spir")
238 .Case("spir64", "spir64")
242 static Triple::ArchType parseArch(StringRef ArchName) {
243 return StringSwitch<Triple::ArchType>(ArchName)
244 .Cases("i386", "i486", "i586", "i686", Triple::x86)
245 // FIXME: Do we need to support these?
246 .Cases("i786", "i886", "i986", Triple::x86)
247 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
248 .Case("powerpc", Triple::ppc)
249 .Cases("powerpc64", "ppu", Triple::ppc64)
250 .Case("powerpc64le", Triple::ppc64le)
251 .Case("aarch64", Triple::aarch64)
252 .Case("aarch64_be", Triple::aarch64_be)
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("arm64", Triple::arm64)
264 .Case("arm64_be", Triple::arm64_be)
265 .Case("msp430", Triple::msp430)
266 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
267 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
268 .Cases("mips64", "mips64eb", Triple::mips64)
269 .Case("mips64el", Triple::mips64el)
270 .Case("r600", Triple::r600)
271 .Case("hexagon", Triple::hexagon)
272 .Case("s390x", Triple::systemz)
273 .Case("sparc", Triple::sparc)
274 .Cases("sparcv9", "sparc64", Triple::sparcv9)
275 .Case("tce", Triple::tce)
276 .Case("xcore", Triple::xcore)
277 .Case("nvptx", Triple::nvptx)
278 .Case("nvptx64", Triple::nvptx64)
279 .Case("le32", Triple::le32)
280 .Case("amdil", Triple::amdil)
281 .Case("spir", Triple::spir)
282 .Case("spir64", Triple::spir64)
283 .Default(Triple::UnknownArch);
286 static Triple::VendorType parseVendor(StringRef VendorName) {
287 return StringSwitch<Triple::VendorType>(VendorName)
288 .Case("apple", Triple::Apple)
289 .Case("pc", Triple::PC)
290 .Case("scei", Triple::SCEI)
291 .Case("bgp", Triple::BGP)
292 .Case("bgq", Triple::BGQ)
293 .Case("fsl", Triple::Freescale)
294 .Case("ibm", Triple::IBM)
295 .Case("nvidia", Triple::NVIDIA)
296 .Default(Triple::UnknownVendor);
299 static Triple::OSType parseOS(StringRef OSName) {
300 return StringSwitch<Triple::OSType>(OSName)
301 .StartsWith("auroraux", Triple::AuroraUX)
302 .StartsWith("cygwin", Triple::Cygwin)
303 .StartsWith("darwin", Triple::Darwin)
304 .StartsWith("dragonfly", Triple::DragonFly)
305 .StartsWith("freebsd", Triple::FreeBSD)
306 .StartsWith("ios", Triple::IOS)
307 .StartsWith("kfreebsd", Triple::KFreeBSD)
308 .StartsWith("linux", Triple::Linux)
309 .StartsWith("lv2", Triple::Lv2)
310 .StartsWith("macosx", Triple::MacOSX)
311 .StartsWith("mingw32", Triple::MinGW32)
312 .StartsWith("netbsd", Triple::NetBSD)
313 .StartsWith("openbsd", Triple::OpenBSD)
314 .StartsWith("solaris", Triple::Solaris)
315 .StartsWith("win32", Triple::Win32)
316 .StartsWith("windows", Triple::Win32)
317 .StartsWith("haiku", Triple::Haiku)
318 .StartsWith("minix", Triple::Minix)
319 .StartsWith("rtems", Triple::RTEMS)
320 .StartsWith("nacl", Triple::NaCl)
321 .StartsWith("cnk", Triple::CNK)
322 .StartsWith("bitrig", Triple::Bitrig)
323 .StartsWith("aix", Triple::AIX)
324 .StartsWith("cuda", Triple::CUDA)
325 .StartsWith("nvcl", Triple::NVCL)
326 .Default(Triple::UnknownOS);
329 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
330 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
331 .StartsWith("eabihf", Triple::EABIHF)
332 .StartsWith("eabi", Triple::EABI)
333 .StartsWith("gnueabihf", Triple::GNUEABIHF)
334 .StartsWith("gnueabi", Triple::GNUEABI)
335 .StartsWith("gnux32", Triple::GNUX32)
336 .StartsWith("code16", Triple::CODE16)
337 .StartsWith("gnu", Triple::GNU)
338 .StartsWith("android", Triple::Android)
339 .StartsWith("msvc", Triple::MSVC)
340 .StartsWith("itanium", Triple::Itanium)
341 .StartsWith("cygnus", Triple::Cygnus)
342 .Default(Triple::UnknownEnvironment);
345 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
346 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
347 .EndsWith("coff", Triple::COFF)
348 .EndsWith("elf", Triple::ELF)
349 .EndsWith("macho", Triple::MachO)
350 .Default(Triple::UnknownObjectFormat);
353 static Triple::SubArchType parseSubArch(StringRef SubArchName) {
354 return StringSwitch<Triple::SubArchType>(SubArchName)
355 .EndsWith("v8", Triple::ARMSubArch_v8)
356 .EndsWith("v8a", Triple::ARMSubArch_v8)
357 .EndsWith("v7", Triple::ARMSubArch_v7)
358 .EndsWith("v7a", Triple::ARMSubArch_v7)
359 .EndsWith("v7em", Triple::ARMSubArch_v7em)
360 .EndsWith("v7m", Triple::ARMSubArch_v7m)
361 .EndsWith("v7s", Triple::ARMSubArch_v7s)
362 .EndsWith("v6", Triple::ARMSubArch_v6)
363 .EndsWith("v6m", Triple::ARMSubArch_v6m)
364 .EndsWith("v6t2", Triple::ARMSubArch_v6t2)
365 .EndsWith("v5", Triple::ARMSubArch_v5)
366 .EndsWith("v5t", Triple::ARMSubArch_v5)
367 .EndsWith("v5te", Triple::ARMSubArch_v5te)
368 .EndsWith("v4t", Triple::ARMSubArch_v4t)
369 .EndsWith("v4", Triple::ARMSubArch_v4)
370 .Default(Triple::NoSubArch);
373 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
375 case Triple::UnknownObjectFormat: return "";
376 case Triple::COFF: return "coff";
377 case Triple::ELF: return "elf";
378 case Triple::MachO: return "macho";
380 llvm_unreachable("unknown object format type");
383 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
385 return Triple::MachO;
386 else if (T.isOSWindows())
391 /// \brief Construct a triple from the string representation provided.
393 /// This stores the string representation and parses the various pieces into
395 Triple::Triple(const Twine &Str)
397 Arch(parseArch(getArchName())),
398 SubArch(parseSubArch(getArchName())),
399 Vendor(parseVendor(getVendorName())),
400 OS(parseOS(getOSName())),
401 Environment(parseEnvironment(getEnvironmentName())),
402 ObjectFormat(parseFormat(getEnvironmentName())) {
403 if (ObjectFormat == Triple::UnknownObjectFormat)
404 ObjectFormat = getDefaultFormat(*this);
407 /// \brief Construct a triple from string representations of the architecture,
410 /// This joins each argument into a canonical string representation and parses
411 /// them into enum members. It leaves the environment unknown and omits it from
412 /// the string representation.
413 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
414 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
415 Arch(parseArch(ArchStr.str())),
416 SubArch(parseSubArch(ArchStr.str())),
417 Vendor(parseVendor(VendorStr.str())),
418 OS(parseOS(OSStr.str())),
419 Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
420 ObjectFormat = getDefaultFormat(*this);
423 /// \brief Construct a triple from string representations of the architecture,
424 /// vendor, OS, and environment.
426 /// This joins each argument into a canonical string representation and parses
427 /// them into enum members.
428 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
429 const Twine &EnvironmentStr)
430 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
431 EnvironmentStr).str()),
432 Arch(parseArch(ArchStr.str())),
433 SubArch(parseSubArch(ArchStr.str())),
434 Vendor(parseVendor(VendorStr.str())),
435 OS(parseOS(OSStr.str())),
436 Environment(parseEnvironment(EnvironmentStr.str())),
437 ObjectFormat(parseFormat(EnvironmentStr.str())) {
438 if (ObjectFormat == Triple::UnknownObjectFormat)
439 ObjectFormat = getDefaultFormat(*this);
442 std::string Triple::normalize(StringRef Str) {
443 // Parse into components.
444 SmallVector<StringRef, 4> Components;
445 Str.split(Components, "-");
447 // If the first component corresponds to a known architecture, preferentially
448 // use it for the architecture. If the second component corresponds to a
449 // known vendor, preferentially use it for the vendor, etc. This avoids silly
450 // component movement when a component parses as (eg) both a valid arch and a
452 ArchType Arch = UnknownArch;
453 if (Components.size() > 0)
454 Arch = parseArch(Components[0]);
455 VendorType Vendor = UnknownVendor;
456 if (Components.size() > 1)
457 Vendor = parseVendor(Components[1]);
458 OSType OS = UnknownOS;
459 if (Components.size() > 2)
460 OS = parseOS(Components[2]);
461 EnvironmentType Environment = UnknownEnvironment;
462 if (Components.size() > 3)
463 Environment = parseEnvironment(Components[3]);
464 ObjectFormatType ObjectFormat = UnknownObjectFormat;
465 if (Components.size() > 4)
466 ObjectFormat = parseFormat(Components[4]);
468 // Note which components are already in their final position. These will not
471 Found[0] = Arch != UnknownArch;
472 Found[1] = Vendor != UnknownVendor;
473 Found[2] = OS != UnknownOS;
474 Found[3] = Environment != UnknownEnvironment;
476 // If they are not there already, permute the components into their canonical
477 // positions by seeing if they parse as a valid architecture, and if so moving
478 // the component to the architecture position etc.
479 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
481 continue; // Already in the canonical position.
483 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
484 // Do not reparse any components that already matched.
485 if (Idx < array_lengthof(Found) && Found[Idx])
488 // Does this component parse as valid for the target position?
490 StringRef Comp = Components[Idx];
492 default: llvm_unreachable("unexpected component type!");
494 Arch = parseArch(Comp);
495 Valid = Arch != UnknownArch;
498 Vendor = parseVendor(Comp);
499 Valid = Vendor != UnknownVendor;
503 Valid = OS != UnknownOS;
506 Environment = parseEnvironment(Comp);
507 Valid = Environment != UnknownEnvironment;
509 ObjectFormat = parseFormat(Comp);
510 Valid = ObjectFormat != UnknownObjectFormat;
515 continue; // Nope, try the next component.
517 // Move the component to the target position, pushing any non-fixed
518 // components that are in the way to the right. This tends to give
519 // good results in the common cases of a forgotten vendor component
520 // or a wrongly positioned environment.
522 // Insert left, pushing the existing components to the right. For
523 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
524 StringRef CurrentComponent(""); // The empty component.
525 // Replace the component we are moving with an empty component.
526 std::swap(CurrentComponent, Components[Idx]);
527 // Insert the component being moved at Pos, displacing any existing
528 // components to the right.
529 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
530 // Skip over any fixed components.
531 while (i < array_lengthof(Found) && Found[i])
533 // Place the component at the new position, getting the component
534 // that was at this position - it will be moved right.
535 std::swap(CurrentComponent, Components[i]);
537 } else if (Pos > Idx) {
538 // Push right by inserting empty components until the component at Idx
539 // reaches the target position Pos. For example, pc-a -> -pc-a when
540 // moving pc to the second position.
542 // Insert one empty component at Idx.
543 StringRef CurrentComponent(""); // The empty component.
544 for (unsigned i = Idx; i < Components.size();) {
545 // Place the component at the new position, getting the component
546 // that was at this position - it will be moved right.
547 std::swap(CurrentComponent, Components[i]);
548 // If it was placed on top of an empty component then we are done.
549 if (CurrentComponent.empty())
551 // Advance to the next component, skipping any fixed components.
552 while (++i < array_lengthof(Found) && Found[i])
555 // The last component was pushed off the end - append it.
556 if (!CurrentComponent.empty())
557 Components.push_back(CurrentComponent);
559 // Advance Idx to the component's new position.
560 while (++Idx < array_lengthof(Found) && Found[Idx])
562 } while (Idx < Pos); // Add more until the final position is reached.
564 assert(Pos < Components.size() && Components[Pos] == Comp &&
565 "Component moved wrong!");
571 // Special case logic goes here. At this point Arch, Vendor and OS have the
572 // correct values for the computed components.
574 if (OS == Triple::Win32) {
575 Components.resize(4);
576 Components[2] = "windows";
577 if (Environment == UnknownEnvironment) {
578 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
579 Components[3] = "msvc";
581 Components[3] = getObjectFormatTypeName(ObjectFormat);
583 } else if (OS == Triple::MinGW32) {
584 Components.resize(4);
585 Components[2] = "windows";
586 Components[3] = "gnu";
587 } else if (OS == Triple::Cygwin) {
588 Components.resize(4);
589 Components[2] = "windows";
590 Components[3] = "cygnus";
592 if (OS == Triple::MinGW32 || OS == Triple::Cygwin ||
593 (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
594 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
595 Components.resize(5);
596 Components[4] = getObjectFormatTypeName(ObjectFormat);
600 // Stick the corrected components back together to form the normalized string.
601 std::string Normalized;
602 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
603 if (i) Normalized += '-';
604 Normalized += Components[i];
609 StringRef Triple::getArchName() const {
610 return StringRef(Data).split('-').first; // Isolate first component
613 StringRef Triple::getVendorName() const {
614 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
615 return Tmp.split('-').first; // Isolate second component
618 StringRef Triple::getOSName() const {
619 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
620 Tmp = Tmp.split('-').second; // Strip second component
621 return Tmp.split('-').first; // Isolate third component
624 StringRef Triple::getEnvironmentName() const {
625 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
626 Tmp = Tmp.split('-').second; // Strip second component
627 return Tmp.split('-').second; // Strip third component
630 StringRef Triple::getOSAndEnvironmentName() const {
631 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
632 return Tmp.split('-').second; // Strip second component
635 static unsigned EatNumber(StringRef &Str) {
636 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
640 // Consume the leading digit.
641 Result = Result*10 + (Str[0] - '0');
645 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
650 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
651 unsigned &Micro) const {
652 StringRef OSName = getOSName();
654 // Assume that the OS portion of the triple starts with the canonical name.
655 StringRef OSTypeName = getOSTypeName(getOS());
656 if (OSName.startswith(OSTypeName))
657 OSName = OSName.substr(OSTypeName.size());
659 // Any unset version defaults to 0.
660 Major = Minor = Micro = 0;
662 // Parse up to three components.
663 unsigned *Components[3] = { &Major, &Minor, &Micro };
664 for (unsigned i = 0; i != 3; ++i) {
665 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
668 // Consume the leading number.
669 *Components[i] = EatNumber(OSName);
671 // Consume the separator, if present.
672 if (OSName.startswith("."))
673 OSName = OSName.substr(1);
677 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
678 unsigned &Micro) const {
679 getOSVersion(Major, Minor, Micro);
682 default: llvm_unreachable("unexpected OS for Darwin triple");
684 // Default to darwin8, i.e., MacOSX 10.4.
687 // Darwin version numbers are skewed from OS X versions.
704 // Ignore the version from the triple. This is only handled because the
705 // the clang driver combines OS X and IOS support into a common Darwin
706 // toolchain that wants to know the OS X version number even when targeting
716 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
717 unsigned &Micro) const {
719 default: llvm_unreachable("unexpected OS for Darwin triple");
722 // Ignore the version from the triple. This is only handled because the
723 // the clang driver combines OS X and IOS support into a common Darwin
724 // toolchain that wants to know the iOS version number even when targeting
731 getOSVersion(Major, Minor, Micro);
732 // Default to 5.0 (or 7.0 for arm64).
734 Major = (getArch() == arm64) ? 7 : 5;
739 void Triple::setTriple(const Twine &Str) {
743 void Triple::setArch(ArchType Kind) {
744 setArchName(getArchTypeName(Kind));
747 void Triple::setVendor(VendorType Kind) {
748 setVendorName(getVendorTypeName(Kind));
751 void Triple::setOS(OSType Kind) {
752 setOSName(getOSTypeName(Kind));
755 void Triple::setEnvironment(EnvironmentType Kind) {
756 setEnvironmentName(getEnvironmentTypeName(Kind));
759 void Triple::setObjectFormat(ObjectFormatType Kind) {
760 if (Environment == UnknownEnvironment)
761 return setEnvironmentName(getObjectFormatTypeName(Kind));
763 Twine Env = getEnvironmentTypeName(Environment) + Twine("-") +
764 getObjectFormatTypeName(Kind);
765 setEnvironmentName(Env.str());
768 void Triple::setArchName(StringRef Str) {
769 // Work around a miscompilation bug for Twines in gcc 4.0.3.
770 SmallString<64> Triple;
773 Triple += getVendorName();
775 Triple += getOSAndEnvironmentName();
776 setTriple(Triple.str());
779 void Triple::setVendorName(StringRef Str) {
780 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
783 void Triple::setOSName(StringRef Str) {
784 if (hasEnvironment())
785 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
786 "-" + getEnvironmentName());
788 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
791 void Triple::setEnvironmentName(StringRef Str) {
792 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
796 void Triple::setOSAndEnvironmentName(StringRef Str) {
797 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
800 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
802 case llvm::Triple::UnknownArch:
805 case llvm::Triple::msp430:
808 case llvm::Triple::amdil:
809 case llvm::Triple::arm:
810 case llvm::Triple::armeb:
811 case llvm::Triple::hexagon:
812 case llvm::Triple::le32:
813 case llvm::Triple::mips:
814 case llvm::Triple::mipsel:
815 case llvm::Triple::nvptx:
816 case llvm::Triple::ppc:
817 case llvm::Triple::r600:
818 case llvm::Triple::sparc:
819 case llvm::Triple::tce:
820 case llvm::Triple::thumb:
821 case llvm::Triple::thumbeb:
822 case llvm::Triple::x86:
823 case llvm::Triple::xcore:
824 case llvm::Triple::spir:
827 case llvm::Triple::arm64:
828 case llvm::Triple::arm64_be:
829 case llvm::Triple::aarch64:
830 case llvm::Triple::aarch64_be:
831 case llvm::Triple::mips64:
832 case llvm::Triple::mips64el:
833 case llvm::Triple::nvptx64:
834 case llvm::Triple::ppc64:
835 case llvm::Triple::ppc64le:
836 case llvm::Triple::sparcv9:
837 case llvm::Triple::systemz:
838 case llvm::Triple::x86_64:
839 case llvm::Triple::spir64:
842 llvm_unreachable("Invalid architecture value");
845 bool Triple::isArch64Bit() const {
846 return getArchPointerBitWidth(getArch()) == 64;
849 bool Triple::isArch32Bit() const {
850 return getArchPointerBitWidth(getArch()) == 32;
853 bool Triple::isArch16Bit() const {
854 return getArchPointerBitWidth(getArch()) == 16;
857 Triple Triple::get32BitArchVariant() const {
860 case Triple::UnknownArch:
861 case Triple::aarch64:
862 case Triple::aarch64_be:
864 case Triple::arm64_be:
866 case Triple::systemz:
867 case Triple::ppc64le:
868 T.setArch(UnknownArch);
875 case Triple::hexagon:
885 case Triple::thumbeb:
891 case Triple::mips64: T.setArch(Triple::mips); break;
892 case Triple::mips64el: T.setArch(Triple::mipsel); break;
893 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
894 case Triple::ppc64: T.setArch(Triple::ppc); break;
895 case Triple::sparcv9: T.setArch(Triple::sparc); break;
896 case Triple::x86_64: T.setArch(Triple::x86); break;
897 case Triple::spir64: T.setArch(Triple::spir); break;
902 Triple Triple::get64BitArchVariant() const {
905 case Triple::UnknownArch:
909 case Triple::hexagon:
915 case Triple::thumbeb:
917 T.setArch(UnknownArch);
920 case Triple::aarch64:
921 case Triple::aarch64_be:
924 case Triple::mips64el:
925 case Triple::nvptx64:
927 case Triple::ppc64le:
928 case Triple::sparcv9:
929 case Triple::systemz:
932 case Triple::arm64_be:
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;