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 msp430: return "msp430";
28 case ppc64: return "powerpc64";
29 case ppc: return "powerpc";
30 case sparc: return "sparc";
31 case sparcv9: return "sparcv9";
32 case systemz: return "s390x";
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";
46 const char *Triple::getArchTypePrefix(ArchType Kind) {
51 case alpha: return "alpha";
54 case thumb: return "arm";
56 case bfin: return "bfin";
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";
78 const char *Triple::getVendorTypeName(VendorType Kind) {
80 case UnknownVendor: return "unknown";
82 case Apple: return "apple";
84 case SCEI: return "scei";
90 const char *Triple::getOSTypeName(OSType Kind) {
92 case UnknownOS: return "unknown";
94 case AuroraUX: return "auroraux";
95 case Cygwin: return "cygwin";
96 case Darwin: return "darwin";
97 case DragonFly: return "dragonfly";
98 case FreeBSD: return "freebsd";
99 case IOS: return "ios";
100 case KFreeBSD: return "kfreebsd";
101 case Linux: return "linux";
102 case Lv2: return "lv2";
103 case MacOSX: return "macosx";
104 case MinGW32: return "mingw32";
105 case NetBSD: return "netbsd";
106 case OpenBSD: return "openbsd";
107 case Psp: return "psp";
108 case Solaris: return "solaris";
109 case Win32: return "win32";
110 case Haiku: return "haiku";
111 case Minix: return "minix";
112 case RTEMS: return "rtems";
113 case NativeClient: return "nacl";
119 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
121 case UnknownEnvironment: return "unknown";
122 case GNU: return "gnu";
123 case GNUEABI: return "gnueabi";
124 case EABI: return "eabi";
125 case MachO: return "macho";
131 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
138 if (Name == "cellspu")
142 if (Name == "mipsel")
144 if (Name == "msp430")
152 if (Name == "mblaze")
156 if (Name == "sparcv9")
158 if (Name == "systemz")
166 if (Name == "x86-64")
178 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
179 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
180 // archs which Darwin doesn't use.
182 // The matching this routine does is fairly pointless, since it is neither the
183 // complete architecture list, nor a reasonable subset. The problem is that
184 // historically the driver driver accepts this and also ties its -march=
185 // handling to the architecture name, so we need to be careful before removing
188 // This code must be kept in sync with Clang's Darwin specific argument
191 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
192 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
193 Str == "ppc7450" || Str == "ppc970")
197 return Triple::ppc64;
199 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
200 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
201 Str == "pentIIm5" || Str == "pentium4")
205 return Triple::x86_64;
207 // This is derived from the driver driver.
208 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
209 Str == "armv6" || Str == "armv7" || Str == "armv7f" || Str == "armv7k" ||
214 return Triple::ptx32;
216 return Triple::ptx64;
218 return Triple::UnknownArch;
221 // Returns architecture name that is understood by the target assembler.
222 const char *Triple::getArchNameForAssembler() {
223 if (!isOSDarwin() && getVendor() != Triple::Apple)
226 StringRef Str = getArchName();
231 if (Str == "powerpc")
233 if (Str == "powerpc64")
235 if (Str == "mblaze" || Str == "microblaze")
239 if (Str == "armv4t" || Str == "thumbv4t")
241 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5"
242 || Str == "thumbv5e")
244 if (Str == "armv6" || Str == "thumbv6")
246 if (Str == "armv7" || Str == "thumbv7")
257 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
258 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
259 ArchName[2] == '8' && ArchName[3] == '6' &&
260 ArchName[1] - '3' < 6) // i[3-9]86
262 else if (ArchName == "amd64" || ArchName == "x86_64")
264 else if (ArchName == "bfin")
266 else if (ArchName == "powerpc")
268 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
270 else if (ArchName == "mblaze")
272 else if (ArchName == "arm" ||
273 ArchName.startswith("armv") ||
274 ArchName == "xscale")
276 else if (ArchName == "thumb" ||
277 ArchName.startswith("thumbv"))
279 else if (ArchName.startswith("alpha"))
281 else if (ArchName == "spu" || ArchName == "cellspu")
283 else if (ArchName == "msp430")
285 else if (ArchName == "mips" || ArchName == "mipseb" ||
286 ArchName == "mipsallegrex")
288 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
291 else if (ArchName == "sparc")
293 else if (ArchName == "sparcv9")
295 else if (ArchName == "s390x")
297 else if (ArchName == "tce")
299 else if (ArchName == "xcore")
301 else if (ArchName == "ptx32")
303 else if (ArchName == "ptx64")
309 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
310 if (VendorName == "apple")
312 else if (VendorName == "pc")
314 else if (VendorName == "scei")
317 return UnknownVendor;
320 Triple::OSType Triple::ParseOS(StringRef OSName) {
321 if (OSName.startswith("auroraux"))
323 else if (OSName.startswith("cygwin"))
325 else if (OSName.startswith("darwin"))
327 else if (OSName.startswith("dragonfly"))
329 else if (OSName.startswith("freebsd"))
331 else if (OSName.startswith("ios"))
333 else if (OSName.startswith("kfreebsd"))
335 else if (OSName.startswith("linux"))
337 else if (OSName.startswith("lv2"))
339 else if (OSName.startswith("macosx"))
341 else if (OSName.startswith("mingw32"))
343 else if (OSName.startswith("netbsd"))
345 else if (OSName.startswith("openbsd"))
347 else if (OSName.startswith("psp"))
349 else if (OSName.startswith("solaris"))
351 else if (OSName.startswith("win32"))
353 else if (OSName.startswith("haiku"))
355 else if (OSName.startswith("minix"))
357 else if (OSName.startswith("rtems"))
359 else if (OSName.startswith("nacl"))
365 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
366 if (EnvironmentName.startswith("eabi"))
368 else if (EnvironmentName.startswith("gnueabi"))
370 else if (EnvironmentName.startswith("gnu"))
372 else if (EnvironmentName.startswith("macho"))
375 return UnknownEnvironment;
378 void Triple::Parse() const {
379 assert(!isInitialized() && "Invalid parse call.");
381 Arch = ParseArch(getArchName());
382 Vendor = ParseVendor(getVendorName());
383 OS = ParseOS(getOSName());
384 Environment = ParseEnvironment(getEnvironmentName());
386 assert(isInitialized() && "Failed to initialize!");
389 std::string Triple::normalize(StringRef Str) {
390 // Parse into components.
391 SmallVector<StringRef, 4> Components;
392 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
393 Last = Str.find('-', First);
394 Components.push_back(Str.slice(First, Last));
397 // If the first component corresponds to a known architecture, preferentially
398 // use it for the architecture. If the second component corresponds to a
399 // known vendor, preferentially use it for the vendor, etc. This avoids silly
400 // component movement when a component parses as (eg) both a valid arch and a
402 ArchType Arch = UnknownArch;
403 if (Components.size() > 0)
404 Arch = ParseArch(Components[0]);
405 VendorType Vendor = UnknownVendor;
406 if (Components.size() > 1)
407 Vendor = ParseVendor(Components[1]);
408 OSType OS = UnknownOS;
409 if (Components.size() > 2)
410 OS = ParseOS(Components[2]);
411 EnvironmentType Environment = UnknownEnvironment;
412 if (Components.size() > 3)
413 Environment = ParseEnvironment(Components[3]);
415 // Note which components are already in their final position. These will not
418 Found[0] = Arch != UnknownArch;
419 Found[1] = Vendor != UnknownVendor;
420 Found[2] = OS != UnknownOS;
421 Found[3] = Environment != UnknownEnvironment;
423 // If they are not there already, permute the components into their canonical
424 // positions by seeing if they parse as a valid architecture, and if so moving
425 // the component to the architecture position etc.
426 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
428 continue; // Already in the canonical position.
430 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
431 // Do not reparse any components that already matched.
432 if (Idx < array_lengthof(Found) && Found[Idx])
435 // Does this component parse as valid for the target position?
437 StringRef Comp = Components[Idx];
440 assert(false && "unexpected component type!");
442 Arch = ParseArch(Comp);
443 Valid = Arch != UnknownArch;
446 Vendor = ParseVendor(Comp);
447 Valid = Vendor != UnknownVendor;
451 Valid = OS != UnknownOS;
454 Environment = ParseEnvironment(Comp);
455 Valid = Environment != UnknownEnvironment;
459 continue; // Nope, try the next component.
461 // Move the component to the target position, pushing any non-fixed
462 // components that are in the way to the right. This tends to give
463 // good results in the common cases of a forgotten vendor component
464 // or a wrongly positioned environment.
466 // Insert left, pushing the existing components to the right. For
467 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
468 StringRef CurrentComponent(""); // The empty component.
469 // Replace the component we are moving with an empty component.
470 std::swap(CurrentComponent, Components[Idx]);
471 // Insert the component being moved at Pos, displacing any existing
472 // components to the right.
473 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
474 // Skip over any fixed components.
475 while (i < array_lengthof(Found) && Found[i]) ++i;
476 // Place the component at the new position, getting the component
477 // that was at this position - it will be moved right.
478 std::swap(CurrentComponent, Components[i]);
480 } else if (Pos > Idx) {
481 // Push right by inserting empty components until the component at Idx
482 // reaches the target position Pos. For example, pc-a -> -pc-a when
483 // moving pc to the second position.
485 // Insert one empty component at Idx.
486 StringRef CurrentComponent(""); // The empty component.
487 for (unsigned i = Idx; i < Components.size();) {
488 // Place the component at the new position, getting the component
489 // that was at this position - it will be moved right.
490 std::swap(CurrentComponent, Components[i]);
491 // If it was placed on top of an empty component then we are done.
492 if (CurrentComponent.empty())
494 // Advance to the next component, skipping any fixed components.
495 while (++i < array_lengthof(Found) && Found[i])
498 // The last component was pushed off the end - append it.
499 if (!CurrentComponent.empty())
500 Components.push_back(CurrentComponent);
502 // Advance Idx to the component's new position.
503 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
504 } while (Idx < Pos); // Add more until the final position is reached.
506 assert(Pos < Components.size() && Components[Pos] == Comp &&
507 "Component moved wrong!");
513 // Special case logic goes here. At this point Arch, Vendor and OS have the
514 // correct values for the computed components.
516 // Stick the corrected components back together to form the normalized string.
517 std::string Normalized;
518 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
519 if (i) Normalized += '-';
520 Normalized += Components[i];
525 StringRef Triple::getArchName() const {
526 return StringRef(Data).split('-').first; // Isolate first component
529 StringRef Triple::getVendorName() const {
530 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
531 return Tmp.split('-').first; // Isolate second component
534 StringRef Triple::getOSName() const {
535 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
536 Tmp = Tmp.split('-').second; // Strip second component
537 return Tmp.split('-').first; // Isolate third component
540 StringRef Triple::getEnvironmentName() const {
541 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
542 Tmp = Tmp.split('-').second; // Strip second component
543 return Tmp.split('-').second; // Strip third component
546 StringRef Triple::getOSAndEnvironmentName() const {
547 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
548 return Tmp.split('-').second; // Strip second component
551 static unsigned EatNumber(StringRef &Str) {
552 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
556 // Consume the leading digit.
557 Result = Result*10 + (Str[0] - '0');
561 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
566 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
567 unsigned &Micro) const {
568 StringRef OSName = getOSName();
570 // Assume that the OS portion of the triple starts with the canonical name.
571 StringRef OSTypeName = getOSTypeName(getOS());
572 if (OSName.startswith(OSTypeName))
573 OSName = OSName.substr(OSTypeName.size());
575 // Any unset version defaults to 0.
576 Major = Minor = Micro = 0;
578 // Parse up to three components.
579 unsigned *Components[3] = { &Major, &Minor, &Micro };
580 for (unsigned i = 0; i != 3; ++i) {
581 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
584 // Consume the leading number.
585 *Components[i] = EatNumber(OSName);
587 // Consume the separator, if present.
588 if (OSName.startswith("."))
589 OSName = OSName.substr(1);
593 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);