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 bfin: return "bfin";
24 case cellspu: return "cellspu";
25 case mips: return "mips";
26 case mipsel: return "mipsel";
27 case mips64: return "mips64";
28 case mips64el:return "mips64el";
29 case msp430: return "msp430";
30 case ppc64: return "powerpc64";
31 case ppc: return "powerpc";
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 ptx32: return "ptx32";
41 case ptx64: return "ptx64";
42 case le32: return "le32";
43 case amdil: return "amdil";
49 const char *Triple::getArchTypePrefix(ArchType Kind) {
54 case alpha: return "alpha";
57 case thumb: return "arm";
59 case bfin: return "bfin";
61 case cellspu: return "spu";
64 case ppc: return "ppc";
66 case mblaze: return "mblaze";
69 case sparc: return "sparc";
72 case x86_64: return "x86";
74 case xcore: return "xcore";
76 case ptx32: return "ptx";
77 case ptx64: return "ptx";
78 case le32: return "le32";
79 case amdil: return "amdil";
83 const char *Triple::getVendorTypeName(VendorType Kind) {
85 case UnknownVendor: return "unknown";
87 case Apple: return "apple";
89 case SCEI: return "scei";
95 const char *Triple::getOSTypeName(OSType Kind) {
97 case UnknownOS: return "unknown";
99 case AuroraUX: return "auroraux";
100 case Cygwin: return "cygwin";
101 case Darwin: return "darwin";
102 case DragonFly: return "dragonfly";
103 case FreeBSD: return "freebsd";
104 case IOS: return "ios";
105 case KFreeBSD: return "kfreebsd";
106 case Linux: return "linux";
107 case Lv2: return "lv2";
108 case MacOSX: return "macosx";
109 case MinGW32: return "mingw32";
110 case NetBSD: return "netbsd";
111 case OpenBSD: return "openbsd";
112 case Psp: return "psp";
113 case Solaris: return "solaris";
114 case Win32: return "win32";
115 case Haiku: return "haiku";
116 case Minix: return "minix";
117 case RTEMS: return "rtems";
118 case NativeClient: return "nacl";
124 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
126 case UnknownEnvironment: return "unknown";
127 case GNU: return "gnu";
128 case GNUEABI: return "gnueabi";
129 case EABI: return "eabi";
130 case MachO: return "macho";
136 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
143 if (Name == "cellspu")
147 if (Name == "mipsel")
149 if (Name == "mips64")
151 if (Name == "mips64el")
153 if (Name == "msp430")
161 if (Name == "mblaze")
165 if (Name == "sparcv9")
173 if (Name == "x86-64")
189 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
190 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
191 // archs which Darwin doesn't use.
193 // The matching this routine does is fairly pointless, since it is neither the
194 // complete architecture list, nor a reasonable subset. The problem is that
195 // historically the driver driver accepts this and also ties its -march=
196 // handling to the architecture name, so we need to be careful before removing
199 // This code must be kept in sync with Clang's Darwin specific argument
202 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
203 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
204 Str == "ppc7450" || Str == "ppc970")
208 return Triple::ppc64;
210 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
211 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
212 Str == "pentIIm5" || Str == "pentium4")
216 return Triple::x86_64;
218 // This is derived from the driver driver.
219 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
220 Str == "armv6" || Str == "armv7" || Str == "armv7f" || Str == "armv7k" ||
225 return Triple::ptx32;
227 return Triple::ptx64;
229 return Triple::amdil;
231 return Triple::UnknownArch;
234 // Returns architecture name that is understood by the target assembler.
235 const char *Triple::getArchNameForAssembler() {
236 if (!isOSDarwin() && getVendor() != Triple::Apple)
239 StringRef Str = getArchName();
244 if (Str == "powerpc")
246 if (Str == "powerpc64")
248 if (Str == "mblaze" || Str == "microblaze")
252 if (Str == "armv4t" || Str == "thumbv4t")
254 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5"
255 || Str == "thumbv5e")
257 if (Str == "armv6" || Str == "thumbv6")
259 if (Str == "armv7" || Str == "thumbv7")
274 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
275 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
276 ArchName[2] == '8' && ArchName[3] == '6' &&
277 ArchName[1] - '3' < 6) // i[3-9]86
279 else if (ArchName == "amd64" || ArchName == "x86_64")
281 else if (ArchName == "bfin")
283 else if (ArchName == "powerpc")
285 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
287 else if (ArchName == "mblaze")
289 else if (ArchName == "arm" ||
290 ArchName.startswith("armv") ||
291 ArchName == "xscale")
293 else if (ArchName == "thumb" ||
294 ArchName.startswith("thumbv"))
296 else if (ArchName.startswith("alpha"))
298 else if (ArchName == "spu" || ArchName == "cellspu")
300 else if (ArchName == "msp430")
302 else if (ArchName == "mips" || ArchName == "mipseb" ||
303 ArchName == "mipsallegrex")
305 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
308 else if (ArchName == "mips64" || ArchName == "mips64eb")
310 else if (ArchName == "mips64el")
312 else if (ArchName == "sparc")
314 else if (ArchName == "sparcv9")
316 else if (ArchName == "tce")
318 else if (ArchName == "xcore")
320 else if (ArchName == "ptx32")
322 else if (ArchName == "ptx64")
324 else if (ArchName == "le32")
326 else if (ArchName == "amdil")
332 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
333 if (VendorName == "apple")
335 else if (VendorName == "pc")
337 else if (VendorName == "scei")
340 return UnknownVendor;
343 Triple::OSType Triple::ParseOS(StringRef OSName) {
344 if (OSName.startswith("auroraux"))
346 else if (OSName.startswith("cygwin"))
348 else if (OSName.startswith("darwin"))
350 else if (OSName.startswith("dragonfly"))
352 else if (OSName.startswith("freebsd"))
354 else if (OSName.startswith("ios"))
356 else if (OSName.startswith("kfreebsd"))
358 else if (OSName.startswith("linux"))
360 else if (OSName.startswith("lv2"))
362 else if (OSName.startswith("macosx"))
364 else if (OSName.startswith("mingw32"))
366 else if (OSName.startswith("netbsd"))
368 else if (OSName.startswith("openbsd"))
370 else if (OSName.startswith("psp"))
372 else if (OSName.startswith("solaris"))
374 else if (OSName.startswith("win32"))
376 else if (OSName.startswith("haiku"))
378 else if (OSName.startswith("minix"))
380 else if (OSName.startswith("rtems"))
382 else if (OSName.startswith("nacl"))
388 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
389 if (EnvironmentName.startswith("eabi"))
391 else if (EnvironmentName.startswith("gnueabi"))
393 else if (EnvironmentName.startswith("gnu"))
395 else if (EnvironmentName.startswith("macho"))
398 return UnknownEnvironment;
401 void Triple::Parse() const {
402 assert(!isInitialized() && "Invalid parse call.");
404 Arch = ParseArch(getArchName());
405 Vendor = ParseVendor(getVendorName());
406 OS = ParseOS(getOSName());
407 Environment = ParseEnvironment(getEnvironmentName());
409 assert(isInitialized() && "Failed to initialize!");
412 std::string Triple::normalize(StringRef Str) {
413 // Parse into components.
414 SmallVector<StringRef, 4> Components;
415 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
416 Last = Str.find('-', First);
417 Components.push_back(Str.slice(First, Last));
420 // If the first component corresponds to a known architecture, preferentially
421 // use it for the architecture. If the second component corresponds to a
422 // known vendor, preferentially use it for the vendor, etc. This avoids silly
423 // component movement when a component parses as (eg) both a valid arch and a
425 ArchType Arch = UnknownArch;
426 if (Components.size() > 0)
427 Arch = ParseArch(Components[0]);
428 VendorType Vendor = UnknownVendor;
429 if (Components.size() > 1)
430 Vendor = ParseVendor(Components[1]);
431 OSType OS = UnknownOS;
432 if (Components.size() > 2)
433 OS = ParseOS(Components[2]);
434 EnvironmentType Environment = UnknownEnvironment;
435 if (Components.size() > 3)
436 Environment = ParseEnvironment(Components[3]);
438 // Note which components are already in their final position. These will not
441 Found[0] = Arch != UnknownArch;
442 Found[1] = Vendor != UnknownVendor;
443 Found[2] = OS != UnknownOS;
444 Found[3] = Environment != UnknownEnvironment;
446 // If they are not there already, permute the components into their canonical
447 // positions by seeing if they parse as a valid architecture, and if so moving
448 // the component to the architecture position etc.
449 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
451 continue; // Already in the canonical position.
453 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
454 // Do not reparse any components that already matched.
455 if (Idx < array_lengthof(Found) && Found[Idx])
458 // Does this component parse as valid for the target position?
460 StringRef Comp = Components[Idx];
463 assert(false && "unexpected component type!");
465 Arch = ParseArch(Comp);
466 Valid = Arch != UnknownArch;
469 Vendor = ParseVendor(Comp);
470 Valid = Vendor != UnknownVendor;
474 Valid = OS != UnknownOS;
477 Environment = ParseEnvironment(Comp);
478 Valid = Environment != UnknownEnvironment;
482 continue; // Nope, try the next component.
484 // Move the component to the target position, pushing any non-fixed
485 // components that are in the way to the right. This tends to give
486 // good results in the common cases of a forgotten vendor component
487 // or a wrongly positioned environment.
489 // Insert left, pushing the existing components to the right. For
490 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
491 StringRef CurrentComponent(""); // The empty component.
492 // Replace the component we are moving with an empty component.
493 std::swap(CurrentComponent, Components[Idx]);
494 // Insert the component being moved at Pos, displacing any existing
495 // components to the right.
496 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
497 // Skip over any fixed components.
498 while (i < array_lengthof(Found) && Found[i]) ++i;
499 // Place the component at the new position, getting the component
500 // that was at this position - it will be moved right.
501 std::swap(CurrentComponent, Components[i]);
503 } else if (Pos > Idx) {
504 // Push right by inserting empty components until the component at Idx
505 // reaches the target position Pos. For example, pc-a -> -pc-a when
506 // moving pc to the second position.
508 // Insert one empty component at Idx.
509 StringRef CurrentComponent(""); // The empty component.
510 for (unsigned i = Idx; i < Components.size();) {
511 // Place the component at the new position, getting the component
512 // that was at this position - it will be moved right.
513 std::swap(CurrentComponent, Components[i]);
514 // If it was placed on top of an empty component then we are done.
515 if (CurrentComponent.empty())
517 // Advance to the next component, skipping any fixed components.
518 while (++i < array_lengthof(Found) && Found[i])
521 // The last component was pushed off the end - append it.
522 if (!CurrentComponent.empty())
523 Components.push_back(CurrentComponent);
525 // Advance Idx to the component's new position.
526 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
527 } while (Idx < Pos); // Add more until the final position is reached.
529 assert(Pos < Components.size() && Components[Pos] == Comp &&
530 "Component moved wrong!");
536 // Special case logic goes here. At this point Arch, Vendor and OS have the
537 // correct values for the computed components.
539 // Stick the corrected components back together to form the normalized string.
540 std::string Normalized;
541 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
542 if (i) Normalized += '-';
543 Normalized += Components[i];
548 StringRef Triple::getArchName() const {
549 return StringRef(Data).split('-').first; // Isolate first component
552 StringRef Triple::getVendorName() const {
553 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
554 return Tmp.split('-').first; // Isolate second component
557 StringRef Triple::getOSName() const {
558 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
559 Tmp = Tmp.split('-').second; // Strip second component
560 return Tmp.split('-').first; // Isolate third component
563 StringRef Triple::getEnvironmentName() const {
564 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
565 Tmp = Tmp.split('-').second; // Strip second component
566 return Tmp.split('-').second; // Strip third component
569 StringRef Triple::getOSAndEnvironmentName() const {
570 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
571 return Tmp.split('-').second; // Strip second component
574 static unsigned EatNumber(StringRef &Str) {
575 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
579 // Consume the leading digit.
580 Result = Result*10 + (Str[0] - '0');
584 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
589 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
590 unsigned &Micro) const {
591 StringRef OSName = getOSName();
593 // Assume that the OS portion of the triple starts with the canonical name.
594 StringRef OSTypeName = getOSTypeName(getOS());
595 if (OSName.startswith(OSTypeName))
596 OSName = OSName.substr(OSTypeName.size());
598 // Any unset version defaults to 0.
599 Major = Minor = Micro = 0;
601 // Parse up to three components.
602 unsigned *Components[3] = { &Major, &Minor, &Micro };
603 for (unsigned i = 0; i != 3; ++i) {
604 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
607 // Consume the leading number.
608 *Components[i] = EatNumber(OSName);
610 // Consume the separator, if present.
611 if (OSName.startswith("."))
612 OSName = OSName.substr(1);
616 void Triple::setTriple(const Twine &Str) {
621 void Triple::setArch(ArchType Kind) {
622 setArchName(getArchTypeName(Kind));
625 void Triple::setVendor(VendorType Kind) {
626 setVendorName(getVendorTypeName(Kind));
629 void Triple::setOS(OSType Kind) {
630 setOSName(getOSTypeName(Kind));
633 void Triple::setEnvironment(EnvironmentType Kind) {
634 setEnvironmentName(getEnvironmentTypeName(Kind));
637 void Triple::setArchName(StringRef Str) {
638 // Work around a miscompilation bug for Twines in gcc 4.0.3.
639 SmallString<64> Triple;
642 Triple += getVendorName();
644 Triple += getOSAndEnvironmentName();
645 setTriple(Triple.str());
648 void Triple::setVendorName(StringRef Str) {
649 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
652 void Triple::setOSName(StringRef Str) {
653 if (hasEnvironment())
654 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
655 "-" + getEnvironmentName());
657 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
660 void Triple::setEnvironmentName(StringRef Str) {
661 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
665 void Triple::setOSAndEnvironmentName(StringRef Str) {
666 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);