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 assert(isInitialized() && "Failed to initialize!");
329 std::string Triple::normalize(StringRef Str) {
330 // Parse into components.
331 SmallVector<StringRef, 4> Components;
332 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) {
333 Last = Str.find('-', First);
334 Components.push_back(Str.slice(First, Last));
337 // If the first component corresponds to a known architecture, preferentially
338 // use it for the architecture. If the second component corresponds to a
339 // known vendor, preferentially use it for the vendor, etc. This avoids silly
340 // component movement when a component parses as (eg) both a valid arch and a
342 ArchType Arch = UnknownArch;
343 if (Components.size() > 0)
344 Arch = ParseArch(Components[0]);
345 VendorType Vendor = UnknownVendor;
346 if (Components.size() > 1)
347 Vendor = ParseVendor(Components[1]);
348 OSType OS = UnknownOS;
349 if (Components.size() > 2)
350 OS = ParseOS(Components[2]);
352 // Note which components are already in their final position. These will not
355 Found[0] = Arch != UnknownArch;
356 Found[1] = Vendor != UnknownVendor;
357 Found[2] = OS != UnknownOS;
359 // If they are not there already, permute the components into their canonical
360 // positions by seeing if they parse as a valid architecture, and if so moving
361 // the component to the architecture position etc.
362 for (unsigned Pos = 0; Pos != 3; ++Pos) {
364 continue; // Already in the canonical position.
366 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
367 // Do not reparse any components that already matched.
368 if (Idx < 3 && Found[Idx])
371 // Does this component parse as valid for the target position?
373 StringRef Comp = Components[Idx];
376 assert(false && "unexpected component type!");
378 Arch = ParseArch(Comp);
379 Valid = Arch != UnknownArch;
382 Vendor = ParseVendor(Comp);
383 Valid = Vendor != UnknownVendor;
387 Valid = OS != UnknownOS;
391 continue; // Nope, try the next component.
393 // Move the component to the target position, pushing any non-fixed
394 // components that are in the way to the right. This tends to give
395 // good results in the common cases of a forgotten vendor component
396 // or a wrongly positioned environment.
398 // Insert left, pushing the existing components to the right. For
399 // example, a-b-i386 -> i386-a-b when moving i386 to the front.
400 StringRef CurrentComponent(""); // The empty component.
401 // Replace the component we are moving with an empty component.
402 std::swap(CurrentComponent, Components[Idx]);
403 // Insert the component being moved at Pos, displacing any existing
404 // components to the right.
405 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
406 // Skip over any fixed components.
407 while (i < 3 && Found[i]) ++i;
408 // Place the component at the new position, getting the component
409 // that was at this position - it will be moved right.
410 std::swap(CurrentComponent, Components[i]);
412 } else if (Pos > Idx) {
413 // Push right by inserting empty components until the component at Idx
414 // reaches the target position Pos. For example, pc-a -> -pc-a when
415 // moving pc to the second position.
417 // Insert one empty component at Idx.
418 StringRef CurrentComponent(""); // The empty component.
419 for (unsigned i = Idx; i < Components.size(); ++i) {
420 // Skip over any fixed components.
421 while (i < 3 && Found[i]) ++i;
422 // Place the component at the new position, getting the component
423 // that was at this position - it will be moved right.
424 std::swap(CurrentComponent, Components[i]);
425 // If it was placed on top of an empty component then we are done.
426 if (CurrentComponent.empty())
429 // The last component was pushed off the end - append it.
430 if (!CurrentComponent.empty())
431 Components.push_back(CurrentComponent);
433 // Advance Idx to the component's new position.
434 while (++Idx < 3 && Found[Idx]) {}
435 } while (Idx < Pos); // Add more until the final position is reached.
437 assert(Pos < Components.size() && Components[Pos] == Comp &&
438 "Component moved wrong!");
444 // Special case logic goes here. At this point Arch, Vendor and OS have the
445 // correct values for the computed components.
447 // Stick the corrected components back together to form the normalized string.
448 std::string Normalized;
449 for (unsigned i = 0, e = Components.size(); i != e; ++i) {
450 if (i) Normalized += '-';
451 Normalized += Components[i];
456 StringRef Triple::getArchName() const {
457 return StringRef(Data).split('-').first; // Isolate first component
460 StringRef Triple::getVendorName() const {
461 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
462 return Tmp.split('-').first; // Isolate second component
465 StringRef Triple::getOSName() const {
466 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
467 Tmp = Tmp.split('-').second; // Strip second component
468 return Tmp.split('-').first; // Isolate third component
471 StringRef Triple::getEnvironmentName() const {
472 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
473 Tmp = Tmp.split('-').second; // Strip second component
474 return Tmp.split('-').second; // Strip third component
477 StringRef Triple::getOSAndEnvironmentName() const {
478 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
479 return Tmp.split('-').second; // Strip second component
482 static unsigned EatNumber(StringRef &Str) {
483 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
484 unsigned Result = Str[0]-'0';
489 // Handle "darwin11".
490 if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
491 Result = Result*10 + (Str[0] - '0');
499 /// getDarwinNumber - Parse the 'darwin number' out of the specific target
500 /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
501 /// not defined, return 0's. This requires that the triple have an OSType of
502 /// darwin before it is called.
503 void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
504 unsigned &Revision) const {
505 assert(getOS() == Darwin && "Not a darwin target triple!");
506 StringRef OSName = getOSName();
507 assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
509 // Strip off "darwin".
510 OSName = OSName.substr(6);
512 Maj = Min = Revision = 0;
514 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
517 // The major version is the first digit.
518 Maj = EatNumber(OSName);
519 if (OSName.empty()) return;
521 // Handle minor version: 10.4.9 -> darwin8.9.
522 if (OSName[0] != '.')
526 OSName = OSName.substr(1);
528 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
531 Min = EatNumber(OSName);
532 if (OSName.empty()) return;
534 // Handle revision darwin8.9.1
535 if (OSName[0] != '.')
539 OSName = OSName.substr(1);
541 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
544 Revision = EatNumber(OSName);
547 void Triple::setTriple(const Twine &Str) {
552 void Triple::setArch(ArchType Kind) {
553 setArchName(getArchTypeName(Kind));
556 void Triple::setVendor(VendorType Kind) {
557 setVendorName(getVendorTypeName(Kind));
560 void Triple::setOS(OSType Kind) {
561 setOSName(getOSTypeName(Kind));
564 void Triple::setArchName(StringRef Str) {
565 // Work around a miscompilation bug for Twines in gcc 4.0.3.
566 SmallString<64> Triple;
569 Triple += getVendorName();
571 Triple += getOSAndEnvironmentName();
572 setTriple(Triple.str());
575 void Triple::setVendorName(StringRef Str) {
576 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
579 void Triple::setOSName(StringRef Str) {
580 if (hasEnvironment())
581 setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
582 "-" + getEnvironmentName());
584 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
587 void Triple::setEnvironmentName(StringRef Str) {
588 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
592 void Triple::setOSAndEnvironmentName(StringRef Str) {
593 setTriple(getArchName() + "-" + getVendorName() + "-" + Str);