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/Twine.h"
20 const char *Triple::getArchTypeName(ArchType Kind) {
22 case InvalidArch: return "<invalid>";
23 case UnknownArch: return "unknown";
25 case alpha: return "alpha";
26 case arm: return "arm";
27 case bfin: return "bfin";
28 case cellspu: return "cellspu";
29 case mips: return "mips";
30 case mipsel: return "mipsel";
31 case msp430: return "msp430";
32 case pic16: return "pic16";
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 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
124 if (Name == "cellspu")
128 if (Name == "mipsel")
130 if (Name == "msp430")
138 if (Name == "mblaze")
142 if (Name == "sparcv9")
144 if (Name == "systemz")
152 if (Name == "x86-64")
162 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
163 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
164 // archs which Darwin doesn't use.
166 // The matching this routine does is fairly pointless, since it is neither the
167 // complete architecture list, nor a reasonable subset. The problem is that
168 // historically the driver driver accepts this and also ties its -march=
169 // handling to the architecture name, so we need to be careful before removing
172 // This code must be kept in sync with Clang's Darwin specific argument
175 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
176 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
177 Str == "ppc7450" || Str == "ppc970")
181 return Triple::ppc64;
183 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
184 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
185 Str == "pentIIm5" || Str == "pentium4")
189 return Triple::x86_64;
191 // This is derived from the driver driver.
192 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
193 Str == "armv6" || Str == "armv7")
199 return Triple::UnknownArch;
202 // Returns architecture name that is understood by the target assembler.
203 const char *Triple::getArchNameForAssembler() {
204 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
207 StringRef Str = getArchName();
212 if (Str == "powerpc")
214 if (Str == "powerpc64")
216 if (Str == "mblaze" || Str == "microblaze")
220 if (Str == "armv4t" || Str == "thumbv4t")
222 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e")
224 if (Str == "armv6" || Str == "thumbv6")
226 if (Str == "armv7" || Str == "thumbv7")
235 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
236 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
237 ArchName[2] == '8' && ArchName[3] == '6' &&
238 ArchName[1] - '3' < 6) // i[3-9]86
240 else if (ArchName == "amd64" || ArchName == "x86_64")
242 else if (ArchName == "bfin")
244 else if (ArchName == "pic16")
246 else if (ArchName == "powerpc")
248 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
250 else if (ArchName == "mblaze")
252 else if (ArchName == "arm" ||
253 ArchName.startswith("armv") ||
254 ArchName == "xscale")
256 else if (ArchName == "thumb" ||
257 ArchName.startswith("thumbv"))
259 else if (ArchName.startswith("alpha"))
261 else if (ArchName == "spu" || ArchName == "cellspu")
263 else if (ArchName == "msp430")
265 else if (ArchName == "mips" || ArchName == "mipsallegrex")
267 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
270 else if (ArchName == "sparc")
272 else if (ArchName == "sparcv9")
274 else if (ArchName == "s390x")
276 else if (ArchName == "tce")
278 else if (ArchName == "xcore")
280 else if (ArchName == "ptx")
286 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
287 if (VendorName == "apple")
289 else if (VendorName == "pc")
292 return UnknownVendor;
295 Triple::OSType Triple::ParseOS(StringRef OSName) {
296 if (OSName.startswith("auroraux"))
298 else if (OSName.startswith("cygwin"))
300 else if (OSName.startswith("darwin"))
302 else if (OSName.startswith("dragonfly"))
304 else if (OSName.startswith("freebsd"))
306 else if (OSName.startswith("linux"))
308 else if (OSName.startswith("lv2"))
310 else if (OSName.startswith("mingw32"))
312 else if (OSName.startswith("mingw64"))
314 else if (OSName.startswith("netbsd"))
316 else if (OSName.startswith("openbsd"))
318 else if (OSName.startswith("psp"))
320 else if (OSName.startswith("solaris"))
322 else if (OSName.startswith("win32"))
324 else if (OSName.startswith("haiku"))
326 else if (OSName.startswith("minix"))
332 void Triple::Parse() const {
333 assert(!isInitialized() && "Invalid parse call.");
335 Arch = ParseArch(getArchName());
336 Vendor = ParseVendor(getVendorName());
337 OS = ParseOS(getOSName());
339 assert(isInitialized() && "Failed to initialize!");
342 std::string Triple::normalize(StringRef Str) {
343 // Parse into components.
344 SmallVector<StringRef, 4> Components;
345 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
346 Last = Str.find('-', First);
347 Components.push_back(Str.slice(First, Last));
350 // If the first component corresponds to a known architecture, preferentially
351 // use it for the architecture. If the second component corresponds to a
352 // known vendor, preferentially use it for the vendor, etc. This avoids silly
353 // component movement when a component parses as (eg) both a valid arch and a
355 ArchType Arch = UnknownArch;
356 if (Components.size() > 0)
357 Arch = ParseArch(Components[0]);
358 VendorType Vendor = UnknownVendor;
359 if (Components.size() > 1)
360 Vendor = ParseVendor(Components[1]);
361 OSType OS = UnknownOS;
362 if (Components.size() > 2)
363 OS = ParseOS(Components[2]);
365 // Note which components are already in their final position. These will not
368 Found[0] = Arch != UnknownArch;
369 Found[1] = Vendor != UnknownVendor;
370 Found[2] = OS != UnknownOS;
372 // If they are not there already, permute the components into their canonical
373 // positions by seeing if they parse as a valid architecture, and if so moving
374 // the component to the architecture position etc.
375 for (unsigned Pos = 0; Pos != 3; ++Pos) {
377 continue; // Already in the canonical position.
379 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
380 // Do not reparse any components that already matched.
381 if (Idx < 3 && Found[Idx])
384 // Does this component parse as valid for the target position?
386 StringRef Comp = Components[Idx];
389 assert(false && "unexpected component type!");
391 Arch = ParseArch(Comp);
392 Valid = Arch != UnknownArch;
395 Vendor = ParseVendor(Comp);
396 Valid = Vendor != UnknownVendor;
400 Valid = OS != UnknownOS;
404 continue; // Nope, try the next component.
406 // Move the component to the target position, pushing any non-fixed
407 // components that are in the way to the right. This tends to give
408 // good results in the common cases of a forgotten vendor component
409 // or a wrongly positioned environment.
411 // Insert left, pushing the existing components to the right. For
412 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
413 StringRef CurrentComponent(""); // The empty component.
414 // Replace the component we are moving with an empty component.
415 std::swap(CurrentComponent, Components[Idx]);
416 // Insert the component being moved at Pos, displacing any existing
417 // components to the right.
418 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
419 // Skip over any fixed components.
420 while (i < 3 && Found[i]) ++i;
421 // Place the component at the new position, getting the component
422 // that was at this position - it will be moved right.
423 std::swap(CurrentComponent, Components[i]);
425 } else if (Pos > Idx) {
426 // Push right by inserting empty components until the component at Idx
427 // reaches the target position Pos. For example, pc-a -> -pc-a when
428 // moving pc to the second position.
430 // Insert one empty component at Idx.
431 StringRef CurrentComponent(""); // The empty component.
432 for (unsigned i = Idx; i < Components.size(); ++i) {
433 // Skip over any fixed components.
434 while (i < 3 && Found[i]) ++i;
435 // Place the component at the new position, getting the component
436 // that was at this position - it will be moved right.
437 std::swap(CurrentComponent, Components[i]);
438 // If it was placed on top of an empty component then we are done.
439 if (CurrentComponent.empty())
442 // The last component was pushed off the end - append it.
443 if (!CurrentComponent.empty())
444 Components.push_back(CurrentComponent);
446 // Advance Idx to the component's new position.
447 while (++Idx < 3 && Found[Idx]) {}
448 } while (Idx < Pos); // Add more until the final position is reached.
450 assert(Pos < Components.size() && Components[Pos] == Comp &&
451 "Component moved wrong!");
457 // Special case logic goes here. At this point Arch, Vendor and OS have the
458 // correct values for the computed components.
460 // Stick the corrected components back together to form the normalized string.
461 std::string Normalized;
462 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
463 if (i) Normalized += '-';
464 Normalized += Components[i];
469 StringRef Triple::getArchName() const {
470 return StringRef(Data).split('-').first; // Isolate first component
473 StringRef Triple::getVendorName() const {
474 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
475 return Tmp.split('-').first; // Isolate second component
478 StringRef Triple::getOSName() const {
479 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
480 Tmp = Tmp.split('-').second; // Strip second component
481 return Tmp.split('-').first; // Isolate third component
484 StringRef Triple::getEnvironmentName() const {
485 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
486 Tmp = Tmp.split('-').second; // Strip second component
487 return Tmp.split('-').second; // Strip third component
490 StringRef Triple::getOSAndEnvironmentName() const {
491 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
492 return Tmp.split('-').second; // Strip second component
495 static unsigned EatNumber(StringRef &Str) {
496 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
497 unsigned Result = Str[0]-'0';
502 // Handle "darwin11".
503 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
504 Result = Result*10 + (Str[0] - '0');
512 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
513 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
514 /// not defined, return 0's. This requires that the triple have an OSType of
515 /// darwin before it is called.
516 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
517 unsigned &Revision) const {
518 assert(getOS() == Darwin && "Not a darwin target triple!");
519 StringRef OSName = getOSName();
520 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
522 // Strip off "darwin".
523 OSName = OSName.substr(6);
525 Maj = Min = Revision = 0;
527 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
530 // The major version is the first digit.
531 Maj = EatNumber(OSName);
532 if (OSName.empty()) return;
534 // Handle minor version: 10.4.9 -> darwin8.9.
535 if (OSName[0] != '.')
539 OSName = OSName.substr(1);
541 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
544 Min = EatNumber(OSName);
545 if (OSName.empty()) return;
547 // Handle revision darwin8.9.1
548 if (OSName[0] != '.')
552 OSName = OSName.substr(1);
554 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
557 Revision = EatNumber(OSName);
560 void Triple::setTriple(const Twine &Str) {
565 void Triple::setArch(ArchType Kind) {
566 setArchName(getArchTypeName(Kind));
569 void Triple::setVendor(VendorType Kind) {
570 setVendorName(getVendorTypeName(Kind));
573 void Triple::setOS(OSType Kind) {
574 setOSName(getOSTypeName(Kind));
577 void Triple::setArchName(StringRef Str) {
578 // Work around a miscompilation bug for Twines in gcc 4.0.3.
579 SmallString<64> Triple;
582 Triple += getVendorName();
584 Triple += getOSAndEnvironmentName();
585 setTriple(Triple.str());
588 void Triple::setVendorName(StringRef Str) {
589 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
592 void Triple::setOSName(StringRef Str) {
593 if (hasEnvironment())
594 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
595 "-" + getEnvironmentName());
597 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
600 void Triple::setEnvironmentName(StringRef Str) {
601 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
605 void Triple::setOSAndEnvironmentName(StringRef Str) {
606 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);