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