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 glulx: return "glulx";
31 case mips: return "mips";
32 case mipsel: return "mipsel";
33 case msp430: return "msp430";
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 ptx32: return "ptx32";
46 case ptx64: return "ptx64";
52 const char *Triple::getArchTypePrefix(ArchType Kind) {
57 case alpha: return "alpha";
60 case thumb: return "arm";
62 case bfin: return "bfin";
64 case cellspu: return "spu";
66 case glulx: return "glulx";
69 case ppc: return "ppc";
71 case mblaze: return "mblaze";
74 case sparc: return "sparc";
77 case x86_64: return "x86";
79 case xcore: return "xcore";
81 case ptx32: return "ptx";
82 case ptx64: return "ptx";
86 const char *Triple::getVendorTypeName(VendorType Kind) {
88 case UnknownVendor: return "unknown";
90 case Apple: return "apple";
92 case SCEI: return "scei";
98 const char *Triple::getOSTypeName(OSType Kind) {
100 case UnknownOS: return "unknown";
102 case AuroraUX: return "auroraux";
103 case Cygwin: return "cygwin";
104 case Darwin: return "darwin";
105 case DragonFly: return "dragonfly";
106 case FreeBSD: return "freebsd";
107 case IOS: return "ios";
108 case Linux: return "linux";
109 case Lv2: return "lv2";
110 case MacOSX: return "macosx";
111 case MinGW32: return "mingw32";
112 case NetBSD: return "netbsd";
113 case OpenBSD: return "openbsd";
114 case Psp: return "psp";
115 case Solaris: return "solaris";
116 case Win32: return "win32";
117 case Haiku: return "haiku";
118 case Minix: return "minix";
124 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
126 case UnknownEnvironment: return "unknown";
127 case GNU: return "gnu";
128 case GNUEABI: return "gnueabi";
129 case EABI: return "eabi";
130 case MachO: return "macho";
136 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
143 if (Name == "cellspu")
149 if (Name == "mipsel")
151 if (Name == "msp430")
157 if (Name == "mblaze")
161 if (Name == "sparcv9")
163 if (Name == "systemz")
171 if (Name == "x86-64")
183 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
184 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
185 // archs which Darwin doesn't use.
187 // The matching this routine does is fairly pointless, since it is neither the
188 // complete architecture list, nor a reasonable subset. The problem is that
189 // historically the driver driver accepts this and also ties its -march=
190 // handling to the architecture name, so we need to be careful before removing
193 // This code must be kept in sync with Clang's Darwin specific argument
196 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
197 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
198 Str == "ppc7450" || Str == "ppc970")
202 return Triple::ppc64;
204 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
205 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
206 Str == "pentIIm5" || Str == "pentium4")
210 return Triple::x86_64;
212 // This is derived from the driver driver.
213 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
214 Str == "armv6" || Str == "armv7")
218 return Triple::ptx32;
220 return Triple::ptx64;
222 return Triple::UnknownArch;
225 // Returns architecture name that is understood by the target assembler.
226 const char *Triple::getArchNameForAssembler() {
227 if (!isOSDarwin() && getVendor() != Triple::Apple)
230 StringRef Str = getArchName();
235 if (Str == "powerpc")
237 if (Str == "powerpc64")
239 if (Str == "mblaze" || Str == "microblaze")
243 if (Str == "armv4t" || Str == "thumbv4t")
245 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5"
246 || Str == "thumbv5e")
248 if (Str == "armv6" || Str == "thumbv6")
250 if (Str == "armv7" || Str == "thumbv7")
261 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
262 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
263 ArchName[2] == '8' && ArchName[3] == '6' &&
264 ArchName[1] - '3' < 6) // i[3-9]86
266 else if (ArchName == "amd64" || ArchName == "x86_64")
268 else if (ArchName == "bfin")
270 else if (ArchName == "powerpc")
272 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
274 else if (ArchName == "mblaze")
276 else if (ArchName == "arm" ||
277 ArchName.startswith("armv") ||
278 ArchName == "xscale")
280 else if (ArchName == "thumb" ||
281 ArchName.startswith("thumbv"))
283 else if (ArchName.startswith("alpha"))
285 else if (ArchName.startswith("glulx"))
287 else if (ArchName == "spu" || ArchName == "cellspu")
289 else if (ArchName == "msp430")
291 else if (ArchName == "mips" || ArchName == "mipsallegrex")
293 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
296 else if (ArchName == "sparc")
298 else if (ArchName == "sparcv9")
300 else if (ArchName == "s390x")
302 else if (ArchName == "tce")
304 else if (ArchName == "xcore")
306 else if (ArchName == "ptx32")
308 else if (ArchName == "ptx64")
314 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
315 if (VendorName == "apple")
317 else if (VendorName == "pc")
319 else if (VendorName == "scei")
322 return UnknownVendor;
325 Triple::OSType Triple::ParseOS(StringRef OSName) {
326 if (OSName.startswith("auroraux"))
328 else if (OSName.startswith("cygwin"))
330 else if (OSName.startswith("darwin"))
332 else if (OSName.startswith("dragonfly"))
334 else if (OSName.startswith("freebsd"))
336 else if (OSName.startswith("ios"))
338 else if (OSName.startswith("linux"))
340 else if (OSName.startswith("lv2"))
342 else if (OSName.startswith("macosx"))
344 else if (OSName.startswith("mingw32"))
346 else if (OSName.startswith("netbsd"))
348 else if (OSName.startswith("openbsd"))
350 else if (OSName.startswith("psp"))
352 else if (OSName.startswith("solaris"))
354 else if (OSName.startswith("win32"))
356 else if (OSName.startswith("haiku"))
358 else if (OSName.startswith("minix"))
364 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) {
365 if (EnvironmentName.startswith("eabi"))
367 else if (EnvironmentName.startswith("gnueabi"))
369 else if (EnvironmentName.startswith("gnu"))
371 else if (EnvironmentName.startswith("macho"))
374 return UnknownEnvironment;
377 void Triple::Parse() const {
378 assert(!isInitialized() && "Invalid parse call.");
380 Arch = ParseArch(getArchName());
381 Vendor = ParseVendor(getVendorName());
382 OS = ParseOS(getOSName());
383 Environment = ParseEnvironment(getEnvironmentName());
385 assert(isInitialized() && "Failed to initialize!");
388 std::string Triple::normalize(StringRef Str) {
389 // Parse into components.
390 SmallVector<StringRef, 4> Components;
391 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
392 Last = Str.find('-', First);
393 Components.push_back(Str.slice(First, Last));
396 // If the first component corresponds to a known architecture, preferentially
397 // use it for the architecture. If the second component corresponds to a
398 // known vendor, preferentially use it for the vendor, etc. This avoids silly
399 // component movement when a component parses as (eg) both a valid arch and a
401 ArchType Arch = UnknownArch;
402 if (Components.size() > 0)
403 Arch = ParseArch(Components[0]);
404 VendorType Vendor = UnknownVendor;
405 if (Components.size() > 1)
406 Vendor = ParseVendor(Components[1]);
407 OSType OS = UnknownOS;
408 if (Components.size() > 2)
409 OS = ParseOS(Components[2]);
410 EnvironmentType Environment = UnknownEnvironment;
411 if (Components.size() > 3)
412 Environment = ParseEnvironment(Components[3]);
414 // Note which components are already in their final position. These will not
417 Found[0] = Arch != UnknownArch;
418 Found[1] = Vendor != UnknownVendor;
419 Found[2] = OS != UnknownOS;
420 Found[3] = Environment != UnknownEnvironment;
422 // If they are not there already, permute the components into their canonical
423 // positions by seeing if they parse as a valid architecture, and if so moving
424 // the component to the architecture position etc.
425 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
427 continue; // Already in the canonical position.
429 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
430 // Do not reparse any components that already matched.
431 if (Idx < array_lengthof(Found) && Found[Idx])
434 // Does this component parse as valid for the target position?
436 StringRef Comp = Components[Idx];
439 assert(false && "unexpected component type!");
441 Arch = ParseArch(Comp);
442 Valid = Arch != UnknownArch;
445 Vendor = ParseVendor(Comp);
446 Valid = Vendor != UnknownVendor;
450 Valid = OS != UnknownOS;
453 Environment = ParseEnvironment(Comp);
454 Valid = Environment != UnknownEnvironment;
458 continue; // Nope, try the next component.
460 // Move the component to the target position, pushing any non-fixed
461 // components that are in the way to the right. This tends to give
462 // good results in the common cases of a forgotten vendor component
463 // or a wrongly positioned environment.
465 // Insert left, pushing the existing components to the right. For
466 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
467 StringRef CurrentComponent(""); // The empty component.
468 // Replace the component we are moving with an empty component.
469 std::swap(CurrentComponent, Components[Idx]);
470 // Insert the component being moved at Pos, displacing any existing
471 // components to the right.
472 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
473 // Skip over any fixed components.
474 while (i < array_lengthof(Found) && Found[i]) ++i;
475 // Place the component at the new position, getting the component
476 // that was at this position - it will be moved right.
477 std::swap(CurrentComponent, Components[i]);
479 } else if (Pos > Idx) {
480 // Push right by inserting empty components until the component at Idx
481 // reaches the target position Pos. For example, pc-a -> -pc-a when
482 // moving pc to the second position.
484 // Insert one empty component at Idx.
485 StringRef CurrentComponent(""); // The empty component.
486 for (unsigned i = Idx; i < Components.size();) {
487 // Place the component at the new position, getting the component
488 // that was at this position - it will be moved right.
489 std::swap(CurrentComponent, Components[i]);
490 // If it was placed on top of an empty component then we are done.
491 if (CurrentComponent.empty())
493 // Advance to the next component, skipping any fixed components.
494 while (++i < array_lengthof(Found) && Found[i])
497 // The last component was pushed off the end - append it.
498 if (!CurrentComponent.empty())
499 Components.push_back(CurrentComponent);
501 // Advance Idx to the component's new position.
502 while (++Idx < array_lengthof(Found) && Found[Idx]) {}
503 } while (Idx < Pos); // Add more until the final position is reached.
505 assert(Pos < Components.size() && Components[Pos] == Comp &&
506 "Component moved wrong!");
512 // Special case logic goes here. At this point Arch, Vendor and OS have the
513 // correct values for the computed components.
515 // Stick the corrected components back together to form the normalized string.
516 std::string Normalized;
517 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
518 if (i) Normalized += '-';
519 Normalized += Components[i];
524 StringRef Triple::getArchName() const {
525 return StringRef(Data).split('-').first; // Isolate first component
528 StringRef Triple::getVendorName() const {
529 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
530 return Tmp.split('-').first; // Isolate second component
533 StringRef Triple::getOSName() const {
534 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
535 Tmp = Tmp.split('-').second; // Strip second component
536 return Tmp.split('-').first; // Isolate third component
539 StringRef Triple::getEnvironmentName() const {
540 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
541 Tmp = Tmp.split('-').second; // Strip second component
542 return Tmp.split('-').second; // Strip third component
545 StringRef Triple::getOSAndEnvironmentName() const {
546 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
547 return Tmp.split('-').second; // Strip second component
550 static unsigned EatNumber(StringRef &Str) {
551 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
555 // Consume the leading digit.
556 Result = Result*10 + (Str[0] - '0');
560 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
565 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
566 unsigned &Micro) const {
567 StringRef OSName = getOSName();
569 // Assume that the OS portion of the triple starts with the canonical name.
570 StringRef OSTypeName = getOSTypeName(getOS());
571 if (OSName.startswith(OSTypeName))
572 OSName = OSName.substr(OSTypeName.size());
574 // Any unset version defaults to 0.
575 Major = Minor = Micro = 0;
577 // Parse up to three components.
578 unsigned *Components[3] = { &Major, &Minor, &Micro };
579 for (unsigned i = 0; i != 3; ++i) {
580 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
583 // Consume the leading number.
584 *Components[i] = EatNumber(OSName);
586 // Consume the separator, if present.
587 if (OSName.startswith("."))
588 OSName = OSName.substr(1);
592 void Triple::setTriple(const Twine &Str) {
597 void Triple::setArch(ArchType Kind) {
598 setArchName(getArchTypeName(Kind));
601 void Triple::setVendor(VendorType Kind) {
602 setVendorName(getVendorTypeName(Kind));
605 void Triple::setOS(OSType Kind) {
606 setOSName(getOSTypeName(Kind));
609 void Triple::setEnvironment(EnvironmentType Kind) {
610 setEnvironmentName(getEnvironmentTypeName(Kind));
613 void Triple::setArchName(StringRef Str) {
614 // Work around a miscompilation bug for Twines in gcc 4.0.3.
615 SmallString<64> Triple;
618 Triple += getVendorName();
620 Triple += getOSAndEnvironmentName();
621 setTriple(Triple.str());
624 void Triple::setVendorName(StringRef Str) {
625 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
628 void Triple::setOSName(StringRef Str) {
629 if (hasEnvironment())
630 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
631 "-" + getEnvironmentName());
633 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
636 void Triple::setEnvironmentName(StringRef Str) {
637 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
641 void Triple::setOSAndEnvironmentName(StringRef Str) {
642 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);