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 arm: return "arm";
22 case cellspu: return "cellspu";
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 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) {
54 case thumb: return "arm";
56 case cellspu: return "spu";
59 case ppc: return "ppc";
61 case mblaze: return "mblaze";
63 case hexagon: return "hexagon";
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";
128 case ANDROIDEABI: return "androideabi";
134 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
137 if (Name == "cellspu")
141 if (Name == "mipsel")
143 if (Name == "mips64")
145 if (Name == "mips64el")
147 if (Name == "msp430")
155 if (Name == "mblaze")
157 if (Name == "hexagon")
161 if (Name == "sparcv9")
169 if (Name == "x86-64")
185 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
186 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
187 // archs which Darwin doesn't use.
189 // The matching this routine does is fairly pointless, since it is neither the
190 // complete architecture list, nor a reasonable subset. The problem is that
191 // historically the driver driver accepts this and also ties its -march=
192 // handling to the architecture name, so we need to be careful before removing
195 // This code must be kept in sync with Clang's Darwin specific argument
198 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
199 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
200 Str == "ppc7450" || Str == "ppc970")
204 return Triple::ppc64;
206 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
207 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
208 Str == "pentIIm5" || Str == "pentium4")
212 return Triple::x86_64;
214 // This is derived from the driver driver.
215 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
216 Str == "armv6" || Str == "armv7" || Str == "armv7f" || Str == "armv7k" ||
221 return Triple::ptx32;
223 return Triple::ptx64;
225 return Triple::amdil;
227 return Triple::UnknownArch;
230 // Returns architecture name that is understood by the target assembler.
231 const char *Triple::getArchNameForAssembler() {
232 if (!isOSDarwin() && getVendor() != Triple::Apple)
235 StringRef Str = getArchName();
240 if (Str == "powerpc")
242 if (Str == "powerpc64")
244 if (Str == "mblaze" || Str == "microblaze")
248 if (Str == "armv4t" || Str == "thumbv4t")
250 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5"
251 || Str == "thumbv5e")
253 if (Str == "armv6" || Str == "thumbv6")
255 if (Str == "armv7" || Str == "thumbv7")
270 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
271 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
272 ArchName[2] == '8' && ArchName[3] == '6' &&
273 ArchName[1] - '3' < 6) // i[3-9]86
275 else if (ArchName == "amd64" || ArchName == "x86_64")
277 else if (ArchName == "powerpc")
279 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
281 else if (ArchName == "mblaze")
283 else if (ArchName == "arm" ||
284 ArchName.startswith("armv") ||
285 ArchName == "xscale")
287 else if (ArchName == "thumb" ||
288 ArchName.startswith("thumbv"))
290 else if (ArchName == "spu" || ArchName == "cellspu")
292 else if (ArchName == "msp430")
294 else if (ArchName == "mips" || ArchName == "mipseb" ||
295 ArchName == "mipsallegrex")
297 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
300 else if (ArchName == "mips64" || ArchName == "mips64eb")
302 else if (ArchName == "mips64el")
304 else if (ArchName == "hexagon")
306 else if (ArchName == "sparc")
308 else if (ArchName == "sparcv9")
310 else if (ArchName == "tce")
312 else if (ArchName == "xcore")
314 else if (ArchName == "ptx32")
316 else if (ArchName == "ptx64")
318 else if (ArchName == "le32")
320 else if (ArchName == "amdil")
326 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
327 if (VendorName == "apple")
329 else if (VendorName == "pc")
331 else if (VendorName == "scei")
334 return UnknownVendor;
337 Triple::OSType Triple::ParseOS(StringRef OSName) {
338 if (OSName.startswith("auroraux"))
340 else if (OSName.startswith("cygwin"))
342 else if (OSName.startswith("darwin"))
344 else if (OSName.startswith("dragonfly"))
346 else if (OSName.startswith("freebsd"))
348 else if (OSName.startswith("ios"))
350 else if (OSName.startswith("kfreebsd"))
352 else if (OSName.startswith("linux"))
354 else if (OSName.startswith("lv2"))
356 else if (OSName.startswith("macosx"))
358 else if (OSName.startswith("mingw32"))
360 else if (OSName.startswith("netbsd"))
362 else if (OSName.startswith("openbsd"))
364 else if (OSName.startswith("psp"))
366 else if (OSName.startswith("solaris"))
368 else if (OSName.startswith("win32"))
370 else if (OSName.startswith("haiku"))
372 else if (OSName.startswith("minix"))
374 else if (OSName.startswith("rtems"))
376 else if (OSName.startswith("nacl"))
382 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
383 if (EnvironmentName.startswith("eabi"))
385 else if (EnvironmentName.startswith("gnueabi"))
387 else if (EnvironmentName.startswith("gnu"))
389 else if (EnvironmentName.startswith("macho"))
391 else if (EnvironmentName.startswith("androideabi"))
394 return UnknownEnvironment;
397 void Triple::Parse() const {
398 assert(!isInitialized() && "Invalid parse call.");
400 Arch = ParseArch(getArchName());
401 Vendor = ParseVendor(getVendorName());
402 OS = ParseOS(getOSName());
403 Environment = ParseEnvironment(getEnvironmentName());
405 assert(isInitialized() && "Failed to initialize!");
408 std::string Triple::normalize(StringRef Str) {
409 // Parse into components.
410 SmallVector<StringRef, 4> Components;
411 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
412 Last = Str.find('-', First);
413 Components.push_back(Str.slice(First, Last));
416 // If the first component corresponds to a known architecture, preferentially
417 // use it for the architecture. If the second component corresponds to a
418 // known vendor, preferentially use it for the vendor, etc. This avoids silly
419 // component movement when a component parses as (eg) both a valid arch and a
421 ArchType Arch = UnknownArch;
422 if (Components.size() > 0)
423 Arch = ParseArch(Components[0]);
424 VendorType Vendor = UnknownVendor;
425 if (Components.size() > 1)
426 Vendor = ParseVendor(Components[1]);
427 OSType OS = UnknownOS;
428 if (Components.size() > 2)
429 OS = ParseOS(Components[2]);
430 EnvironmentType Environment = UnknownEnvironment;
431 if (Components.size() > 3)
432 Environment = ParseEnvironment(Components[3]);
434 // Note which components are already in their final position. These will not
437 Found[0] = Arch != UnknownArch;
438 Found[1] = Vendor != UnknownVendor;
439 Found[2] = OS != UnknownOS;
440 Found[3] = Environment != UnknownEnvironment;
442 // If they are not there already, permute the components into their canonical
443 // positions by seeing if they parse as a valid architecture, and if so moving
444 // the component to the architecture position etc.
445 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
447 continue; // Already in the canonical position.
449 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
450 // Do not reparse any components that already matched.
451 if (Idx < array_lengthof(Found) && Found[Idx])
454 // Does this component parse as valid for the target position?
456 StringRef Comp = Components[Idx];
459 assert(false && "unexpected component type!");
461 Arch = ParseArch(Comp);
462 Valid = Arch != UnknownArch;
465 Vendor = ParseVendor(Comp);
466 Valid = Vendor != UnknownVendor;
470 Valid = OS != UnknownOS;
473 Environment = ParseEnvironment(Comp);
474 Valid = Environment != UnknownEnvironment;
478 continue; // Nope, try the next component.
480 // Move the component to the target position, pushing any non-fixed
481 // components that are in the way to the right. This tends to give
482 // good results in the common cases of a forgotten vendor component
483 // or a wrongly positioned environment.
485 // Insert left, pushing the existing components to the right. For
486 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
487 StringRef CurrentComponent(""); // The empty component.
488 // Replace the component we are moving with an empty component.
489 std::swap(CurrentComponent, Components[Idx]);
490 // Insert the component being moved at Pos, displacing any existing
491 // components to the right.
492 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
493 // Skip over any fixed components.
494 while (i < array_lengthof(Found) && Found[i]) ++i;
495 // Place the component at the new position, getting the component
496 // that was at this position - it will be moved right.
497 std::swap(CurrentComponent, Components[i]);
499 } else if (Pos > Idx) {
500 // Push right by inserting empty components until the component at Idx
501 // reaches the target position Pos. For example, pc-a -> -pc-a when
502 // moving pc to the second position.
504 // Insert one empty component at Idx.
505 StringRef CurrentComponent(""); // The empty component.
506 for (unsigned i = Idx; i < Components.size();) {
507 // Place the component at the new position, getting the component
508 // that was at this position - it will be moved right.
509 std::swap(CurrentComponent, Components[i]);
510 // If it was placed on top of an empty component then we are done.
511 if (CurrentComponent.empty())
513 // Advance to the next component, skipping any fixed components.
514 while (++i < array_lengthof(Found) && Found[i])
517 // The last component was pushed off the end - append it.
518 if (!CurrentComponent.empty())
519 Components.push_back(CurrentComponent);
521 // Advance Idx to the component's new position.
522 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
523 } while (Idx < Pos); // Add more until the final position is reached.
525 assert(Pos < Components.size() && Components[Pos] == Comp &&
526 "Component moved wrong!");
532 // Special case logic goes here. At this point Arch, Vendor and OS have the
533 // correct values for the computed components.
535 // Stick the corrected components back together to form the normalized string.
536 std::string Normalized;
537 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
538 if (i) Normalized += '-';
539 Normalized += Components[i];
544 StringRef Triple::getArchName() const {
545 return StringRef(Data).split('-').first; // Isolate first component
548 StringRef Triple::getVendorName() const {
549 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
550 return Tmp.split('-').first; // Isolate second component
553 StringRef Triple::getOSName() const {
554 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
555 Tmp = Tmp.split('-').second; // Strip second component
556 return Tmp.split('-').first; // Isolate third component
559 StringRef Triple::getEnvironmentName() const {
560 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
561 Tmp = Tmp.split('-').second; // Strip second component
562 return Tmp.split('-').second; // Strip third component
565 StringRef Triple::getOSAndEnvironmentName() const {
566 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
567 return Tmp.split('-').second; // Strip second component
570 static unsigned EatNumber(StringRef &Str) {
571 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
575 // Consume the leading digit.
576 Result = Result*10 + (Str[0] - '0');
580 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
585 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
586 unsigned &Micro) const {
587 StringRef OSName = getOSName();
589 // Assume that the OS portion of the triple starts with the canonical name.
590 StringRef OSTypeName = getOSTypeName(getOS());
591 if (OSName.startswith(OSTypeName))
592 OSName = OSName.substr(OSTypeName.size());
594 // Any unset version defaults to 0.
595 Major = Minor = Micro = 0;
597 // Parse up to three components.
598 unsigned *Components[3] = { &Major, &Minor, &Micro };
599 for (unsigned i = 0; i != 3; ++i) {
600 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
603 // Consume the leading number.
604 *Components[i] = EatNumber(OSName);
606 // Consume the separator, if present.
607 if (OSName.startswith("."))
608 OSName = OSName.substr(1);
612 void Triple::setTriple(const Twine &Str) {
617 void Triple::setArch(ArchType Kind) {
618 setArchName(getArchTypeName(Kind));
621 void Triple::setVendor(VendorType Kind) {
622 setVendorName(getVendorTypeName(Kind));
625 void Triple::setOS(OSType Kind) {
626 setOSName(getOSTypeName(Kind));
629 void Triple::setEnvironment(EnvironmentType Kind) {
630 setEnvironmentName(getEnvironmentTypeName(Kind));
633 void Triple::setArchName(StringRef Str) {
634 // Work around a miscompilation bug for Twines in gcc 4.0.3.
635 SmallString<64> Triple;
638 Triple += getVendorName();
640 Triple += getOSAndEnvironmentName();
641 setTriple(Triple.str());
644 void Triple::setVendorName(StringRef Str) {
645 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
648 void Triple::setOSName(StringRef Str) {
649 if (hasEnvironment())
650 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
651 "-" + getEnvironmentName());
653 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
656 void Triple::setEnvironmentName(StringRef Str) {
657 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
661 void Triple::setOSAndEnvironmentName(StringRef Str) {
662 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);