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 pic16: return "pic16";
34 case ppc64: return "powerpc64";
35 case ppc: return "powerpc";
36 case sparc: return "sparc";
37 case sparcv9: return "sparcv9";
38 case systemz: return "s390x";
39 case tce: return "tce";
40 case thumb: return "thumb";
41 case x86: return "i386";
42 case x86_64: return "x86_64";
43 case xcore: return "xcore";
44 case mblaze: return "mblaze";
45 case ptx: return "ptx";
51 const char *Triple::getArchTypePrefix(ArchType Kind) {
56 case alpha: return "alpha";
59 case thumb: return "arm";
61 case bfin: return "bfin";
63 case cellspu: return "spu";
66 case ppc: return "ppc";
68 case mblaze: return "mblaze";
71 case sparc: return "sparc";
74 case x86_64: return "x86";
76 case xcore: return "xcore";
78 case ptx: return "ptx";
82 const char *Triple::getVendorTypeName(VendorType Kind) {
84 case UnknownVendor: return "unknown";
86 case Apple: return "apple";
93 const char *Triple::getOSTypeName(OSType Kind) {
95 case UnknownOS: return "unknown";
97 case AuroraUX: return "auroraux";
98 case Cygwin: return "cygwin";
99 case Darwin: return "darwin";
100 case DragonFly: return "dragonfly";
101 case FreeBSD: return "freebsd";
102 case Linux: return "linux";
103 case Lv2: return "lv2";
104 case MinGW32: return "mingw32";
105 case MinGW64: return "mingw64";
106 case NetBSD: return "netbsd";
107 case OpenBSD: return "openbsd";
108 case Psp: return "psp";
109 case Solaris: return "solaris";
110 case Win32: return "win32";
111 case Haiku: return "haiku";
112 case Minix: return "minix";
118 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
120 case UnknownEnvironment: return "unknown";
126 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
133 if (Name == "cellspu")
137 if (Name == "mipsel")
139 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" || Str == "thumbv5e")
233 if (Str == "armv6" || Str == "thumbv6")
235 if (Str == "armv7" || Str == "thumbv7")
244 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
245 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
246 ArchName[2] == '8' && ArchName[3] == '6' &&
247 ArchName[1] - '3' < 6) // i[3-9]86
249 else if (ArchName == "amd64" || ArchName == "x86_64")
251 else if (ArchName == "bfin")
253 else if (ArchName == "pic16")
255 else if (ArchName == "powerpc")
257 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
259 else if (ArchName == "mblaze")
261 else if (ArchName == "arm" ||
262 ArchName.startswith("armv") ||
263 ArchName == "xscale")
265 else if (ArchName == "thumb" ||
266 ArchName.startswith("thumbv"))
268 else if (ArchName.startswith("alpha"))
270 else if (ArchName == "spu" || ArchName == "cellspu")
272 else if (ArchName == "msp430")
274 else if (ArchName == "mips" || ArchName == "mipsallegrex")
276 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
279 else if (ArchName == "sparc")
281 else if (ArchName == "sparcv9")
283 else if (ArchName == "s390x")
285 else if (ArchName == "tce")
287 else if (ArchName == "xcore")
289 else if (ArchName == "ptx")
295 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
296 if (VendorName == "apple")
298 else if (VendorName == "pc")
301 return UnknownVendor;
304 Triple::OSType Triple::ParseOS(StringRef OSName) {
305 if (OSName.startswith("auroraux"))
307 else if (OSName.startswith("cygwin"))
309 else if (OSName.startswith("darwin"))
311 else if (OSName.startswith("dragonfly"))
313 else if (OSName.startswith("freebsd"))
315 else if (OSName.startswith("linux"))
317 else if (OSName.startswith("lv2"))
319 else if (OSName.startswith("mingw32"))
321 else if (OSName.startswith("mingw64"))
323 else if (OSName.startswith("netbsd"))
325 else if (OSName.startswith("openbsd"))
327 else if (OSName.startswith("psp"))
329 else if (OSName.startswith("solaris"))
331 else if (OSName.startswith("win32"))
333 else if (OSName.startswith("haiku"))
335 else if (OSName.startswith("minix"))
341 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
342 return UnknownEnvironment;
345 void Triple::Parse() const {
346 assert(!isInitialized() && "Invalid parse call.");
348 Arch = ParseArch(getArchName());
349 Vendor = ParseVendor(getVendorName());
350 OS = ParseOS(getOSName());
351 Environment = ParseEnvironment(getEnvironmentName());
353 assert(isInitialized() && "Failed to initialize!");
356 std::string Triple::normalize(StringRef Str) {
357 // Parse into components.
358 SmallVector<StringRef, 4> Components;
359 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
360 Last = Str.find('-', First);
361 Components.push_back(Str.slice(First, Last));
364 // If the first component corresponds to a known architecture, preferentially
365 // use it for the architecture. If the second component corresponds to a
366 // known vendor, preferentially use it for the vendor, etc. This avoids silly
367 // component movement when a component parses as (eg) both a valid arch and a
369 ArchType Arch = UnknownArch;
370 if (Components.size() > 0)
371 Arch = ParseArch(Components[0]);
372 VendorType Vendor = UnknownVendor;
373 if (Components.size() > 1)
374 Vendor = ParseVendor(Components[1]);
375 OSType OS = UnknownOS;
376 if (Components.size() > 2)
377 OS = ParseOS(Components[2]);
378 EnvironmentType Environment = UnknownEnvironment;
379 if (Components.size() > 3)
380 Environment = ParseEnvironment(Components[3]);
382 // Note which components are already in their final position. These will not
385 Found[0] = Arch != UnknownArch;
386 Found[1] = Vendor != UnknownVendor;
387 Found[2] = OS != UnknownOS;
388 Found[3] = Environment != UnknownEnvironment;
390 // If they are not there already, permute the components into their canonical
391 // positions by seeing if they parse as a valid architecture, and if so moving
392 // the component to the architecture position etc.
393 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
395 continue; // Already in the canonical position.
397 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
398 // Do not reparse any components that already matched.
399 if (Idx < array_lengthof(Found) && Found[Idx])
402 // Does this component parse as valid for the target position?
404 StringRef Comp = Components[Idx];
407 assert(false && "unexpected component type!");
409 Arch = ParseArch(Comp);
410 Valid = Arch != UnknownArch;
413 Vendor = ParseVendor(Comp);
414 Valid = Vendor != UnknownVendor;
418 Valid = OS != UnknownOS;
421 Environment = ParseEnvironment(Comp);
422 Valid = Environment != UnknownEnvironment;
426 continue; // Nope, try the next component.
428 // Move the component to the target position, pushing any non-fixed
429 // components that are in the way to the right. This tends to give
430 // good results in the common cases of a forgotten vendor component
431 // or a wrongly positioned environment.
433 // Insert left, pushing the existing components to the right. For
434 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
435 StringRef CurrentComponent(""); // The empty component.
436 // Replace the component we are moving with an empty component.
437 std::swap(CurrentComponent, Components[Idx]);
438 // Insert the component being moved at Pos, displacing any existing
439 // components to the right.
440 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
441 // Skip over any fixed components.
442 while (i < array_lengthof(Found) && Found[i]) ++i;
443 // Place the component at the new position, getting the component
444 // that was at this position - it will be moved right.
445 std::swap(CurrentComponent, Components[i]);
447 } else if (Pos > Idx) {
448 // Push right by inserting empty components until the component at Idx
449 // reaches the target position Pos. For example, pc-a -> -pc-a when
450 // moving pc to the second position.
452 // Insert one empty component at Idx.
453 StringRef CurrentComponent(""); // The empty component.
454 for (unsigned i = Idx; i < Components.size(); ++i) {
455 // Skip over any fixed components.
456 while (i < array_lengthof(Found) && Found[i]) ++i;
457 // Place the component at the new position, getting the component
458 // that was at this position - it will be moved right.
459 std::swap(CurrentComponent, Components[i]);
460 // If it was placed on top of an empty component then we are done.
461 if (CurrentComponent.empty())
464 // The last component was pushed off the end - append it.
465 if (!CurrentComponent.empty())
466 Components.push_back(CurrentComponent);
468 // Advance Idx to the component's new position.
469 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
470 } while (Idx < Pos); // Add more until the final position is reached.
472 assert(Pos < Components.size() && Components[Pos] == Comp &&
473 "Component moved wrong!");
479 // Special case logic goes here. At this point Arch, Vendor and OS have the
480 // correct values for the computed components.
482 // Stick the corrected components back together to form the normalized string.
483 std::string Normalized;
484 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
485 if (i) Normalized += '-';
486 Normalized += Components[i];
491 StringRef Triple::getArchName() const {
492 return StringRef(Data).split('-').first; // Isolate first component
495 StringRef Triple::getVendorName() const {
496 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
497 return Tmp.split('-').first; // Isolate second component
500 StringRef Triple::getOSName() const {
501 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
502 Tmp = Tmp.split('-').second; // Strip second component
503 return Tmp.split('-').first; // Isolate third component
506 StringRef Triple::getEnvironmentName() const {
507 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
508 Tmp = Tmp.split('-').second; // Strip second component
509 return Tmp.split('-').second; // Strip third component
512 StringRef Triple::getOSAndEnvironmentName() const {
513 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
514 return Tmp.split('-').second; // Strip second component
517 static unsigned EatNumber(StringRef &Str) {
518 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
519 unsigned Result = Str[0]-'0';
524 // Handle "darwin11".
525 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
526 Result = Result*10 + (Str[0] - '0');
534 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
535 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
536 /// not defined, return 0's. This requires that the triple have an OSType of
537 /// darwin before it is called.
538 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
539 unsigned &Revision) const {
540 assert(getOS() == Darwin && "Not a darwin target triple!");
541 StringRef OSName = getOSName();
542 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
544 // Strip off "darwin".
545 OSName = OSName.substr(6);
547 Maj = Min = Revision = 0;
549 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
552 // The major version is the first digit.
553 Maj = EatNumber(OSName);
554 if (OSName.empty()) return;
556 // Handle minor version: 10.4.9 -> darwin8.9.
557 if (OSName[0] != '.')
561 OSName = OSName.substr(1);
563 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
566 Min = EatNumber(OSName);
567 if (OSName.empty()) return;
569 // Handle revision darwin8.9.1
570 if (OSName[0] != '.')
574 OSName = OSName.substr(1);
576 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
579 Revision = EatNumber(OSName);
582 void Triple::setTriple(const Twine &Str) {
587 void Triple::setArch(ArchType Kind) {
588 setArchName(getArchTypeName(Kind));
591 void Triple::setVendor(VendorType Kind) {
592 setVendorName(getVendorTypeName(Kind));
595 void Triple::setOS(OSType Kind) {
596 setOSName(getOSTypeName(Kind));
599 void Triple::setEnvironment(EnvironmentType Kind) {
600 setEnvironmentName(getEnvironmentTypeName(Kind));
603 void Triple::setArchName(StringRef Str) {
604 // Work around a miscompilation bug for Twines in gcc 4.0.3.
605 SmallString<64> Triple;
608 Triple += getVendorName();
610 Triple += getOSAndEnvironmentName();
611 setTriple(Triple.str());
614 void Triple::setVendorName(StringRef Str) {
615 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
618 void Triple::setOSName(StringRef Str) {
619 if (hasEnvironment())
620 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
621 "-" + getEnvironmentName());
623 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
626 void Triple::setEnvironmentName(StringRef Str) {
627 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
631 void Triple::setOSAndEnvironmentName(StringRef Str) {
632 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);