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