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 aarch64_be: return "aarch64_be"; 00024 case arm: return "arm"; 00025 case armeb: return "armeb"; 00026 case hexagon: return "hexagon"; 00027 case mips: return "mips"; 00028 case mipsel: return "mipsel"; 00029 case mips64: return "mips64"; 00030 case mips64el: return "mips64el"; 00031 case msp430: return "msp430"; 00032 case ppc64: return "powerpc64"; 00033 case ppc64le: return "powerpc64le"; 00034 case ppc: return "powerpc"; 00035 case r600: return "r600"; 00036 case sparc: return "sparc"; 00037 case sparcv9: return "sparcv9"; 00038 case systemz: return "s390x"; 00039 case tce: return "tce"; 00040 case thumb: return "thumb"; 00041 case thumbeb: return "thumbeb"; 00042 case x86: return "i386"; 00043 case x86_64: return "x86_64"; 00044 case xcore: return "xcore"; 00045 case nvptx: return "nvptx"; 00046 case nvptx64: return "nvptx64"; 00047 case le32: return "le32"; 00048 case le64: return "le64"; 00049 case amdil: return "amdil"; 00050 case spir: return "spir"; 00051 case spir64: return "spir64"; 00052 case kalimba: return "kalimba"; 00053 } 00054 00055 llvm_unreachable("Invalid ArchType!"); 00056 } 00057 00058 const char *Triple::getArchTypePrefix(ArchType Kind) { 00059 switch (Kind) { 00060 default: 00061 return nullptr; 00062 00063 case aarch64: 00064 case aarch64_be: return "aarch64"; 00065 00066 case arm: 00067 case armeb: 00068 case thumb: 00069 case thumbeb: return "arm"; 00070 00071 case ppc64: 00072 case ppc64le: 00073 case ppc: return "ppc"; 00074 00075 case mips: 00076 case mipsel: 00077 case mips64: 00078 case mips64el: return "mips"; 00079 00080 case hexagon: return "hexagon"; 00081 00082 case r600: return "r600"; 00083 00084 case sparcv9: 00085 case sparc: return "sparc"; 00086 00087 case systemz: return "systemz"; 00088 00089 case x86: 00090 case x86_64: return "x86"; 00091 00092 case xcore: return "xcore"; 00093 00094 case nvptx: return "nvptx"; 00095 case nvptx64: return "nvptx"; 00096 00097 case le32: return "le32"; 00098 case le64: return "le64"; 00099 case amdil: return "amdil"; 00100 case spir: return "spir"; 00101 case spir64: return "spir"; 00102 case kalimba: return "kalimba"; 00103 } 00104 } 00105 00106 const char *Triple::getVendorTypeName(VendorType Kind) { 00107 switch (Kind) { 00108 case UnknownVendor: return "unknown"; 00109 00110 case Apple: return "apple"; 00111 case PC: return "pc"; 00112 case SCEI: return "scei"; 00113 case BGP: return "bgp"; 00114 case BGQ: return "bgq"; 00115 case Freescale: return "fsl"; 00116 case IBM: return "ibm"; 00117 case ImaginationTechnologies: return "img"; 00118 case MipsTechnologies: return "mti"; 00119 case NVIDIA: return "nvidia"; 00120 case CSR: return "csr"; 00121 } 00122 00123 llvm_unreachable("Invalid VendorType!"); 00124 } 00125 00126 const char *Triple::getOSTypeName(OSType Kind) { 00127 switch (Kind) { 00128 case UnknownOS: return "unknown"; 00129 00130 case Darwin: return "darwin"; 00131 case DragonFly: return "dragonfly"; 00132 case FreeBSD: return "freebsd"; 00133 case IOS: return "ios"; 00134 case KFreeBSD: return "kfreebsd"; 00135 case Linux: return "linux"; 00136 case Lv2: return "lv2"; 00137 case MacOSX: return "macosx"; 00138 case NetBSD: return "netbsd"; 00139 case OpenBSD: return "openbsd"; 00140 case Solaris: return "solaris"; 00141 case Win32: return "windows"; 00142 case Haiku: return "haiku"; 00143 case Minix: return "minix"; 00144 case RTEMS: return "rtems"; 00145 case NaCl: return "nacl"; 00146 case CNK: return "cnk"; 00147 case Bitrig: return "bitrig"; 00148 case AIX: return "aix"; 00149 case CUDA: return "cuda"; 00150 case NVCL: return "nvcl"; 00151 } 00152 00153 llvm_unreachable("Invalid OSType"); 00154 } 00155 00156 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { 00157 switch (Kind) { 00158 case UnknownEnvironment: return "unknown"; 00159 case GNU: return "gnu"; 00160 case GNUEABIHF: return "gnueabihf"; 00161 case GNUEABI: return "gnueabi"; 00162 case GNUX32: return "gnux32"; 00163 case CODE16: return "code16"; 00164 case EABI: return "eabi"; 00165 case EABIHF: return "eabihf"; 00166 case Android: return "android"; 00167 case MSVC: return "msvc"; 00168 case Itanium: return "itanium"; 00169 case Cygnus: return "cygnus"; 00170 } 00171 00172 llvm_unreachable("Invalid EnvironmentType!"); 00173 } 00174 00175 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { 00176 return StringSwitch<Triple::ArchType>(Name) 00177 .Case("aarch64", aarch64) 00178 .Case("aarch64_be", aarch64_be) 00179 .Case("arm64", aarch64) // "arm64" is an alias for "aarch64" 00180 .Case("arm", arm) 00181 .Case("armeb", armeb) 00182 .Case("mips", mips) 00183 .Case("mipsel", mipsel) 00184 .Case("mips64", mips64) 00185 .Case("mips64el", mips64el) 00186 .Case("msp430", msp430) 00187 .Case("ppc64", ppc64) 00188 .Case("ppc32", ppc) 00189 .Case("ppc", ppc) 00190 .Case("ppc64le", ppc64le) 00191 .Case("r600", r600) 00192 .Case("hexagon", hexagon) 00193 .Case("sparc", sparc) 00194 .Case("sparcv9", sparcv9) 00195 .Case("systemz", systemz) 00196 .Case("tce", tce) 00197 .Case("thumb", thumb) 00198 .Case("thumbeb", thumbeb) 00199 .Case("x86", x86) 00200 .Case("x86-64", x86_64) 00201 .Case("xcore", xcore) 00202 .Case("nvptx", nvptx) 00203 .Case("nvptx64", nvptx64) 00204 .Case("le32", le32) 00205 .Case("le64", le64) 00206 .Case("amdil", amdil) 00207 .Case("spir", spir) 00208 .Case("spir64", spir64) 00209 .Case("kalimba", kalimba) 00210 .Default(UnknownArch); 00211 } 00212 00213 static Triple::ArchType parseArch(StringRef ArchName) { 00214 return StringSwitch<Triple::ArchType>(ArchName) 00215 .Cases("i386", "i486", "i586", "i686", Triple::x86) 00216 // FIXME: Do we need to support these? 00217 .Cases("i786", "i886", "i986", Triple::x86) 00218 .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64) 00219 .Case("powerpc", Triple::ppc) 00220 .Cases("powerpc64", "ppu", Triple::ppc64) 00221 .Case("powerpc64le", Triple::ppc64le) 00222 .Case("aarch64", Triple::aarch64) 00223 .Case("aarch64_be", Triple::aarch64_be) 00224 .Case("arm64", Triple::aarch64) 00225 .Cases("arm", "xscale", Triple::arm) 00226 // FIXME: It would be good to replace these with explicit names for all the 00227 // various suffixes supported. 00228 .StartsWith("armv", Triple::arm) 00229 .Case("armeb", Triple::armeb) 00230 .StartsWith("armebv", Triple::armeb) 00231 .Case("thumb", Triple::thumb) 00232 .StartsWith("thumbv", Triple::thumb) 00233 .Case("thumbeb", Triple::thumbeb) 00234 .StartsWith("thumbebv", Triple::thumbeb) 00235 .Case("msp430", Triple::msp430) 00236 .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) 00237 .Cases("mipsel", "mipsallegrexel", Triple::mipsel) 00238 .Cases("mips64", "mips64eb", Triple::mips64) 00239 .Case("mips64el", Triple::mips64el) 00240 .Case("r600", Triple::r600) 00241 .Case("hexagon", Triple::hexagon) 00242 .Case("s390x", Triple::systemz) 00243 .Case("sparc", Triple::sparc) 00244 .Cases("sparcv9", "sparc64", Triple::sparcv9) 00245 .Case("tce", Triple::tce) 00246 .Case("xcore", Triple::xcore) 00247 .Case("nvptx", Triple::nvptx) 00248 .Case("nvptx64", Triple::nvptx64) 00249 .Case("le32", Triple::le32) 00250 .Case("le64", Triple::le64) 00251 .Case("amdil", Triple::amdil) 00252 .Case("spir", Triple::spir) 00253 .Case("spir64", Triple::spir64) 00254 .StartsWith("kalimba", Triple::kalimba) 00255 .Default(Triple::UnknownArch); 00256 } 00257 00258 static Triple::VendorType parseVendor(StringRef VendorName) { 00259 return StringSwitch<Triple::VendorType>(VendorName) 00260 .Case("apple", Triple::Apple) 00261 .Case("pc", Triple::PC) 00262 .Case("scei", Triple::SCEI) 00263 .Case("bgp", Triple::BGP) 00264 .Case("bgq", Triple::BGQ) 00265 .Case("fsl", Triple::Freescale) 00266 .Case("ibm", Triple::IBM) 00267 .Case("img", Triple::ImaginationTechnologies) 00268 .Case("mti", Triple::MipsTechnologies) 00269 .Case("nvidia", Triple::NVIDIA) 00270 .Case("csr", Triple::CSR) 00271 .Default(Triple::UnknownVendor); 00272 } 00273 00274 static Triple::OSType parseOS(StringRef OSName) { 00275 return StringSwitch<Triple::OSType>(OSName) 00276 .StartsWith("darwin", Triple::Darwin) 00277 .StartsWith("dragonfly", Triple::DragonFly) 00278 .StartsWith("freebsd", Triple::FreeBSD) 00279 .StartsWith("ios", Triple::IOS) 00280 .StartsWith("kfreebsd", Triple::KFreeBSD) 00281 .StartsWith("linux", Triple::Linux) 00282 .StartsWith("lv2", Triple::Lv2) 00283 .StartsWith("macosx", Triple::MacOSX) 00284 .StartsWith("netbsd", Triple::NetBSD) 00285 .StartsWith("openbsd", Triple::OpenBSD) 00286 .StartsWith("solaris", Triple::Solaris) 00287 .StartsWith("win32", Triple::Win32) 00288 .StartsWith("windows", Triple::Win32) 00289 .StartsWith("haiku", Triple::Haiku) 00290 .StartsWith("minix", Triple::Minix) 00291 .StartsWith("rtems", Triple::RTEMS) 00292 .StartsWith("nacl", Triple::NaCl) 00293 .StartsWith("cnk", Triple::CNK) 00294 .StartsWith("bitrig", Triple::Bitrig) 00295 .StartsWith("aix", Triple::AIX) 00296 .StartsWith("cuda", Triple::CUDA) 00297 .StartsWith("nvcl", Triple::NVCL) 00298 .Default(Triple::UnknownOS); 00299 } 00300 00301 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { 00302 return StringSwitch<Triple::EnvironmentType>(EnvironmentName) 00303 .StartsWith("eabihf", Triple::EABIHF) 00304 .StartsWith("eabi", Triple::EABI) 00305 .StartsWith("gnueabihf", Triple::GNUEABIHF) 00306 .StartsWith("gnueabi", Triple::GNUEABI) 00307 .StartsWith("gnux32", Triple::GNUX32) 00308 .StartsWith("code16", Triple::CODE16) 00309 .StartsWith("gnu", Triple::GNU) 00310 .StartsWith("android", Triple::Android) 00311 .StartsWith("msvc", Triple::MSVC) 00312 .StartsWith("itanium", Triple::Itanium) 00313 .StartsWith("cygnus", Triple::Cygnus) 00314 .Default(Triple::UnknownEnvironment); 00315 } 00316 00317 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) { 00318 return StringSwitch<Triple::ObjectFormatType>(EnvironmentName) 00319 .EndsWith("coff", Triple::COFF) 00320 .EndsWith("elf", Triple::ELF) 00321 .EndsWith("macho", Triple::MachO) 00322 .Default(Triple::UnknownObjectFormat); 00323 } 00324 00325 static Triple::SubArchType parseSubArch(StringRef SubArchName) { 00326 return StringSwitch<Triple::SubArchType>(SubArchName) 00327 .EndsWith("v8", Triple::ARMSubArch_v8) 00328 .EndsWith("v8a", Triple::ARMSubArch_v8) 00329 .EndsWith("v7", Triple::ARMSubArch_v7) 00330 .EndsWith("v7a", Triple::ARMSubArch_v7) 00331 .EndsWith("v7em", Triple::ARMSubArch_v7em) 00332 .EndsWith("v7l", Triple::ARMSubArch_v7) 00333 .EndsWith("v7m", Triple::ARMSubArch_v7m) 00334 .EndsWith("v7r", Triple::ARMSubArch_v7) 00335 .EndsWith("v7s", Triple::ARMSubArch_v7s) 00336 .EndsWith("v6", Triple::ARMSubArch_v6) 00337 .EndsWith("v6m", Triple::ARMSubArch_v6m) 00338 .EndsWith("v6t2", Triple::ARMSubArch_v6t2) 00339 .EndsWith("v5", Triple::ARMSubArch_v5) 00340 .EndsWith("v5e", Triple::ARMSubArch_v5) 00341 .EndsWith("v5t", Triple::ARMSubArch_v5) 00342 .EndsWith("v5te", Triple::ARMSubArch_v5te) 00343 .EndsWith("v4t", Triple::ARMSubArch_v4t) 00344 .EndsWith("kalimba3", Triple::KalimbaSubArch_v3) 00345 .EndsWith("kalimba4", Triple::KalimbaSubArch_v4) 00346 .EndsWith("kalimba5", Triple::KalimbaSubArch_v5) 00347 .Default(Triple::NoSubArch); 00348 } 00349 00350 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) { 00351 switch (Kind) { 00352 case Triple::UnknownObjectFormat: return ""; 00353 case Triple::COFF: return "coff"; 00354 case Triple::ELF: return "elf"; 00355 case Triple::MachO: return "macho"; 00356 } 00357 llvm_unreachable("unknown object format type"); 00358 } 00359 00360 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { 00361 if (T.isOSDarwin()) 00362 return Triple::MachO; 00363 else if (T.isOSWindows()) 00364 return Triple::COFF; 00365 return Triple::ELF; 00366 } 00367 00368 /// \brief Construct a triple from the string representation provided. 00369 /// 00370 /// This stores the string representation and parses the various pieces into 00371 /// enum members. 00372 Triple::Triple(const Twine &Str) 00373 : Data(Str.str()), 00374 Arch(parseArch(getArchName())), 00375 SubArch(parseSubArch(getArchName())), 00376 Vendor(parseVendor(getVendorName())), 00377 OS(parseOS(getOSName())), 00378 Environment(parseEnvironment(getEnvironmentName())), 00379 ObjectFormat(parseFormat(getEnvironmentName())) { 00380 if (ObjectFormat == Triple::UnknownObjectFormat) 00381 ObjectFormat = getDefaultFormat(*this); 00382 } 00383 00384 /// \brief Construct a triple from string representations of the architecture, 00385 /// vendor, and OS. 00386 /// 00387 /// This joins each argument into a canonical string representation and parses 00388 /// them into enum members. It leaves the environment unknown and omits it from 00389 /// the string representation. 00390 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) 00391 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()), 00392 Arch(parseArch(ArchStr.str())), 00393 SubArch(parseSubArch(ArchStr.str())), 00394 Vendor(parseVendor(VendorStr.str())), 00395 OS(parseOS(OSStr.str())), 00396 Environment(), ObjectFormat(Triple::UnknownObjectFormat) { 00397 ObjectFormat = getDefaultFormat(*this); 00398 } 00399 00400 /// \brief Construct a triple from string representations of the architecture, 00401 /// vendor, OS, and environment. 00402 /// 00403 /// This joins each argument into a canonical string representation and parses 00404 /// them into enum members. 00405 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, 00406 const Twine &EnvironmentStr) 00407 : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') + 00408 EnvironmentStr).str()), 00409 Arch(parseArch(ArchStr.str())), 00410 SubArch(parseSubArch(ArchStr.str())), 00411 Vendor(parseVendor(VendorStr.str())), 00412 OS(parseOS(OSStr.str())), 00413 Environment(parseEnvironment(EnvironmentStr.str())), 00414 ObjectFormat(parseFormat(EnvironmentStr.str())) { 00415 if (ObjectFormat == Triple::UnknownObjectFormat) 00416 ObjectFormat = getDefaultFormat(*this); 00417 } 00418 00419 std::string Triple::normalize(StringRef Str) { 00420 bool IsMinGW32 = false; 00421 bool IsCygwin = false; 00422 00423 // Parse into components. 00424 SmallVector<StringRef, 4> Components; 00425 Str.split(Components, "-"); 00426 00427 // If the first component corresponds to a known architecture, preferentially 00428 // use it for the architecture. If the second component corresponds to a 00429 // known vendor, preferentially use it for the vendor, etc. This avoids silly 00430 // component movement when a component parses as (eg) both a valid arch and a 00431 // valid os. 00432 ArchType Arch = UnknownArch; 00433 if (Components.size() > 0) 00434 Arch = parseArch(Components[0]); 00435 VendorType Vendor = UnknownVendor; 00436 if (Components.size() > 1) 00437 Vendor = parseVendor(Components[1]); 00438 OSType OS = UnknownOS; 00439 if (Components.size() > 2) { 00440 OS = parseOS(Components[2]); 00441 IsCygwin = Components[2].startswith("cygwin"); 00442 IsMinGW32 = Components[2].startswith("mingw"); 00443 } 00444 EnvironmentType Environment = UnknownEnvironment; 00445 if (Components.size() > 3) 00446 Environment = parseEnvironment(Components[3]); 00447 ObjectFormatType ObjectFormat = UnknownObjectFormat; 00448 if (Components.size() > 4) 00449 ObjectFormat = parseFormat(Components[4]); 00450 00451 // Note which components are already in their final position. These will not 00452 // be moved. 00453 bool Found[4]; 00454 Found[0] = Arch != UnknownArch; 00455 Found[1] = Vendor != UnknownVendor; 00456 Found[2] = OS != UnknownOS; 00457 Found[3] = Environment != UnknownEnvironment; 00458 00459 // If they are not there already, permute the components into their canonical 00460 // positions by seeing if they parse as a valid architecture, and if so moving 00461 // the component to the architecture position etc. 00462 for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) { 00463 if (Found[Pos]) 00464 continue; // Already in the canonical position. 00465 00466 for (unsigned Idx = 0; Idx != Components.size(); ++Idx) { 00467 // Do not reparse any components that already matched. 00468 if (Idx < array_lengthof(Found) && Found[Idx]) 00469 continue; 00470 00471 // Does this component parse as valid for the target position? 00472 bool Valid = false; 00473 StringRef Comp = Components[Idx]; 00474 switch (Pos) { 00475 default: llvm_unreachable("unexpected component type!"); 00476 case 0: 00477 Arch = parseArch(Comp); 00478 Valid = Arch != UnknownArch; 00479 break; 00480 case 1: 00481 Vendor = parseVendor(Comp); 00482 Valid = Vendor != UnknownVendor; 00483 break; 00484 case 2: 00485 OS = parseOS(Comp); 00486 IsCygwin = Comp.startswith("cygwin"); 00487 IsMinGW32 = Comp.startswith("mingw"); 00488 Valid = OS != UnknownOS || IsCygwin || IsMinGW32; 00489 break; 00490 case 3: 00491 Environment = parseEnvironment(Comp); 00492 Valid = Environment != UnknownEnvironment; 00493 if (!Valid) { 00494 ObjectFormat = parseFormat(Comp); 00495 Valid = ObjectFormat != UnknownObjectFormat; 00496 } 00497 break; 00498 } 00499 if (!Valid) 00500 continue; // Nope, try the next component. 00501 00502 // Move the component to the target position, pushing any non-fixed 00503 // components that are in the way to the right. This tends to give 00504 // good results in the common cases of a forgotten vendor component 00505 // or a wrongly positioned environment. 00506 if (Pos < Idx) { 00507 // Insert left, pushing the existing components to the right. For 00508 // example, a-b-i386 -> i386-a-b when moving i386 to the front. 00509 StringRef CurrentComponent(""); // The empty component. 00510 // Replace the component we are moving with an empty component. 00511 std::swap(CurrentComponent, Components[Idx]); 00512 // Insert the component being moved at Pos, displacing any existing 00513 // components to the right. 00514 for (unsigned i = Pos; !CurrentComponent.empty(); ++i) { 00515 // Skip over any fixed components. 00516 while (i < array_lengthof(Found) && Found[i]) 00517 ++i; 00518 // Place the component at the new position, getting the component 00519 // that was at this position - it will be moved right. 00520 std::swap(CurrentComponent, Components[i]); 00521 } 00522 } else if (Pos > Idx) { 00523 // Push right by inserting empty components until the component at Idx 00524 // reaches the target position Pos. For example, pc-a -> -pc-a when 00525 // moving pc to the second position. 00526 do { 00527 // Insert one empty component at Idx. 00528 StringRef CurrentComponent(""); // The empty component. 00529 for (unsigned i = Idx; i < Components.size();) { 00530 // Place the component at the new position, getting the component 00531 // that was at this position - it will be moved right. 00532 std::swap(CurrentComponent, Components[i]); 00533 // If it was placed on top of an empty component then we are done. 00534 if (CurrentComponent.empty()) 00535 break; 00536 // Advance to the next component, skipping any fixed components. 00537 while (++i < array_lengthof(Found) && Found[i]) 00538 ; 00539 } 00540 // The last component was pushed off the end - append it. 00541 if (!CurrentComponent.empty()) 00542 Components.push_back(CurrentComponent); 00543 00544 // Advance Idx to the component's new position. 00545 while (++Idx < array_lengthof(Found) && Found[Idx]) 00546 ; 00547 } while (Idx < Pos); // Add more until the final position is reached. 00548 } 00549 assert(Pos < Components.size() && Components[Pos] == Comp && 00550 "Component moved wrong!"); 00551 Found[Pos] = true; 00552 break; 00553 } 00554 } 00555 00556 // Special case logic goes here. At this point Arch, Vendor and OS have the 00557 // correct values for the computed components. 00558 00559 if (OS == Triple::Win32) { 00560 Components.resize(4); 00561 Components[2] = "windows"; 00562 if (Environment == UnknownEnvironment) { 00563 if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF) 00564 Components[3] = "msvc"; 00565 else 00566 Components[3] = getObjectFormatTypeName(ObjectFormat); 00567 } 00568 } else if (IsMinGW32) { 00569 Components.resize(4); 00570 Components[2] = "windows"; 00571 Components[3] = "gnu"; 00572 } else if (IsCygwin) { 00573 Components.resize(4); 00574 Components[2] = "windows"; 00575 Components[3] = "cygnus"; 00576 } 00577 if (IsMinGW32 || IsCygwin || 00578 (OS == Triple::Win32 && Environment != UnknownEnvironment)) { 00579 if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) { 00580 Components.resize(5); 00581 Components[4] = getObjectFormatTypeName(ObjectFormat); 00582 } 00583 } 00584 00585 // Stick the corrected components back together to form the normalized string. 00586 std::string Normalized; 00587 for (unsigned i = 0, e = Components.size(); i != e; ++i) { 00588 if (i) Normalized += '-'; 00589 Normalized += Components[i]; 00590 } 00591 return Normalized; 00592 } 00593 00594 StringRef Triple::getArchName() const { 00595 return StringRef(Data).split('-').first; // Isolate first component 00596 } 00597 00598 StringRef Triple::getVendorName() const { 00599 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 00600 return Tmp.split('-').first; // Isolate second component 00601 } 00602 00603 StringRef Triple::getOSName() const { 00604 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 00605 Tmp = Tmp.split('-').second; // Strip second component 00606 return Tmp.split('-').first; // Isolate third component 00607 } 00608 00609 StringRef Triple::getEnvironmentName() const { 00610 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 00611 Tmp = Tmp.split('-').second; // Strip second component 00612 return Tmp.split('-').second; // Strip third component 00613 } 00614 00615 StringRef Triple::getOSAndEnvironmentName() const { 00616 StringRef Tmp = StringRef(Data).split('-').second; // Strip first component 00617 return Tmp.split('-').second; // Strip second component 00618 } 00619 00620 static unsigned EatNumber(StringRef &Str) { 00621 assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number"); 00622 unsigned Result = 0; 00623 00624 do { 00625 // Consume the leading digit. 00626 Result = Result*10 + (Str[0] - '0'); 00627 00628 // Eat the digit. 00629 Str = Str.substr(1); 00630 } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9'); 00631 00632 return Result; 00633 } 00634 00635 void Triple::getOSVersion(unsigned &Major, unsigned &Minor, 00636 unsigned &Micro) const { 00637 StringRef OSName = getOSName(); 00638 00639 // Assume that the OS portion of the triple starts with the canonical name. 00640 StringRef OSTypeName = getOSTypeName(getOS()); 00641 if (OSName.startswith(OSTypeName)) 00642 OSName = OSName.substr(OSTypeName.size()); 00643 00644 // Any unset version defaults to 0. 00645 Major = Minor = Micro = 0; 00646 00647 // Parse up to three components. 00648 unsigned *Components[3] = { &Major, &Minor, &Micro }; 00649 for (unsigned i = 0; i != 3; ++i) { 00650 if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9') 00651 break; 00652 00653 // Consume the leading number. 00654 *Components[i] = EatNumber(OSName); 00655 00656 // Consume the separator, if present. 00657 if (OSName.startswith(".")) 00658 OSName = OSName.substr(1); 00659 } 00660 } 00661 00662 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, 00663 unsigned &Micro) const { 00664 getOSVersion(Major, Minor, Micro); 00665 00666 switch (getOS()) { 00667 default: llvm_unreachable("unexpected OS for Darwin triple"); 00668 case Darwin: 00669 // Default to darwin8, i.e., MacOSX 10.4. 00670 if (Major == 0) 00671 Major = 8; 00672 // Darwin version numbers are skewed from OS X versions. 00673 if (Major < 4) 00674 return false; 00675 Micro = 0; 00676 Minor = Major - 4; 00677 Major = 10; 00678 break; 00679 case MacOSX: 00680 // Default to 10.4. 00681 if (Major == 0) { 00682 Major = 10; 00683 Minor = 4; 00684 } 00685 if (Major != 10) 00686 return false; 00687 break; 00688 case IOS: 00689 // Ignore the version from the triple. This is only handled because the 00690 // the clang driver combines OS X and IOS support into a common Darwin 00691 // toolchain that wants to know the OS X version number even when targeting 00692 // IOS. 00693 Major = 10; 00694 Minor = 4; 00695 Micro = 0; 00696 break; 00697 } 00698 return true; 00699 } 00700 00701 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor, 00702 unsigned &Micro) const { 00703 switch (getOS()) { 00704 default: llvm_unreachable("unexpected OS for Darwin triple"); 00705 case Darwin: 00706 case MacOSX: 00707 // Ignore the version from the triple. This is only handled because the 00708 // the clang driver combines OS X and IOS support into a common Darwin 00709 // toolchain that wants to know the iOS version number even when targeting 00710 // OS X. 00711 Major = 5; 00712 Minor = 0; 00713 Micro = 0; 00714 break; 00715 case IOS: 00716 getOSVersion(Major, Minor, Micro); 00717 // Default to 5.0 (or 7.0 for arm64). 00718 if (Major == 0) 00719 Major = (getArch() == aarch64) ? 7 : 5; 00720 break; 00721 } 00722 } 00723 00724 void Triple::setTriple(const Twine &Str) { 00725 *this = Triple(Str); 00726 } 00727 00728 void Triple::setArch(ArchType Kind) { 00729 setArchName(getArchTypeName(Kind)); 00730 } 00731 00732 void Triple::setVendor(VendorType Kind) { 00733 setVendorName(getVendorTypeName(Kind)); 00734 } 00735 00736 void Triple::setOS(OSType Kind) { 00737 setOSName(getOSTypeName(Kind)); 00738 } 00739 00740 void Triple::setEnvironment(EnvironmentType Kind) { 00741 setEnvironmentName(getEnvironmentTypeName(Kind)); 00742 } 00743 00744 void Triple::setObjectFormat(ObjectFormatType Kind) { 00745 if (Environment == UnknownEnvironment) 00746 return setEnvironmentName(getObjectFormatTypeName(Kind)); 00747 00748 setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") + 00749 getObjectFormatTypeName(Kind)).str()); 00750 } 00751 00752 void Triple::setArchName(StringRef Str) { 00753 // Work around a miscompilation bug for Twines in gcc 4.0.3. 00754 SmallString<64> Triple; 00755 Triple += Str; 00756 Triple += "-"; 00757 Triple += getVendorName(); 00758 Triple += "-"; 00759 Triple += getOSAndEnvironmentName(); 00760 setTriple(Triple.str()); 00761 } 00762 00763 void Triple::setVendorName(StringRef Str) { 00764 setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName()); 00765 } 00766 00767 void Triple::setOSName(StringRef Str) { 00768 if (hasEnvironment()) 00769 setTriple(getArchName() + "-" + getVendorName() + "-" + Str + 00770 "-" + getEnvironmentName()); 00771 else 00772 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 00773 } 00774 00775 void Triple::setEnvironmentName(StringRef Str) { 00776 setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() + 00777 "-" + Str); 00778 } 00779 00780 void Triple::setOSAndEnvironmentName(StringRef Str) { 00781 setTriple(getArchName() + "-" + getVendorName() + "-" + Str); 00782 } 00783 00784 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { 00785 switch (Arch) { 00786 case llvm::Triple::UnknownArch: 00787 return 0; 00788 00789 case llvm::Triple::msp430: 00790 return 16; 00791 00792 case llvm::Triple::amdil: 00793 case llvm::Triple::arm: 00794 case llvm::Triple::armeb: 00795 case llvm::Triple::hexagon: 00796 case llvm::Triple::le32: 00797 case llvm::Triple::mips: 00798 case llvm::Triple::mipsel: 00799 case llvm::Triple::nvptx: 00800 case llvm::Triple::ppc: 00801 case llvm::Triple::r600: 00802 case llvm::Triple::sparc: 00803 case llvm::Triple::tce: 00804 case llvm::Triple::thumb: 00805 case llvm::Triple::thumbeb: 00806 case llvm::Triple::x86: 00807 case llvm::Triple::xcore: 00808 case llvm::Triple::spir: 00809 case llvm::Triple::kalimba: 00810 return 32; 00811 00812 case llvm::Triple::aarch64: 00813 case llvm::Triple::aarch64_be: 00814 case llvm::Triple::le64: 00815 case llvm::Triple::mips64: 00816 case llvm::Triple::mips64el: 00817 case llvm::Triple::nvptx64: 00818 case llvm::Triple::ppc64: 00819 case llvm::Triple::ppc64le: 00820 case llvm::Triple::sparcv9: 00821 case llvm::Triple::systemz: 00822 case llvm::Triple::x86_64: 00823 case llvm::Triple::spir64: 00824 return 64; 00825 } 00826 llvm_unreachable("Invalid architecture value"); 00827 } 00828 00829 bool Triple::isArch64Bit() const { 00830 return getArchPointerBitWidth(getArch()) == 64; 00831 } 00832 00833 bool Triple::isArch32Bit() const { 00834 return getArchPointerBitWidth(getArch()) == 32; 00835 } 00836 00837 bool Triple::isArch16Bit() const { 00838 return getArchPointerBitWidth(getArch()) == 16; 00839 } 00840 00841 Triple Triple::get32BitArchVariant() const { 00842 Triple T(*this); 00843 switch (getArch()) { 00844 case Triple::UnknownArch: 00845 case Triple::aarch64: 00846 case Triple::aarch64_be: 00847 case Triple::msp430: 00848 case Triple::systemz: 00849 case Triple::ppc64le: 00850 T.setArch(UnknownArch); 00851 break; 00852 00853 case Triple::amdil: 00854 case Triple::spir: 00855 case Triple::arm: 00856 case Triple::armeb: 00857 case Triple::hexagon: 00858 case Triple::kalimba: 00859 case Triple::le32: 00860 case Triple::mips: 00861 case Triple::mipsel: 00862 case Triple::nvptx: 00863 case Triple::ppc: 00864 case Triple::r600: 00865 case Triple::sparc: 00866 case Triple::tce: 00867 case Triple::thumb: 00868 case Triple::thumbeb: 00869 case Triple::x86: 00870 case Triple::xcore: 00871 // Already 32-bit. 00872 break; 00873 00874 case Triple::le64: T.setArch(Triple::le32); break; 00875 case Triple::mips64: T.setArch(Triple::mips); break; 00876 case Triple::mips64el: T.setArch(Triple::mipsel); break; 00877 case Triple::nvptx64: T.setArch(Triple::nvptx); break; 00878 case Triple::ppc64: T.setArch(Triple::ppc); break; 00879 case Triple::sparcv9: T.setArch(Triple::sparc); break; 00880 case Triple::x86_64: T.setArch(Triple::x86); break; 00881 case Triple::spir64: T.setArch(Triple::spir); break; 00882 } 00883 return T; 00884 } 00885 00886 Triple Triple::get64BitArchVariant() const { 00887 Triple T(*this); 00888 switch (getArch()) { 00889 case Triple::UnknownArch: 00890 case Triple::amdil: 00891 case Triple::arm: 00892 case Triple::armeb: 00893 case Triple::hexagon: 00894 case Triple::kalimba: 00895 case Triple::msp430: 00896 case Triple::r600: 00897 case Triple::tce: 00898 case Triple::thumb: 00899 case Triple::thumbeb: 00900 case Triple::xcore: 00901 T.setArch(UnknownArch); 00902 break; 00903 00904 case Triple::aarch64: 00905 case Triple::aarch64_be: 00906 case Triple::le64: 00907 case Triple::mips64: 00908 case Triple::mips64el: 00909 case Triple::nvptx64: 00910 case Triple::ppc64: 00911 case Triple::ppc64le: 00912 case Triple::sparcv9: 00913 case Triple::spir64: 00914 case Triple::systemz: 00915 case Triple::x86_64: 00916 // Already 64-bit. 00917 break; 00918 00919 case Triple::le32: T.setArch(Triple::le64); break; 00920 case Triple::mips: T.setArch(Triple::mips64); break; 00921 case Triple::mipsel: T.setArch(Triple::mips64el); break; 00922 case Triple::nvptx: T.setArch(Triple::nvptx64); break; 00923 case Triple::ppc: T.setArch(Triple::ppc64); break; 00924 case Triple::sparc: T.setArch(Triple::sparcv9); break; 00925 case Triple::x86: T.setArch(Triple::x86_64); break; 00926 case Triple::spir: T.setArch(Triple::spir64); break; 00927 } 00928 return T; 00929 } 00930 00931 // FIXME: tblgen this. 00932 const char *Triple::getARMCPUForArch(StringRef MArch) const { 00933 if (MArch.empty()) 00934 MArch = getArchName(); 00935 00936 switch (getOS()) { 00937 case llvm::Triple::FreeBSD: 00938 case llvm::Triple::NetBSD: 00939 if (MArch == "armv6") 00940 return "arm1176jzf-s"; 00941 break; 00942 case llvm::Triple::Win32: 00943 // FIXME: this is invalid for WindowsCE 00944 return "cortex-a9"; 00945 default: 00946 break; 00947 } 00948 00949 const char *result = nullptr; 00950 size_t offset = StringRef::npos; 00951 if (MArch.startswith("arm")) 00952 offset = 3; 00953 if (MArch.startswith("thumb")) 00954 offset = 5; 00955 if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb") 00956 offset += 2; 00957 if (offset != StringRef::npos) 00958 result = llvm::StringSwitch<const char *>(MArch.substr(offset)) 00959 .Cases("v2", "v2a", "arm2") 00960 .Case("v3", "arm6") 00961 .Case("v3m", "arm7m") 00962 .Case("v4", "strongarm") 00963 .Case("v4t", "arm7tdmi") 00964 .Cases("v5", "v5t", "arm10tdmi") 00965 .Cases("v5e", "v5te", "arm1022e") 00966 .Case("v5tej", "arm926ej-s") 00967 .Cases("v6", "v6k", "arm1136jf-s") 00968 .Case("v6j", "arm1136j-s") 00969 .Cases("v6z", "v6zk", "arm1176jzf-s") 00970 .Case("v6t2", "arm1156t2-s") 00971 .Cases("v6m", "v6-m", "cortex-m0") 00972 .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8") 00973 .Cases("v7s", "v7-s", "swift") 00974 .Cases("v7r", "v7-r", "cortex-r4") 00975 .Cases("v7m", "v7-m", "cortex-m3") 00976 .Cases("v7em", "v7e-m", "cortex-m4") 00977 .Cases("v8", "v8a", "v8-a", "cortex-a53") 00978 .Default(nullptr); 00979 else 00980 result = llvm::StringSwitch<const char *>(MArch) 00981 .Case("ep9312", "ep9312") 00982 .Case("iwmmxt", "iwmmxt") 00983 .Case("xscale", "xscale") 00984 .Default(nullptr); 00985 00986 if (result) 00987 return result; 00988 00989 // If all else failed, return the most base CPU with thumb interworking 00990 // supported by LLVM. 00991 // FIXME: Should warn once that we're falling back. 00992 switch (getOS()) { 00993 case llvm::Triple::NetBSD: 00994 switch (getEnvironment()) { 00995 case llvm::Triple::GNUEABIHF: 00996 case llvm::Triple::GNUEABI: 00997 case llvm::Triple::EABIHF: 00998 case llvm::Triple::EABI: 00999 return "arm926ej-s"; 01000 default: 01001 return "strongarm"; 01002 } 01003 default: 01004 switch (getEnvironment()) { 01005 case llvm::Triple::EABIHF: 01006 case llvm::Triple::GNUEABIHF: 01007 return "arm1176jzf-s"; 01008 default: 01009 return "arm7tdmi"; 01010 } 01011 } 01012 }