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"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/Twine.h"
21 const char *Triple::getArchTypeName(ArchType Kind) {
23 case InvalidArch: return "<invalid>";
24 case UnknownArch: return "unknown";
26 case alpha: return "alpha";
27 case arm: return "arm";
28 case bfin: return "bfin";
29 case cellspu: return "cellspu";
30 case mips: return "mips";
31 case mipsel: return "mipsel";
32 case msp430: return "msp430";
33 case ppc64: return "powerpc64";
34 case ppc: return "powerpc";
35 case sparc: return "sparc";
36 case sparcv9: return "sparcv9";
37 case systemz: return "s390x";
38 case tce: return "tce";
39 case thumb: return "thumb";
40 case x86: return "i386";
41 case x86_64: return "x86_64";
42 case xcore: return "xcore";
43 case mblaze: return "mblaze";
44 case ptx: return "ptx";
50 const char *Triple::getArchTypePrefix(ArchType Kind) {
55 case alpha: return "alpha";
58 case thumb: return "arm";
60 case bfin: return "bfin";
62 case cellspu: return "spu";
65 case ppc: return "ppc";
67 case mblaze: return "mblaze";
70 case sparc: return "sparc";
73 case x86_64: return "x86";
75 case xcore: return "xcore";
77 case ptx: return "ptx";
81 const char *Triple::getVendorTypeName(VendorType Kind) {
83 case UnknownVendor: return "unknown";
85 case Apple: return "apple";
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 Linux: return "linux";
102 case Lv2: return "lv2";
103 case MinGW32: return "mingw32";
104 case NetBSD: return "netbsd";
105 case OpenBSD: return "openbsd";
106 case Psp: return "psp";
107 case Solaris: return "solaris";
108 case Win32: return "win32";
109 case Haiku: return "haiku";
110 case Minix: return "minix";
116 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
118 case UnknownEnvironment: return "unknown";
119 case GNU: return "gnu";
120 case GNUEABI: return "gnueabi";
121 case EABI: return "eabi";
122 case MachO: return "macho";
128 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
135 if (Name == "cellspu")
139 if (Name == "mipsel")
141 if (Name == "msp430")
147 if (Name == "mblaze")
151 if (Name == "sparcv9")
153 if (Name == "systemz")
161 if (Name == "x86-64")
171 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
172 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
173 // archs which Darwin doesn't use.
175 // The matching this routine does is fairly pointless, since it is neither the
176 // complete architecture list, nor a reasonable subset. The problem is that
177 // historically the driver driver accepts this and also ties its -march=
178 // handling to the architecture name, so we need to be careful before removing
181 // This code must be kept in sync with Clang's Darwin specific argument
184 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
185 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
186 Str == "ppc7450" || Str == "ppc970")
190 return Triple::ppc64;
192 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
193 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
194 Str == "pentIIm5" || Str == "pentium4")
198 return Triple::x86_64;
200 // This is derived from the driver driver.
201 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
202 Str == "armv6" || Str == "armv7")
208 return Triple::UnknownArch;
211 // Returns architecture name that is understood by the target assembler.
212 const char *Triple::getArchNameForAssembler() {
213 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
216 StringRef Str = getArchName();
221 if (Str == "powerpc")
223 if (Str == "powerpc64")
225 if (Str == "mblaze" || Str == "microblaze")
229 if (Str == "armv4t" || Str == "thumbv4t")
231 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5"
232 || Str == "thumbv5e")
234 if (Str == "armv6" || Str == "thumbv6")
236 if (Str == "armv7" || Str == "thumbv7")
245 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
246 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
247 ArchName[2] == '8' && ArchName[3] == '6' &&
248 ArchName[1] - '3' < 6) // i[3-9]86
250 else if (ArchName == "amd64" || ArchName == "x86_64")
252 else if (ArchName == "bfin")
254 else if (ArchName == "powerpc")
256 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
258 else if (ArchName == "mblaze")
260 else if (ArchName == "arm" ||
261 ArchName.startswith("armv") ||
262 ArchName == "xscale")
264 else if (ArchName == "thumb" ||
265 ArchName.startswith("thumbv"))
267 else if (ArchName.startswith("alpha"))
269 else if (ArchName == "spu" || ArchName == "cellspu")
271 else if (ArchName == "msp430")
273 else if (ArchName == "mips" || ArchName == "mipsallegrex")
275 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
278 else if (ArchName == "sparc")
280 else if (ArchName == "sparcv9")
282 else if (ArchName == "s390x")
284 else if (ArchName == "tce")
286 else if (ArchName == "xcore")
288 else if (ArchName == "ptx")
294 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
295 if (VendorName == "apple")
297 else if (VendorName == "pc")
300 return UnknownVendor;
303 Triple::OSType Triple::ParseOS(StringRef OSName) {
304 if (OSName.startswith("auroraux"))
306 else if (OSName.startswith("cygwin"))
308 else if (OSName.startswith("darwin"))
310 else if (OSName.startswith("dragonfly"))
312 else if (OSName.startswith("freebsd"))
314 else if (OSName.startswith("linux"))
316 else if (OSName.startswith("lv2"))
318 else if (OSName.startswith("mingw32"))
320 else if (OSName.startswith("netbsd"))
322 else if (OSName.startswith("openbsd"))
324 else if (OSName.startswith("psp"))
326 else if (OSName.startswith("solaris"))
328 else if (OSName.startswith("win32"))
330 else if (OSName.startswith("haiku"))
332 else if (OSName.startswith("minix"))
338 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
339 if (EnvironmentName.startswith("eabi"))
341 else if (EnvironmentName.startswith("gnueabi"))
343 else if (EnvironmentName.startswith("gnu"))
345 else if (EnvironmentName.startswith("macho"))
348 return UnknownEnvironment;
351 void Triple::Parse() const {
352 assert(!isInitialized() && "Invalid parse call.");
354 Arch = ParseArch(getArchName());
355 Vendor = ParseVendor(getVendorName());
356 OS = ParseOS(getOSName());
357 Environment = ParseEnvironment(getEnvironmentName());
359 assert(isInitialized() && "Failed to initialize!");
362 std::string Triple::normalize(StringRef Str) {
363 // Parse into components.
364 SmallVector<StringRef, 4> Components;
365 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
366 Last = Str.find('-', First);
367 Components.push_back(Str.slice(First, Last));
370 // If the first component corresponds to a known architecture, preferentially
371 // use it for the architecture. If the second component corresponds to a
372 // known vendor, preferentially use it for the vendor, etc. This avoids silly
373 // component movement when a component parses as (eg) both a valid arch and a
375 ArchType Arch = UnknownArch;
376 if (Components.size() > 0)
377 Arch = ParseArch(Components[0]);
378 VendorType Vendor = UnknownVendor;
379 if (Components.size() > 1)
380 Vendor = ParseVendor(Components[1]);
381 OSType OS = UnknownOS;
382 if (Components.size() > 2)
383 OS = ParseOS(Components[2]);
384 EnvironmentType Environment = UnknownEnvironment;
385 if (Components.size() > 3)
386 Environment = ParseEnvironment(Components[3]);
388 // Note which components are already in their final position. These will not
391 Found[0] = Arch != UnknownArch;
392 Found[1] = Vendor != UnknownVendor;
393 Found[2] = OS != UnknownOS;
394 Found[3] = Environment != UnknownEnvironment;
396 // If they are not there already, permute the components into their canonical
397 // positions by seeing if they parse as a valid architecture, and if so moving
398 // the component to the architecture position etc.
399 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
401 continue; // Already in the canonical position.
403 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
404 // Do not reparse any components that already matched.
405 if (Idx < array_lengthof(Found) && Found[Idx])
408 // Does this component parse as valid for the target position?
410 StringRef Comp = Components[Idx];
413 assert(false && "unexpected component type!");
415 Arch = ParseArch(Comp);
416 Valid = Arch != UnknownArch;
419 Vendor = ParseVendor(Comp);
420 Valid = Vendor != UnknownVendor;
424 Valid = OS != UnknownOS;
427 Environment = ParseEnvironment(Comp);
428 Valid = Environment != UnknownEnvironment;
432 continue; // Nope, try the next component.
434 // Move the component to the target position, pushing any non-fixed
435 // components that are in the way to the right. This tends to give
436 // good results in the common cases of a forgotten vendor component
437 // or a wrongly positioned environment.
439 // Insert left, pushing the existing components to the right. For
440 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
441 StringRef CurrentComponent(""); // The empty component.
442 // Replace the component we are moving with an empty component.
443 std::swap(CurrentComponent, Components[Idx]);
444 // Insert the component being moved at Pos, displacing any existing
445 // components to the right.
446 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
447 // Skip over any fixed components.
448 while (i < array_lengthof(Found) && Found[i]) ++i;
449 // Place the component at the new position, getting the component
450 // that was at this position - it will be moved right.
451 std::swap(CurrentComponent, Components[i]);
453 } else if (Pos > Idx) {
454 // Push right by inserting empty components until the component at Idx
455 // reaches the target position Pos. For example, pc-a -> -pc-a when
456 // moving pc to the second position.
458 // Insert one empty component at Idx.
459 StringRef CurrentComponent(""); // The empty component.
460 for (unsigned i = Idx; i < Components.size();) {
461 // Place the component at the new position, getting the component
462 // that was at this position - it will be moved right.
463 std::swap(CurrentComponent, Components[i]);
464 // If it was placed on top of an empty component then we are done.
465 if (CurrentComponent.empty())
467 // Advance to the next component, skipping any fixed components.
468 while (++i < array_lengthof(Found) && Found[i])
471 // The last component was pushed off the end - append it.
472 if (!CurrentComponent.empty())
473 Components.push_back(CurrentComponent);
475 // Advance Idx to the component's new position.
476 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
477 } while (Idx < Pos); // Add more until the final position is reached.
479 assert(Pos < Components.size() && Components[Pos] == Comp &&
480 "Component moved wrong!");
486 // Special case logic goes here. At this point Arch, Vendor and OS have the
487 // correct values for the computed components.
489 // Stick the corrected components back together to form the normalized string.
490 std::string Normalized;
491 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
492 if (i) Normalized += '-';
493 Normalized += Components[i];
498 StringRef Triple::getArchName() const {
499 return StringRef(Data).split('-').first; // Isolate first component
502 StringRef Triple::getVendorName() const {
503 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
504 return Tmp.split('-').first; // Isolate second component
507 StringRef Triple::getOSName() const {
508 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
509 Tmp = Tmp.split('-').second; // Strip second component
510 return Tmp.split('-').first; // Isolate third component
513 StringRef Triple::getEnvironmentName() const {
514 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
515 Tmp = Tmp.split('-').second; // Strip second component
516 return Tmp.split('-').second; // Strip third component
519 StringRef Triple::getOSAndEnvironmentName() const {
520 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
521 return Tmp.split('-').second; // Strip second component
524 static unsigned EatNumber(StringRef &Str) {
525 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
526 unsigned Result = Str[0]-'0';
531 // Handle "darwin11".
532 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
533 Result = Result*10 + (Str[0] - '0');
541 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
542 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
543 /// not defined, return 0's. This requires that the triple have an OSType of
544 /// darwin before it is called.
545 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
546 unsigned &Revision) const {
547 assert(getOS() == Darwin && "Not a darwin target triple!");
548 StringRef OSName = getOSName();
549 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
551 // Strip off "darwin".
552 OSName = OSName.substr(6);
554 Maj = Min = Revision = 0;
556 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
559 // The major version is the first digit.
560 Maj = EatNumber(OSName);
561 if (OSName.empty()) return;
563 // Handle minor version: 10.4.9 -> darwin8.9.
564 if (OSName[0] != '.')
568 OSName = OSName.substr(1);
570 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
573 Min = EatNumber(OSName);
574 if (OSName.empty()) return;
576 // Handle revision darwin8.9.1
577 if (OSName[0] != '.')
581 OSName = OSName.substr(1);
583 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
586 Revision = EatNumber(OSName);
589 void Triple::setTriple(const Twine &Str) {
594 void Triple::setArch(ArchType Kind) {
595 setArchName(getArchTypeName(Kind));
598 void Triple::setVendor(VendorType Kind) {
599 setVendorName(getVendorTypeName(Kind));
602 void Triple::setOS(OSType Kind) {
603 setOSName(getOSTypeName(Kind));
606 void Triple::setEnvironment(EnvironmentType Kind) {
607 setEnvironmentName(getEnvironmentTypeName(Kind));
610 void Triple::setArchName(StringRef Str) {
611 // Work around a miscompilation bug for Twines in gcc 4.0.3.
612 SmallString<64> Triple;
615 Triple += getVendorName();
617 Triple += getOSAndEnvironmentName();
618 setTriple(Triple.str());
621 void Triple::setVendorName(StringRef Str) {
622 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
625 void Triple::setOSName(StringRef Str) {
626 if (hasEnvironment())
627 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
628 "-" + getEnvironmentName());
630 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
633 void Triple::setEnvironmentName(StringRef Str) {
634 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
638 void Triple::setOSAndEnvironmentName(StringRef Str) {
639 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);