PageRenderTime 53ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Support/Triple.cpp

https://github.com/ChocoChipset/llvm
C++ | 914 lines | 734 code | 93 blank | 87 comment | 118 complexity | 99a1f191426ff9843ef7558b58904126 MD5 | raw file
  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. #include "llvm/ADT/Triple.h"
  10. #include "llvm/ADT/STLExtras.h"
  11. #include "llvm/ADT/SmallString.h"
  12. #include "llvm/ADT/StringSwitch.h"
  13. #include "llvm/Support/ErrorHandling.h"
  14. #include <cstring>
  15. using namespace llvm;
  16. const char *Triple::getArchTypeName(ArchType Kind) {
  17. switch (Kind) {
  18. case UnknownArch: return "unknown";
  19. case aarch64: return "aarch64";
  20. case aarch64_be: return "aarch64_be";
  21. case arm: return "arm";
  22. case armeb: return "armeb";
  23. case arm64: return "arm64";
  24. case hexagon: return "hexagon";
  25. case mips: return "mips";
  26. case mipsel: return "mipsel";
  27. case mips64: return "mips64";
  28. case mips64el: return "mips64el";
  29. case msp430: return "msp430";
  30. case ppc64: return "powerpc64";
  31. case ppc64le: return "powerpc64le";
  32. case ppc: return "powerpc";
  33. case r600: return "r600";
  34. case sparc: return "sparc";
  35. case sparcv9: return "sparcv9";
  36. case systemz: return "s390x";
  37. case tce: return "tce";
  38. case thumb: return "thumb";
  39. case thumbeb: return "thumbeb";
  40. case x86: return "i386";
  41. case x86_64: return "x86_64";
  42. case xcore: return "xcore";
  43. case nvptx: return "nvptx";
  44. case nvptx64: return "nvptx64";
  45. case le32: return "le32";
  46. case amdil: return "amdil";
  47. case spir: return "spir";
  48. case spir64: return "spir64";
  49. }
  50. llvm_unreachable("Invalid ArchType!");
  51. }
  52. const char *Triple::getArchTypePrefix(ArchType Kind) {
  53. switch (Kind) {
  54. default:
  55. return nullptr;
  56. case aarch64:
  57. case aarch64_be: return "aarch64";
  58. case arm:
  59. case armeb:
  60. case thumb:
  61. case thumbeb: return "arm";
  62. case arm64: return "arm64";
  63. case ppc64:
  64. case ppc64le:
  65. case ppc: return "ppc";
  66. case mips:
  67. case mipsel:
  68. case mips64:
  69. case mips64el: return "mips";
  70. case hexagon: return "hexagon";
  71. case r600: return "r600";
  72. case sparcv9:
  73. case sparc: return "sparc";
  74. case systemz: return "systemz";
  75. case x86:
  76. case x86_64: return "x86";
  77. case xcore: return "xcore";
  78. case nvptx: return "nvptx";
  79. case nvptx64: return "nvptx";
  80. case le32: return "le32";
  81. case amdil: return "amdil";
  82. case spir: return "spir";
  83. case spir64: return "spir";
  84. }
  85. }
  86. const char *Triple::getVendorTypeName(VendorType Kind) {
  87. switch (Kind) {
  88. case UnknownVendor: return "unknown";
  89. case Apple: return "apple";
  90. case PC: return "pc";
  91. case SCEI: return "scei";
  92. case BGP: return "bgp";
  93. case BGQ: return "bgq";
  94. case Freescale: return "fsl";
  95. case IBM: return "ibm";
  96. case NVIDIA: return "nvidia";
  97. }
  98. llvm_unreachable("Invalid VendorType!");
  99. }
  100. const char *Triple::getOSTypeName(OSType Kind) {
  101. switch (Kind) {
  102. case UnknownOS: return "unknown";
  103. case AuroraUX: return "auroraux";
  104. case Cygwin: return "cygwin";
  105. case Darwin: return "darwin";
  106. case DragonFly: return "dragonfly";
  107. case FreeBSD: return "freebsd";
  108. case IOS: return "ios";
  109. case KFreeBSD: return "kfreebsd";
  110. case Linux: return "linux";
  111. case Lv2: return "lv2";
  112. case MacOSX: return "macosx";
  113. case MinGW32: return "mingw32";
  114. case NetBSD: return "netbsd";
  115. case OpenBSD: return "openbsd";
  116. case Solaris: return "solaris";
  117. case Win32: return "windows";
  118. case Haiku: return "haiku";
  119. case Minix: return "minix";
  120. case RTEMS: return "rtems";
  121. case NaCl: return "nacl";
  122. case CNK: return "cnk";
  123. case Bitrig: return "bitrig";
  124. case AIX: return "aix";
  125. case CUDA: return "cuda";
  126. case NVCL: return "nvcl";
  127. }
  128. llvm_unreachable("Invalid OSType");
  129. }
  130. const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
  131. switch (Kind) {
  132. case UnknownEnvironment: return "unknown";
  133. case GNU: return "gnu";
  134. case GNUEABIHF: return "gnueabihf";
  135. case GNUEABI: return "gnueabi";
  136. case GNUX32: return "gnux32";
  137. case CODE16: return "code16";
  138. case EABI: return "eabi";
  139. case EABIHF: return "eabihf";
  140. case Android: return "android";
  141. case MSVC: return "msvc";
  142. case Itanium: return "itanium";
  143. case Cygnus: return "cygnus";
  144. }
  145. llvm_unreachable("Invalid EnvironmentType!");
  146. }
  147. Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
  148. return StringSwitch<Triple::ArchType>(Name)
  149. .Case("aarch64", aarch64)
  150. .Case("aarch64_be", aarch64_be)
  151. .Case("arm", arm)
  152. .Case("armeb", armeb)
  153. .Case("arm64", arm64)
  154. .Case("mips", mips)
  155. .Case("mipsel", mipsel)
  156. .Case("mips64", mips64)
  157. .Case("mips64el", mips64el)
  158. .Case("msp430", msp430)
  159. .Case("ppc64", ppc64)
  160. .Case("ppc32", ppc)
  161. .Case("ppc", ppc)
  162. .Case("ppc64le", ppc64le)
  163. .Case("r600", r600)
  164. .Case("hexagon", hexagon)
  165. .Case("sparc", sparc)
  166. .Case("sparcv9", sparcv9)
  167. .Case("systemz", systemz)
  168. .Case("tce", tce)
  169. .Case("thumb", thumb)
  170. .Case("thumbeb", thumbeb)
  171. .Case("x86", x86)
  172. .Case("x86-64", x86_64)
  173. .Case("xcore", xcore)
  174. .Case("nvptx", nvptx)
  175. .Case("nvptx64", nvptx64)
  176. .Case("le32", le32)
  177. .Case("amdil", amdil)
  178. .Case("spir", spir)
  179. .Case("spir64", spir64)
  180. .Default(UnknownArch);
  181. }
  182. // Returns architecture name that is understood by the target assembler.
  183. const char *Triple::getArchNameForAssembler() {
  184. if (!isOSDarwin() && getVendor() != Triple::Apple)
  185. return nullptr;
  186. return StringSwitch<const char*>(getArchName())
  187. .Case("i386", "i386")
  188. .Case("x86_64", "x86_64")
  189. .Case("powerpc", "ppc")
  190. .Case("powerpc64", "ppc64")
  191. .Case("powerpc64le", "ppc64le")
  192. .Case("arm", "arm")
  193. .Cases("armv4t", "thumbv4t", "armv4t")
  194. .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
  195. .Cases("armv6", "thumbv6", "armv6")
  196. .Cases("armv7", "thumbv7", "armv7")
  197. .Case("armeb", "armeb")
  198. .Case("arm64", "arm64")
  199. .Case("r600", "r600")
  200. .Case("nvptx", "nvptx")
  201. .Case("nvptx64", "nvptx64")
  202. .Case("le32", "le32")
  203. .Case("amdil", "amdil")
  204. .Case("spir", "spir")
  205. .Case("spir64", "spir64")
  206. .Default(nullptr);
  207. }
  208. static Triple::ArchType parseArch(StringRef ArchName) {
  209. return StringSwitch<Triple::ArchType>(ArchName)
  210. .Cases("i386", "i486", "i586", "i686", Triple::x86)
  211. // FIXME: Do we need to support these?
  212. .Cases("i786", "i886", "i986", Triple::x86)
  213. .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
  214. .Case("powerpc", Triple::ppc)
  215. .Cases("powerpc64", "ppu", Triple::ppc64)
  216. .Case("powerpc64le", Triple::ppc64le)
  217. .Case("aarch64", Triple::aarch64)
  218. .Case("aarch64_be", Triple::aarch64_be)
  219. .Cases("arm", "xscale", Triple::arm)
  220. // FIXME: It would be good to replace these with explicit names for all the
  221. // various suffixes supported.
  222. .StartsWith("armv", Triple::arm)
  223. .Case("armeb", Triple::armeb)
  224. .StartsWith("armebv", Triple::armeb)
  225. .Case("thumb", Triple::thumb)
  226. .StartsWith("thumbv", Triple::thumb)
  227. .Case("thumbeb", Triple::thumbeb)
  228. .StartsWith("thumbebv", Triple::thumbeb)
  229. .Case("arm64", Triple::arm64)
  230. .Case("msp430", Triple::msp430)
  231. .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
  232. .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
  233. .Cases("mips64", "mips64eb", Triple::mips64)
  234. .Case("mips64el", Triple::mips64el)
  235. .Case("r600", Triple::r600)
  236. .Case("hexagon", Triple::hexagon)
  237. .Case("s390x", Triple::systemz)
  238. .Case("sparc", Triple::sparc)
  239. .Cases("sparcv9", "sparc64", Triple::sparcv9)
  240. .Case("tce", Triple::tce)
  241. .Case("xcore", Triple::xcore)
  242. .Case("nvptx", Triple::nvptx)
  243. .Case("nvptx64", Triple::nvptx64)
  244. .Case("le32", Triple::le32)
  245. .Case("amdil", Triple::amdil)
  246. .Case("spir", Triple::spir)
  247. .Case("spir64", Triple::spir64)
  248. .Default(Triple::UnknownArch);
  249. }
  250. static Triple::VendorType parseVendor(StringRef VendorName) {
  251. return StringSwitch<Triple::VendorType>(VendorName)
  252. .Case("apple", Triple::Apple)
  253. .Case("pc", Triple::PC)
  254. .Case("scei", Triple::SCEI)
  255. .Case("bgp", Triple::BGP)
  256. .Case("bgq", Triple::BGQ)
  257. .Case("fsl", Triple::Freescale)
  258. .Case("ibm", Triple::IBM)
  259. .Case("nvidia", Triple::NVIDIA)
  260. .Default(Triple::UnknownVendor);
  261. }
  262. static Triple::OSType parseOS(StringRef OSName) {
  263. return StringSwitch<Triple::OSType>(OSName)
  264. .StartsWith("auroraux", Triple::AuroraUX)
  265. .StartsWith("cygwin", Triple::Cygwin)
  266. .StartsWith("darwin", Triple::Darwin)
  267. .StartsWith("dragonfly", Triple::DragonFly)
  268. .StartsWith("freebsd", Triple::FreeBSD)
  269. .StartsWith("ios", Triple::IOS)
  270. .StartsWith("kfreebsd", Triple::KFreeBSD)
  271. .StartsWith("linux", Triple::Linux)
  272. .StartsWith("lv2", Triple::Lv2)
  273. .StartsWith("macosx", Triple::MacOSX)
  274. .StartsWith("mingw32", Triple::MinGW32)
  275. .StartsWith("netbsd", Triple::NetBSD)
  276. .StartsWith("openbsd", Triple::OpenBSD)
  277. .StartsWith("solaris", Triple::Solaris)
  278. .StartsWith("win32", Triple::Win32)
  279. .StartsWith("windows", Triple::Win32)
  280. .StartsWith("haiku", Triple::Haiku)
  281. .StartsWith("minix", Triple::Minix)
  282. .StartsWith("rtems", Triple::RTEMS)
  283. .StartsWith("nacl", Triple::NaCl)
  284. .StartsWith("cnk", Triple::CNK)
  285. .StartsWith("bitrig", Triple::Bitrig)
  286. .StartsWith("aix", Triple::AIX)
  287. .StartsWith("cuda", Triple::CUDA)
  288. .StartsWith("nvcl", Triple::NVCL)
  289. .Default(Triple::UnknownOS);
  290. }
  291. static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
  292. return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
  293. .StartsWith("eabihf", Triple::EABIHF)
  294. .StartsWith("eabi", Triple::EABI)
  295. .StartsWith("gnueabihf", Triple::GNUEABIHF)
  296. .StartsWith("gnueabi", Triple::GNUEABI)
  297. .StartsWith("gnux32", Triple::GNUX32)
  298. .StartsWith("code16", Triple::CODE16)
  299. .StartsWith("gnu", Triple::GNU)
  300. .StartsWith("android", Triple::Android)
  301. .StartsWith("msvc", Triple::MSVC)
  302. .StartsWith("itanium", Triple::Itanium)
  303. .StartsWith("cygnus", Triple::Cygnus)
  304. .Default(Triple::UnknownEnvironment);
  305. }
  306. static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
  307. return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
  308. .EndsWith("coff", Triple::COFF)
  309. .EndsWith("elf", Triple::ELF)
  310. .EndsWith("macho", Triple::MachO)
  311. .Default(Triple::UnknownObjectFormat);
  312. }
  313. static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
  314. switch (Kind) {
  315. case Triple::UnknownObjectFormat: return "";
  316. case Triple::COFF: return "coff";
  317. case Triple::ELF: return "elf";
  318. case Triple::MachO: return "macho";
  319. }
  320. llvm_unreachable("unknown object format type");
  321. }
  322. static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
  323. if (T.isOSDarwin())
  324. return Triple::MachO;
  325. else if (T.isOSWindows())
  326. return Triple::COFF;
  327. return Triple::ELF;
  328. }
  329. /// \brief Construct a triple from the string representation provided.
  330. ///
  331. /// This stores the string representation and parses the various pieces into
  332. /// enum members.
  333. Triple::Triple(const Twine &Str)
  334. : Data(Str.str()),
  335. Arch(parseArch(getArchName())),
  336. Vendor(parseVendor(getVendorName())),
  337. OS(parseOS(getOSName())),
  338. Environment(parseEnvironment(getEnvironmentName())),
  339. ObjectFormat(parseFormat(getEnvironmentName())) {
  340. if (ObjectFormat == Triple::UnknownObjectFormat)
  341. ObjectFormat = getDefaultFormat(*this);
  342. }
  343. /// \brief Construct a triple from string representations of the architecture,
  344. /// vendor, and OS.
  345. ///
  346. /// This joins each argument into a canonical string representation and parses
  347. /// them into enum members. It leaves the environment unknown and omits it from
  348. /// the string representation.
  349. Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
  350. : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
  351. Arch(parseArch(ArchStr.str())),
  352. Vendor(parseVendor(VendorStr.str())),
  353. OS(parseOS(OSStr.str())),
  354. Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
  355. ObjectFormat = getDefaultFormat(*this);
  356. }
  357. /// \brief Construct a triple from string representations of the architecture,
  358. /// vendor, OS, and environment.
  359. ///
  360. /// This joins each argument into a canonical string representation and parses
  361. /// them into enum members.
  362. Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
  363. const Twine &EnvironmentStr)
  364. : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
  365. EnvironmentStr).str()),
  366. Arch(parseArch(ArchStr.str())),
  367. Vendor(parseVendor(VendorStr.str())),
  368. OS(parseOS(OSStr.str())),
  369. Environment(parseEnvironment(EnvironmentStr.str())),
  370. ObjectFormat(parseFormat(EnvironmentStr.str())) {
  371. if (ObjectFormat == Triple::UnknownObjectFormat)
  372. ObjectFormat = getDefaultFormat(*this);
  373. }
  374. std::string Triple::normalize(StringRef Str) {
  375. // Parse into components.
  376. SmallVector<StringRef, 4> Components;
  377. Str.split(Components, "-");
  378. // If the first component corresponds to a known architecture, preferentially
  379. // use it for the architecture. If the second component corresponds to a
  380. // known vendor, preferentially use it for the vendor, etc. This avoids silly
  381. // component movement when a component parses as (eg) both a valid arch and a
  382. // valid os.
  383. ArchType Arch = UnknownArch;
  384. if (Components.size() > 0)
  385. Arch = parseArch(Components[0]);
  386. VendorType Vendor = UnknownVendor;
  387. if (Components.size() > 1)
  388. Vendor = parseVendor(Components[1]);
  389. OSType OS = UnknownOS;
  390. if (Components.size() > 2)
  391. OS = parseOS(Components[2]);
  392. EnvironmentType Environment = UnknownEnvironment;
  393. if (Components.size() > 3)
  394. Environment = parseEnvironment(Components[3]);
  395. ObjectFormatType ObjectFormat = UnknownObjectFormat;
  396. if (Components.size() > 4)
  397. ObjectFormat = parseFormat(Components[4]);
  398. // Note which components are already in their final position. These will not
  399. // be moved.
  400. bool Found[4];
  401. Found[0] = Arch != UnknownArch;
  402. Found[1] = Vendor != UnknownVendor;
  403. Found[2] = OS != UnknownOS;
  404. Found[3] = Environment != UnknownEnvironment;
  405. // If they are not there already, permute the components into their canonical
  406. // positions by seeing if they parse as a valid architecture, and if so moving
  407. // the component to the architecture position etc.
  408. for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
  409. if (Found[Pos])
  410. continue; // Already in the canonical position.
  411. for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
  412. // Do not reparse any components that already matched.
  413. if (Idx < array_lengthof(Found) && Found[Idx])
  414. continue;
  415. // Does this component parse as valid for the target position?
  416. bool Valid = false;
  417. StringRef Comp = Components[Idx];
  418. switch (Pos) {
  419. default: llvm_unreachable("unexpected component type!");
  420. case 0:
  421. Arch = parseArch(Comp);
  422. Valid = Arch != UnknownArch;
  423. break;
  424. case 1:
  425. Vendor = parseVendor(Comp);
  426. Valid = Vendor != UnknownVendor;
  427. break;
  428. case 2:
  429. OS = parseOS(Comp);
  430. Valid = OS != UnknownOS;
  431. break;
  432. case 3:
  433. Environment = parseEnvironment(Comp);
  434. Valid = Environment != UnknownEnvironment;
  435. if (!Valid) {
  436. ObjectFormat = parseFormat(Comp);
  437. Valid = ObjectFormat != UnknownObjectFormat;
  438. }
  439. break;
  440. }
  441. if (!Valid)
  442. continue; // Nope, try the next component.
  443. // Move the component to the target position, pushing any non-fixed
  444. // components that are in the way to the right. This tends to give
  445. // good results in the common cases of a forgotten vendor component
  446. // or a wrongly positioned environment.
  447. if (Pos < Idx) {
  448. // Insert left, pushing the existing components to the right. For
  449. // example, a-b-i386 -> i386-a-b when moving i386 to the front.
  450. StringRef CurrentComponent(""); // The empty component.
  451. // Replace the component we are moving with an empty component.
  452. std::swap(CurrentComponent, Components[Idx]);
  453. // Insert the component being moved at Pos, displacing any existing
  454. // components to the right.
  455. for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
  456. // Skip over any fixed components.
  457. while (i < array_lengthof(Found) && Found[i])
  458. ++i;
  459. // Place the component at the new position, getting the component
  460. // that was at this position - it will be moved right.
  461. std::swap(CurrentComponent, Components[i]);
  462. }
  463. } else if (Pos > Idx) {
  464. // Push right by inserting empty components until the component at Idx
  465. // reaches the target position Pos. For example, pc-a -> -pc-a when
  466. // moving pc to the second position.
  467. do {
  468. // Insert one empty component at Idx.
  469. StringRef CurrentComponent(""); // The empty component.
  470. for (unsigned i = Idx; i < Components.size();) {
  471. // Place the component at the new position, getting the component
  472. // that was at this position - it will be moved right.
  473. std::swap(CurrentComponent, Components[i]);
  474. // If it was placed on top of an empty component then we are done.
  475. if (CurrentComponent.empty())
  476. break;
  477. // Advance to the next component, skipping any fixed components.
  478. while (++i < array_lengthof(Found) && Found[i])
  479. ;
  480. }
  481. // The last component was pushed off the end - append it.
  482. if (!CurrentComponent.empty())
  483. Components.push_back(CurrentComponent);
  484. // Advance Idx to the component's new position.
  485. while (++Idx < array_lengthof(Found) && Found[Idx])
  486. ;
  487. } while (Idx < Pos); // Add more until the final position is reached.
  488. }
  489. assert(Pos < Components.size() && Components[Pos] == Comp &&
  490. "Component moved wrong!");
  491. Found[Pos] = true;
  492. break;
  493. }
  494. }
  495. // Special case logic goes here. At this point Arch, Vendor and OS have the
  496. // correct values for the computed components.
  497. if (OS == Triple::Win32) {
  498. Components.resize(4);
  499. Components[2] = "windows";
  500. if (Environment == UnknownEnvironment) {
  501. if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
  502. Components[3] = "msvc";
  503. else
  504. Components[3] = getObjectFormatTypeName(ObjectFormat);
  505. }
  506. } else if (OS == Triple::MinGW32) {
  507. Components.resize(4);
  508. Components[2] = "windows";
  509. Components[3] = "gnu";
  510. } else if (OS == Triple::Cygwin) {
  511. Components.resize(4);
  512. Components[2] = "windows";
  513. Components[3] = "cygnus";
  514. }
  515. if (OS == Triple::MinGW32 || OS == Triple::Cygwin ||
  516. (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
  517. if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
  518. Components.resize(5);
  519. Components[4] = getObjectFormatTypeName(ObjectFormat);
  520. }
  521. }
  522. // Stick the corrected components back together to form the normalized string.
  523. std::string Normalized;
  524. for (unsigned i = 0, e = Components.size(); i != e; ++i) {
  525. if (i) Normalized += '-';
  526. Normalized += Components[i];
  527. }
  528. return Normalized;
  529. }
  530. StringRef Triple::getArchName() const {
  531. return StringRef(Data).split('-').first; // Isolate first component
  532. }
  533. StringRef Triple::getVendorName() const {
  534. StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  535. return Tmp.split('-').first; // Isolate second component
  536. }
  537. StringRef Triple::getOSName() const {
  538. StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  539. Tmp = Tmp.split('-').second; // Strip second component
  540. return Tmp.split('-').first; // Isolate third component
  541. }
  542. StringRef Triple::getEnvironmentName() const {
  543. StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  544. Tmp = Tmp.split('-').second; // Strip second component
  545. return Tmp.split('-').second; // Strip third component
  546. }
  547. StringRef Triple::getOSAndEnvironmentName() const {
  548. StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  549. return Tmp.split('-').second; // Strip second component
  550. }
  551. static unsigned EatNumber(StringRef &Str) {
  552. assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
  553. unsigned Result = 0;
  554. do {
  555. // Consume the leading digit.
  556. Result = Result*10 + (Str[0] - '0');
  557. // Eat the digit.
  558. Str = Str.substr(1);
  559. } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
  560. return Result;
  561. }
  562. void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
  563. unsigned &Micro) const {
  564. StringRef OSName = getOSName();
  565. // Assume that the OS portion of the triple starts with the canonical name.
  566. StringRef OSTypeName = getOSTypeName(getOS());
  567. if (OSName.startswith(OSTypeName))
  568. OSName = OSName.substr(OSTypeName.size());
  569. // Any unset version defaults to 0.
  570. Major = Minor = Micro = 0;
  571. // Parse up to three components.
  572. unsigned *Components[3] = { &Major, &Minor, &Micro };
  573. for (unsigned i = 0; i != 3; ++i) {
  574. if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
  575. break;
  576. // Consume the leading number.
  577. *Components[i] = EatNumber(OSName);
  578. // Consume the separator, if present.
  579. if (OSName.startswith("."))
  580. OSName = OSName.substr(1);
  581. }
  582. }
  583. bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
  584. unsigned &Micro) const {
  585. getOSVersion(Major, Minor, Micro);
  586. switch (getOS()) {
  587. default: llvm_unreachable("unexpected OS for Darwin triple");
  588. case Darwin:
  589. // Default to darwin8, i.e., MacOSX 10.4.
  590. if (Major == 0)
  591. Major = 8;
  592. // Darwin version numbers are skewed from OS X versions.
  593. if (Major < 4)
  594. return false;
  595. Micro = 0;
  596. Minor = Major - 4;
  597. Major = 10;
  598. break;
  599. case MacOSX:
  600. // Default to 10.4.
  601. if (Major == 0) {
  602. Major = 10;
  603. Minor = 4;
  604. }
  605. if (Major != 10)
  606. return false;
  607. break;
  608. case IOS:
  609. // Ignore the version from the triple. This is only handled because the
  610. // the clang driver combines OS X and IOS support into a common Darwin
  611. // toolchain that wants to know the OS X version number even when targeting
  612. // IOS.
  613. Major = 10;
  614. Minor = 4;
  615. Micro = 0;
  616. break;
  617. }
  618. return true;
  619. }
  620. void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
  621. unsigned &Micro) const {
  622. switch (getOS()) {
  623. default: llvm_unreachable("unexpected OS for Darwin triple");
  624. case Darwin:
  625. case MacOSX:
  626. // Ignore the version from the triple. This is only handled because the
  627. // the clang driver combines OS X and IOS support into a common Darwin
  628. // toolchain that wants to know the iOS version number even when targeting
  629. // OS X.
  630. Major = 5;
  631. Minor = 0;
  632. Micro = 0;
  633. break;
  634. case IOS:
  635. getOSVersion(Major, Minor, Micro);
  636. // Default to 5.0 (or 7.0 for arm64).
  637. if (Major == 0)
  638. Major = (getArch() == arm64) ? 7 : 5;
  639. break;
  640. }
  641. }
  642. void Triple::setTriple(const Twine &Str) {
  643. *this = Triple(Str);
  644. }
  645. void Triple::setArch(ArchType Kind) {
  646. setArchName(getArchTypeName(Kind));
  647. }
  648. void Triple::setVendor(VendorType Kind) {
  649. setVendorName(getVendorTypeName(Kind));
  650. }
  651. void Triple::setOS(OSType Kind) {
  652. setOSName(getOSTypeName(Kind));
  653. }
  654. void Triple::setEnvironment(EnvironmentType Kind) {
  655. setEnvironmentName(getEnvironmentTypeName(Kind));
  656. }
  657. void Triple::setObjectFormat(ObjectFormatType Kind) {
  658. if (Environment == UnknownEnvironment)
  659. return setEnvironmentName(getObjectFormatTypeName(Kind));
  660. Twine Env = getEnvironmentTypeName(Environment) + Twine("-") +
  661. getObjectFormatTypeName(Kind);
  662. setEnvironmentName(Env.str());
  663. }
  664. void Triple::setArchName(StringRef Str) {
  665. // Work around a miscompilation bug for Twines in gcc 4.0.3.
  666. SmallString<64> Triple;
  667. Triple += Str;
  668. Triple += "-";
  669. Triple += getVendorName();
  670. Triple += "-";
  671. Triple += getOSAndEnvironmentName();
  672. setTriple(Triple.str());
  673. }
  674. void Triple::setVendorName(StringRef Str) {
  675. setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
  676. }
  677. void Triple::setOSName(StringRef Str) {
  678. if (hasEnvironment())
  679. setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
  680. "-" + getEnvironmentName());
  681. else
  682. setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
  683. }
  684. void Triple::setEnvironmentName(StringRef Str) {
  685. setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
  686. "-" + Str);
  687. }
  688. void Triple::setOSAndEnvironmentName(StringRef Str) {
  689. setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
  690. }
  691. static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
  692. switch (Arch) {
  693. case llvm::Triple::UnknownArch:
  694. return 0;
  695. case llvm::Triple::msp430:
  696. return 16;
  697. case llvm::Triple::amdil:
  698. case llvm::Triple::arm:
  699. case llvm::Triple::armeb:
  700. case llvm::Triple::hexagon:
  701. case llvm::Triple::le32:
  702. case llvm::Triple::mips:
  703. case llvm::Triple::mipsel:
  704. case llvm::Triple::nvptx:
  705. case llvm::Triple::ppc:
  706. case llvm::Triple::r600:
  707. case llvm::Triple::sparc:
  708. case llvm::Triple::tce:
  709. case llvm::Triple::thumb:
  710. case llvm::Triple::thumbeb:
  711. case llvm::Triple::x86:
  712. case llvm::Triple::xcore:
  713. case llvm::Triple::spir:
  714. return 32;
  715. case llvm::Triple::arm64:
  716. case llvm::Triple::aarch64:
  717. case llvm::Triple::aarch64_be:
  718. case llvm::Triple::mips64:
  719. case llvm::Triple::mips64el:
  720. case llvm::Triple::nvptx64:
  721. case llvm::Triple::ppc64:
  722. case llvm::Triple::ppc64le:
  723. case llvm::Triple::sparcv9:
  724. case llvm::Triple::systemz:
  725. case llvm::Triple::x86_64:
  726. case llvm::Triple::spir64:
  727. return 64;
  728. }
  729. llvm_unreachable("Invalid architecture value");
  730. }
  731. bool Triple::isArch64Bit() const {
  732. return getArchPointerBitWidth(getArch()) == 64;
  733. }
  734. bool Triple::isArch32Bit() const {
  735. return getArchPointerBitWidth(getArch()) == 32;
  736. }
  737. bool Triple::isArch16Bit() const {
  738. return getArchPointerBitWidth(getArch()) == 16;
  739. }
  740. Triple Triple::get32BitArchVariant() const {
  741. Triple T(*this);
  742. switch (getArch()) {
  743. case Triple::UnknownArch:
  744. case Triple::aarch64:
  745. case Triple::aarch64_be:
  746. case Triple::arm64:
  747. case Triple::msp430:
  748. case Triple::systemz:
  749. case Triple::ppc64le:
  750. T.setArch(UnknownArch);
  751. break;
  752. case Triple::amdil:
  753. case Triple::spir:
  754. case Triple::arm:
  755. case Triple::armeb:
  756. case Triple::hexagon:
  757. case Triple::le32:
  758. case Triple::mips:
  759. case Triple::mipsel:
  760. case Triple::nvptx:
  761. case Triple::ppc:
  762. case Triple::r600:
  763. case Triple::sparc:
  764. case Triple::tce:
  765. case Triple::thumb:
  766. case Triple::thumbeb:
  767. case Triple::x86:
  768. case Triple::xcore:
  769. // Already 32-bit.
  770. break;
  771. case Triple::mips64: T.setArch(Triple::mips); break;
  772. case Triple::mips64el: T.setArch(Triple::mipsel); break;
  773. case Triple::nvptx64: T.setArch(Triple::nvptx); break;
  774. case Triple::ppc64: T.setArch(Triple::ppc); break;
  775. case Triple::sparcv9: T.setArch(Triple::sparc); break;
  776. case Triple::x86_64: T.setArch(Triple::x86); break;
  777. case Triple::spir64: T.setArch(Triple::spir); break;
  778. }
  779. return T;
  780. }
  781. Triple Triple::get64BitArchVariant() const {
  782. Triple T(*this);
  783. switch (getArch()) {
  784. case Triple::UnknownArch:
  785. case Triple::amdil:
  786. case Triple::arm:
  787. case Triple::armeb:
  788. case Triple::hexagon:
  789. case Triple::le32:
  790. case Triple::msp430:
  791. case Triple::r600:
  792. case Triple::tce:
  793. case Triple::thumb:
  794. case Triple::thumbeb:
  795. case Triple::xcore:
  796. T.setArch(UnknownArch);
  797. break;
  798. case Triple::aarch64:
  799. case Triple::aarch64_be:
  800. case Triple::spir64:
  801. case Triple::mips64:
  802. case Triple::mips64el:
  803. case Triple::nvptx64:
  804. case Triple::ppc64:
  805. case Triple::ppc64le:
  806. case Triple::sparcv9:
  807. case Triple::systemz:
  808. case Triple::x86_64:
  809. case Triple::arm64:
  810. // Already 64-bit.
  811. break;
  812. case Triple::mips: T.setArch(Triple::mips64); break;
  813. case Triple::mipsel: T.setArch(Triple::mips64el); break;
  814. case Triple::nvptx: T.setArch(Triple::nvptx64); break;
  815. case Triple::ppc: T.setArch(Triple::ppc64); break;
  816. case Triple::sparc: T.setArch(Triple::sparcv9); break;
  817. case Triple::x86: T.setArch(Triple::x86_64); break;
  818. case Triple::spir: T.setArch(Triple::spir64); break;
  819. }
  820. return T;
  821. }