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