TargetParser.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements a target parser to recognise hardware features such as
  11. // FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/Support/ARMBuildAttributes.h"
  15. #include "llvm/Support/TargetParser.h"
  16. #include "llvm/ADT/StringSwitch.h"
  17. #include "llvm/ADT/Twine.h"
  18. #include <cctype>
  19. using namespace llvm;
  20. using namespace ARM;
  21. using namespace AArch64;
  22. namespace {
  23. // List of canonical FPU names (use getFPUSynonym) and which architectural
  24. // features they correspond to (use getFPUFeatures).
  25. // FIXME: TableGen this.
  26. // The entries must appear in the order listed in ARM::FPUKind for correct indexing
  27. static const struct {
  28. const char *NameCStr;
  29. size_t NameLength;
  30. ARM::FPUKind ID;
  31. ARM::FPUVersion FPUVersion;
  32. ARM::NeonSupportLevel NeonSupport;
  33. ARM::FPURestriction Restriction;
  34. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  35. } FPUNames[] = {
  36. #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
  37. { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
  38. #include "llvm/Support/ARMTargetParser.def"
  39. };
  40. // List of canonical arch names (use getArchSynonym).
  41. // This table also provides the build attribute fields for CPU arch
  42. // and Arch ID, according to the Addenda to the ARM ABI, chapters
  43. // 2.4 and 2.3.5.2 respectively.
  44. // FIXME: SubArch values were simplified to fit into the expectations
  45. // of the triples and are not conforming with their official names.
  46. // Check to see if the expectation should be changed.
  47. // FIXME: TableGen this.
  48. template <typename T> struct ArchNames {
  49. const char *NameCStr;
  50. size_t NameLength;
  51. const char *CPUAttrCStr;
  52. size_t CPUAttrLength;
  53. const char *SubArchCStr;
  54. size_t SubArchLength;
  55. unsigned DefaultFPU;
  56. unsigned ArchBaseExtensions;
  57. T ID;
  58. ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
  59. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  60. // CPU class in build attributes.
  61. StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
  62. // Sub-Arch name.
  63. StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
  64. };
  65. ArchNames<ARM::ArchKind> ARCHNames[] = {
  66. #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
  67. {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
  68. sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ARM::ArchKind::ID, ARCH_ATTR},
  69. #include "llvm/Support/ARMTargetParser.def"
  70. };
  71. ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = {
  72. #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
  73. {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
  74. sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
  75. #include "llvm/Support/AArch64TargetParser.def"
  76. };
  77. // List of Arch Extension names.
  78. // FIXME: TableGen this.
  79. static const struct {
  80. const char *NameCStr;
  81. size_t NameLength;
  82. unsigned ID;
  83. const char *Feature;
  84. const char *NegFeature;
  85. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  86. } ARCHExtNames[] = {
  87. #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
  88. { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
  89. #include "llvm/Support/ARMTargetParser.def"
  90. },AArch64ARCHExtNames[] = {
  91. #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
  92. { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
  93. #include "llvm/Support/AArch64TargetParser.def"
  94. };
  95. // List of HWDiv names (use getHWDivSynonym) and which architectural
  96. // features they correspond to (use getHWDivFeatures).
  97. // FIXME: TableGen this.
  98. static const struct {
  99. const char *NameCStr;
  100. size_t NameLength;
  101. unsigned ID;
  102. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  103. } HWDivNames[] = {
  104. #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
  105. #include "llvm/Support/ARMTargetParser.def"
  106. };
  107. // List of CPU names and their arches.
  108. // The same CPU can have multiple arches and can be default on multiple arches.
  109. // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
  110. // When this becomes table-generated, we'd probably need two tables.
  111. // FIXME: TableGen this.
  112. template <typename T> struct CpuNames {
  113. const char *NameCStr;
  114. size_t NameLength;
  115. T ArchID;
  116. bool Default; // is $Name the default CPU for $ArchID ?
  117. unsigned DefaultExtensions;
  118. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  119. };
  120. CpuNames<ARM::ArchKind> CPUNames[] = {
  121. #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
  122. { NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
  123. #include "llvm/Support/ARMTargetParser.def"
  124. };
  125. CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
  126. #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
  127. { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
  128. #include "llvm/Support/AArch64TargetParser.def"
  129. };
  130. } // namespace
  131. // ======================================================= //
  132. // Information by ID
  133. // ======================================================= //
  134. StringRef ARM::getFPUName(unsigned FPUKind) {
  135. if (FPUKind >= ARM::FK_LAST)
  136. return StringRef();
  137. return FPUNames[FPUKind].getName();
  138. }
  139. FPUVersion ARM::getFPUVersion(unsigned FPUKind) {
  140. if (FPUKind >= ARM::FK_LAST)
  141. return FPUVersion::NONE;
  142. return FPUNames[FPUKind].FPUVersion;
  143. }
  144. ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
  145. if (FPUKind >= ARM::FK_LAST)
  146. return ARM::NeonSupportLevel::None;
  147. return FPUNames[FPUKind].NeonSupport;
  148. }
  149. ARM::FPURestriction ARM::getFPURestriction(unsigned FPUKind) {
  150. if (FPUKind >= ARM::FK_LAST)
  151. return ARM::FPURestriction::None;
  152. return FPUNames[FPUKind].Restriction;
  153. }
  154. unsigned llvm::ARM::getDefaultFPU(StringRef CPU, ArchKind AK) {
  155. if (CPU == "generic")
  156. return ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
  157. return StringSwitch<unsigned>(CPU)
  158. #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
  159. .Case(NAME, DEFAULT_FPU)
  160. #include "llvm/Support/ARMTargetParser.def"
  161. .Default(ARM::FK_INVALID);
  162. }
  163. unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, ArchKind AK) {
  164. if (CPU == "generic")
  165. return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
  166. return StringSwitch<unsigned>(CPU)
  167. #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
  168. .Case(NAME, ARCHNames[static_cast<unsigned>(ARM::ArchKind::ID)]\
  169. .ArchBaseExtensions | DEFAULT_EXT)
  170. #include "llvm/Support/ARMTargetParser.def"
  171. .Default(ARM::AEK_INVALID);
  172. }
  173. bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
  174. std::vector<StringRef> &Features) {
  175. if (HWDivKind == ARM::AEK_INVALID)
  176. return false;
  177. if (HWDivKind & ARM::AEK_HWDIVARM)
  178. Features.push_back("+hwdiv-arm");
  179. else
  180. Features.push_back("-hwdiv-arm");
  181. if (HWDivKind & ARM::AEK_HWDIVTHUMB)
  182. Features.push_back("+hwdiv");
  183. else
  184. Features.push_back("-hwdiv");
  185. return true;
  186. }
  187. bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
  188. std::vector<StringRef> &Features) {
  189. if (Extensions == ARM::AEK_INVALID)
  190. return false;
  191. if (Extensions & ARM::AEK_CRC)
  192. Features.push_back("+crc");
  193. else
  194. Features.push_back("-crc");
  195. if (Extensions & ARM::AEK_DSP)
  196. Features.push_back("+dsp");
  197. else
  198. Features.push_back("-dsp");
  199. if (Extensions & ARM::AEK_RAS)
  200. Features.push_back("+ras");
  201. else
  202. Features.push_back("-ras");
  203. if (Extensions & ARM::AEK_DOTPROD)
  204. Features.push_back("+dotprod");
  205. else
  206. Features.push_back("-dotprod");
  207. return getHWDivFeatures(Extensions, Features);
  208. }
  209. bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
  210. std::vector<StringRef> &Features) {
  211. if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
  212. return false;
  213. // fp-only-sp and d16 subtarget features are independent of each other, so we
  214. // must enable/disable both.
  215. switch (FPUNames[FPUKind].Restriction) {
  216. case ARM::FPURestriction::SP_D16:
  217. Features.push_back("+fp-only-sp");
  218. Features.push_back("+d16");
  219. break;
  220. case ARM::FPURestriction::D16:
  221. Features.push_back("-fp-only-sp");
  222. Features.push_back("+d16");
  223. break;
  224. case ARM::FPURestriction::None:
  225. Features.push_back("-fp-only-sp");
  226. Features.push_back("-d16");
  227. break;
  228. }
  229. // FPU version subtarget features are inclusive of lower-numbered ones, so
  230. // enable the one corresponding to this version and disable all that are
  231. // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
  232. // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
  233. switch (FPUNames[FPUKind].FPUVersion) {
  234. case ARM::FPUVersion::VFPV5:
  235. Features.push_back("+fp-armv8");
  236. break;
  237. case ARM::FPUVersion::VFPV4:
  238. Features.push_back("+vfp4");
  239. Features.push_back("-fp-armv8");
  240. break;
  241. case ARM::FPUVersion::VFPV3_FP16:
  242. Features.push_back("+vfp3");
  243. Features.push_back("+fp16");
  244. Features.push_back("-vfp4");
  245. Features.push_back("-fp-armv8");
  246. break;
  247. case ARM::FPUVersion::VFPV3:
  248. Features.push_back("+vfp3");
  249. Features.push_back("-fp16");
  250. Features.push_back("-vfp4");
  251. Features.push_back("-fp-armv8");
  252. break;
  253. case ARM::FPUVersion::VFPV2:
  254. Features.push_back("+vfp2");
  255. Features.push_back("-vfp3");
  256. Features.push_back("-fp16");
  257. Features.push_back("-vfp4");
  258. Features.push_back("-fp-armv8");
  259. break;
  260. case ARM::FPUVersion::NONE:
  261. Features.push_back("-vfp2");
  262. Features.push_back("-vfp3");
  263. Features.push_back("-fp16");
  264. Features.push_back("-vfp4");
  265. Features.push_back("-fp-armv8");
  266. break;
  267. }
  268. // crypto includes neon, so we handle this similarly to FPU version.
  269. switch (FPUNames[FPUKind].NeonSupport) {
  270. case ARM::NeonSupportLevel::Crypto:
  271. Features.push_back("+neon");
  272. Features.push_back("+crypto");
  273. break;
  274. case ARM::NeonSupportLevel::Neon:
  275. Features.push_back("+neon");
  276. Features.push_back("-crypto");
  277. break;
  278. case ARM::NeonSupportLevel::None:
  279. Features.push_back("-neon");
  280. Features.push_back("-crypto");
  281. break;
  282. }
  283. return true;
  284. }
  285. StringRef llvm::ARM::getArchName(ArchKind AK) {
  286. return ARCHNames[static_cast<unsigned>(AK)].getName();
  287. }
  288. StringRef llvm::ARM::getCPUAttr(ArchKind AK) {
  289. return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
  290. }
  291. StringRef llvm::ARM::getSubArch(ArchKind AK) {
  292. return ARCHNames[static_cast<unsigned>(AK)].getSubArch();
  293. }
  294. unsigned llvm::ARM::getArchAttr(ArchKind AK) {
  295. return ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
  296. }
  297. StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
  298. for (const auto AE : ARCHExtNames) {
  299. if (ArchExtKind == AE.ID)
  300. return AE.getName();
  301. }
  302. return StringRef();
  303. }
  304. StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) {
  305. if (ArchExt.startswith("no")) {
  306. StringRef ArchExtBase(ArchExt.substr(2));
  307. for (const auto AE : ARCHExtNames) {
  308. if (AE.NegFeature && ArchExtBase == AE.getName())
  309. return StringRef(AE.NegFeature);
  310. }
  311. }
  312. for (const auto AE : ARCHExtNames) {
  313. if (AE.Feature && ArchExt == AE.getName())
  314. return StringRef(AE.Feature);
  315. }
  316. return StringRef();
  317. }
  318. StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
  319. for (const auto D : HWDivNames) {
  320. if (HWDivKind == D.ID)
  321. return D.getName();
  322. }
  323. return StringRef();
  324. }
  325. StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
  326. ArchKind AK = parseArch(Arch);
  327. if (AK == ARM::ArchKind::INVALID)
  328. return StringRef();
  329. // Look for multiple AKs to find the default for pair AK+Name.
  330. for (const auto CPU : CPUNames) {
  331. if (CPU.ArchID == AK && CPU.Default)
  332. return CPU.getName();
  333. }
  334. // If we can't find a default then target the architecture instead
  335. return "generic";
  336. }
  337. StringRef llvm::AArch64::getFPUName(unsigned FPUKind) {
  338. return ARM::getFPUName(FPUKind);
  339. }
  340. ARM::FPUVersion AArch64::getFPUVersion(unsigned FPUKind) {
  341. return ARM::getFPUVersion(FPUKind);
  342. }
  343. ARM::NeonSupportLevel AArch64::getFPUNeonSupportLevel(unsigned FPUKind) {
  344. return ARM::getFPUNeonSupportLevel( FPUKind);
  345. }
  346. ARM::FPURestriction AArch64::getFPURestriction(unsigned FPUKind) {
  347. return ARM::getFPURestriction(FPUKind);
  348. }
  349. unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, ArchKind AK) {
  350. if (CPU == "generic")
  351. return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
  352. return StringSwitch<unsigned>(CPU)
  353. #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
  354. .Case(NAME, DEFAULT_FPU)
  355. #include "llvm/Support/AArch64TargetParser.def"
  356. .Default(ARM::FK_INVALID);
  357. }
  358. unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, ArchKind AK) {
  359. if (CPU == "generic")
  360. return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
  361. return StringSwitch<unsigned>(CPU)
  362. #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
  363. .Case(NAME, \
  364. AArch64ARCHNames[static_cast<unsigned>(AArch64::ArchKind::ID)] \
  365. .ArchBaseExtensions | \
  366. DEFAULT_EXT)
  367. #include "llvm/Support/AArch64TargetParser.def"
  368. .Default(AArch64::AEK_INVALID);
  369. }
  370. bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
  371. std::vector<StringRef> &Features) {
  372. if (Extensions == AArch64::AEK_INVALID)
  373. return false;
  374. if (Extensions & AArch64::AEK_FP)
  375. Features.push_back("+fp-armv8");
  376. if (Extensions & AArch64::AEK_SIMD)
  377. Features.push_back("+neon");
  378. if (Extensions & AArch64::AEK_CRC)
  379. Features.push_back("+crc");
  380. if (Extensions & AArch64::AEK_CRYPTO)
  381. Features.push_back("+crypto");
  382. if (Extensions & AArch64::AEK_DOTPROD)
  383. Features.push_back("+dotprod");
  384. if (Extensions & AArch64::AEK_FP16)
  385. Features.push_back("+fullfp16");
  386. if (Extensions & AArch64::AEK_PROFILE)
  387. Features.push_back("+spe");
  388. if (Extensions & AArch64::AEK_RAS)
  389. Features.push_back("+ras");
  390. if (Extensions & AArch64::AEK_LSE)
  391. Features.push_back("+lse");
  392. if (Extensions & AArch64::AEK_RDM)
  393. Features.push_back("+rdm");
  394. if (Extensions & AArch64::AEK_SVE)
  395. Features.push_back("+sve");
  396. if (Extensions & AArch64::AEK_RCPC)
  397. Features.push_back("+rcpc");
  398. return true;
  399. }
  400. bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
  401. std::vector<StringRef> &Features) {
  402. return ARM::getFPUFeatures(FPUKind, Features);
  403. }
  404. bool llvm::AArch64::getArchFeatures(AArch64::ArchKind AK,
  405. std::vector<StringRef> &Features) {
  406. if (AK == AArch64::ArchKind::ARMV8_1A)
  407. Features.push_back("+v8.1a");
  408. if (AK == AArch64::ArchKind::ARMV8_2A)
  409. Features.push_back("+v8.2a");
  410. if (AK == AArch64::ArchKind::ARMV8_3A)
  411. Features.push_back("+v8.3a");
  412. return AK != AArch64::ArchKind::INVALID;
  413. }
  414. StringRef llvm::AArch64::getArchName(ArchKind AK) {
  415. return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
  416. }
  417. StringRef llvm::AArch64::getCPUAttr(ArchKind AK) {
  418. return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
  419. }
  420. StringRef llvm::AArch64::getSubArch(ArchKind AK) {
  421. return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
  422. }
  423. unsigned llvm::AArch64::getArchAttr(ArchKind AK) {
  424. return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
  425. }
  426. StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
  427. for (const auto &AE : AArch64ARCHExtNames)
  428. if (ArchExtKind == AE.ID)
  429. return AE.getName();
  430. return StringRef();
  431. }
  432. StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
  433. if (ArchExt.startswith("no")) {
  434. StringRef ArchExtBase(ArchExt.substr(2));
  435. for (const auto &AE : AArch64ARCHExtNames) {
  436. if (AE.NegFeature && ArchExtBase == AE.getName())
  437. return StringRef(AE.NegFeature);
  438. }
  439. }
  440. for (const auto &AE : AArch64ARCHExtNames)
  441. if (AE.Feature && ArchExt == AE.getName())
  442. return StringRef(AE.Feature);
  443. return StringRef();
  444. }
  445. StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
  446. AArch64::ArchKind AK = parseArch(Arch);
  447. if (AK == ArchKind::INVALID)
  448. return StringRef();
  449. // Look for multiple AKs to find the default for pair AK+Name.
  450. for (const auto &CPU : AArch64CPUNames)
  451. if (CPU.ArchID == AK && CPU.Default)
  452. return CPU.getName();
  453. // If we can't find a default then target the architecture instead
  454. return "generic";
  455. }
  456. unsigned llvm::AArch64::checkArchVersion(StringRef Arch) {
  457. if (Arch[0] == 'v' && std::isdigit(Arch[1]))
  458. return (Arch[1] - 48);
  459. return 0;
  460. }
  461. // ======================================================= //
  462. // Parsers
  463. // ======================================================= //
  464. static StringRef getHWDivSynonym(StringRef HWDiv) {
  465. return StringSwitch<StringRef>(HWDiv)
  466. .Case("thumb,arm", "arm,thumb")
  467. .Default(HWDiv);
  468. }
  469. static StringRef getFPUSynonym(StringRef FPU) {
  470. return StringSwitch<StringRef>(FPU)
  471. .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
  472. .Case("vfp2", "vfpv2")
  473. .Case("vfp3", "vfpv3")
  474. .Case("vfp4", "vfpv4")
  475. .Case("vfp3-d16", "vfpv3-d16")
  476. .Case("vfp4-d16", "vfpv4-d16")
  477. .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
  478. .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
  479. .Case("fp5-sp-d16", "fpv5-sp-d16")
  480. .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
  481. // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
  482. .Case("neon-vfpv3", "neon")
  483. .Default(FPU);
  484. }
  485. static StringRef getArchSynonym(StringRef Arch) {
  486. return StringSwitch<StringRef>(Arch)
  487. .Case("v5", "v5t")
  488. .Case("v5e", "v5te")
  489. .Case("v6j", "v6")
  490. .Case("v6hl", "v6k")
  491. .Cases("v6m", "v6sm", "v6s-m", "v6-m")
  492. .Cases("v6z", "v6zk", "v6kz")
  493. .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
  494. .Case("v7r", "v7-r")
  495. .Case("v7m", "v7-m")
  496. .Case("v7em", "v7e-m")
  497. .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
  498. .Case("v8.1a", "v8.1-a")
  499. .Case("v8.2a", "v8.2-a")
  500. .Case("v8.3a", "v8.3-a")
  501. .Case("v8r", "v8-r")
  502. .Case("v8m.base", "v8-m.base")
  503. .Case("v8m.main", "v8-m.main")
  504. .Default(Arch);
  505. }
  506. // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
  507. // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
  508. // "v.+", if the latter, return unmodified string, minus 'eb'.
  509. // If invalid, return empty string.
  510. StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
  511. size_t offset = StringRef::npos;
  512. StringRef A = Arch;
  513. StringRef Error = "";
  514. // Begins with "arm" / "thumb", move past it.
  515. if (A.startswith("arm64"))
  516. offset = 5;
  517. else if (A.startswith("arm"))
  518. offset = 3;
  519. else if (A.startswith("thumb"))
  520. offset = 5;
  521. else if (A.startswith("aarch64")) {
  522. offset = 7;
  523. // AArch64 uses "_be", not "eb" suffix.
  524. if (A.find("eb") != StringRef::npos)
  525. return Error;
  526. if (A.substr(offset, 3) == "_be")
  527. offset += 3;
  528. }
  529. // Ex. "armebv7", move past the "eb".
  530. if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
  531. offset += 2;
  532. // Or, if it ends with eb ("armv7eb"), chop it off.
  533. else if (A.endswith("eb"))
  534. A = A.substr(0, A.size() - 2);
  535. // Trim the head
  536. if (offset != StringRef::npos)
  537. A = A.substr(offset);
  538. // Empty string means offset reached the end, which means it's valid.
  539. if (A.empty())
  540. return Arch;
  541. // Only match non-marketing names
  542. if (offset != StringRef::npos) {
  543. // Must start with 'vN'.
  544. if (A[0] != 'v' || !std::isdigit(A[1]))
  545. return Error;
  546. // Can't have an extra 'eb'.
  547. if (A.find("eb") != StringRef::npos)
  548. return Error;
  549. }
  550. // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
  551. return A;
  552. }
  553. unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
  554. StringRef Syn = getHWDivSynonym(HWDiv);
  555. for (const auto D : HWDivNames) {
  556. if (Syn == D.getName())
  557. return D.ID;
  558. }
  559. return ARM::AEK_INVALID;
  560. }
  561. unsigned llvm::ARM::parseFPU(StringRef FPU) {
  562. StringRef Syn = getFPUSynonym(FPU);
  563. for (const auto F : FPUNames) {
  564. if (Syn == F.getName())
  565. return F.ID;
  566. }
  567. return ARM::FK_INVALID;
  568. }
  569. // Allows partial match, ex. "v7a" matches "armv7a".
  570. ARM::ArchKind ARM::parseArch(StringRef Arch) {
  571. Arch = getCanonicalArchName(Arch);
  572. StringRef Syn = getArchSynonym(Arch);
  573. for (const auto A : ARCHNames) {
  574. if (A.getName().endswith(Syn))
  575. return A.ID;
  576. }
  577. return ARM::ArchKind::INVALID;
  578. }
  579. unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
  580. for (const auto A : ARCHExtNames) {
  581. if (ArchExt == A.getName())
  582. return A.ID;
  583. }
  584. return ARM::AEK_INVALID;
  585. }
  586. ARM::ArchKind llvm::ARM::parseCPUArch(StringRef CPU) {
  587. for (const auto C : CPUNames) {
  588. if (CPU == C.getName())
  589. return C.ArchID;
  590. }
  591. return ARM::ArchKind::INVALID;
  592. }
  593. // ARM, Thumb, AArch64
  594. ARM::ISAKind ARM::parseArchISA(StringRef Arch) {
  595. return StringSwitch<ARM::ISAKind>(Arch)
  596. .StartsWith("aarch64", ARM::ISAKind::AARCH64)
  597. .StartsWith("arm64", ARM::ISAKind::AARCH64)
  598. .StartsWith("thumb", ARM::ISAKind::THUMB)
  599. .StartsWith("arm", ARM::ISAKind::ARM)
  600. .Default(ARM::ISAKind::INVALID);
  601. }
  602. // Little/Big endian
  603. ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
  604. if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
  605. Arch.startswith("aarch64_be"))
  606. return ARM::EndianKind::BIG;
  607. if (Arch.startswith("arm") || Arch.startswith("thumb")) {
  608. if (Arch.endswith("eb"))
  609. return ARM::EndianKind::BIG;
  610. else
  611. return ARM::EndianKind::LITTLE;
  612. }
  613. if (Arch.startswith("aarch64"))
  614. return ARM::EndianKind::LITTLE;
  615. return ARM::EndianKind::INVALID;
  616. }
  617. // Profile A/R/M
  618. ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
  619. Arch = getCanonicalArchName(Arch);
  620. switch (parseArch(Arch)) {
  621. case ARM::ArchKind::ARMV6M:
  622. case ARM::ArchKind::ARMV7M:
  623. case ARM::ArchKind::ARMV7EM:
  624. case ARM::ArchKind::ARMV8MMainline:
  625. case ARM::ArchKind::ARMV8MBaseline:
  626. return ARM::ProfileKind::M;
  627. case ARM::ArchKind::ARMV7R:
  628. case ARM::ArchKind::ARMV8R:
  629. return ARM::ProfileKind::R;
  630. case ARM::ArchKind::ARMV7A:
  631. case ARM::ArchKind::ARMV7VE:
  632. case ARM::ArchKind::ARMV7K:
  633. case ARM::ArchKind::ARMV8A:
  634. case ARM::ArchKind::ARMV8_1A:
  635. case ARM::ArchKind::ARMV8_2A:
  636. case ARM::ArchKind::ARMV8_3A:
  637. return ARM::ProfileKind::A;
  638. case ARM::ArchKind::ARMV2:
  639. case ARM::ArchKind::ARMV2A:
  640. case ARM::ArchKind::ARMV3:
  641. case ARM::ArchKind::ARMV3M:
  642. case ARM::ArchKind::ARMV4:
  643. case ARM::ArchKind::ARMV4T:
  644. case ARM::ArchKind::ARMV5T:
  645. case ARM::ArchKind::ARMV5TE:
  646. case ARM::ArchKind::ARMV5TEJ:
  647. case ARM::ArchKind::ARMV6:
  648. case ARM::ArchKind::ARMV6K:
  649. case ARM::ArchKind::ARMV6T2:
  650. case ARM::ArchKind::ARMV6KZ:
  651. case ARM::ArchKind::ARMV7S:
  652. case ARM::ArchKind::IWMMXT:
  653. case ARM::ArchKind::IWMMXT2:
  654. case ARM::ArchKind::XSCALE:
  655. case ARM::ArchKind::INVALID:
  656. return ARM::ProfileKind::INVALID;
  657. }
  658. llvm_unreachable("Unhandled architecture");
  659. }
  660. // Version number (ex. v7 = 7).
  661. unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
  662. Arch = getCanonicalArchName(Arch);
  663. switch (parseArch(Arch)) {
  664. case ARM::ArchKind::ARMV2:
  665. case ARM::ArchKind::ARMV2A:
  666. return 2;
  667. case ARM::ArchKind::ARMV3:
  668. case ARM::ArchKind::ARMV3M:
  669. return 3;
  670. case ARM::ArchKind::ARMV4:
  671. case ARM::ArchKind::ARMV4T:
  672. return 4;
  673. case ARM::ArchKind::ARMV5T:
  674. case ARM::ArchKind::ARMV5TE:
  675. case ARM::ArchKind::IWMMXT:
  676. case ARM::ArchKind::IWMMXT2:
  677. case ARM::ArchKind::XSCALE:
  678. case ARM::ArchKind::ARMV5TEJ:
  679. return 5;
  680. case ARM::ArchKind::ARMV6:
  681. case ARM::ArchKind::ARMV6K:
  682. case ARM::ArchKind::ARMV6T2:
  683. case ARM::ArchKind::ARMV6KZ:
  684. case ARM::ArchKind::ARMV6M:
  685. return 6;
  686. case ARM::ArchKind::ARMV7A:
  687. case ARM::ArchKind::ARMV7VE:
  688. case ARM::ArchKind::ARMV7R:
  689. case ARM::ArchKind::ARMV7M:
  690. case ARM::ArchKind::ARMV7S:
  691. case ARM::ArchKind::ARMV7EM:
  692. case ARM::ArchKind::ARMV7K:
  693. return 7;
  694. case ARM::ArchKind::ARMV8A:
  695. case ARM::ArchKind::ARMV8_1A:
  696. case ARM::ArchKind::ARMV8_2A:
  697. case ARM::ArchKind::ARMV8_3A:
  698. case ARM::ArchKind::ARMV8R:
  699. case ARM::ArchKind::ARMV8MBaseline:
  700. case ARM::ArchKind::ARMV8MMainline:
  701. return 8;
  702. case ARM::ArchKind::INVALID:
  703. return 0;
  704. }
  705. llvm_unreachable("Unhandled architecture");
  706. }
  707. StringRef llvm::ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
  708. StringRef ArchName =
  709. CPU.empty() ? TT.getArchName() : ARM::getArchName(ARM::parseCPUArch(CPU));
  710. if (TT.isOSBinFormatMachO()) {
  711. if (TT.getEnvironment() == Triple::EABI ||
  712. TT.getOS() == Triple::UnknownOS ||
  713. llvm::ARM::parseArchProfile(ArchName) == ARM::ProfileKind::M)
  714. return "aapcs";
  715. if (TT.isWatchABI())
  716. return "aapcs16";
  717. return "apcs-gnu";
  718. } else if (TT.isOSWindows())
  719. // FIXME: this is invalid for WindowsCE.
  720. return "aapcs";
  721. // Select the default based on the platform.
  722. switch (TT.getEnvironment()) {
  723. case Triple::Android:
  724. case Triple::GNUEABI:
  725. case Triple::GNUEABIHF:
  726. case Triple::MuslEABI:
  727. case Triple::MuslEABIHF:
  728. return "aapcs-linux";
  729. case Triple::EABIHF:
  730. case Triple::EABI:
  731. return "aapcs";
  732. default:
  733. if (TT.isOSNetBSD())
  734. return "apcs-gnu";
  735. if (TT.isOSOpenBSD())
  736. return "aapcs-linux";
  737. return "aapcs";
  738. }
  739. }
  740. StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) {
  741. return ARM::getCanonicalArchName(Arch);
  742. }
  743. unsigned llvm::AArch64::parseFPU(StringRef FPU) {
  744. return ARM::parseFPU(FPU);
  745. }
  746. // Allows partial match, ex. "v8a" matches "armv8a".
  747. AArch64::ArchKind AArch64::parseArch(StringRef Arch) {
  748. Arch = getCanonicalArchName(Arch);
  749. if (checkArchVersion(Arch) < 8)
  750. return ArchKind::INVALID;
  751. StringRef Syn = getArchSynonym(Arch);
  752. for (const auto A : AArch64ARCHNames) {
  753. if (A.getName().endswith(Syn))
  754. return A.ID;
  755. }
  756. return ArchKind::INVALID;
  757. }
  758. unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) {
  759. for (const auto A : AArch64ARCHExtNames) {
  760. if (ArchExt == A.getName())
  761. return A.ID;
  762. }
  763. return AArch64::AEK_INVALID;
  764. }
  765. AArch64::ArchKind llvm::AArch64::parseCPUArch(StringRef CPU) {
  766. for (const auto C : AArch64CPUNames) {
  767. if (CPU == C.getName())
  768. return C.ArchID;
  769. }
  770. return ArchKind::INVALID;
  771. }
  772. // ARM, Thumb, AArch64
  773. ARM::ISAKind AArch64::parseArchISA(StringRef Arch) {
  774. return ARM::parseArchISA(Arch);
  775. }
  776. // Little/Big endian
  777. ARM::EndianKind AArch64::parseArchEndian(StringRef Arch) {
  778. return ARM::parseArchEndian(Arch);
  779. }
  780. // Profile A/R/M
  781. ARM::ProfileKind AArch64::parseArchProfile(StringRef Arch) {
  782. return ARM::parseArchProfile(Arch);
  783. }
  784. // Version number (ex. v8 = 8).
  785. unsigned llvm::AArch64::parseArchVersion(StringRef Arch) {
  786. return ARM::parseArchVersion(Arch);
  787. }