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