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";
49 const char *Triple::getArchTypePrefix(ArchType Kind) {
54 case alpha: return "alpha";
57 case thumb: return "arm";
59 case bfin: return "bfin";
61 case cellspu: return "spu";
64 case ppc: return "ppc";
66 case mblaze: return "mblaze";
69 case sparc: return "sparc";
72 case x86_64: return "x86";
73 case xcore: return "xcore";
77 const char *Triple::getVendorTypeName(VendorType Kind) {
79 case UnknownVendor: return "unknown";
81 case Apple: return "apple";
88 const char *Triple::getOSTypeName(OSType Kind) {
90 case UnknownOS: return "unknown";
92 case AuroraUX: return "auroraux";
93 case Cygwin: return "cygwin";
94 case Darwin: return "darwin";
95 case DragonFly: return "dragonfly";
96 case FreeBSD: return "freebsd";
97 case Linux: return "linux";
98 case Lv2: return "lv2";
99 case MinGW32: return "mingw32";
100 case MinGW64: return "mingw64";
101 case NetBSD: return "netbsd";
102 case OpenBSD: return "openbsd";
103 case Psp: return "psp";
104 case Solaris: return "solaris";
105 case Win32: return "win32";
106 case Haiku: return "haiku";
107 case Minix: return "minix";
113 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
120 if (Name == "cellspu")
124 if (Name == "mipsel")
126 if (Name == "msp430")
134 if (Name == "mblaze")
138 if (Name == "sparcv9")
140 if (Name == "systemz")
148 if (Name == "x86-64")
156 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
157 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
158 // archs which Darwin doesn't use.
160 // The matching this routine does is fairly pointless, since it is neither the
161 // complete architecture list, nor a reasonable subset. The problem is that
162 // historically the driver driver accepts this and also ties its -march=
163 // handling to the architecture name, so we need to be careful before removing
166 // This code must be kept in sync with Clang's Darwin specific argument
169 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
170 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
171 Str == "ppc7450" || Str == "ppc970")
175 return Triple::ppc64;
177 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
178 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
179 Str == "pentIIm5" || Str == "pentium4")
183 return Triple::x86_64;
185 // This is derived from the driver driver.
186 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
187 Str == "armv6" || Str == "armv7")
190 return Triple::UnknownArch;
193 // Returns architecture name that is understood by the target assembler.
194 const char *Triple::getArchNameForAssembler() {
195 if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
198 StringRef Str = getArchName();
203 if (Str == "powerpc")
205 if (Str == "powerpc64")
207 if (Str == "mblaze" || Str == "microblaze")
211 if (Str == "armv4t" || Str == "thumbv4t")
213 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" || Str == "thumbv5e")
215 if (Str == "armv6" || Str == "thumbv6")
217 if (Str == "armv7" || Str == "thumbv7")
224 Triple::ArchType Triple::ParseArch(StringRef ArchName) {
225 if (ArchName.size() == 4 && ArchName[0] == 'i' &&
226 ArchName[2] == '8' && ArchName[3] == '6' &&
227 ArchName[1] - '3' < 6) // i[3-9]86
229 else if (ArchName == "amd64" || ArchName == "x86_64")
231 else if (ArchName == "bfin")
233 else if (ArchName == "pic16")
235 else if (ArchName == "powerpc")
237 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
239 else if (ArchName == "mblaze")
241 else if (ArchName == "arm" ||
242 ArchName.startswith("armv") ||
243 ArchName == "xscale")
245 else if (ArchName == "thumb" ||
246 ArchName.startswith("thumbv"))
248 else if (ArchName.startswith("alpha"))
250 else if (ArchName == "spu" || ArchName == "cellspu")
252 else if (ArchName == "msp430")
254 else if (ArchName == "mips" || ArchName == "mipsallegrex")
256 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
259 else if (ArchName == "sparc")
261 else if (ArchName == "sparcv9")
263 else if (ArchName == "s390x")
265 else if (ArchName == "tce")
267 else if (ArchName == "xcore")
273 Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
274 if (VendorName == "apple")
276 else if (VendorName == "pc")
279 return UnknownVendor;
282 Triple::OSType Triple::ParseOS(StringRef OSName) {
283 if (OSName.startswith("auroraux"))
285 else if (OSName.startswith("cygwin"))
287 else if (OSName.startswith("darwin"))
289 else if (OSName.startswith("dragonfly"))
291 else if (OSName.startswith("freebsd"))
293 else if (OSName.startswith("linux"))
295 else if (OSName.startswith("lv2"))
297 else if (OSName.startswith("mingw32"))
299 else if (OSName.startswith("mingw64"))
301 else if (OSName.startswith("netbsd"))
303 else if (OSName.startswith("openbsd"))
305 else if (OSName.startswith("psp"))
307 else if (OSName.startswith("solaris"))
309 else if (OSName.startswith("win32"))
311 else if (OSName.startswith("haiku"))
313 else if (OSName.startswith("minix"))
319 void Triple::Parse() const {
320 assert(!isInitialized() && "Invalid parse call.");
322 Arch = ParseArch(getArchName());
323 Vendor = ParseVendor(getVendorName());
324 OS = ParseOS(getOSName());
326 // Handle some exceptional cases where the OS / environment components are
327 // stuck into the vendor field.
328 // TODO: Remove this logic and have places that need it use 'normalize'.
329 if (StringRef(getTriple()).count('-') == 1) {
330 StringRef VendorName = getVendorName();
332 if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
338 // arm-elf is another example, but we don't currently parse anything about
342 assert(isInitialized() && "Failed to initialize!");
345 std::string Triple::normalize(StringRef Str) {
346 // Parse into components.
347 SmallVector<StringRef, 4> Components;
348 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
349 Last = Str.find('-', First);
350 Components.push_back(Str.slice(First, Last));
353 // If the first component corresponds to a known architecture, preferentially
354 // use it for the architecture. If the second component corresponds to a
355 // known vendor, preferentially use it for the vendor, etc. This avoids silly
356 // component movement when a component parses as (eg) both a valid arch and a
358 ArchType Arch = UnknownArch;
359 if (Components.size() > 0)
360 Arch = ParseArch(Components[0]);
361 VendorType Vendor = UnknownVendor;
362 if (Components.size() > 1)
363 Vendor = ParseVendor(Components[1]);
364 OSType OS = UnknownOS;
365 if (Components.size() > 2)
366 OS = ParseOS(Components[2]);
368 // Note which components are already in their final position. These will not
371 Found[0] = Arch != UnknownArch;
372 Found[1] = Vendor != UnknownVendor;
373 Found[2] = OS != UnknownOS;
375 // If they are not there already, permute the components into their canonical
376 // positions by seeing if they parse as a valid architecture, and if so moving
377 // the component to the architecture position etc.
378 for (unsigned Pos = 0; Pos != 3; ++Pos) {
380 continue; // Already in the canonical position.
382 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
383 // Do not reparse any components that already matched.
384 if (Idx < 3 && Found[Idx])
387 // Does this component parse as valid for the target position?
389 StringRef Comp = Components[Idx];
392 assert(false && "unexpected component type!");
394 Arch = ParseArch(Comp);
395 Valid = Arch != UnknownArch;
398 Vendor = ParseVendor(Comp);
399 Valid = Vendor != UnknownVendor;
403 Valid = OS != UnknownOS;
407 continue; // Nope, try the next component.
409 // Move the component to the target position, pushing any non-fixed
410 // components that are in the way to the right. This tends to give
411 // good results in the common cases of a forgotten vendor component
412 // or a wrongly positioned environment.
414 // Insert left, pushing the existing components to the right. For
415 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
416 StringRef CurrentComponent(""); // The empty component.
417 // Replace the component we are moving with an empty component.
418 std::swap(CurrentComponent, Components[Idx]);
419 // Insert the component being moved at Pos, displacing any existing
420 // components to the right.
421 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
422 // Skip over any fixed components.
423 while (i < 3 && Found[i]) ++i;
424 // Place the component at the new position, getting the component
425 // that was at this position - it will be moved right.
426 std::swap(CurrentComponent, Components[i]);
428 } else if (Pos > Idx) {
429 // Push right by inserting empty components until the component at Idx
430 // reaches the target position Pos. For example, pc-a -> -pc-a when
431 // moving pc to the second position.
433 // Insert one empty component at Idx.
434 StringRef CurrentComponent(""); // The empty component.
435 for (unsigned i = Idx; i < Components.size(); ++i) {
436 // Skip over any fixed components.
437 while (i < 3 && 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]);
441 // If it was placed on top of an empty component then we are done.
442 if (CurrentComponent.empty())
445 // The last component was pushed off the end - append it.
446 if (!CurrentComponent.empty())
447 Components.push_back(CurrentComponent);
449 // Advance Idx to the component's new position.
450 while (++Idx < 3 && Found[Idx]) {}
451 } while (Idx < Pos); // Add more until the final position is reached.
453 assert(Pos < Components.size() && Components[Pos] == Comp &&
454 "Component moved wrong!");
460 // Special case logic goes here. At this point Arch, Vendor and OS have the
461 // correct values for the computed components.
463 // Stick the corrected components back together to form the normalized string.
464 std::string Normalized;
465 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
466 if (i) Normalized += '-';
467 Normalized += Components[i];
472 StringRef Triple::getArchName() const {
473 return StringRef(Data).split('-').first; // Isolate first component
476 StringRef Triple::getVendorName() const {
477 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
478 return Tmp.split('-').first; // Isolate second component
481 StringRef Triple::getOSName() const {
482 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
483 Tmp = Tmp.split('-').second; // Strip second component
484 return Tmp.split('-').first; // Isolate third component
487 StringRef Triple::getEnvironmentName() const {
488 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
489 Tmp = Tmp.split('-').second; // Strip second component
490 return Tmp.split('-').second; // Strip third component
493 StringRef Triple::getOSAndEnvironmentName() const {
494 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
495 return Tmp.split('-').second; // Strip second component
498 static unsigned EatNumber(StringRef &Str) {
499 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
500 unsigned Result = Str[0]-'0';
505 // Handle "darwin11".
506 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
507 Result = Result*10 + (Str[0] - '0');
515 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
516 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
517 /// not defined, return 0's. This requires that the triple have an OSType of
518 /// darwin before it is called.
519 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
520 unsigned &Revision) const {
521 assert(getOS() == Darwin && "Not a darwin target triple!");
522 StringRef OSName = getOSName();
523 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
525 // Strip off "darwin".
526 OSName = OSName.substr(6);
528 Maj = Min = Revision = 0;
530 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
533 // The major version is the first digit.
534 Maj = EatNumber(OSName);
535 if (OSName.empty()) return;
537 // Handle minor version: 10.4.9 -> darwin8.9.
538 if (OSName[0] != '.')
542 OSName = OSName.substr(1);
544 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
547 Min = EatNumber(OSName);
548 if (OSName.empty()) return;
550 // Handle revision darwin8.9.1
551 if (OSName[0] != '.')
555 OSName = OSName.substr(1);
557 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
560 Revision = EatNumber(OSName);
563 void Triple::setTriple(const Twine &Str) {
568 void Triple::setArch(ArchType Kind) {
569 setArchName(getArchTypeName(Kind));
572 void Triple::setVendor(VendorType Kind) {
573 setVendorName(getVendorTypeName(Kind));
576 void Triple::setOS(OSType Kind) {
577 setOSName(getOSTypeName(Kind));
580 void Triple::setArchName(StringRef Str) {
581 // Work around a miscompilation bug for Twines in gcc 4.0.3.
582 SmallString<64> Triple;
585 Triple += getVendorName();
587 Triple += getOSAndEnvironmentName();
588 setTriple(Triple.str());
591 void Triple::setVendorName(StringRef Str) {
592 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
595 void Triple::setOSName(StringRef Str) {
596 if (hasEnvironment())
597 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
598 "-" + getEnvironmentName());
600 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
603 void Triple::setEnvironmentName(StringRef Str) {
604 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
608 void Triple::setOSAndEnvironmentName(StringRef Str) {
609 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);