1 //===--- Triple.cpp - Target triple helper class --------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/Triple.h" 11 #include "llvm/ADT/SmallString.h" 12 #include "llvm/ADT/STLExtras.h" 13 #include <cstring> 14 using namespace llvm; 15 16 const char *Triple::getArchTypeName(ArchType Kind) { 17 switch (Kind) { 18 case InvalidArch: return "<invalid>"; 19 case UnknownArch: return "unknown"; 20 21 case arm: return "arm"; 22 case cellspu: return "cellspu"; 23 case mips: return "mips"; 24 case mipsel: return "mipsel"; 25 case mips64: return "mips64"; 26 case mips64el:return "mips64el"; 27 case msp430: return "msp430"; 28 case ppc64: return "powerpc64"; 29 case ppc: return "powerpc"; 30 case sparc: return "sparc"; 31 case sparcv9: return "sparcv9"; 32 case tce: return "tce"; 33 case thumb: return "thumb"; 34 case x86: return "i386"; 35 case x86_64: return "x86_64"; 36 case xcore: return "xcore"; 37 case mblaze: return "mblaze"; 38 case ptx32: return "ptx32"; 39 case ptx64: return "ptx64"; 40 case le32: return "le32"; 41 case amdil: return "amdil"; 42 } 43 44 return "<invalid>"; 45 } 46 47 const char *Triple::getArchTypePrefix(ArchType Kind) { 48 switch (Kind) { 49 default: 50 return 0; 51 52 case arm: 53 case thumb: return "arm"; 54 55 case cellspu: return "spu"; 56 57 case ppc64: 58 case ppc: return "ppc"; 59 60 case mblaze: return "mblaze"; 61 62 case sparcv9: 63 case sparc: return "sparc"; 64 65 case x86: 66 case x86_64: return "x86"; 67 68 case xcore: return "xcore"; 69 70 case ptx32: return "ptx"; 71 case ptx64: return "ptx"; 72 case le32: return "le32"; 73 case amdil: return "amdil"; 74 } 75 } 76 77 const char *Triple::getVendorTypeName(VendorType Kind) { 78 switch (Kind) { 79 case UnknownVendor: return "unknown"; 80 81 case Apple: return "apple"; 82 case PC: return "pc"; 83 case SCEI: return "scei"; 84 } 85 86 return "<invalid>"; 87 } 88 89 const char *Triple::getOSTypeName(OSType Kind) { 90 switch (Kind) { 91 case UnknownOS: return "unknown"; 92 93 case AuroraUX: return "auroraux"; 94 case Cygwin: return "cygwin"; 95 case Darwin: return "darwin"; 96 case DragonFly: return "dragonfly"; 97 case FreeBSD: return "freebsd"; 98 case IOS: return "ios"; 99 case KFreeBSD: return "kfreebsd"; 100 case Linux: return "linux"; 101 case Lv2: return "lv2"; 102 case MacOSX: return "macosx"; 103 case MinGW32: return "mingw32"; 104 case NetBSD: return "netbsd"; 105 case OpenBSD: return "openbsd"; 106 case Psp: return "psp"; 107 case Solaris: return "solaris"; 108 case Win32: return "win32"; 109 case Haiku: return "haiku"; 110 case Minix: return "minix"; 111 case RTEMS: return "rtems"; 112 case NativeClient: return "nacl"; 113 } 114 115 return "<invalid>"; 116 } 117 118 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { 119 switch (Kind) { 120 case UnknownEnvironment: return "unknown"; 121 case GNU: return "gnu"; 122 case GNUEABI: return "gnueabi"; 123 case EABI: return "eabi"; 124 case MachO: return "macho"; 125 } 126 127 return "<invalid>"; 128 } 129 130 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 131 if (Name == "arm") 132 return arm; 133 if (Name == "cellspu") 134 return cellspu; 135 if (Name == "mips") 136 return mips; 137 if (Name == "mipsel") 138 return mipsel; 139 if (Name == "mips64") 140 return mips64; 141 if (Name == "mips64el") 142 return mips64el; 143 if (Name == "msp430") 144 return msp430; 145 if (Name == "ppc64") 146 return ppc64; 147 if (Name == "ppc32") 148 return ppc; 149 if (Name == "ppc") 150 return ppc; 151 if (Name == "mblaze") 152 return mblaze; 153 if (Name == "sparc") 154 return sparc; 155 if (Name == "sparcv9") 156 return sparcv9; 157 if (Name == "tce") 158 return tce; 159 if (Name == "thumb") 160 return thumb; 161 if (Name == "x86") 162 return x86; 163 if (Name == "x86-64") 164 return x86_64; 165 if (Name == "xcore") 166 return xcore; 167 if (Name == "ptx32") 168 return ptx32; 169 if (Name == "ptx64") 170 return ptx64; 171 if (Name == "le32") 172 return le32; 173 if (Name == "amdil") 174 return amdil; 175 176 return UnknownArch; 177 } 178 179 Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) { 180 // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for 181 // archs which Darwin doesn't use. 182 183 // The matching this routine does is fairly pointless, since it is neither the 184 // complete architecture list, nor a reasonable subset. The problem is that 185 // historically the driver driver accepts this and also ties its -march= 186 // handling to the architecture name, so we need to be careful before removing 187 // support for it. 188 189 // This code must be kept in sync with Clang's Darwin specific argument 190 // translation. 191 192 if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" || 193 Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" || 194 Str == "ppc7450" || Str == "ppc970") 195 return Triple::ppc; 196 197 if (Str == "ppc64") 198 return Triple::ppc64; 199 200 if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" || 201 Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" || 202 Str == "pentIIm5" || Str == "pentium4") 203 return Triple::x86; 204 205 if (Str == "x86_64") 206 return Triple::x86_64; 207 208 // This is derived from the driver driver. 209 if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" || 210 Str == "armv6" || Str == "armv7" || Str == "armv7f" || Str == "armv7k" || 211 Str == "armv7s") 212 return Triple::arm; 213 214 if (Str == "ptx32") 215 return Triple::ptx32; 216 if (Str == "ptx64") 217 return Triple::ptx64; 218 if (Str == "amdil") 219 return Triple::amdil; 220 221 return Triple::UnknownArch; 222 } 223 224 // Returns architecture name that is understood by the target assembler. 225 const char *Triple::getArchNameForAssembler() { 226 if (!isOSDarwin() && getVendor() != Triple::Apple) 227 return NULL; 228 229 StringRef Str = getArchName(); 230 if (Str == "i386") 231 return "i386"; 232 if (Str == "x86_64") 233 return "x86_64"; 234 if (Str == "powerpc") 235 return "ppc"; 236 if (Str == "powerpc64") 237 return "ppc64"; 238 if (Str == "mblaze" || Str == "microblaze") 239 return "mblaze"; 240 if (Str == "arm") 241 return "arm"; 242 if (Str == "armv4t" || Str == "thumbv4t") 243 return "armv4t"; 244 if (Str == "armv5" || Str == "armv5e" || Str == "thumbv5" 245 || Str == "thumbv5e") 246 return "armv5"; 247 if (Str == "armv6" || Str == "thumbv6") 248 return "armv6"; 249 if (Str == "armv7" || Str == "thumbv7") 250 return "armv7"; 251 if (Str == "ptx32") 252 return "ptx32"; 253 if (Str == "ptx64") 254 return "ptx64"; 255 if (Str == "le32") 256 return "le32"; 257 if (Str == "amdil") 258 return "amdil"; 259 return NULL; 260 } 261 262 // 263 264 Triple::ArchType Triple::ParseArch(StringRef ArchName) { 265 if (ArchName.size() == 4 && ArchName[0] == 'i' && 266 ArchName[2] == '8' && ArchName[3] == '6' && 267 ArchName[1] - '3' < 6) // i[3-9]86 268 return x86; 269 else if (ArchName == "amd64" || ArchName == "x86_64") 270 return x86_64; 271 else if (ArchName == "powerpc") 272 return ppc; 273 else if ((ArchName == "powerpc64") || (ArchName == "ppu")) 274 return ppc64; 275 else if (ArchName == "mblaze") 276 return mblaze; 277 else if (ArchName == "arm" || 278 ArchName.startswith("armv") || 279 ArchName == "xscale") 280 return arm; 281 else if (ArchName == "thumb" || 282 ArchName.startswith("thumbv")) 283 return thumb; 284 else if (ArchName == "spu" || ArchName == "cellspu") 285 return cellspu; 286 else if (ArchName == "msp430") 287 return msp430; 288 else if (ArchName == "mips" || ArchName == "mipseb" || 289 ArchName == "mipsallegrex") 290 return mips; 291 else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" || 292 ArchName == "psp") 293 return mipsel; 294 else if (ArchName == "mips64" || ArchName == "mips64eb") 295 return mips64; 296 else if (ArchName == "mips64el") 297 return mips64el; 298 else if (ArchName == "sparc") 299 return sparc; 300 else if (ArchName == "sparcv9") 301 return sparcv9; 302 else if (ArchName == "tce") 303 return tce; 304 else if (ArchName == "xcore") 305 return xcore; 306 else if (ArchName == "ptx32") 307 return ptx32; 308 else if (ArchName == "ptx64") 309 return ptx64; 310 else if (ArchName == "le32") 311 return le32; 312 else if (ArchName == "amdil") 313 return amdil; 314 else 315 return UnknownArch; 316 } 317 318 Triple::VendorType Triple::ParseVendor(StringRef VendorName) { 319 if (VendorName == "apple") 320 return Apple; 321 else if (VendorName == "pc") 322 return PC; 323 else if (VendorName == "scei") 324 return SCEI; 325 else 326 return UnknownVendor; 327 } 328 329 Triple::OSType Triple::ParseOS(StringRef OSName) { 330 if (OSName.startswith("auroraux")) 331 return AuroraUX; 332 else if (OSName.startswith("cygwin")) 333 return Cygwin; 334 else if (OSName.startswith("darwin")) 335 return Darwin; 336 else if (OSName.startswith("dragonfly")) 337 return DragonFly; 338 else if (OSName.startswith("freebsd")) 339 return FreeBSD; 340 else if (OSName.startswith("ios")) 341 return IOS; 342 else if (OSName.startswith("kfreebsd")) 343 return KFreeBSD; 344 else if (OSName.startswith("linux")) 345 return Linux; 346 else if (OSName.startswith("lv2")) 347 return Lv2; 348 else if (OSName.startswith("macosx")) 349 return MacOSX; 350 else if (OSName.startswith("mingw32")) 351 return MinGW32; 352 else if (OSName.startswith("netbsd")) 353 return NetBSD; 354 else if (OSName.startswith("openbsd")) 355 return OpenBSD; 356 else if (OSName.startswith("psp")) 357 return Psp; 358 else if (OSName.startswith("solaris")) 359 return Solaris; 360 else if (OSName.startswith("win32")) 361 return Win32; 362 else if (OSName.startswith("haiku")) 363 return Haiku; 364 else if (OSName.startswith("minix")) 365 return Minix; 366 else if (OSName.startswith("rtems")) 367 return RTEMS; 368 else if (OSName.startswith("nacl")) 369 return NativeClient; 370 else 371 return UnknownOS; 372 } 373 374 Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) { 375 if (EnvironmentName.startswith("eabi")) 376 return EABI; 377 else if (EnvironmentName.startswith("gnueabi")) 378 return GNUEABI; 379 else if (EnvironmentName.startswith("gnu")) 380 return GNU; 381 else if (EnvironmentName.startswith("macho")) 382 return MachO; 383 else 384 return UnknownEnvironment; 385 } 386 387 void Triple::Parse() const { 388 assert(!isInitialized() && "Invalid parse call."); 389 390 Arch = ParseArch(getArchName()); 391 Vendor = ParseVendor(getVendorName()); 392 OS = ParseOS(getOSName()); 393 Environment = ParseEnvironment(getEnvironmentName()); 394 395 assert(isInitialized() && "Failed to initialize!"); 396 } 397 398 std::string Triple::normalize(StringRef Str) { 399 // Parse into components. 400 SmallVector<StringRef, 4> Components; 401 for (size_t First = 0, Last = 0; Last != StringRef::npos; First = Last + 1) { 402 Last = Str.find('-', First); 403 Components.push_back(Str.slice(First, Last)); 404 } 405 406 // If the first component corresponds to a known architecture, preferentially 407 // use it for the architecture. If the second component corresponds to a 408 // known vendor, preferentially use it for the vendor, etc. This avoids silly 409 // component movement when a component parses as (eg) both a valid arch and a 410 // valid os. 411 ArchType Arch = UnknownArch; 412 if (Components.size() > 0) 413 Arch = ParseArch(Components[0]); 414 VendorType Vendor = UnknownVendor; 415 if (Components.size() > 1) 416 Vendor = ParseVendor(Components[1]); 417 OSType OS = UnknownOS; 418 if (Components.size() > 2) 419 OS = ParseOS(Components[2]); 420 EnvironmentType Environment = UnknownEnvironment; 421 if (Components.size() > 3) 422 Environment = ParseEnvironment(Components[3]); 423 424 // Note which components are already in their final position. These will not 425 // be moved. 426 bool Found[4]; 427 Found[0] = Arch != UnknownArch; 428 Found[1] = Vendor != UnknownVendor; 429 Found[2] = OS != UnknownOS; 430 Found[3] = Environment != UnknownEnvironment; 431 432 // If they are not there already, permute the components into their canonical 433 // positions by seeing if they parse as a valid architecture, and if so moving 434 // the component to the architecture position etc. 435 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) { 436 if (Found[Pos]) 437 continue; // Already in the canonical position. 438 439 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) { 440 // Do not reparse any components that already matched. 441 if (Idx < array_lengthof(Found) && Found[Idx]) 442 continue; 443 444 // Does this component parse as valid for the target position? 445 bool Valid = false; 446 StringRef Comp = Components[Idx]; 447 switch (Pos) { 448 default: 449 assert(false && "unexpected component type!"); 450 case 0: 451 Arch = ParseArch(Comp); 452 Valid = Arch != UnknownArch; 453 break; 454 case 1: 455 Vendor = ParseVendor(Comp); 456 Valid = Vendor != UnknownVendor; 457 break; 458 case 2: 459 OS = ParseOS(Comp); 460 Valid = OS != UnknownOS; 461 break; 462 case 3: 463 Environment = ParseEnvironment(Comp); 464 Valid = Environment != UnknownEnvironment; 465 break; 466 } 467 if (!Valid) 468 continue; // Nope, try the next component. 469 470 // Move the component to the target position, pushing any non-fixed 471 // components that are in the way to the right. This tends to give 472 // good results in the common cases of a forgotten vendor component 473 // or a wrongly positioned environment. 474 if (Pos < Idx) { 475 // Insert left, pushing the existing components to the right. For 476 // example, a-b-i386 -> i386-a-b when moving i386 to the front. 477 StringRef CurrentComponent(""); // The empty component. 478 // Replace the component we are moving with an empty component. 479 std::swap(CurrentComponent, Components[Idx]); 480 // Insert the component being moved at Pos, displacing any existing 481 // components to the right. 482 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) { 483 // Skip over any fixed components. 484 while (i < array_lengthof(Found) && Found[i]) ++i; 485 // Place the component at the new position, getting the component 486 // that was at this position - it will be moved right. 487 std::swap(CurrentComponent, Components[i]); 488 } 489 } else if (Pos > Idx) { 490 // Push right by inserting empty components until the component at Idx 491 // reaches the target position Pos. For example, pc-a -> -pc-a when 492 // moving pc to the second position. 493 do { 494 // Insert one empty component at Idx. 495 StringRef CurrentComponent(""); // The empty component. 496 for (unsigned i = Idx; i < Components.size();) { 497 // Place the component at the new position, getting the component 498 // that was at this position - it will be moved right. 499 std::swap(CurrentComponent, Components[i]); 500 // If it was placed on top of an empty component then we are done. 501 if (CurrentComponent.empty()) 502 break; 503 // Advance to the next component, skipping any fixed components. 504 while (++i < array_lengthof(Found) && Found[i]) 505 ; 506 } 507 // The last component was pushed off the end - append it. 508 if (!CurrentComponent.empty()) 509 Components.push_back(CurrentComponent); 510 511 // Advance Idx to the component's new position. 512 while (++Idx < array_lengthof(Found) && Found[Idx]) {} 513 } while (Idx < Pos); // Add more until the final position is reached. 514 } 515 assert(Pos < Components.size() && Components[Pos] == Comp && 516 "Component moved wrong!"); 517 Found[Pos] = true; 518 break; 519 } 520 } 521 522 // Special case logic goes here. At this point Arch, Vendor and OS have the 523 // correct values for the computed components. 524 525 // Stick the corrected components back together to form the normalized string. 526 std::string Normalized; 527 for (unsigned i = 0, e = Components.size(); i != e; ++i) { 528 if (i) Normalized += '-'; 529 Normalized += Components[i]; 530 } 531 return Normalized; 532 } 533 534 StringRef Triple::getArchName() const { 535 return StringRef(Data).split('-').first; // Isolate first component 536 } 537 538 StringRef Triple::getVendorName() const { 539 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 540 return Tmp.split('-').first; // Isolate second component 541 } 542 543 StringRef Triple::getOSName() const { 544 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 545 Tmp = Tmp.split('-').second; // Strip second component 546 return Tmp.split('-').first; // Isolate third component 547 } 548 549 StringRef Triple::getEnvironmentName() const { 550 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 551 Tmp = Tmp.split('-').second; // Strip second component 552 return Tmp.split('-').second; // Strip third component 553 } 554 555 StringRef Triple::getOSAndEnvironmentName() const { 556 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 557 return Tmp.split('-').second; // Strip second component 558 } 559 560 static unsigned EatNumber(StringRef &Str) { 561 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 562 unsigned Result = 0; 563 564 do { 565 // Consume the leading digit. 566 Result = Result*10 + (Str[0] - '0'); 567 568 // Eat the digit. 569 Str = Str.substr(1); 570 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9'); 571 572 return Result; 573 } 574 575 void Triple::getOSVersion(unsigned &Major, unsigned &Minor, 576 unsigned &Micro) const { 577 StringRef OSName = getOSName(); 578 579 // Assume that the OS portion of the triple starts with the canonical name. 580 StringRef OSTypeName = getOSTypeName(getOS()); 581 if (OSName.startswith(OSTypeName)) 582 OSName = OSName.substr(OSTypeName.size()); 583 584 // Any unset version defaults to 0. 585 Major = Minor = Micro = 0; 586 587 // Parse up to three components. 588 unsigned *Components[3] = { &Major, &Minor, &Micro }; 589 for (unsigned i = 0; i != 3; ++i) { 590 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 591 break; 592 593 // Consume the leading number. 594 *Components[i] = EatNumber(OSName); 595 596 // Consume the separator, if present. 597 if (OSName.startswith(".")) 598 OSName = OSName.substr(1); 599 } 600 } 601 602 void Triple::setTriple(const Twine &Str) { 603 Data = Str.str(); 604 Arch = InvalidArch; 605 } 606 607 void Triple::setArch(ArchType Kind) { 608 setArchName(getArchTypeName(Kind)); 609 } 610 611 void Triple::setVendor(VendorType Kind) { 612 setVendorName(getVendorTypeName(Kind)); 613 } 614 615 void Triple::setOS(OSType Kind) { 616 setOSName(getOSTypeName(Kind)); 617 } 618 619 void Triple::setEnvironment(EnvironmentType Kind) { 620 setEnvironmentName(getEnvironmentTypeName(Kind)); 621 } 622 623 void Triple::setArchName(StringRef Str) { 624 // Work around a miscompilation bug for Twines in gcc 4.0.3. 625 SmallString<64> Triple; 626 Triple += Str; 627 Triple += "-"; 628 Triple += getVendorName(); 629 Triple += "-"; 630 Triple += getOSAndEnvironmentName(); 631 setTriple(Triple.str()); 632 } 633 634 void Triple::setVendorName(StringRef Str) { 635 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 636 } 637 638 void Triple::setOSName(StringRef Str) { 639 if (hasEnvironment()) 640 setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 641 "-" + getEnvironmentName()); 642 else 643 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 644 } 645 646 void Triple::setEnvironmentName(StringRef Str) { 647 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 648 "-" + Str); 649 } 650 651 void Triple::setOSAndEnvironmentName(StringRef Str) { 652 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 653 } 654