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/STLExtras.h"
16 const char *Triple::getArchTypeName(ArchType Kind) {
18 case InvalidArch: return "<invalid>";
19 case UnknownArch: return "unknown";
21 case alpha: return "alpha";
22 case arm: return "arm";
23 case cellspu: return "cellspu";
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 sparc: return "sparc";
32 case sparcv9: return "sparcv9";
33 case tce: return "tce";
34 case thumb: return "thumb";
35 case x86: return "i386";
36 case x86_64: return "x86_64";
37 case xcore: return "xcore";
38 case mblaze: return "mblaze";
39 case ptx32: return "ptx32";
40 case ptx64: return "ptx64";
41 case le32: return "le32";
42 case amdil: return "amdil";
48 const char *Triple::getArchTypePrefix(ArchType Kind) {
53 case alpha: return "alpha";
56 case thumb: return "arm";
58 case cellspu: return "spu";
61 case ppc: return "ppc";
63 case mblaze: return "mblaze";
66 case sparc: return "sparc";
69 case x86_64: return "x86";
71 case xcore: return "xcore";
73 case ptx32: return "ptx";
74 case ptx64: return "ptx";
75 case le32: return "le32";
76 case amdil: return "amdil";
80 const char *Triple::getVendorTypeName(VendorType Kind) {
82 case UnknownVendor: return "unknown";
84 case Apple: return "apple";
86 case SCEI: return "scei";
92 const char *Triple::getOSTypeName(OSType Kind) {
94 case UnknownOS: return "unknown";
96 case AuroraUX: return "auroraux";
97 case Cygwin: return "cygwin";
98 case Darwin: return "darwin";
99 case DragonFly: return "dragonfly";
100 case FreeBSD: return "freebsd";
101 case IOS: return "ios";
102 case KFreeBSD: return "kfreebsd";
103 case Linux: return "linux";
104 case Lv2: return "lv2";
105 case MacOSX: return "macosx";
106 case MinGW32: return "mingw32";
107 case NetBSD: return "netbsd";
108 case OpenBSD: return "openbsd";
109 case Psp: return "psp";
110 case Solaris: return "solaris";
111 case Win32: return "win32";
112 case Haiku: return "haiku";
113 case Minix: return "minix";
114 case RTEMS: return "rtems";
115 case NativeClient: return "nacl";
121 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
123 case UnknownEnvironment: return "unknown";
124 case GNU: return "gnu";
125 case GNUEABI: return "gnueabi";
126 case EABI: return "eabi";
127 case MachO: return "macho";
133 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
138 if (Name == "cellspu")
142 if (Name == "mipsel")
144 if (Name == "mips64")
146 if (Name == "mips64el")
148 if (Name == "msp430")
156 if (Name == "mblaze")
160 if (Name == "sparcv9")
168 if (Name == "x86-64")
184 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
185 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
186 // archs which Darwin doesn't use.
188 // The matching this routine does is fairly pointless, since it is neither the
189 // complete architecture list, nor a reasonable subset. The problem is that
190 // historically the driver driver accepts this and also ties its -march=
191 // handling to the architecture name, so we need to be careful before removing
194 // This code must be kept in sync with Clang's Darwin specific argument
197 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
198 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
199 Str == "ppc7450" || Str == "ppc970")
203 return Triple::ppc64;
205 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
206 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
207 Str == "pentIIm5" || Str == "pentium4")
211 return Triple::x86_64;
213 // This is derived from the driver driver.
214 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
215 Str == "armv6" || Str == "armv7" || Str == "armv7f" || Str == "armv7k" ||
220 return Triple::ptx32;
222 return Triple::ptx64;
224 return Triple::amdil;
226 return Triple::UnknownArch;
229 // Returns architecture name that is understood by the target assembler.
230 const char *Triple::getArchNameForAssembler() {
231 if (!isOSDarwin() && getVendor() != Triple::Apple)
234 StringRef Str = getArchName();
239 if (Str == "powerpc")
241 if (Str == "powerpc64")
243 if (Str == "mblaze" || Str == "microblaze")
247 if (Str == "armv4t" || Str == "thumbv4t")
249 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5"
250 || Str == "thumbv5e")
252 if (Str == "armv6" || Str == "thumbv6")
254 if (Str == "armv7" || Str == "thumbv7")
269 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
270 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
271 ArchName[2] == '8' && ArchName[3] == '6' &&
272 ArchName[1] - '3' < 6) // i[3-9]86
274 else if (ArchName == "amd64" || ArchName == "x86_64")
276 else if (ArchName == "powerpc")
278 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
280 else if (ArchName == "mblaze")
282 else if (ArchName == "arm" ||
283 ArchName.startswith("armv") ||
284 ArchName == "xscale")
286 else if (ArchName == "thumb" ||
287 ArchName.startswith("thumbv"))
289 else if (ArchName.startswith("alpha"))
291 else if (ArchName == "spu" || ArchName == "cellspu")
293 else if (ArchName == "msp430")
295 else if (ArchName == "mips" || ArchName == "mipseb" ||
296 ArchName == "mipsallegrex")
298 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
301 else if (ArchName == "mips64" || ArchName == "mips64eb")
303 else if (ArchName == "mips64el")
305 else if (ArchName == "sparc")
307 else if (ArchName == "sparcv9")
309 else if (ArchName == "tce")
311 else if (ArchName == "xcore")
313 else if (ArchName == "ptx32")
315 else if (ArchName == "ptx64")
317 else if (ArchName == "le32")
319 else if (ArchName == "amdil")
325 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
326 if (VendorName == "apple")
328 else if (VendorName == "pc")
330 else if (VendorName == "scei")
333 return UnknownVendor;
336 Triple::OSType Triple::ParseOS(StringRef OSName) {
337 if (OSName.startswith("auroraux"))
339 else if (OSName.startswith("cygwin"))
341 else if (OSName.startswith("darwin"))
343 else if (OSName.startswith("dragonfly"))
345 else if (OSName.startswith("freebsd"))
347 else if (OSName.startswith("ios"))
349 else if (OSName.startswith("kfreebsd"))
351 else if (OSName.startswith("linux"))
353 else if (OSName.startswith("lv2"))
355 else if (OSName.startswith("macosx"))
357 else if (OSName.startswith("mingw32"))
359 else if (OSName.startswith("netbsd"))
361 else if (OSName.startswith("openbsd"))
363 else if (OSName.startswith("psp"))
365 else if (OSName.startswith("solaris"))
367 else if (OSName.startswith("win32"))
369 else if (OSName.startswith("haiku"))
371 else if (OSName.startswith("minix"))
373 else if (OSName.startswith("rtems"))
375 else if (OSName.startswith("nacl"))
381 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
382 if (EnvironmentName.startswith("eabi"))
384 else if (EnvironmentName.startswith("gnueabi"))
386 else if (EnvironmentName.startswith("gnu"))
388 else if (EnvironmentName.startswith("macho"))
391 return UnknownEnvironment;
394 void Triple::Parse() const {
395 assert(!isInitialized() && "Invalid parse call.");
397 Arch = ParseArch(getArchName());
398 Vendor = ParseVendor(getVendorName());
399 OS = ParseOS(getOSName());
400 Environment = ParseEnvironment(getEnvironmentName());
402 assert(isInitialized() && "Failed to initialize!");
405 std::string Triple::normalize(StringRef Str) {
406 // Parse into components.
407 SmallVector<StringRef, 4> Components;
408 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
409 Last = Str.find('-', First);
410 Components.push_back(Str.slice(First, Last));
413 // If the first component corresponds to a known architecture, preferentially
414 // use it for the architecture. If the second component corresponds to a
415 // known vendor, preferentially use it for the vendor, etc. This avoids silly
416 // component movement when a component parses as (eg) both a valid arch and a
418 ArchType Arch = UnknownArch;
419 if (Components.size() > 0)
420 Arch = ParseArch(Components[0]);
421 VendorType Vendor = UnknownVendor;
422 if (Components.size() > 1)
423 Vendor = ParseVendor(Components[1]);
424 OSType OS = UnknownOS;
425 if (Components.size() > 2)
426 OS = ParseOS(Components[2]);
427 EnvironmentType Environment = UnknownEnvironment;
428 if (Components.size() > 3)
429 Environment = ParseEnvironment(Components[3]);
431 // Note which components are already in their final position. These will not
434 Found[0] = Arch != UnknownArch;
435 Found[1] = Vendor != UnknownVendor;
436 Found[2] = OS != UnknownOS;
437 Found[3] = Environment != UnknownEnvironment;
439 // If they are not there already, permute the components into their canonical
440 // positions by seeing if they parse as a valid architecture, and if so moving
441 // the component to the architecture position etc.
442 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
444 continue; // Already in the canonical position.
446 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
447 // Do not reparse any components that already matched.
448 if (Idx < array_lengthof(Found) && Found[Idx])
451 // Does this component parse as valid for the target position?
453 StringRef Comp = Components[Idx];
456 assert(false && "unexpected component type!");
458 Arch = ParseArch(Comp);
459 Valid = Arch != UnknownArch;
462 Vendor = ParseVendor(Comp);
463 Valid = Vendor != UnknownVendor;
467 Valid = OS != UnknownOS;
470 Environment = ParseEnvironment(Comp);
471 Valid = Environment != UnknownEnvironment;
475 continue; // Nope, try the next component.
477 // Move the component to the target position, pushing any non-fixed
478 // components that are in the way to the right. This tends to give
479 // good results in the common cases of a forgotten vendor component
480 // or a wrongly positioned environment.
482 // Insert left, pushing the existing components to the right. For
483 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
484 StringRef CurrentComponent(""); // The empty component.
485 // Replace the component we are moving with an empty component.
486 std::swap(CurrentComponent, Components[Idx]);
487 // Insert the component being moved at Pos, displacing any existing
488 // components to the right.
489 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
490 // Skip over any fixed components.
491 while (i < array_lengthof(Found) && Found[i]) ++i;
492 // Place the component at the new position, getting the component
493 // that was at this position - it will be moved right.
494 std::swap(CurrentComponent, Components[i]);
496 } else if (Pos > Idx) {
497 // Push right by inserting empty components until the component at Idx
498 // reaches the target position Pos. For example, pc-a -> -pc-a when
499 // moving pc to the second position.
501 // Insert one empty component at Idx.
502 StringRef CurrentComponent(""); // The empty component.
503 for (unsigned i = Idx; i < Components.size();) {
504 // Place the component at the new position, getting the component
505 // that was at this position - it will be moved right.
506 std::swap(CurrentComponent, Components[i]);
507 // If it was placed on top of an empty component then we are done.
508 if (CurrentComponent.empty())
510 // Advance to the next component, skipping any fixed components.
511 while (++i < array_lengthof(Found) && Found[i])
514 // The last component was pushed off the end - append it.
515 if (!CurrentComponent.empty())
516 Components.push_back(CurrentComponent);
518 // Advance Idx to the component's new position.
519 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
520 } while (Idx < Pos); // Add more until the final position is reached.
522 assert(Pos < Components.size() && Components[Pos] == Comp &&
523 "Component moved wrong!");
529 // Special case logic goes here. At this point Arch, Vendor and OS have the
530 // correct values for the computed components.
532 // Stick the corrected components back together to form the normalized string.
533 std::string Normalized;
534 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
535 if (i) Normalized += '-';
536 Normalized += Components[i];
541 StringRef Triple::getArchName() const {
542 return StringRef(Data).split('-').first; // Isolate first component
545 StringRef Triple::getVendorName() const {
546 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
547 return Tmp.split('-').first; // Isolate second component
550 StringRef Triple::getOSName() const {
551 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
552 Tmp = Tmp.split('-').second; // Strip second component
553 return Tmp.split('-').first; // Isolate third component
556 StringRef Triple::getEnvironmentName() const {
557 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
558 Tmp = Tmp.split('-').second; // Strip second component
559 return Tmp.split('-').second; // Strip third component
562 StringRef Triple::getOSAndEnvironmentName() const {
563 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
564 return Tmp.split('-').second; // Strip second component
567 static unsigned EatNumber(StringRef &Str) {
568 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
572 // Consume the leading digit.
573 Result = Result*10 + (Str[0] - '0');
577 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
582 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
583 unsigned &Micro) const {
584 StringRef OSName = getOSName();
586 // Assume that the OS portion of the triple starts with the canonical name.
587 StringRef OSTypeName = getOSTypeName(getOS());
588 if (OSName.startswith(OSTypeName))
589 OSName = OSName.substr(OSTypeName.size());
591 // Any unset version defaults to 0.
592 Major = Minor = Micro = 0;
594 // Parse up to three components.
595 unsigned *Components[3] = { &Major, &Minor, &Micro };
596 for (unsigned i = 0; i != 3; ++i) {
597 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
600 // Consume the leading number.
601 *Components[i] = EatNumber(OSName);
603 // Consume the separator, if present.
604 if (OSName.startswith("."))
605 OSName = OSName.substr(1);
609 void Triple::setTriple(const Twine &Str) {
614 void Triple::setArch(ArchType Kind) {
615 setArchName(getArchTypeName(Kind));
618 void Triple::setVendor(VendorType Kind) {
619 setVendorName(getVendorTypeName(Kind));
622 void Triple::setOS(OSType Kind) {
623 setOSName(getOSTypeName(Kind));
626 void Triple::setEnvironment(EnvironmentType Kind) {
627 setEnvironmentName(getEnvironmentTypeName(Kind));
630 void Triple::setArchName(StringRef Str) {
631 // Work around a miscompilation bug for Twines in gcc 4.0.3.
632 SmallString<64> Triple;
635 Triple += getVendorName();
637 Triple += getOSAndEnvironmentName();
638 setTriple(Triple.str());
641 void Triple::setVendorName(StringRef Str) {
642 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
645 void Triple::setOSName(StringRef Str) {
646 if (hasEnvironment())
647 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
648 "-" + getEnvironmentName());
650 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
653 void Triple::setEnvironmentName(StringRef Str) {
654 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
658 void Triple::setOSAndEnvironmentName(StringRef Str) {
659 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);