LLVM API Documentation
00001 //===--- Triple.cpp - Target triple helper class --------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/ADT/Triple.h" 00011 #include "llvm/ADT/STLExtras.h" 00012 #include "llvm/ADT/SmallString.h" 00013 #include "llvm/ADT/StringSwitch.h" 00014 #include "llvm/Support/ErrorHandling.h" 00015 #include <cstring> 00016 using namespace llvm; 00017 00018 const char *Triple::getArchTypeName(ArchType Kind) { 00019 switch (Kind) { 00020 case UnknownArch: return "unknown"; 00021 00022 case aarch64: return "aarch64"; 00023 case arm: return "arm"; 00024 case hexagon: return "hexagon"; 00025 case mips: return "mips"; 00026 case mipsel: return "mipsel"; 00027 case mips64: return "mips64"; 00028 case mips64el:return "mips64el"; 00029 case msp430: return "msp430"; 00030 case ppc64: return "powerpc64"; 00031 case ppc: return "powerpc"; 00032 case r600: return "r600"; 00033 case sparc: return "sparc"; 00034 case sparcv9: return "sparcv9"; 00035 case systemz: return "s390x"; 00036 case tce: return "tce"; 00037 case thumb: return "thumb"; 00038 case x86: return "i386"; 00039 case x86_64: return "x86_64"; 00040 case xcore: return "xcore"; 00041 case mblaze: return "mblaze"; 00042 case nvptx: return "nvptx"; 00043 case nvptx64: return "nvptx64"; 00044 case le32: return "le32"; 00045 case amdil: return "amdil"; 00046 case spir: return "spir"; 00047 case spir64: return "spir64"; 00048 } 00049 00050 llvm_unreachable("Invalid ArchType!"); 00051 } 00052 00053 const char *Triple::getArchTypePrefix(ArchType Kind) { 00054 switch (Kind) { 00055 default: 00056 return 0; 00057 00058 case aarch64: return "aarch64"; 00059 00060 case arm: 00061 case thumb: return "arm"; 00062 00063 case ppc64: 00064 case ppc: return "ppc"; 00065 00066 case mblaze: return "mblaze"; 00067 00068 case mips: 00069 case mipsel: 00070 case mips64: 00071 case mips64el:return "mips"; 00072 00073 case hexagon: return "hexagon"; 00074 00075 case r600: return "r600"; 00076 00077 case sparcv9: 00078 case sparc: return "sparc"; 00079 00080 case systemz: return "systemz"; 00081 00082 case x86: 00083 case x86_64: return "x86"; 00084 00085 case xcore: return "xcore"; 00086 00087 case nvptx: return "nvptx"; 00088 case nvptx64: return "nvptx"; 00089 case le32: return "le32"; 00090 case amdil: return "amdil"; 00091 case spir: return "spir"; 00092 case spir64: return "spir"; 00093 } 00094 } 00095 00096 const char *Triple::getVendorTypeName(VendorType Kind) { 00097 switch (Kind) { 00098 case UnknownVendor: return "unknown"; 00099 00100 case Apple: return "apple"; 00101 case PC: return "pc"; 00102 case SCEI: return "scei"; 00103 case BGP: return "bgp"; 00104 case BGQ: return "bgq"; 00105 case Freescale: return "fsl"; 00106 case IBM: return "ibm"; 00107 } 00108 00109 llvm_unreachable("Invalid VendorType!"); 00110 } 00111 00112 const char *Triple::getOSTypeName(OSType Kind) { 00113 switch (Kind) { 00114 case UnknownOS: return "unknown"; 00115 00116 case AuroraUX: return "auroraux"; 00117 case Cygwin: return "cygwin"; 00118 case Darwin: return "darwin"; 00119 case DragonFly: return "dragonfly"; 00120 case FreeBSD: return "freebsd"; 00121 case IOS: return "ios"; 00122 case KFreeBSD: return "kfreebsd"; 00123 case Linux: return "linux"; 00124 case Lv2: return "lv2"; 00125 case MacOSX: return "macosx"; 00126 case MinGW32: return "mingw32"; 00127 case NetBSD: return "netbsd"; 00128 case OpenBSD: return "openbsd"; 00129 case Solaris: return "solaris"; 00130 case Win32: return "win32"; 00131 case Haiku: return "haiku"; 00132 case Minix: return "minix"; 00133 case RTEMS: return "rtems"; 00134 case NaCl: return "nacl"; 00135 case CNK: return "cnk"; 00136 case Bitrig: return "bitrig"; 00137 case AIX: return "aix"; 00138 } 00139 00140 llvm_unreachable("Invalid OSType"); 00141 } 00142 00143 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { 00144 switch (Kind) { 00145 case UnknownEnvironment: return "unknown"; 00146 case GNU: return "gnu"; 00147 case GNUEABIHF: return "gnueabihf"; 00148 case GNUEABI: return "gnueabi"; 00149 case GNUX32: return "gnux32"; 00150 case EABI: return "eabi"; 00151 case MachO: return "macho"; 00152 case Android: return "android"; 00153 case ELF: return "elf"; 00154 } 00155 00156 llvm_unreachable("Invalid EnvironmentType!"); 00157 } 00158 00159 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 00160 return StringSwitch<Triple::ArchType>(Name) 00161 .Case("aarch64", aarch64) 00162 .Case("arm", arm) 00163 .Case("mips", mips) 00164 .Case("mipsel", mipsel) 00165 .Case("mips64", mips64) 00166 .Case("mips64el", mips64el) 00167 .Case("msp430", msp430) 00168 .Case("ppc64", ppc64) 00169 .Case("ppc32", ppc) 00170 .Case("ppc", ppc) 00171 .Case("mblaze", mblaze) 00172 .Case("r600", r600) 00173 .Case("hexagon", hexagon) 00174 .Case("sparc", sparc) 00175 .Case("sparcv9", sparcv9) 00176 .Case("systemz", systemz) 00177 .Case("tce", tce) 00178 .Case("thumb", thumb) 00179 .Case("x86", x86) 00180 .Case("x86-64", x86_64) 00181 .Case("xcore", xcore) 00182 .Case("nvptx", nvptx) 00183 .Case("nvptx64", nvptx64) 00184 .Case("le32", le32) 00185 .Case("amdil", amdil) 00186 .Case("spir", spir) 00187 .Case("spir64", spir64) 00188 .Default(UnknownArch); 00189 } 00190 00191 // Returns architecture name that is understood by the target assembler. 00192 const char *Triple::getArchNameForAssembler() { 00193 if (!isOSDarwin() && getVendor() != Triple::Apple) 00194 return NULL; 00195 00196 return StringSwitch<const char*>(getArchName()) 00197 .Case("i386", "i386") 00198 .Case("x86_64", "x86_64") 00199 .Case("powerpc", "ppc") 00200 .Case("powerpc64", "ppc64") 00201 .Cases("mblaze", "microblaze", "mblaze") 00202 .Case("arm", "arm") 00203 .Cases("armv4t", "thumbv4t", "armv4t") 00204 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5") 00205 .Cases("armv6", "thumbv6", "armv6") 00206 .Cases("armv7", "thumbv7", "armv7") 00207 .Case("r600", "r600") 00208 .Case("nvptx", "nvptx") 00209 .Case("nvptx64", "nvptx64") 00210 .Case("le32", "le32") 00211 .Case("amdil", "amdil") 00212 .Case("spir", "spir") 00213 .Case("spir64", "spir64") 00214 .Default(NULL); 00215 } 00216 00217 static Triple::ArchType parseArch(StringRef ArchName) { 00218 return StringSwitch<Triple::ArchType>(ArchName) 00219 .Cases("i386", "i486", "i586", "i686", Triple::x86) 00220 // FIXME: Do we need to support these? 00221 .Cases("i786", "i886", "i986", Triple::x86) 00222 .Cases("amd64", "x86_64", Triple::x86_64) 00223 .Case("powerpc", Triple::ppc) 00224 .Cases("powerpc64", "ppu", Triple::ppc64) 00225 .Case("mblaze", Triple::mblaze) 00226 .Case("aarch64", Triple::aarch64) 00227 .Cases("arm", "xscale", Triple::arm) 00228 // FIXME: It would be good to replace these with explicit names for all the 00229 // various suffixes supported. 00230 .StartsWith("armv", Triple::arm) 00231 .Case("thumb", Triple::thumb) 00232 .StartsWith("thumbv", Triple::thumb) 00233 .Case("msp430", Triple::msp430) 00234 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) 00235 .Cases("mipsel", "mipsallegrexel", Triple::mipsel) 00236 .Cases("mips64", "mips64eb", Triple::mips64) 00237 .Case("mips64el", Triple::mips64el) 00238 .Case("r600", Triple::r600) 00239 .Case("hexagon", Triple::hexagon) 00240 .Case("s390x", Triple::systemz) 00241 .Case("sparc", Triple::sparc) 00242 .Cases("sparcv9", "sparc64", Triple::sparcv9) 00243 .Case("tce", Triple::tce) 00244 .Case("xcore", Triple::xcore) 00245 .Case("nvptx", Triple::nvptx) 00246 .Case("nvptx64", Triple::nvptx64) 00247 .Case("le32", Triple::le32) 00248 .Case("amdil", Triple::amdil) 00249 .Case("spir", Triple::spir) 00250 .Case("spir64", Triple::spir64) 00251 .Default(Triple::UnknownArch); 00252 } 00253 00254 static Triple::VendorType parseVendor(StringRef VendorName) { 00255 return StringSwitch<Triple::VendorType>(VendorName) 00256 .Case("apple", Triple::Apple) 00257 .Case("pc", Triple::PC) 00258 .Case("scei", Triple::SCEI) 00259 .Case("bgp", Triple::BGP) 00260 .Case("bgq", Triple::BGQ) 00261 .Case("fsl", Triple::Freescale) 00262 .Case("ibm", Triple::IBM) 00263 .Default(Triple::UnknownVendor); 00264 } 00265 00266 static Triple::OSType parseOS(StringRef OSName) { 00267 return StringSwitch<Triple::OSType>(OSName) 00268 .StartsWith("auroraux", Triple::AuroraUX) 00269 .StartsWith("cygwin", Triple::Cygwin) 00270 .StartsWith("darwin", Triple::Darwin) 00271 .StartsWith("dragonfly", Triple::DragonFly) 00272 .StartsWith("freebsd", Triple::FreeBSD) 00273 .StartsWith("ios", Triple::IOS) 00274 .StartsWith("kfreebsd", Triple::KFreeBSD) 00275 .StartsWith("linux", Triple::Linux) 00276 .StartsWith("lv2", Triple::Lv2) 00277 .StartsWith("macosx", Triple::MacOSX) 00278 .StartsWith("mingw32", Triple::MinGW32) 00279 .StartsWith("netbsd", Triple::NetBSD) 00280 .StartsWith("openbsd", Triple::OpenBSD) 00281 .StartsWith("solaris", Triple::Solaris) 00282 .StartsWith("win32", Triple::Win32) 00283 .StartsWith("haiku", Triple::Haiku) 00284 .StartsWith("minix", Triple::Minix) 00285 .StartsWith("rtems", Triple::RTEMS) 00286 .StartsWith("nacl", Triple::NaCl) 00287 .StartsWith("cnk", Triple::CNK) 00288 .StartsWith("bitrig", Triple::Bitrig) 00289 .StartsWith("aix", Triple::AIX) 00290 .Default(Triple::UnknownOS); 00291 } 00292 00293 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { 00294 return StringSwitch<Triple::EnvironmentType>(EnvironmentName) 00295 .StartsWith("eabi", Triple::EABI) 00296 .StartsWith("gnueabihf", Triple::GNUEABIHF) 00297 .StartsWith("gnueabi", Triple::GNUEABI) 00298 .StartsWith("gnux32", Triple::GNUX32) 00299 .StartsWith("gnu", Triple::GNU) 00300 .StartsWith("macho", Triple::MachO) 00301 .StartsWith("android", Triple::Android) 00302 .StartsWith("elf", Triple::ELF) 00303 .Default(Triple::UnknownEnvironment); 00304 } 00305 00306 /// \brief Construct a triple from the string representation provided. 00307 /// 00308 /// This stores the string representation and parses the various pieces into 00309 /// enum members. 00310 Triple::Triple(const Twine &Str) 00311 : Data(Str.str()), 00312 Arch(parseArch(getArchName())), 00313 Vendor(parseVendor(getVendorName())), 00314 OS(parseOS(getOSName())), 00315 Environment(parseEnvironment(getEnvironmentName())) { 00316 } 00317 00318 /// \brief Construct a triple from string representations of the architecture, 00319 /// vendor, and OS. 00320 /// 00321 /// This joins each argument into a canonical string representation and parses 00322 /// them into enum members. It leaves the environment unknown and omits it from 00323 /// the string representation. 00324 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) 00325 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()), 00326 Arch(parseArch(ArchStr.str())), 00327 Vendor(parseVendor(VendorStr.str())), 00328 OS(parseOS(OSStr.str())), 00329 Environment() { 00330 } 00331 00332 /// \brief Construct a triple from string representations of the architecture, 00333 /// vendor, OS, and environment. 00334 /// 00335 /// This joins each argument into a canonical string representation and parses 00336 /// them into enum members. 00337 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, 00338 const Twine &EnvironmentStr) 00339 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') + 00340 EnvironmentStr).str()), 00341 Arch(parseArch(ArchStr.str())), 00342 Vendor(parseVendor(VendorStr.str())), 00343 OS(parseOS(OSStr.str())), 00344 Environment(parseEnvironment(EnvironmentStr.str())) { 00345 } 00346 00347 std::string Triple::normalize(StringRef Str) { 00348 // Parse into components. 00349 SmallVector<StringRef, 4> Components; 00350 Str.split(Components, "-"); 00351 00352 // If the first component corresponds to a known architecture, preferentially 00353 // use it for the architecture. If the second component corresponds to a 00354 // known vendor, preferentially use it for the vendor, etc. This avoids silly 00355 // component movement when a component parses as (eg) both a valid arch and a 00356 // valid os. 00357 ArchType Arch = UnknownArch; 00358 if (Components.size() > 0) 00359 Arch = parseArch(Components[0]); 00360 VendorType Vendor = UnknownVendor; 00361 if (Components.size() > 1) 00362 Vendor = parseVendor(Components[1]); 00363 OSType OS = UnknownOS; 00364 if (Components.size() > 2) 00365 OS = parseOS(Components[2]); 00366 EnvironmentType Environment = UnknownEnvironment; 00367 if (Components.size() > 3) 00368 Environment = parseEnvironment(Components[3]); 00369 00370 // Note which components are already in their final position. These will not 00371 // be moved. 00372 bool Found[4]; 00373 Found[0] = Arch != UnknownArch; 00374 Found[1] = Vendor != UnknownVendor; 00375 Found[2] = OS != UnknownOS; 00376 Found[3] = Environment != UnknownEnvironment; 00377 00378 // If they are not there already, permute the components into their canonical 00379 // positions by seeing if they parse as a valid architecture, and if so moving 00380 // the component to the architecture position etc. 00381 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) { 00382 if (Found[Pos]) 00383 continue; // Already in the canonical position. 00384 00385 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) { 00386 // Do not reparse any components that already matched. 00387 if (Idx < array_lengthof(Found) && Found[Idx]) 00388 continue; 00389 00390 // Does this component parse as valid for the target position? 00391 bool Valid = false; 00392 StringRef Comp = Components[Idx]; 00393 switch (Pos) { 00394 default: llvm_unreachable("unexpected component type!"); 00395 case 0: 00396 Arch = parseArch(Comp); 00397 Valid = Arch != UnknownArch; 00398 break; 00399 case 1: 00400 Vendor = parseVendor(Comp); 00401 Valid = Vendor != UnknownVendor; 00402 break; 00403 case 2: 00404 OS = parseOS(Comp); 00405 Valid = OS != UnknownOS; 00406 break; 00407 case 3: 00408 Environment = parseEnvironment(Comp); 00409 Valid = Environment != UnknownEnvironment; 00410 break; 00411 } 00412 if (!Valid) 00413 continue; // Nope, try the next component. 00414 00415 // Move the component to the target position, pushing any non-fixed 00416 // components that are in the way to the right. This tends to give 00417 // good results in the common cases of a forgotten vendor component 00418 // or a wrongly positioned environment. 00419 if (Pos < Idx) { 00420 // Insert left, pushing the existing components to the right. For 00421 // example, a-b-i386 -> i386-a-b when moving i386 to the front. 00422 StringRef CurrentComponent(""); // The empty component. 00423 // Replace the component we are moving with an empty component. 00424 std::swap(CurrentComponent, Components[Idx]); 00425 // Insert the component being moved at Pos, displacing any existing 00426 // components to the right. 00427 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) { 00428 // Skip over any fixed components. 00429 while (i < array_lengthof(Found) && Found[i]) 00430 ++i; 00431 // Place the component at the new position, getting the component 00432 // that was at this position - it will be moved right. 00433 std::swap(CurrentComponent, Components[i]); 00434 } 00435 } else if (Pos > Idx) { 00436 // Push right by inserting empty components until the component at Idx 00437 // reaches the target position Pos. For example, pc-a -> -pc-a when 00438 // moving pc to the second position. 00439 do { 00440 // Insert one empty component at Idx. 00441 StringRef CurrentComponent(""); // The empty component. 00442 for (unsigned i = Idx; i < Components.size();) { 00443 // Place the component at the new position, getting the component 00444 // that was at this position - it will be moved right. 00445 std::swap(CurrentComponent, Components[i]); 00446 // If it was placed on top of an empty component then we are done. 00447 if (CurrentComponent.empty()) 00448 break; 00449 // Advance to the next component, skipping any fixed components. 00450 while (++i < array_lengthof(Found) && Found[i]) 00451 ; 00452 } 00453 // The last component was pushed off the end - append it. 00454 if (!CurrentComponent.empty()) 00455 Components.push_back(CurrentComponent); 00456 00457 // Advance Idx to the component's new position. 00458 while (++Idx < array_lengthof(Found) && Found[Idx]) 00459 ; 00460 } while (Idx < Pos); // Add more until the final position is reached. 00461 } 00462 assert(Pos < Components.size() && Components[Pos] == Comp && 00463 "Component moved wrong!"); 00464 Found[Pos] = true; 00465 break; 00466 } 00467 } 00468 00469 // Special case logic goes here. At this point Arch, Vendor and OS have the 00470 // correct values for the computed components. 00471 00472 // Stick the corrected components back together to form the normalized string. 00473 std::string Normalized; 00474 for (unsigned i = 0, e = Components.size(); i != e; ++i) { 00475 if (i) Normalized += '-'; 00476 Normalized += Components[i]; 00477 } 00478 return Normalized; 00479 } 00480 00481 StringRef Triple::getArchName() const { 00482 return StringRef(Data).split('-').first; // Isolate first component 00483 } 00484 00485 StringRef Triple::getVendorName() const { 00486 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 00487 return Tmp.split('-').first; // Isolate second component 00488 } 00489 00490 StringRef Triple::getOSName() const { 00491 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 00492 Tmp = Tmp.split('-').second; // Strip second component 00493 return Tmp.split('-').first; // Isolate third component 00494 } 00495 00496 StringRef Triple::getEnvironmentName() const { 00497 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 00498 Tmp = Tmp.split('-').second; // Strip second component 00499 return Tmp.split('-').second; // Strip third component 00500 } 00501 00502 StringRef Triple::getOSAndEnvironmentName() const { 00503 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 00504 return Tmp.split('-').second; // Strip second component 00505 } 00506 00507 static unsigned EatNumber(StringRef &Str) { 00508 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 00509 unsigned Result = 0; 00510 00511 do { 00512 // Consume the leading digit. 00513 Result = Result*10 + (Str[0] - '0'); 00514 00515 // Eat the digit. 00516 Str = Str.substr(1); 00517 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9'); 00518 00519 return Result; 00520 } 00521 00522 void Triple::getOSVersion(unsigned &Major, unsigned &Minor, 00523 unsigned &Micro) const { 00524 StringRef OSName = getOSName(); 00525 00526 // Assume that the OS portion of the triple starts with the canonical name. 00527 StringRef OSTypeName = getOSTypeName(getOS()); 00528 if (OSName.startswith(OSTypeName)) 00529 OSName = OSName.substr(OSTypeName.size()); 00530 00531 // Any unset version defaults to 0. 00532 Major = Minor = Micro = 0; 00533 00534 // Parse up to three components. 00535 unsigned *Components[3] = { &Major, &Minor, &Micro }; 00536 for (unsigned i = 0; i != 3; ++i) { 00537 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 00538 break; 00539 00540 // Consume the leading number. 00541 *Components[i] = EatNumber(OSName); 00542 00543 // Consume the separator, if present. 00544 if (OSName.startswith(".")) 00545 OSName = OSName.substr(1); 00546 } 00547 } 00548 00549 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, 00550 unsigned &Micro) const { 00551 getOSVersion(Major, Minor, Micro); 00552 00553 switch (getOS()) { 00554 default: llvm_unreachable("unexpected OS for Darwin triple"); 00555 case Darwin: 00556 // Default to darwin8, i.e., MacOSX 10.4. 00557 if (Major == 0) 00558 Major = 8; 00559 // Darwin version numbers are skewed from OS X versions. 00560 if (Major < 4) 00561 return false; 00562 Micro = 0; 00563 Minor = Major - 4; 00564 Major = 10; 00565 break; 00566 case MacOSX: 00567 // Default to 10.4. 00568 if (Major == 0) { 00569 Major = 10; 00570 Minor = 4; 00571 } 00572 if (Major != 10) 00573 return false; 00574 break; 00575 case IOS: 00576 // Ignore the version from the triple. This is only handled because the 00577 // the clang driver combines OS X and IOS support into a common Darwin 00578 // toolchain that wants to know the OS X version number even when targeting 00579 // IOS. 00580 Major = 10; 00581 Minor = 4; 00582 Micro = 0; 00583 break; 00584 } 00585 return true; 00586 } 00587 00588 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor, 00589 unsigned &Micro) const { 00590 switch (getOS()) { 00591 default: llvm_unreachable("unexpected OS for Darwin triple"); 00592 case Darwin: 00593 case MacOSX: 00594 // Ignore the version from the triple. This is only handled because the 00595 // the clang driver combines OS X and IOS support into a common Darwin 00596 // toolchain that wants to know the iOS version number even when targeting 00597 // OS X. 00598 Major = 3; 00599 Minor = 0; 00600 Micro = 0; 00601 break; 00602 case IOS: 00603 getOSVersion(Major, Minor, Micro); 00604 // Default to 3.0. 00605 if (Major == 0) 00606 Major = 3; 00607 break; 00608 } 00609 } 00610 00611 void Triple::setTriple(const Twine &Str) { 00612 *this = Triple(Str); 00613 } 00614 00615 void Triple::setArch(ArchType Kind) { 00616 setArchName(getArchTypeName(Kind)); 00617 } 00618 00619 void Triple::setVendor(VendorType Kind) { 00620 setVendorName(getVendorTypeName(Kind)); 00621 } 00622 00623 void Triple::setOS(OSType Kind) { 00624 setOSName(getOSTypeName(Kind)); 00625 } 00626 00627 void Triple::setEnvironment(EnvironmentType Kind) { 00628 setEnvironmentName(getEnvironmentTypeName(Kind)); 00629 } 00630 00631 void Triple::setArchName(StringRef Str) { 00632 // Work around a miscompilation bug for Twines in gcc 4.0.3. 00633 SmallString<64> Triple; 00634 Triple += Str; 00635 Triple += "-"; 00636 Triple += getVendorName(); 00637 Triple += "-"; 00638 Triple += getOSAndEnvironmentName(); 00639 setTriple(Triple.str()); 00640 } 00641 00642 void Triple::setVendorName(StringRef Str) { 00643 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 00644 } 00645 00646 void Triple::setOSName(StringRef Str) { 00647 if (hasEnvironment()) 00648 setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 00649 "-" + getEnvironmentName()); 00650 else 00651 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 00652 } 00653 00654 void Triple::setEnvironmentName(StringRef Str) { 00655 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 00656 "-" + Str); 00657 } 00658 00659 void Triple::setOSAndEnvironmentName(StringRef Str) { 00660 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 00661 } 00662 00663 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { 00664 switch (Arch) { 00665 case llvm::Triple::UnknownArch: 00666 return 0; 00667 00668 case llvm::Triple::msp430: 00669 return 16; 00670 00671 case llvm::Triple::amdil: 00672 case llvm::Triple::arm: 00673 case llvm::Triple::hexagon: 00674 case llvm::Triple::le32: 00675 case llvm::Triple::mblaze: 00676 case llvm::Triple::mips: 00677 case llvm::Triple::mipsel: 00678 case llvm::Triple::nvptx: 00679 case llvm::Triple::ppc: 00680 case llvm::Triple::r600: 00681 case llvm::Triple::sparc: 00682 case llvm::Triple::tce: 00683 case llvm::Triple::thumb: 00684 case llvm::Triple::x86: 00685 case llvm::Triple::xcore: 00686 case llvm::Triple::spir: 00687 return 32; 00688 00689 case llvm::Triple::aarch64: 00690 case llvm::Triple::mips64: 00691 case llvm::Triple::mips64el: 00692 case llvm::Triple::nvptx64: 00693 case llvm::Triple::ppc64: 00694 case llvm::Triple::sparcv9: 00695 case llvm::Triple::systemz: 00696 case llvm::Triple::x86_64: 00697 case llvm::Triple::spir64: 00698 return 64; 00699 } 00700 llvm_unreachable("Invalid architecture value"); 00701 } 00702 00703 bool Triple::isArch64Bit() const { 00704 return getArchPointerBitWidth(getArch()) == 64; 00705 } 00706 00707 bool Triple::isArch32Bit() const { 00708 return getArchPointerBitWidth(getArch()) == 32; 00709 } 00710 00711 bool Triple::isArch16Bit() const { 00712 return getArchPointerBitWidth(getArch()) == 16; 00713 } 00714 00715 Triple Triple::get32BitArchVariant() const { 00716 Triple T(*this); 00717 switch (getArch()) { 00718 case Triple::UnknownArch: 00719 case Triple::aarch64: 00720 case Triple::msp430: 00721 case Triple::systemz: 00722 T.setArch(UnknownArch); 00723 break; 00724 00725 case Triple::amdil: 00726 case Triple::spir: 00727 case Triple::arm: 00728 case Triple::hexagon: 00729 case Triple::le32: 00730 case Triple::mblaze: 00731 case Triple::mips: 00732 case Triple::mipsel: 00733 case Triple::nvptx: 00734 case Triple::ppc: 00735 case Triple::r600: 00736 case Triple::sparc: 00737 case Triple::tce: 00738 case Triple::thumb: 00739 case Triple::x86: 00740 case Triple::xcore: 00741 // Already 32-bit. 00742 break; 00743 00744 case Triple::mips64: T.setArch(Triple::mips); break; 00745 case Triple::mips64el: T.setArch(Triple::mipsel); break; 00746 case Triple::nvptx64: T.setArch(Triple::nvptx); break; 00747 case Triple::ppc64: T.setArch(Triple::ppc); break; 00748 case Triple::sparcv9: T.setArch(Triple::sparc); break; 00749 case Triple::x86_64: T.setArch(Triple::x86); break; 00750 case Triple::spir64: T.setArch(Triple::spir); break; 00751 } 00752 return T; 00753 } 00754 00755 Triple Triple::get64BitArchVariant() const { 00756 Triple T(*this); 00757 switch (getArch()) { 00758 case Triple::UnknownArch: 00759 case Triple::amdil: 00760 case Triple::arm: 00761 case Triple::hexagon: 00762 case Triple::le32: 00763 case Triple::mblaze: 00764 case Triple::msp430: 00765 case Triple::r600: 00766 case Triple::tce: 00767 case Triple::thumb: 00768 case Triple::xcore: 00769 T.setArch(UnknownArch); 00770 break; 00771 00772 case Triple::aarch64: 00773 case Triple::spir64: 00774 case Triple::mips64: 00775 case Triple::mips64el: 00776 case Triple::nvptx64: 00777 case Triple::ppc64: 00778 case Triple::sparcv9: 00779 case Triple::systemz: 00780 case Triple::x86_64: 00781 // Already 64-bit. 00782 break; 00783 00784 case Triple::mips: T.setArch(Triple::mips64); break; 00785 case Triple::mipsel: T.setArch(Triple::mips64el); break; 00786 case Triple::nvptx: T.setArch(Triple::nvptx64); break; 00787 case Triple::ppc: T.setArch(Triple::ppc64); break; 00788 case Triple::sparc: T.setArch(Triple::sparcv9); break; 00789 case Triple::x86: T.setArch(Triple::x86_64); break; 00790 case Triple::spir: T.setArch(Triple::spir64); break; 00791 } 00792 return T; 00793 }