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 MinGW64: return "mingw64";
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";
117 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
119 case UnknownEnvironment: return "unknown";
125 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
132 if (Name == "cellspu")
136 if (Name == "mipsel")
138 if (Name == "msp430")
144 if (Name == "mblaze")
148 if (Name == "sparcv9")
150 if (Name == "systemz")
158 if (Name == "x86-64")
168 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
169 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
170 // archs which Darwin doesn't use.
172 // The matching this routine does is fairly pointless, since it is neither the
173 // complete architecture list, nor a reasonable subset. The problem is that
174 // historically the driver driver accepts this and also ties its -march=
175 // handling to the architecture name, so we need to be careful before removing
178 // This code must be kept in sync with Clang's Darwin specific argument
181 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
182 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
183 Str == "ppc7450" || Str == "ppc970")
187 return Triple::ppc64;
189 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
190 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
191 Str == "pentIIm5" || Str == "pentium4")
195 return Triple::x86_64;
197 // This is derived from the driver driver.
198 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
199 Str == "armv6" || Str == "armv7")
205 return Triple::UnknownArch;
208 // Returns architecture name that is understood by the target assembler.
209 const char *Triple::getArchNameForAssembler() {
210 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
213 StringRef Str = getArchName();
218 if (Str == "powerpc")
220 if (Str == "powerpc64")
222 if (Str == "mblaze" || Str == "microblaze")
226 if (Str == "armv4t" || Str == "thumbv4t")
228 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5"
229 || Str == "thumbv5e")
231 if (Str == "armv6" || Str == "thumbv6")
233 if (Str == "armv7" || Str == "thumbv7")
242 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
243 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
244 ArchName[2] == '8' && ArchName[3] == '6' &&
245 ArchName[1] - '3' < 6) // i[3-9]86
247 else if (ArchName == "amd64" || ArchName == "x86_64")
249 else if (ArchName == "bfin")
251 else if (ArchName == "powerpc")
253 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
255 else if (ArchName == "mblaze")
257 else if (ArchName == "arm" ||
258 ArchName.startswith("armv") ||
259 ArchName == "xscale")
261 else if (ArchName == "thumb" ||
262 ArchName.startswith("thumbv"))
264 else if (ArchName.startswith("alpha"))
266 else if (ArchName == "spu" || ArchName == "cellspu")
268 else if (ArchName == "msp430")
270 else if (ArchName == "mips" || ArchName == "mipsallegrex")
272 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
275 else if (ArchName == "sparc")
277 else if (ArchName == "sparcv9")
279 else if (ArchName == "s390x")
281 else if (ArchName == "tce")
283 else if (ArchName == "xcore")
285 else if (ArchName == "ptx")
291 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
292 if (VendorName == "apple")
294 else if (VendorName == "pc")
297 return UnknownVendor;
300 Triple::OSType Triple::ParseOS(StringRef OSName) {
301 if (OSName.startswith("auroraux"))
303 else if (OSName.startswith("cygwin"))
305 else if (OSName.startswith("darwin"))
307 else if (OSName.startswith("dragonfly"))
309 else if (OSName.startswith("freebsd"))
311 else if (OSName.startswith("linux"))
313 else if (OSName.startswith("lv2"))
315 else if (OSName.startswith("mingw32"))
317 else if (OSName.startswith("mingw64"))
319 else if (OSName.startswith("netbsd"))
321 else if (OSName.startswith("openbsd"))
323 else if (OSName.startswith("psp"))
325 else if (OSName.startswith("solaris"))
327 else if (OSName.startswith("win32"))
329 else if (OSName.startswith("haiku"))
331 else if (OSName.startswith("minix"))
337 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
338 return UnknownEnvironment;
341 void Triple::Parse() const {
342 assert(!isInitialized() && "Invalid parse call.");
344 Arch = ParseArch(getArchName());
345 Vendor = ParseVendor(getVendorName());
346 OS = ParseOS(getOSName());
347 Environment = ParseEnvironment(getEnvironmentName());
349 assert(isInitialized() && "Failed to initialize!");
352 std::string Triple::normalize(StringRef Str) {
353 // Parse into components.
354 SmallVector<StringRef, 4> Components;
355 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
356 Last = Str.find('-', First);
357 Components.push_back(Str.slice(First, Last));
360 // If the first component corresponds to a known architecture, preferentially
361 // use it for the architecture. If the second component corresponds to a
362 // known vendor, preferentially use it for the vendor, etc. This avoids silly
363 // component movement when a component parses as (eg) both a valid arch and a
365 ArchType Arch = UnknownArch;
366 if (Components.size() > 0)
367 Arch = ParseArch(Components[0]);
368 VendorType Vendor = UnknownVendor;
369 if (Components.size() > 1)
370 Vendor = ParseVendor(Components[1]);
371 OSType OS = UnknownOS;
372 if (Components.size() > 2)
373 OS = ParseOS(Components[2]);
374 EnvironmentType Environment = UnknownEnvironment;
375 if (Components.size() > 3)
376 Environment = ParseEnvironment(Components[3]);
378 // Note which components are already in their final position. These will not
381 Found[0] = Arch != UnknownArch;
382 Found[1] = Vendor != UnknownVendor;
383 Found[2] = OS != UnknownOS;
384 Found[3] = Environment != UnknownEnvironment;
386 // If they are not there already, permute the components into their canonical
387 // positions by seeing if they parse as a valid architecture, and if so moving
388 // the component to the architecture position etc.
389 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
391 continue; // Already in the canonical position.
393 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
394 // Do not reparse any components that already matched.
395 if (Idx < array_lengthof(Found) && Found[Idx])
398 // Does this component parse as valid for the target position?
400 StringRef Comp = Components[Idx];
403 assert(false && "unexpected component type!");
405 Arch = ParseArch(Comp);
406 Valid = Arch != UnknownArch;
409 Vendor = ParseVendor(Comp);
410 Valid = Vendor != UnknownVendor;
414 Valid = OS != UnknownOS;
417 Environment = ParseEnvironment(Comp);
418 Valid = Environment != UnknownEnvironment;
422 continue; // Nope, try the next component.
424 // Move the component to the target position, pushing any non-fixed
425 // components that are in the way to the right. This tends to give
426 // good results in the common cases of a forgotten vendor component
427 // or a wrongly positioned environment.
429 // Insert left, pushing the existing components to the right. For
430 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
431 StringRef CurrentComponent(""); // The empty component.
432 // Replace the component we are moving with an empty component.
433 std::swap(CurrentComponent, Components[Idx]);
434 // Insert the component being moved at Pos, displacing any existing
435 // components to the right.
436 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
437 // Skip over any fixed components.
438 while (i < array_lengthof(Found) && Found[i]) ++i;
439 // Place the component at the new position, getting the component
440 // that was at this position - it will be moved right.
441 std::swap(CurrentComponent, Components[i]);
443 } else if (Pos > Idx) {
444 // Push right by inserting empty components until the component at Idx
445 // reaches the target position Pos. For example, pc-a -> -pc-a when
446 // moving pc to the second position.
448 // Insert one empty component at Idx.
449 StringRef CurrentComponent(""); // The empty component.
450 for (unsigned i = Idx; i < Components.size(); ++i) {
451 // Skip over any fixed components.
452 while (i < array_lengthof(Found) && Found[i]) ++i;
453 // Place the component at the new position, getting the component
454 // that was at this position - it will be moved right.
455 std::swap(CurrentComponent, Components[i]);
456 // If it was placed on top of an empty component then we are done.
457 if (CurrentComponent.empty())
460 // The last component was pushed off the end - append it.
461 if (!CurrentComponent.empty())
462 Components.push_back(CurrentComponent);
464 // Advance Idx to the component's new position.
465 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
466 } while (Idx < Pos); // Add more until the final position is reached.
468 assert(Pos < Components.size() && Components[Pos] == Comp &&
469 "Component moved wrong!");
475 // Special case logic goes here. At this point Arch, Vendor and OS have the
476 // correct values for the computed components.
478 // Stick the corrected components back together to form the normalized string.
479 std::string Normalized;
480 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
481 if (i) Normalized += '-';
482 Normalized += Components[i];
487 StringRef Triple::getArchName() const {
488 return StringRef(Data).split('-').first; // Isolate first component
491 StringRef Triple::getVendorName() const {
492 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
493 return Tmp.split('-').first; // Isolate second component
496 StringRef Triple::getOSName() const {
497 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
498 Tmp = Tmp.split('-').second; // Strip second component
499 return Tmp.split('-').first; // Isolate third component
502 StringRef Triple::getEnvironmentName() const {
503 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
504 Tmp = Tmp.split('-').second; // Strip second component
505 return Tmp.split('-').second; // Strip third component
508 StringRef Triple::getOSAndEnvironmentName() const {
509 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
510 return Tmp.split('-').second; // Strip second component
513 static unsigned EatNumber(StringRef &Str) {
514 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
515 unsigned Result = Str[0]-'0';
520 // Handle "darwin11".
521 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
522 Result = Result*10 + (Str[0] - '0');
530 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
531 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
532 /// not defined, return 0's. This requires that the triple have an OSType of
533 /// darwin before it is called.
534 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
535 unsigned &Revision) const {
536 assert(getOS() == Darwin && "Not a darwin target triple!");
537 StringRef OSName = getOSName();
538 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
540 // Strip off "darwin".
541 OSName = OSName.substr(6);
543 Maj = Min = Revision = 0;
545 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
548 // The major version is the first digit.
549 Maj = EatNumber(OSName);
550 if (OSName.empty()) return;
552 // Handle minor version: 10.4.9 -> darwin8.9.
553 if (OSName[0] != '.')
557 OSName = OSName.substr(1);
559 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
562 Min = EatNumber(OSName);
563 if (OSName.empty()) return;
565 // Handle revision darwin8.9.1
566 if (OSName[0] != '.')
570 OSName = OSName.substr(1);
572 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
575 Revision = EatNumber(OSName);
578 void Triple::setTriple(const Twine &Str) {
583 void Triple::setArch(ArchType Kind) {
584 setArchName(getArchTypeName(Kind));
587 void Triple::setVendor(VendorType Kind) {
588 setVendorName(getVendorTypeName(Kind));
591 void Triple::setOS(OSType Kind) {
592 setOSName(getOSTypeName(Kind));
595 void Triple::setEnvironment(EnvironmentType Kind) {
596 setEnvironmentName(getEnvironmentTypeName(Kind));
599 void Triple::setArchName(StringRef Str) {
600 // Work around a miscompilation bug for Twines in gcc 4.0.3.
601 SmallString<64> Triple;
604 Triple += getVendorName();
606 Triple += getOSAndEnvironmentName();
607 setTriple(Triple.str());
610 void Triple::setVendorName(StringRef Str) {
611 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
614 void Triple::setOSName(StringRef Str) {
615 if (hasEnvironment())
616 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
617 "-" + getEnvironmentName());
619 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
622 void Triple::setEnvironmentName(StringRef Str) {
623 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
627 void Triple::setOSAndEnvironmentName(StringRef Str) {
628 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);