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/SmallString.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/Support/ErrorHandling.h"
18 const char *Triple::getArchTypeName(ArchType Kind) {
20 case UnknownArch: return "unknown";
22 case arm: return "arm";
23 case hexagon: return "hexagon";
24 case mips: return "mips";
25 case mipsel: return "mipsel";
26 case mips64: return "mips64";
27 case mips64el:return "mips64el";
28 case msp430: return "msp430";
29 case ppc64: return "powerpc64";
30 case ppc: return "powerpc";
31 case r600: return "r600";
32 case sparc: return "sparc";
33 case sparcv9: return "sparcv9";
34 case tce: return "tce";
35 case thumb: return "thumb";
36 case x86: return "i386";
37 case x86_64: return "x86_64";
38 case xcore: return "xcore";
39 case mblaze: return "mblaze";
40 case nvptx: return "nvptx";
41 case nvptx64: return "nvptx64";
42 case le32: return "le32";
43 case amdil: return "amdil";
44 case spir: return "spir";
47 llvm_unreachable("Invalid ArchType!");
50 const char *Triple::getArchTypePrefix(ArchType Kind) {
56 case thumb: return "arm";
59 case ppc: return "ppc";
61 case mblaze: return "mblaze";
66 case mips64el:return "mips";
68 case hexagon: return "hexagon";
70 case r600: return "r600";
73 case sparc: return "sparc";
76 case x86_64: return "x86";
78 case xcore: return "xcore";
80 case nvptx: return "nvptx";
81 case nvptx64: return "nvptx";
82 case le32: return "le32";
83 case amdil: return "amdil";
84 case spir: return "spir";
88 const char *Triple::getVendorTypeName(VendorType Kind) {
90 case UnknownVendor: return "unknown";
92 case Apple: return "apple";
94 case SCEI: return "scei";
95 case BGP: return "bgp";
96 case BGQ: return "bgq";
97 case Freescale: return "fsl";
98 case IBM: return "ibm";
101 llvm_unreachable("Invalid VendorType!");
104 const char *Triple::getOSTypeName(OSType Kind) {
106 case UnknownOS: return "unknown";
108 case AuroraUX: return "auroraux";
109 case Cygwin: return "cygwin";
110 case Darwin: return "darwin";
111 case DragonFly: return "dragonfly";
112 case FreeBSD: return "freebsd";
113 case IOS: return "ios";
114 case KFreeBSD: return "kfreebsd";
115 case Linux: return "linux";
116 case Lv2: return "lv2";
117 case MacOSX: return "macosx";
118 case MinGW32: return "mingw32";
119 case NetBSD: return "netbsd";
120 case OpenBSD: return "openbsd";
121 case Solaris: return "solaris";
122 case Win32: return "win32";
123 case Haiku: return "haiku";
124 case Minix: return "minix";
125 case RTEMS: return "rtems";
126 case NativeClient: return "nacl";
127 case CNK: return "cnk";
128 case Bitrig: return "bitrig";
129 case AIX: return "aix";
132 llvm_unreachable("Invalid OSType");
135 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
137 case UnknownEnvironment: return "unknown";
138 case GNU: return "gnu";
139 case GNUEABIHF: return "gnueabihf";
140 case GNUEABI: return "gnueabi";
141 case EABI: return "eabi";
142 case MachO: return "macho";
143 case Android: return "android";
144 case ELF: return "elf";
147 llvm_unreachable("Invalid EnvironmentType!");
150 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
151 return StringSwitch<Triple::ArchType>(Name)
154 .Case("mipsel", mipsel)
155 .Case("mips64", mips64)
156 .Case("mips64el", mips64el)
157 .Case("msp430", msp430)
158 .Case("ppc64", ppc64)
161 .Case("mblaze", mblaze)
163 .Case("hexagon", hexagon)
164 .Case("sparc", sparc)
165 .Case("sparcv9", sparcv9)
167 .Case("thumb", thumb)
169 .Case("x86-64", x86_64)
170 .Case("xcore", xcore)
171 .Case("nvptx", nvptx)
172 .Case("nvptx64", nvptx64)
174 .Case("amdil", amdil)
176 .Default(UnknownArch);
179 // Returns architecture name that is understood by the target assembler.
180 const char *Triple::getArchNameForAssembler() {
181 if (!isOSDarwin() && getVendor() != Triple::Apple)
184 return StringSwitch<const char*>(getArchName())
185 .Case("i386", "i386")
186 .Case("x86_64", "x86_64")
187 .Case("powerpc", "ppc")
188 .Case("powerpc64", "ppc64")
189 .Cases("mblaze", "microblaze", "mblaze")
191 .Cases("armv4t", "thumbv4t", "armv4t")
192 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
193 .Cases("armv6", "thumbv6", "armv6")
194 .Cases("armv7", "thumbv7", "armv7")
195 .Case("r600", "r600")
196 .Case("nvptx", "nvptx")
197 .Case("nvptx64", "nvptx64")
198 .Case("le32", "le32")
199 .Case("amdil", "amdil")
200 .Case("spir", "spir")
204 static Triple::ArchType parseArch(StringRef ArchName) {
205 return StringSwitch<Triple::ArchType>(ArchName)
206 .Cases("i386", "i486", "i586", "i686", Triple::x86)
207 // FIXME: Do we need to support these?
208 .Cases("i786", "i886", "i986", Triple::x86)
209 .Cases("amd64", "x86_64", Triple::x86_64)
210 .Case("powerpc", Triple::ppc)
211 .Cases("powerpc64", "ppu", Triple::ppc64)
212 .Case("mblaze", Triple::mblaze)
213 .Cases("arm", "xscale", Triple::arm)
214 // FIXME: It would be good to replace these with explicit names for all the
215 // various suffixes supported.
216 .StartsWith("armv", Triple::arm)
217 .Case("thumb", Triple::thumb)
218 .StartsWith("thumbv", Triple::thumb)
219 .Case("msp430", Triple::msp430)
220 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
221 .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
222 .Cases("mips64", "mips64eb", Triple::mips64)
223 .Case("mips64el", Triple::mips64el)
224 .Case("r600", Triple::r600)
225 .Case("hexagon", Triple::hexagon)
226 .Case("sparc", Triple::sparc)
227 .Case("sparcv9", Triple::sparcv9)
228 .Case("tce", Triple::tce)
229 .Case("xcore", Triple::xcore)
230 .Case("nvptx", Triple::nvptx)
231 .Case("nvptx64", Triple::nvptx64)
232 .Case("le32", Triple::le32)
233 .Case("amdil", Triple::amdil)
234 .Case("spir", Triple::spir)
235 .Default(Triple::UnknownArch);
238 static Triple::VendorType parseVendor(StringRef VendorName) {
239 return StringSwitch<Triple::VendorType>(VendorName)
240 .Case("apple", Triple::Apple)
241 .Case("pc", Triple::PC)
242 .Case("scei", Triple::SCEI)
243 .Case("bgp", Triple::BGP)
244 .Case("bgq", Triple::BGQ)
245 .Case("fsl", Triple::Freescale)
246 .Case("ibm", Triple::IBM)
247 .Default(Triple::UnknownVendor);
250 static Triple::OSType parseOS(StringRef OSName) {
251 return StringSwitch<Triple::OSType>(OSName)
252 .StartsWith("auroraux", Triple::AuroraUX)
253 .StartsWith("cygwin", Triple::Cygwin)
254 .StartsWith("darwin", Triple::Darwin)
255 .StartsWith("dragonfly", Triple::DragonFly)
256 .StartsWith("freebsd", Triple::FreeBSD)
257 .StartsWith("ios", Triple::IOS)
258 .StartsWith("kfreebsd", Triple::KFreeBSD)
259 .StartsWith("linux", Triple::Linux)
260 .StartsWith("lv2", Triple::Lv2)
261 .StartsWith("macosx", Triple::MacOSX)
262 .StartsWith("mingw32", Triple::MinGW32)
263 .StartsWith("netbsd", Triple::NetBSD)
264 .StartsWith("openbsd", Triple::OpenBSD)
265 .StartsWith("solaris", Triple::Solaris)
266 .StartsWith("win32", Triple::Win32)
267 .StartsWith("haiku", Triple::Haiku)
268 .StartsWith("minix", Triple::Minix)
269 .StartsWith("rtems", Triple::RTEMS)
270 .StartsWith("nacl", Triple::NativeClient)
271 .StartsWith("cnk", Triple::CNK)
272 .StartsWith("bitrig", Triple::Bitrig)
273 .StartsWith("aix", Triple::AIX)
274 .Default(Triple::UnknownOS);
277 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
278 return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
279 .StartsWith("eabi", Triple::EABI)
280 .StartsWith("gnueabihf", Triple::GNUEABIHF)
281 .StartsWith("gnueabi", Triple::GNUEABI)
282 .StartsWith("gnu", Triple::GNU)
283 .StartsWith("macho", Triple::MachO)
284 .StartsWith("android", Triple::Android)
285 .StartsWith("elf", Triple::ELF)
286 .Default(Triple::UnknownEnvironment);
289 /// \brief Construct a triple from the string representation provided.
291 /// This stores the string representation and parses the various pieces into
293 Triple::Triple(const Twine &Str)
295 Arch(parseArch(getArchName())),
296 Vendor(parseVendor(getVendorName())),
297 OS(parseOS(getOSName())),
298 Environment(parseEnvironment(getEnvironmentName())) {
301 /// \brief Construct a triple from string representations of the architecture,
304 /// This joins each argument into a canonical string representation and parses
305 /// them into enum members. It leaves the environment unknown and omits it from
306 /// the string representation.
307 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
308 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
309 Arch(parseArch(ArchStr.str())),
310 Vendor(parseVendor(VendorStr.str())),
311 OS(parseOS(OSStr.str())),
315 /// \brief Construct a triple from string representations of the architecture,
316 /// vendor, OS, and environment.
318 /// This joins each argument into a canonical string representation and parses
319 /// them into enum members.
320 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
321 const Twine &EnvironmentStr)
322 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
323 EnvironmentStr).str()),
324 Arch(parseArch(ArchStr.str())),
325 Vendor(parseVendor(VendorStr.str())),
326 OS(parseOS(OSStr.str())),
327 Environment(parseEnvironment(EnvironmentStr.str())) {
330 std::string Triple::normalize(StringRef Str) {
331 // Parse into components.
332 SmallVector<StringRef, 4> Components;
333 Str.split(Components, "-");
335 // If the first component corresponds to a known architecture, preferentially
336 // use it for the architecture. If the second component corresponds to a
337 // known vendor, preferentially use it for the vendor, etc. This avoids silly
338 // component movement when a component parses as (eg) both a valid arch and a
340 ArchType Arch = UnknownArch;
341 if (Components.size() > 0)
342 Arch = parseArch(Components[0]);
343 VendorType Vendor = UnknownVendor;
344 if (Components.size() > 1)
345 Vendor = parseVendor(Components[1]);
346 OSType OS = UnknownOS;
347 if (Components.size() > 2)
348 OS = parseOS(Components[2]);
349 EnvironmentType Environment = UnknownEnvironment;
350 if (Components.size() > 3)
351 Environment = parseEnvironment(Components[3]);
353 // Note which components are already in their final position. These will not
356 Found[0] = Arch != UnknownArch;
357 Found[1] = Vendor != UnknownVendor;
358 Found[2] = OS != UnknownOS;
359 Found[3] = Environment != UnknownEnvironment;
361 // If they are not there already, permute the components into their canonical
362 // positions by seeing if they parse as a valid architecture, and if so moving
363 // the component to the architecture position etc.
364 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
366 continue; // Already in the canonical position.
368 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
369 // Do not reparse any components that already matched.
370 if (Idx < array_lengthof(Found) && Found[Idx])
373 // Does this component parse as valid for the target position?
375 StringRef Comp = Components[Idx];
377 default: llvm_unreachable("unexpected component type!");
379 Arch = parseArch(Comp);
380 Valid = Arch != UnknownArch;
383 Vendor = parseVendor(Comp);
384 Valid = Vendor != UnknownVendor;
388 Valid = OS != UnknownOS;
391 Environment = parseEnvironment(Comp);
392 Valid = Environment != UnknownEnvironment;
396 continue; // Nope, try the next component.
398 // Move the component to the target position, pushing any non-fixed
399 // components that are in the way to the right. This tends to give
400 // good results in the common cases of a forgotten vendor component
401 // or a wrongly positioned environment.
403 // Insert left, pushing the existing components to the right. For
404 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
405 StringRef CurrentComponent(""); // The empty component.
406 // Replace the component we are moving with an empty component.
407 std::swap(CurrentComponent, Components[Idx]);
408 // Insert the component being moved at Pos, displacing any existing
409 // components to the right.
410 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
411 // Skip over any fixed components.
412 while (i < array_lengthof(Found) && Found[i])
414 // Place the component at the new position, getting the component
415 // that was at this position - it will be moved right.
416 std::swap(CurrentComponent, Components[i]);
418 } else if (Pos > Idx) {
419 // Push right by inserting empty components until the component at Idx
420 // reaches the target position Pos. For example, pc-a -> -pc-a when
421 // moving pc to the second position.
423 // Insert one empty component at Idx.
424 StringRef CurrentComponent(""); // The empty component.
425 for (unsigned i = Idx; i < Components.size();) {
426 // Place the component at the new position, getting the component
427 // that was at this position - it will be moved right.
428 std::swap(CurrentComponent, Components[i]);
429 // If it was placed on top of an empty component then we are done.
430 if (CurrentComponent.empty())
432 // Advance to the next component, skipping any fixed components.
433 while (++i < array_lengthof(Found) && Found[i])
436 // The last component was pushed off the end - append it.
437 if (!CurrentComponent.empty())
438 Components.push_back(CurrentComponent);
440 // Advance Idx to the component's new position.
441 while (++Idx < array_lengthof(Found) && Found[Idx])
443 } while (Idx < Pos); // Add more until the final position is reached.
445 assert(Pos < Components.size() && Components[Pos] == Comp &&
446 "Component moved wrong!");
452 // Special case logic goes here. At this point Arch, Vendor and OS have the
453 // correct values for the computed components.
455 // Stick the corrected components back together to form the normalized string.
456 std::string Normalized;
457 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
458 if (i) Normalized += '-';
459 Normalized += Components[i];
464 StringRef Triple::getArchName() const {
465 return StringRef(Data).split('-').first; // Isolate first component
468 StringRef Triple::getVendorName() const {
469 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
470 return Tmp.split('-').first; // Isolate second component
473 StringRef Triple::getOSName() const {
474 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
475 Tmp = Tmp.split('-').second; // Strip second component
476 return Tmp.split('-').first; // Isolate third component
479 StringRef Triple::getEnvironmentName() const {
480 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
481 Tmp = Tmp.split('-').second; // Strip second component
482 return Tmp.split('-').second; // Strip third component
485 StringRef Triple::getOSAndEnvironmentName() const {
486 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
487 return Tmp.split('-').second; // Strip second component
490 static unsigned EatNumber(StringRef &Str) {
491 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
495 // Consume the leading digit.
496 Result = Result*10 + (Str[0] - '0');
500 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
505 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
506 unsigned &Micro) const {
507 StringRef OSName = getOSName();
509 // Assume that the OS portion of the triple starts with the canonical name.
510 StringRef OSTypeName = getOSTypeName(getOS());
511 if (OSName.startswith(OSTypeName))
512 OSName = OSName.substr(OSTypeName.size());
514 // Any unset version defaults to 0.
515 Major = Minor = Micro = 0;
517 // Parse up to three components.
518 unsigned *Components[3] = { &Major, &Minor, &Micro };
519 for (unsigned i = 0; i != 3; ++i) {
520 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
523 // Consume the leading number.
524 *Components[i] = EatNumber(OSName);
526 // Consume the separator, if present.
527 if (OSName.startswith("."))
528 OSName = OSName.substr(1);
532 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
533 unsigned &Micro) const {
534 getOSVersion(Major, Minor, Micro);
537 default: llvm_unreachable("unexpected OS for Darwin triple");
539 // Default to darwin8, i.e., MacOSX 10.4.
542 // Darwin version numbers are skewed from OS X versions.
559 // Ignore the version from the triple. This is only handled because the
560 // the clang driver combines OS X and IOS support into a common Darwin
561 // toolchain that wants to know the OS X version number even when targeting
571 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
572 unsigned &Micro) const {
574 default: llvm_unreachable("unexpected OS for Darwin triple");
577 // Ignore the version from the triple. This is only handled because the
578 // the clang driver combines OS X and IOS support into a common Darwin
579 // toolchain that wants to know the iOS version number even when targeting
586 getOSVersion(Major, Minor, Micro);
594 void Triple::setTriple(const Twine &Str) {
598 void Triple::setArch(ArchType Kind) {
599 setArchName(getArchTypeName(Kind));
602 void Triple::setVendor(VendorType Kind) {
603 setVendorName(getVendorTypeName(Kind));
606 void Triple::setOS(OSType Kind) {
607 setOSName(getOSTypeName(Kind));
610 void Triple::setEnvironment(EnvironmentType Kind) {
611 setEnvironmentName(getEnvironmentTypeName(Kind));
614 void Triple::setArchName(StringRef Str) {
615 // Work around a miscompilation bug for Twines in gcc 4.0.3.
616 SmallString<64> Triple;
619 Triple += getVendorName();
621 Triple += getOSAndEnvironmentName();
622 setTriple(Triple.str());
625 void Triple::setVendorName(StringRef Str) {
626 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
629 void Triple::setOSName(StringRef Str) {
630 if (hasEnvironment())
631 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
632 "-" + getEnvironmentName());
634 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
637 void Triple::setEnvironmentName(StringRef Str) {
638 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
642 void Triple::setOSAndEnvironmentName(StringRef Str) {
643 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
646 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
648 case llvm::Triple::spir:
649 case llvm::Triple::UnknownArch:
652 case llvm::Triple::msp430:
655 case llvm::Triple::amdil:
656 case llvm::Triple::arm:
657 case llvm::Triple::hexagon:
658 case llvm::Triple::le32:
659 case llvm::Triple::mblaze:
660 case llvm::Triple::mips:
661 case llvm::Triple::mipsel:
662 case llvm::Triple::nvptx:
663 case llvm::Triple::ppc:
664 case llvm::Triple::r600:
665 case llvm::Triple::sparc:
666 case llvm::Triple::tce:
667 case llvm::Triple::thumb:
668 case llvm::Triple::x86:
669 case llvm::Triple::xcore:
672 case llvm::Triple::mips64:
673 case llvm::Triple::mips64el:
674 case llvm::Triple::nvptx64:
675 case llvm::Triple::ppc64:
676 case llvm::Triple::sparcv9:
677 case llvm::Triple::x86_64:
680 llvm_unreachable("Invalid architecture value");
683 bool Triple::isArch64Bit() const {
684 return getArchPointerBitWidth(getArch()) == 64;
687 bool Triple::isArch32Bit() const {
688 return getArchPointerBitWidth(getArch()) == 32;
691 bool Triple::isArch16Bit() const {
692 return getArchPointerBitWidth(getArch()) == 16;
695 Triple Triple::get32BitArchVariant() const {
698 case Triple::UnknownArch:
700 T.setArch(UnknownArch);
706 case Triple::hexagon:
722 case Triple::mips64: T.setArch(Triple::mips); break;
723 case Triple::mips64el: T.setArch(Triple::mipsel); break;
724 case Triple::nvptx64: T.setArch(Triple::nvptx); break;
725 case Triple::ppc64: T.setArch(Triple::ppc); break;
726 case Triple::sparcv9: T.setArch(Triple::sparc); break;
727 case Triple::x86_64: T.setArch(Triple::x86); break;
732 Triple Triple::get64BitArchVariant() const {
735 case Triple::UnknownArch:
738 case Triple::hexagon:
746 T.setArch(UnknownArch);
751 case Triple::mips64el:
752 case Triple::nvptx64:
754 case Triple::sparcv9:
759 case Triple::mips: T.setArch(Triple::mips64); break;
760 case Triple::mipsel: T.setArch(Triple::mips64el); break;
761 case Triple::nvptx: T.setArch(Triple::nvptx64); break;
762 case Triple::ppc: T.setArch(Triple::ppc64); break;
763 case Triple::sparc: T.setArch(Triple::sparcv9); break;
764 case Triple::x86: T.setArch(Triple::x86_64); break;