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" || Str == "thumbv5e")
230 if (Str == "armv6" || Str == "thumbv6")
232 if (Str == "armv7" || Str == "thumbv7")
241 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
242 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
243 ArchName[2] == '8' && ArchName[3] == '6' &&
244 ArchName[1] - '3' < 6) // i[3-9]86
246 else if (ArchName == "amd64" || ArchName == "x86_64")
248 else if (ArchName == "bfin")
250 else if (ArchName == "powerpc")
252 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
254 else if (ArchName == "mblaze")
256 else if (ArchName == "arm" ||
257 ArchName.startswith("armv") ||
258 ArchName == "xscale")
260 else if (ArchName == "thumb" ||
261 ArchName.startswith("thumbv"))
263 else if (ArchName.startswith("alpha"))
265 else if (ArchName == "spu" || ArchName == "cellspu")
267 else if (ArchName == "msp430")
269 else if (ArchName == "mips" || ArchName == "mipsallegrex")
271 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
274 else if (ArchName == "sparc")
276 else if (ArchName == "sparcv9")
278 else if (ArchName == "s390x")
280 else if (ArchName == "tce")
282 else if (ArchName == "xcore")
284 else if (ArchName == "ptx")
290 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
291 if (VendorName == "apple")
293 else if (VendorName == "pc")
296 return UnknownVendor;
299 Triple::OSType Triple::ParseOS(StringRef OSName) {
300 if (OSName.startswith("auroraux"))
302 else if (OSName.startswith("cygwin"))
304 else if (OSName.startswith("darwin"))
306 else if (OSName.startswith("dragonfly"))
308 else if (OSName.startswith("freebsd"))
310 else if (OSName.startswith("linux"))
312 else if (OSName.startswith("lv2"))
314 else if (OSName.startswith("mingw32"))
316 else if (OSName.startswith("mingw64"))
318 else if (OSName.startswith("netbsd"))
320 else if (OSName.startswith("openbsd"))
322 else if (OSName.startswith("psp"))
324 else if (OSName.startswith("solaris"))
326 else if (OSName.startswith("win32"))
328 else if (OSName.startswith("haiku"))
330 else if (OSName.startswith("minix"))
336 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
337 return UnknownEnvironment;
340 void Triple::Parse() const {
341 assert(!isInitialized() && "Invalid parse call.");
343 Arch = ParseArch(getArchName());
344 Vendor = ParseVendor(getVendorName());
345 OS = ParseOS(getOSName());
346 Environment = ParseEnvironment(getEnvironmentName());
348 assert(isInitialized() && "Failed to initialize!");
351 std::string Triple::normalize(StringRef Str) {
352 // Parse into components.
353 SmallVector<StringRef, 4> Components;
354 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
355 Last = Str.find('-', First);
356 Components.push_back(Str.slice(First, Last));
359 // If the first component corresponds to a known architecture, preferentially
360 // use it for the architecture. If the second component corresponds to a
361 // known vendor, preferentially use it for the vendor, etc. This avoids silly
362 // component movement when a component parses as (eg) both a valid arch and a
364 ArchType Arch = UnknownArch;
365 if (Components.size() > 0)
366 Arch = ParseArch(Components[0]);
367 VendorType Vendor = UnknownVendor;
368 if (Components.size() > 1)
369 Vendor = ParseVendor(Components[1]);
370 OSType OS = UnknownOS;
371 if (Components.size() > 2)
372 OS = ParseOS(Components[2]);
373 EnvironmentType Environment = UnknownEnvironment;
374 if (Components.size() > 3)
375 Environment = ParseEnvironment(Components[3]);
377 // Note which components are already in their final position. These will not
380 Found[0] = Arch != UnknownArch;
381 Found[1] = Vendor != UnknownVendor;
382 Found[2] = OS != UnknownOS;
383 Found[3] = Environment != UnknownEnvironment;
385 // If they are not there already, permute the components into their canonical
386 // positions by seeing if they parse as a valid architecture, and if so moving
387 // the component to the architecture position etc.
388 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
390 continue; // Already in the canonical position.
392 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
393 // Do not reparse any components that already matched.
394 if (Idx < array_lengthof(Found) && Found[Idx])
397 // Does this component parse as valid for the target position?
399 StringRef Comp = Components[Idx];
402 assert(false && "unexpected component type!");
404 Arch = ParseArch(Comp);
405 Valid = Arch != UnknownArch;
408 Vendor = ParseVendor(Comp);
409 Valid = Vendor != UnknownVendor;
413 Valid = OS != UnknownOS;
416 Environment = ParseEnvironment(Comp);
417 Valid = Environment != UnknownEnvironment;
421 continue; // Nope, try the next component.
423 // Move the component to the target position, pushing any non-fixed
424 // components that are in the way to the right. This tends to give
425 // good results in the common cases of a forgotten vendor component
426 // or a wrongly positioned environment.
428 // Insert left, pushing the existing components to the right. For
429 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
430 StringRef CurrentComponent(""); // The empty component.
431 // Replace the component we are moving with an empty component.
432 std::swap(CurrentComponent, Components[Idx]);
433 // Insert the component being moved at Pos, displacing any existing
434 // components to the right.
435 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
436 // Skip over any fixed components.
437 while (i < array_lengthof(Found) && Found[i]) ++i;
438 // Place the component at the new position, getting the component
439 // that was at this position - it will be moved right.
440 std::swap(CurrentComponent, Components[i]);
442 } else if (Pos > Idx) {
443 // Push right by inserting empty components until the component at Idx
444 // reaches the target position Pos. For example, pc-a -> -pc-a when
445 // moving pc to the second position.
447 // Insert one empty component at Idx.
448 StringRef CurrentComponent(""); // The empty component.
449 for (unsigned i = Idx; i < Components.size(); ++i) {
450 // Skip over any fixed components.
451 while (i < array_lengthof(Found) && Found[i]) ++i;
452 // Place the component at the new position, getting the component
453 // that was at this position - it will be moved right.
454 std::swap(CurrentComponent, Components[i]);
455 // If it was placed on top of an empty component then we are done.
456 if (CurrentComponent.empty())
459 // The last component was pushed off the end - append it.
460 if (!CurrentComponent.empty())
461 Components.push_back(CurrentComponent);
463 // Advance Idx to the component's new position.
464 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
465 } while (Idx < Pos); // Add more until the final position is reached.
467 assert(Pos < Components.size() && Components[Pos] == Comp &&
468 "Component moved wrong!");
474 // Special case logic goes here. At this point Arch, Vendor and OS have the
475 // correct values for the computed components.
477 // Stick the corrected components back together to form the normalized string.
478 std::string Normalized;
479 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
480 if (i) Normalized += '-';
481 Normalized += Components[i];
486 StringRef Triple::getArchName() const {
487 return StringRef(Data).split('-').first; // Isolate first component
490 StringRef Triple::getVendorName() const {
491 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
492 return Tmp.split('-').first; // Isolate second component
495 StringRef Triple::getOSName() const {
496 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
497 Tmp = Tmp.split('-').second; // Strip second component
498 return Tmp.split('-').first; // Isolate third component
501 StringRef Triple::getEnvironmentName() const {
502 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
503 Tmp = Tmp.split('-').second; // Strip second component
504 return Tmp.split('-').second; // Strip third component
507 StringRef Triple::getOSAndEnvironmentName() const {
508 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
509 return Tmp.split('-').second; // Strip second component
512 static unsigned EatNumber(StringRef &Str) {
513 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
514 unsigned Result = Str[0]-'0';
519 // Handle "darwin11".
520 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
521 Result = Result*10 + (Str[0] - '0');
529 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
530 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
531 /// not defined, return 0's. This requires that the triple have an OSType of
532 /// darwin before it is called.
533 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
534 unsigned &Revision) const {
535 assert(getOS() == Darwin && "Not a darwin target triple!");
536 StringRef OSName = getOSName();
537 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
539 // Strip off "darwin".
540 OSName = OSName.substr(6);
542 Maj = Min = Revision = 0;
544 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
547 // The major version is the first digit.
548 Maj = EatNumber(OSName);
549 if (OSName.empty()) return;
551 // Handle minor version: 10.4.9 -> darwin8.9.
552 if (OSName[0] != '.')
556 OSName = OSName.substr(1);
558 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
561 Min = EatNumber(OSName);
562 if (OSName.empty()) return;
564 // Handle revision darwin8.9.1
565 if (OSName[0] != '.')
569 OSName = OSName.substr(1);
571 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
574 Revision = EatNumber(OSName);
577 void Triple::setTriple(const Twine &Str) {
582 void Triple::setArch(ArchType Kind) {
583 setArchName(getArchTypeName(Kind));
586 void Triple::setVendor(VendorType Kind) {
587 setVendorName(getVendorTypeName(Kind));
590 void Triple::setOS(OSType Kind) {
591 setOSName(getOSTypeName(Kind));
594 void Triple::setEnvironment(EnvironmentType Kind) {
595 setEnvironmentName(getEnvironmentTypeName(Kind));
598 void Triple::setArchName(StringRef Str) {
599 // Work around a miscompilation bug for Twines in gcc 4.0.3.
600 SmallString<64> Triple;
603 Triple += getVendorName();
605 Triple += getOSAndEnvironmentName();
606 setTriple(Triple.str());
609 void Triple::setVendorName(StringRef Str) {
610 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
613 void Triple::setOSName(StringRef Str) {
614 if (hasEnvironment())
615 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
616 "-" + getEnvironmentName());
618 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
621 void Triple::setEnvironmentName(StringRef Str) {
622 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
626 void Triple::setOSAndEnvironmentName(StringRef Str) {
627 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);