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/STLExtras.h" 12 #include "llvm/ADT/SmallString.h" 13 #include "llvm/ADT/StringSwitch.h" 14 #include "llvm/Support/ErrorHandling.h" 15 #include <cstring> 16 using namespace llvm; 17 getArchTypeName(ArchType Kind)18 const char *Triple::getArchTypeName(ArchType Kind) { 19 switch (Kind) { 20 case UnknownArch: return "unknown"; 21 22 case aarch64: return "aarch64"; 23 case aarch64_be: return "aarch64_be"; 24 case arm: return "arm"; 25 case armeb: return "armeb"; 26 case arm64: return "arm64"; 27 case arm64_be: return "arm64_be"; 28 case hexagon: return "hexagon"; 29 case mips: return "mips"; 30 case mipsel: return "mipsel"; 31 case mips64: return "mips64"; 32 case mips64el: return "mips64el"; 33 case msp430: return "msp430"; 34 case ppc64: return "powerpc64"; 35 case ppc64le: return "powerpc64le"; 36 case ppc: return "powerpc"; 37 case r600: return "r600"; 38 case sparc: return "sparc"; 39 case sparcv9: return "sparcv9"; 40 case systemz: return "s390x"; 41 case tce: return "tce"; 42 case thumb: return "thumb"; 43 case thumbeb: return "thumbeb"; 44 case x86: return "i386"; 45 case x86_64: return "x86_64"; 46 case xcore: return "xcore"; 47 case nvptx: return "nvptx"; 48 case nvptx64: return "nvptx64"; 49 case le32: return "le32"; 50 case amdil: return "amdil"; 51 case spir: return "spir"; 52 case spir64: return "spir64"; 53 case kalimba: return "kalimba"; 54 } 55 56 llvm_unreachable("Invalid ArchType!"); 57 } 58 getArchTypePrefix(ArchType Kind)59 const char *Triple::getArchTypePrefix(ArchType Kind) { 60 switch (Kind) { 61 default: 62 return nullptr; 63 64 case aarch64: 65 case aarch64_be: return "aarch64"; 66 67 case arm: 68 case armeb: 69 case thumb: 70 case thumbeb: return "arm"; 71 72 case arm64: 73 case arm64_be: return "arm64"; 74 75 case ppc64: 76 case ppc64le: 77 case ppc: return "ppc"; 78 79 case mips: 80 case mipsel: 81 case mips64: 82 case mips64el: return "mips"; 83 84 case hexagon: return "hexagon"; 85 86 case r600: return "r600"; 87 88 case sparcv9: 89 case sparc: return "sparc"; 90 91 case systemz: return "systemz"; 92 93 case x86: 94 case x86_64: return "x86"; 95 96 case xcore: return "xcore"; 97 98 case nvptx: return "nvptx"; 99 case nvptx64: return "nvptx"; 100 101 case le32: return "le32"; 102 case amdil: return "amdil"; 103 case spir: return "spir"; 104 case spir64: return "spir"; 105 case kalimba: return "kalimba"; 106 } 107 } 108 getVendorTypeName(VendorType Kind)109 const char *Triple::getVendorTypeName(VendorType Kind) { 110 switch (Kind) { 111 case UnknownVendor: return "unknown"; 112 113 case Apple: return "apple"; 114 case PC: return "pc"; 115 case SCEI: return "scei"; 116 case BGP: return "bgp"; 117 case BGQ: return "bgq"; 118 case Freescale: return "fsl"; 119 case IBM: return "ibm"; 120 case ImaginationTechnologies: return "img"; 121 case NVIDIA: return "nvidia"; 122 case CSR: return "csr"; 123 } 124 125 llvm_unreachable("Invalid VendorType!"); 126 } 127 getOSTypeName(OSType Kind)128 const char *Triple::getOSTypeName(OSType Kind) { 129 switch (Kind) { 130 case UnknownOS: return "unknown"; 131 132 case AuroraUX: return "auroraux"; 133 case Cygwin: return "cygwin"; 134 case Darwin: return "darwin"; 135 case DragonFly: return "dragonfly"; 136 case FreeBSD: return "freebsd"; 137 case IOS: return "ios"; 138 case KFreeBSD: return "kfreebsd"; 139 case Linux: return "linux"; 140 case Lv2: return "lv2"; 141 case MacOSX: return "macosx"; 142 case MinGW32: return "mingw32"; 143 case NetBSD: return "netbsd"; 144 case OpenBSD: return "openbsd"; 145 case Solaris: return "solaris"; 146 case Win32: return "windows"; 147 case Haiku: return "haiku"; 148 case Minix: return "minix"; 149 case RTEMS: return "rtems"; 150 case NaCl: return "nacl"; 151 case CNK: return "cnk"; 152 case Bitrig: return "bitrig"; 153 case AIX: return "aix"; 154 case CUDA: return "cuda"; 155 case NVCL: return "nvcl"; 156 } 157 158 llvm_unreachable("Invalid OSType"); 159 } 160 getEnvironmentTypeName(EnvironmentType Kind)161 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { 162 switch (Kind) { 163 case UnknownEnvironment: return "unknown"; 164 case GNU: return "gnu"; 165 case GNUEABIHF: return "gnueabihf"; 166 case GNUEABI: return "gnueabi"; 167 case GNUX32: return "gnux32"; 168 case CODE16: return "code16"; 169 case EABI: return "eabi"; 170 case EABIHF: return "eabihf"; 171 case Android: return "android"; 172 case MSVC: return "msvc"; 173 case Itanium: return "itanium"; 174 case Cygnus: return "cygnus"; 175 } 176 177 llvm_unreachable("Invalid EnvironmentType!"); 178 } 179 getArchTypeForLLVMName(StringRef Name)180 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 181 return StringSwitch<Triple::ArchType>(Name) 182 .Case("aarch64", aarch64) 183 .Case("aarch64_be", aarch64_be) 184 .Case("arm", arm) 185 .Case("armeb", armeb) 186 .Case("arm64", arm64) 187 .Case("arm64_be", arm64_be) 188 .Case("mips", mips) 189 .Case("mipsel", mipsel) 190 .Case("mips64", mips64) 191 .Case("mips64el", mips64el) 192 .Case("msp430", msp430) 193 .Case("ppc64", ppc64) 194 .Case("ppc32", ppc) 195 .Case("ppc", ppc) 196 .Case("ppc64le", ppc64le) 197 .Case("r600", r600) 198 .Case("hexagon", hexagon) 199 .Case("sparc", sparc) 200 .Case("sparcv9", sparcv9) 201 .Case("systemz", systemz) 202 .Case("tce", tce) 203 .Case("thumb", thumb) 204 .Case("thumbeb", thumbeb) 205 .Case("x86", x86) 206 .Case("x86-64", x86_64) 207 .Case("xcore", xcore) 208 .Case("nvptx", nvptx) 209 .Case("nvptx64", nvptx64) 210 .Case("le32", le32) 211 .Case("amdil", amdil) 212 .Case("spir", spir) 213 .Case("spir64", spir64) 214 .Case("kalimba", kalimba) 215 .Default(UnknownArch); 216 } 217 218 // Returns architecture name that is understood by the target assembler. getArchNameForAssembler()219 const char *Triple::getArchNameForAssembler() { 220 if (!isOSDarwin() && getVendor() != Triple::Apple) 221 return nullptr; 222 223 return StringSwitch<const char*>(getArchName()) 224 .Case("i386", "i386") 225 .Case("x86_64", "x86_64") 226 .Case("powerpc", "ppc") 227 .Case("powerpc64", "ppc64") 228 .Case("powerpc64le", "ppc64le") 229 .Case("arm", "arm") 230 .Cases("armv4t", "thumbv4t", "armv4t") 231 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5") 232 .Cases("armv6", "thumbv6", "armv6") 233 .Cases("armv7", "thumbv7", "armv7") 234 .Case("armeb", "armeb") 235 .Case("arm64", "arm64") 236 .Case("arm64_be", "arm64") 237 .Case("r600", "r600") 238 .Case("nvptx", "nvptx") 239 .Case("nvptx64", "nvptx64") 240 .Case("le32", "le32") 241 .Case("amdil", "amdil") 242 .Case("spir", "spir") 243 .Case("spir64", "spir64") 244 .Default(nullptr); 245 } 246 parseArch(StringRef ArchName)247 static Triple::ArchType parseArch(StringRef ArchName) { 248 return StringSwitch<Triple::ArchType>(ArchName) 249 .Cases("i386", "i486", "i586", "i686", Triple::x86) 250 // FIXME: Do we need to support these? 251 .Cases("i786", "i886", "i986", Triple::x86) 252 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64) 253 .Case("powerpc", Triple::ppc) 254 .Cases("powerpc64", "ppu", Triple::ppc64) 255 .Case("powerpc64le", Triple::ppc64le) 256 .Case("aarch64", Triple::aarch64) 257 .Case("aarch64_be", Triple::aarch64_be) 258 .Cases("arm", "xscale", Triple::arm) 259 // FIXME: It would be good to replace these with explicit names for all the 260 // various suffixes supported. 261 .StartsWith("armv", Triple::arm) 262 .Case("armeb", Triple::armeb) 263 .StartsWith("armebv", Triple::armeb) 264 .Case("thumb", Triple::thumb) 265 .StartsWith("thumbv", Triple::thumb) 266 .Case("thumbeb", Triple::thumbeb) 267 .StartsWith("thumbebv", Triple::thumbeb) 268 .Case("arm64", Triple::arm64) 269 .Case("arm64_be", Triple::arm64_be) 270 .Case("msp430", Triple::msp430) 271 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) 272 .Cases("mipsel", "mipsallegrexel", Triple::mipsel) 273 .Cases("mips64", "mips64eb", Triple::mips64) 274 .Case("mips64el", Triple::mips64el) 275 .Case("r600", Triple::r600) 276 .Case("hexagon", Triple::hexagon) 277 .Case("s390x", Triple::systemz) 278 .Case("sparc", Triple::sparc) 279 .Cases("sparcv9", "sparc64", Triple::sparcv9) 280 .Case("tce", Triple::tce) 281 .Case("xcore", Triple::xcore) 282 .Case("nvptx", Triple::nvptx) 283 .Case("nvptx64", Triple::nvptx64) 284 .Case("le32", Triple::le32) 285 .Case("amdil", Triple::amdil) 286 .Case("spir", Triple::spir) 287 .Case("spir64", Triple::spir64) 288 .Case("kalimba", Triple::kalimba) 289 .Default(Triple::UnknownArch); 290 } 291 parseVendor(StringRef VendorName)292 static Triple::VendorType parseVendor(StringRef VendorName) { 293 return StringSwitch<Triple::VendorType>(VendorName) 294 .Case("apple", Triple::Apple) 295 .Case("pc", Triple::PC) 296 .Case("scei", Triple::SCEI) 297 .Case("bgp", Triple::BGP) 298 .Case("bgq", Triple::BGQ) 299 .Case("fsl", Triple::Freescale) 300 .Case("ibm", Triple::IBM) 301 .Case("img", Triple::ImaginationTechnologies) 302 .Case("nvidia", Triple::NVIDIA) 303 .Case("csr", Triple::CSR) 304 .Default(Triple::UnknownVendor); 305 } 306 parseOS(StringRef OSName)307 static Triple::OSType parseOS(StringRef OSName) { 308 return StringSwitch<Triple::OSType>(OSName) 309 .StartsWith("auroraux", Triple::AuroraUX) 310 .StartsWith("cygwin", Triple::Cygwin) 311 .StartsWith("darwin", Triple::Darwin) 312 .StartsWith("dragonfly", Triple::DragonFly) 313 .StartsWith("freebsd", Triple::FreeBSD) 314 .StartsWith("ios", Triple::IOS) 315 .StartsWith("kfreebsd", Triple::KFreeBSD) 316 .StartsWith("linux", Triple::Linux) 317 .StartsWith("lv2", Triple::Lv2) 318 .StartsWith("macosx", Triple::MacOSX) 319 .StartsWith("mingw32", Triple::MinGW32) 320 .StartsWith("netbsd", Triple::NetBSD) 321 .StartsWith("openbsd", Triple::OpenBSD) 322 .StartsWith("solaris", Triple::Solaris) 323 .StartsWith("win32", Triple::Win32) 324 .StartsWith("windows", Triple::Win32) 325 .StartsWith("haiku", Triple::Haiku) 326 .StartsWith("minix", Triple::Minix) 327 .StartsWith("rtems", Triple::RTEMS) 328 .StartsWith("nacl", Triple::NaCl) 329 .StartsWith("cnk", Triple::CNK) 330 .StartsWith("bitrig", Triple::Bitrig) 331 .StartsWith("aix", Triple::AIX) 332 .StartsWith("cuda", Triple::CUDA) 333 .StartsWith("nvcl", Triple::NVCL) 334 .Default(Triple::UnknownOS); 335 } 336 parseEnvironment(StringRef EnvironmentName)337 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { 338 return StringSwitch<Triple::EnvironmentType>(EnvironmentName) 339 .StartsWith("eabihf", Triple::EABIHF) 340 .StartsWith("eabi", Triple::EABI) 341 .StartsWith("gnueabihf", Triple::GNUEABIHF) 342 .StartsWith("gnueabi", Triple::GNUEABI) 343 .StartsWith("gnux32", Triple::GNUX32) 344 .StartsWith("code16", Triple::CODE16) 345 .StartsWith("gnu", Triple::GNU) 346 .StartsWith("android", Triple::Android) 347 .StartsWith("msvc", Triple::MSVC) 348 .StartsWith("itanium", Triple::Itanium) 349 .StartsWith("cygnus", Triple::Cygnus) 350 .Default(Triple::UnknownEnvironment); 351 } 352 parseFormat(StringRef EnvironmentName)353 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) { 354 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName) 355 .EndsWith("coff", Triple::COFF) 356 .EndsWith("elf", Triple::ELF) 357 .EndsWith("macho", Triple::MachO) 358 .Default(Triple::UnknownObjectFormat); 359 } 360 getObjectFormatTypeName(Triple::ObjectFormatType Kind)361 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) { 362 switch (Kind) { 363 case Triple::UnknownObjectFormat: return ""; 364 case Triple::COFF: return "coff"; 365 case Triple::ELF: return "elf"; 366 case Triple::MachO: return "macho"; 367 } 368 llvm_unreachable("unknown object format type"); 369 } 370 getDefaultFormat(const Triple & T)371 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { 372 if (T.isOSDarwin()) 373 return Triple::MachO; 374 else if (T.isOSWindows()) 375 return Triple::COFF; 376 return Triple::ELF; 377 } 378 379 /// \brief Construct a triple from the string representation provided. 380 /// 381 /// This stores the string representation and parses the various pieces into 382 /// enum members. Triple(const Twine & Str)383 Triple::Triple(const Twine &Str) 384 : Data(Str.str()), 385 Arch(parseArch(getArchName())), 386 Vendor(parseVendor(getVendorName())), 387 OS(parseOS(getOSName())), 388 Environment(parseEnvironment(getEnvironmentName())), 389 ObjectFormat(parseFormat(getEnvironmentName())) { 390 if (ObjectFormat == Triple::UnknownObjectFormat) 391 ObjectFormat = getDefaultFormat(*this); 392 } 393 394 /// \brief Construct a triple from string representations of the architecture, 395 /// vendor, and OS. 396 /// 397 /// This joins each argument into a canonical string representation and parses 398 /// them into enum members. It leaves the environment unknown and omits it from 399 /// the string representation. Triple(const Twine & ArchStr,const Twine & VendorStr,const Twine & OSStr)400 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) 401 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()), 402 Arch(parseArch(ArchStr.str())), 403 Vendor(parseVendor(VendorStr.str())), 404 OS(parseOS(OSStr.str())), 405 Environment(), ObjectFormat(Triple::UnknownObjectFormat) { 406 ObjectFormat = getDefaultFormat(*this); 407 } 408 409 /// \brief Construct a triple from string representations of the architecture, 410 /// vendor, OS, and environment. 411 /// 412 /// This joins each argument into a canonical string representation and parses 413 /// them into enum members. Triple(const Twine & ArchStr,const Twine & VendorStr,const Twine & OSStr,const Twine & EnvironmentStr)414 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, 415 const Twine &EnvironmentStr) 416 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') + 417 EnvironmentStr).str()), 418 Arch(parseArch(ArchStr.str())), 419 Vendor(parseVendor(VendorStr.str())), 420 OS(parseOS(OSStr.str())), 421 Environment(parseEnvironment(EnvironmentStr.str())), 422 ObjectFormat(parseFormat(EnvironmentStr.str())) { 423 if (ObjectFormat == Triple::UnknownObjectFormat) 424 ObjectFormat = getDefaultFormat(*this); 425 } 426 normalize(StringRef Str)427 std::string Triple::normalize(StringRef Str) { 428 // Parse into components. 429 SmallVector<StringRef, 4> Components; 430 Str.split(Components, "-"); 431 432 // If the first component corresponds to a known architecture, preferentially 433 // use it for the architecture. If the second component corresponds to a 434 // known vendor, preferentially use it for the vendor, etc. This avoids silly 435 // component movement when a component parses as (eg) both a valid arch and a 436 // valid os. 437 ArchType Arch = UnknownArch; 438 if (Components.size() > 0) 439 Arch = parseArch(Components[0]); 440 VendorType Vendor = UnknownVendor; 441 if (Components.size() > 1) 442 Vendor = parseVendor(Components[1]); 443 OSType OS = UnknownOS; 444 if (Components.size() > 2) 445 OS = parseOS(Components[2]); 446 EnvironmentType Environment = UnknownEnvironment; 447 if (Components.size() > 3) 448 Environment = parseEnvironment(Components[3]); 449 ObjectFormatType ObjectFormat = UnknownObjectFormat; 450 if (Components.size() > 4) 451 ObjectFormat = parseFormat(Components[4]); 452 453 // Note which components are already in their final position. These will not 454 // be moved. 455 bool Found[4]; 456 Found[0] = Arch != UnknownArch; 457 Found[1] = Vendor != UnknownVendor; 458 Found[2] = OS != UnknownOS; 459 Found[3] = Environment != UnknownEnvironment; 460 461 // If they are not there already, permute the components into their canonical 462 // positions by seeing if they parse as a valid architecture, and if so moving 463 // the component to the architecture position etc. 464 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) { 465 if (Found[Pos]) 466 continue; // Already in the canonical position. 467 468 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) { 469 // Do not reparse any components that already matched. 470 if (Idx < array_lengthof(Found) && Found[Idx]) 471 continue; 472 473 // Does this component parse as valid for the target position? 474 bool Valid = false; 475 StringRef Comp = Components[Idx]; 476 switch (Pos) { 477 default: llvm_unreachable("unexpected component type!"); 478 case 0: 479 Arch = parseArch(Comp); 480 Valid = Arch != UnknownArch; 481 break; 482 case 1: 483 Vendor = parseVendor(Comp); 484 Valid = Vendor != UnknownVendor; 485 break; 486 case 2: 487 OS = parseOS(Comp); 488 Valid = OS != UnknownOS; 489 break; 490 case 3: 491 Environment = parseEnvironment(Comp); 492 Valid = Environment != UnknownEnvironment; 493 if (!Valid) { 494 ObjectFormat = parseFormat(Comp); 495 Valid = ObjectFormat != UnknownObjectFormat; 496 } 497 break; 498 } 499 if (!Valid) 500 continue; // Nope, try the next component. 501 502 // Move the component to the target position, pushing any non-fixed 503 // components that are in the way to the right. This tends to give 504 // good results in the common cases of a forgotten vendor component 505 // or a wrongly positioned environment. 506 if (Pos < Idx) { 507 // Insert left, pushing the existing components to the right. For 508 // example, a-b-i386 -> i386-a-b when moving i386 to the front. 509 StringRef CurrentComponent(""); // The empty component. 510 // Replace the component we are moving with an empty component. 511 std::swap(CurrentComponent, Components[Idx]); 512 // Insert the component being moved at Pos, displacing any existing 513 // components to the right. 514 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) { 515 // Skip over any fixed components. 516 while (i < array_lengthof(Found) && Found[i]) 517 ++i; 518 // Place the component at the new position, getting the component 519 // that was at this position - it will be moved right. 520 std::swap(CurrentComponent, Components[i]); 521 } 522 } else if (Pos > Idx) { 523 // Push right by inserting empty components until the component at Idx 524 // reaches the target position Pos. For example, pc-a -> -pc-a when 525 // moving pc to the second position. 526 do { 527 // Insert one empty component at Idx. 528 StringRef CurrentComponent(""); // The empty component. 529 for (unsigned i = Idx; i < Components.size();) { 530 // Place the component at the new position, getting the component 531 // that was at this position - it will be moved right. 532 std::swap(CurrentComponent, Components[i]); 533 // If it was placed on top of an empty component then we are done. 534 if (CurrentComponent.empty()) 535 break; 536 // Advance to the next component, skipping any fixed components. 537 while (++i < array_lengthof(Found) && Found[i]) 538 ; 539 } 540 // The last component was pushed off the end - append it. 541 if (!CurrentComponent.empty()) 542 Components.push_back(CurrentComponent); 543 544 // Advance Idx to the component's new position. 545 while (++Idx < array_lengthof(Found) && Found[Idx]) 546 ; 547 } while (Idx < Pos); // Add more until the final position is reached. 548 } 549 assert(Pos < Components.size() && Components[Pos] == Comp && 550 "Component moved wrong!"); 551 Found[Pos] = true; 552 break; 553 } 554 } 555 556 // Special case logic goes here. At this point Arch, Vendor and OS have the 557 // correct values for the computed components. 558 559 if (OS == Triple::Win32) { 560 Components.resize(4); 561 Components[2] = "windows"; 562 if (Environment == UnknownEnvironment) { 563 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF) 564 Components[3] = "msvc"; 565 else 566 Components[3] = getObjectFormatTypeName(ObjectFormat); 567 } 568 } else if (OS == Triple::MinGW32) { 569 Components.resize(4); 570 Components[2] = "windows"; 571 Components[3] = "gnu"; 572 } else if (OS == Triple::Cygwin) { 573 Components.resize(4); 574 Components[2] = "windows"; 575 Components[3] = "cygnus"; 576 } 577 if (OS == Triple::MinGW32 || OS == Triple::Cygwin || 578 (OS == Triple::Win32 && Environment != UnknownEnvironment)) { 579 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) { 580 Components.resize(5); 581 Components[4] = getObjectFormatTypeName(ObjectFormat); 582 } 583 } 584 585 // Stick the corrected components back together to form the normalized string. 586 std::string Normalized; 587 for (unsigned i = 0, e = Components.size(); i != e; ++i) { 588 if (i) Normalized += '-'; 589 Normalized += Components[i]; 590 } 591 return Normalized; 592 } 593 getArchName() const594 StringRef Triple::getArchName() const { 595 return StringRef(Data).split('-').first; // Isolate first component 596 } 597 getVendorName() const598 StringRef Triple::getVendorName() const { 599 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 600 return Tmp.split('-').first; // Isolate second component 601 } 602 getOSName() const603 StringRef Triple::getOSName() const { 604 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 605 Tmp = Tmp.split('-').second; // Strip second component 606 return Tmp.split('-').first; // Isolate third component 607 } 608 getEnvironmentName() const609 StringRef Triple::getEnvironmentName() const { 610 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 611 Tmp = Tmp.split('-').second; // Strip second component 612 return Tmp.split('-').second; // Strip third component 613 } 614 getOSAndEnvironmentName() const615 StringRef Triple::getOSAndEnvironmentName() const { 616 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 617 return Tmp.split('-').second; // Strip second component 618 } 619 EatNumber(StringRef & Str)620 static unsigned EatNumber(StringRef &Str) { 621 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 622 unsigned Result = 0; 623 624 do { 625 // Consume the leading digit. 626 Result = Result*10 + (Str[0] - '0'); 627 628 // Eat the digit. 629 Str = Str.substr(1); 630 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9'); 631 632 return Result; 633 } 634 getOSVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const635 void Triple::getOSVersion(unsigned &Major, unsigned &Minor, 636 unsigned &Micro) const { 637 StringRef OSName = getOSName(); 638 639 // Assume that the OS portion of the triple starts with the canonical name. 640 StringRef OSTypeName = getOSTypeName(getOS()); 641 if (OSName.startswith(OSTypeName)) 642 OSName = OSName.substr(OSTypeName.size()); 643 644 // Any unset version defaults to 0. 645 Major = Minor = Micro = 0; 646 647 // Parse up to three components. 648 unsigned *Components[3] = { &Major, &Minor, &Micro }; 649 for (unsigned i = 0; i != 3; ++i) { 650 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 651 break; 652 653 // Consume the leading number. 654 *Components[i] = EatNumber(OSName); 655 656 // Consume the separator, if present. 657 if (OSName.startswith(".")) 658 OSName = OSName.substr(1); 659 } 660 } 661 getMacOSXVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const662 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, 663 unsigned &Micro) const { 664 getOSVersion(Major, Minor, Micro); 665 666 switch (getOS()) { 667 default: llvm_unreachable("unexpected OS for Darwin triple"); 668 case Darwin: 669 // Default to darwin8, i.e., MacOSX 10.4. 670 if (Major == 0) 671 Major = 8; 672 // Darwin version numbers are skewed from OS X versions. 673 if (Major < 4) 674 return false; 675 Micro = 0; 676 Minor = Major - 4; 677 Major = 10; 678 break; 679 case MacOSX: 680 // Default to 10.4. 681 if (Major == 0) { 682 Major = 10; 683 Minor = 4; 684 } 685 if (Major != 10) 686 return false; 687 break; 688 case IOS: 689 // Ignore the version from the triple. This is only handled because the 690 // the clang driver combines OS X and IOS support into a common Darwin 691 // toolchain that wants to know the OS X version number even when targeting 692 // IOS. 693 Major = 10; 694 Minor = 4; 695 Micro = 0; 696 break; 697 } 698 return true; 699 } 700 getiOSVersion(unsigned & Major,unsigned & Minor,unsigned & Micro) const701 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor, 702 unsigned &Micro) const { 703 switch (getOS()) { 704 default: llvm_unreachable("unexpected OS for Darwin triple"); 705 case Darwin: 706 case MacOSX: 707 // Ignore the version from the triple. This is only handled because the 708 // the clang driver combines OS X and IOS support into a common Darwin 709 // toolchain that wants to know the iOS version number even when targeting 710 // OS X. 711 Major = 5; 712 Minor = 0; 713 Micro = 0; 714 break; 715 case IOS: 716 getOSVersion(Major, Minor, Micro); 717 // Default to 5.0 (or 7.0 for arm64). 718 if (Major == 0) 719 Major = (getArch() == arm64) ? 7 : 5; 720 break; 721 } 722 } 723 setTriple(const Twine & Str)724 void Triple::setTriple(const Twine &Str) { 725 *this = Triple(Str); 726 } 727 setArch(ArchType Kind)728 void Triple::setArch(ArchType Kind) { 729 setArchName(getArchTypeName(Kind)); 730 } 731 setVendor(VendorType Kind)732 void Triple::setVendor(VendorType Kind) { 733 setVendorName(getVendorTypeName(Kind)); 734 } 735 setOS(OSType Kind)736 void Triple::setOS(OSType Kind) { 737 setOSName(getOSTypeName(Kind)); 738 } 739 setEnvironment(EnvironmentType Kind)740 void Triple::setEnvironment(EnvironmentType Kind) { 741 setEnvironmentName(getEnvironmentTypeName(Kind)); 742 } 743 setObjectFormat(ObjectFormatType Kind)744 void Triple::setObjectFormat(ObjectFormatType Kind) { 745 if (Environment == UnknownEnvironment) 746 return setEnvironmentName(getObjectFormatTypeName(Kind)); 747 748 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") + 749 getObjectFormatTypeName(Kind)).str()); 750 } 751 setArchName(StringRef Str)752 void Triple::setArchName(StringRef Str) { 753 // Work around a miscompilation bug for Twines in gcc 4.0.3. 754 SmallString<64> Triple; 755 Triple += Str; 756 Triple += "-"; 757 Triple += getVendorName(); 758 Triple += "-"; 759 Triple += getOSAndEnvironmentName(); 760 setTriple(Triple.str()); 761 } 762 setVendorName(StringRef Str)763 void Triple::setVendorName(StringRef Str) { 764 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 765 } 766 setOSName(StringRef Str)767 void Triple::setOSName(StringRef Str) { 768 if (hasEnvironment()) 769 setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 770 "-" + getEnvironmentName()); 771 else 772 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 773 } 774 setEnvironmentName(StringRef Str)775 void Triple::setEnvironmentName(StringRef Str) { 776 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 777 "-" + Str); 778 } 779 setOSAndEnvironmentName(StringRef Str)780 void Triple::setOSAndEnvironmentName(StringRef Str) { 781 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 782 } 783 getArchPointerBitWidth(llvm::Triple::ArchType Arch)784 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { 785 switch (Arch) { 786 case llvm::Triple::UnknownArch: 787 return 0; 788 789 case llvm::Triple::msp430: 790 return 16; 791 792 case llvm::Triple::amdil: 793 case llvm::Triple::arm: 794 case llvm::Triple::armeb: 795 case llvm::Triple::hexagon: 796 case llvm::Triple::le32: 797 case llvm::Triple::mips: 798 case llvm::Triple::mipsel: 799 case llvm::Triple::nvptx: 800 case llvm::Triple::ppc: 801 case llvm::Triple::r600: 802 case llvm::Triple::sparc: 803 case llvm::Triple::tce: 804 case llvm::Triple::thumb: 805 case llvm::Triple::thumbeb: 806 case llvm::Triple::x86: 807 case llvm::Triple::xcore: 808 case llvm::Triple::spir: 809 case llvm::Triple::kalimba: 810 return 32; 811 812 case llvm::Triple::arm64: 813 case llvm::Triple::arm64_be: 814 case llvm::Triple::aarch64: 815 case llvm::Triple::aarch64_be: 816 case llvm::Triple::mips64: 817 case llvm::Triple::mips64el: 818 case llvm::Triple::nvptx64: 819 case llvm::Triple::ppc64: 820 case llvm::Triple::ppc64le: 821 case llvm::Triple::sparcv9: 822 case llvm::Triple::systemz: 823 case llvm::Triple::x86_64: 824 case llvm::Triple::spir64: 825 return 64; 826 } 827 llvm_unreachable("Invalid architecture value"); 828 } 829 isArch64Bit() const830 bool Triple::isArch64Bit() const { 831 return getArchPointerBitWidth(getArch()) == 64; 832 } 833 isArch32Bit() const834 bool Triple::isArch32Bit() const { 835 return getArchPointerBitWidth(getArch()) == 32; 836 } 837 isArch16Bit() const838 bool Triple::isArch16Bit() const { 839 return getArchPointerBitWidth(getArch()) == 16; 840 } 841 get32BitArchVariant() const842 Triple Triple::get32BitArchVariant() const { 843 Triple T(*this); 844 switch (getArch()) { 845 case Triple::UnknownArch: 846 case Triple::aarch64: 847 case Triple::aarch64_be: 848 case Triple::arm64: 849 case Triple::arm64_be: 850 case Triple::msp430: 851 case Triple::systemz: 852 case Triple::ppc64le: 853 T.setArch(UnknownArch); 854 break; 855 856 case Triple::amdil: 857 case Triple::spir: 858 case Triple::arm: 859 case Triple::armeb: 860 case Triple::hexagon: 861 case Triple::kalimba: 862 case Triple::le32: 863 case Triple::mips: 864 case Triple::mipsel: 865 case Triple::nvptx: 866 case Triple::ppc: 867 case Triple::r600: 868 case Triple::sparc: 869 case Triple::tce: 870 case Triple::thumb: 871 case Triple::thumbeb: 872 case Triple::x86: 873 case Triple::xcore: 874 // Already 32-bit. 875 break; 876 877 case Triple::mips64: T.setArch(Triple::mips); break; 878 case Triple::mips64el: T.setArch(Triple::mipsel); break; 879 case Triple::nvptx64: T.setArch(Triple::nvptx); break; 880 case Triple::ppc64: T.setArch(Triple::ppc); break; 881 case Triple::sparcv9: T.setArch(Triple::sparc); break; 882 case Triple::x86_64: T.setArch(Triple::x86); break; 883 case Triple::spir64: T.setArch(Triple::spir); break; 884 } 885 return T; 886 } 887 get64BitArchVariant() const888 Triple Triple::get64BitArchVariant() const { 889 Triple T(*this); 890 switch (getArch()) { 891 case Triple::UnknownArch: 892 case Triple::amdil: 893 case Triple::arm: 894 case Triple::armeb: 895 case Triple::hexagon: 896 case Triple::kalimba: 897 case Triple::le32: 898 case Triple::msp430: 899 case Triple::r600: 900 case Triple::tce: 901 case Triple::thumb: 902 case Triple::thumbeb: 903 case Triple::xcore: 904 T.setArch(UnknownArch); 905 break; 906 907 case Triple::aarch64: 908 case Triple::aarch64_be: 909 case Triple::spir64: 910 case Triple::mips64: 911 case Triple::mips64el: 912 case Triple::nvptx64: 913 case Triple::ppc64: 914 case Triple::ppc64le: 915 case Triple::sparcv9: 916 case Triple::systemz: 917 case Triple::x86_64: 918 case Triple::arm64: 919 case Triple::arm64_be: 920 // Already 64-bit. 921 break; 922 923 case Triple::mips: T.setArch(Triple::mips64); break; 924 case Triple::mipsel: T.setArch(Triple::mips64el); break; 925 case Triple::nvptx: T.setArch(Triple::nvptx64); break; 926 case Triple::ppc: T.setArch(Triple::ppc64); break; 927 case Triple::sparc: T.setArch(Triple::sparcv9); break; 928 case Triple::x86: T.setArch(Triple::x86_64); break; 929 case Triple::spir: T.setArch(Triple::spir64); break; 930 } 931 return T; 932 } 933