AArch64TargetParser.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- AArch64TargetParser - Parser for AArch64 features -------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file implements a target parser to recognise AArch64 hardware features
  15. // such as FPU/CPU/ARCH and extension names.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
  19. #define LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
  20. #include "llvm/ADT/ArrayRef.h"
  21. #include "llvm/ADT/StringRef.h"
  22. #include "llvm/Support/VersionTuple.h"
  23. #include <array>
  24. #include <vector>
  25. namespace llvm {
  26. class Triple;
  27. namespace AArch64 {
  28. enum CPUFeatures {
  29. FEAT_RNG,
  30. FEAT_FLAGM,
  31. FEAT_FLAGM2,
  32. FEAT_FP16FML,
  33. FEAT_DOTPROD,
  34. FEAT_SM4,
  35. FEAT_RDM,
  36. FEAT_LSE,
  37. FEAT_FP,
  38. FEAT_SIMD,
  39. FEAT_CRC,
  40. FEAT_SHA1,
  41. FEAT_SHA2,
  42. FEAT_SHA3,
  43. FEAT_AES,
  44. FEAT_PMULL,
  45. FEAT_FP16,
  46. FEAT_DIT,
  47. FEAT_DPB,
  48. FEAT_DPB2,
  49. FEAT_JSCVT,
  50. FEAT_FCMA,
  51. FEAT_RCPC,
  52. FEAT_RCPC2,
  53. FEAT_FRINTTS,
  54. FEAT_DGH,
  55. FEAT_I8MM,
  56. FEAT_BF16,
  57. FEAT_EBF16,
  58. FEAT_RPRES,
  59. FEAT_SVE,
  60. FEAT_SVE_BF16,
  61. FEAT_SVE_EBF16,
  62. FEAT_SVE_I8MM,
  63. FEAT_SVE_F32MM,
  64. FEAT_SVE_F64MM,
  65. FEAT_SVE2,
  66. FEAT_SVE_AES,
  67. FEAT_SVE_PMULL128,
  68. FEAT_SVE_BITPERM,
  69. FEAT_SVE_SHA3,
  70. FEAT_SVE_SM4,
  71. FEAT_SME,
  72. FEAT_MEMTAG,
  73. FEAT_MEMTAG2,
  74. FEAT_MEMTAG3,
  75. FEAT_SB,
  76. FEAT_PREDRES,
  77. FEAT_SSBS,
  78. FEAT_SSBS2,
  79. FEAT_BTI,
  80. FEAT_LS64,
  81. FEAT_LS64_V,
  82. FEAT_LS64_ACCDATA,
  83. FEAT_WFXT,
  84. FEAT_SME_F64,
  85. FEAT_SME_I64,
  86. FEAT_SME2,
  87. FEAT_MAX
  88. };
  89. // Arch extension modifiers for CPUs. These are labelled with their Arm ARM
  90. // feature name (though the canonical reference for those is AArch64.td)
  91. // clang-format off
  92. enum ArchExtKind : uint64_t {
  93. AEK_INVALID = 0,
  94. AEK_NONE = 1,
  95. AEK_CRC = 1 << 1, // FEAT_CRC32
  96. AEK_CRYPTO = 1 << 2,
  97. AEK_FP = 1 << 3, // FEAT_FP
  98. AEK_SIMD = 1 << 4, // FEAT_AdvSIMD
  99. AEK_FP16 = 1 << 5, // FEAT_FP16
  100. AEK_PROFILE = 1 << 6, // FEAT_SPE
  101. AEK_RAS = 1 << 7, // FEAT_RAS, FEAT_RASv1p1
  102. AEK_LSE = 1 << 8, // FEAT_LSE
  103. AEK_SVE = 1 << 9, // FEAT_SVE
  104. AEK_DOTPROD = 1 << 10, // FEAT_DotProd
  105. AEK_RCPC = 1 << 11, // FEAT_LRCPC
  106. AEK_RDM = 1 << 12, // FEAT_RDM
  107. AEK_SM4 = 1 << 13, // FEAT_SM4, FEAT_SM3
  108. AEK_SHA3 = 1 << 14, // FEAT_SHA3, FEAT_SHA512
  109. AEK_SHA2 = 1 << 15, // FEAT_SHA1, FEAT_SHA256
  110. AEK_AES = 1 << 16, // FEAT_AES, FEAT_PMULL
  111. AEK_FP16FML = 1 << 17, // FEAT_FHM
  112. AEK_RAND = 1 << 18, // FEAT_RNG
  113. AEK_MTE = 1 << 19, // FEAT_MTE, FEAT_MTE2
  114. AEK_SSBS = 1 << 20, // FEAT_SSBS, FEAT_SSBS2
  115. AEK_SB = 1 << 21, // FEAT_SB
  116. AEK_PREDRES = 1 << 22, // FEAT_SPECRES
  117. AEK_SVE2 = 1 << 23, // FEAT_SVE2
  118. AEK_SVE2AES = 1 << 24, // FEAT_SVE_AES, FEAT_SVE_PMULL128
  119. AEK_SVE2SM4 = 1 << 25, // FEAT_SVE_SM4
  120. AEK_SVE2SHA3 = 1 << 26, // FEAT_SVE_SHA3
  121. AEK_SVE2BITPERM = 1 << 27, // FEAT_SVE_BitPerm
  122. AEK_TME = 1 << 28, // FEAT_TME
  123. AEK_BF16 = 1 << 29, // FEAT_BF16
  124. AEK_I8MM = 1 << 30, // FEAT_I8MM
  125. AEK_F32MM = 1ULL << 31, // FEAT_F32MM
  126. AEK_F64MM = 1ULL << 32, // FEAT_F64MM
  127. AEK_LS64 = 1ULL << 33, // FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA
  128. AEK_BRBE = 1ULL << 34, // FEAT_BRBE
  129. AEK_PAUTH = 1ULL << 35, // FEAT_PAuth
  130. AEK_FLAGM = 1ULL << 36, // FEAT_FlagM
  131. AEK_SME = 1ULL << 37, // FEAT_SME
  132. AEK_SMEF64F64 = 1ULL << 38, // FEAT_SME_F64F64
  133. AEK_SMEI16I64 = 1ULL << 39, // FEAT_SME_I16I64
  134. AEK_HBC = 1ULL << 40, // FEAT_HBC
  135. AEK_MOPS = 1ULL << 41, // FEAT_MOPS
  136. AEK_PERFMON = 1ULL << 42, // FEAT_PMUv3
  137. AEK_SME2 = 1ULL << 43, // FEAT_SME2
  138. AEK_SVE2p1 = 1ULL << 44, // FEAT_SVE2p1
  139. AEK_SME2p1 = 1ULL << 45, // FEAT_SME2p1
  140. AEK_B16B16 = 1ULL << 46, // FEAT_B16B16
  141. AEK_SMEF16F16 = 1ULL << 47, // FEAT_SMEF16F16
  142. AEK_CSSC = 1ULL << 48, // FEAT_CSSC
  143. AEK_RCPC3 = 1ULL << 49, // FEAT_LRCPC3
  144. AEK_THE = 1ULL << 50, // FEAT_THE
  145. AEK_D128 = 1ULL << 51, // FEAT_D128
  146. AEK_LSE128 = 1ULL << 52, // FEAT_LSE128
  147. AEK_SPECRES2 = 1ULL << 53, // FEAT_SPECRES2
  148. AEK_RASv2 = 1ULL << 54, // FEAT_RASv2
  149. AEK_ITE = 1ULL << 55, // FEAT_ITE
  150. };
  151. // clang-format on
  152. // Represents an extension that can be enabled with -march=<arch>+<extension>.
  153. // Typically these correspond to Arm Architecture extensions, unlike
  154. // SubtargetFeature which may represent either an actual extension or some
  155. // internal LLVM property.
  156. struct ExtensionInfo {
  157. StringRef Name; // Human readable name, e.g. "profile".
  158. ArchExtKind ID; // Corresponding to the ArchExtKind, this extensions
  159. // representation in the bitfield.
  160. StringRef Feature; // -mattr enable string, e.g. "+spe"
  161. StringRef NegFeature; // -mattr disable string, e.g. "-spe"
  162. // FIXME These were added by D127812 FMV support and need documenting:
  163. CPUFeatures CPUFeature; // Bitfield value set in __aarch64_cpu_features
  164. StringRef DependentFeatures;
  165. unsigned FmvPriority;
  166. static constexpr unsigned MaxFMVPriority = 1000;
  167. };
  168. // clang-format off
  169. inline constexpr ExtensionInfo Extensions[] = {
  170. {"aes", AArch64::AEK_AES, "+aes", "-aes", FEAT_AES, "+fp-armv8,+neon", 150},
  171. {"b16b16", AArch64::AEK_B16B16, "+b16b16", "-b16b16", FEAT_MAX, "", 0},
  172. {"bf16", AArch64::AEK_BF16, "+bf16", "-bf16", FEAT_BF16, "+bf16", 280},
  173. {"brbe", AArch64::AEK_BRBE, "+brbe", "-brbe", FEAT_MAX, "", 0},
  174. {"bti", AArch64::AEK_NONE, {}, {}, FEAT_BTI, "+bti", 510},
  175. {"crc", AArch64::AEK_CRC, "+crc", "-crc", FEAT_CRC, "+crc", 110},
  176. {"crypto", AArch64::AEK_CRYPTO, "+crypto", "-crypto", FEAT_MAX, "", 0},
  177. {"cssc", AArch64::AEK_CSSC, "+cssc", "-cssc", FEAT_MAX, "", 0},
  178. {"d128", AArch64::AEK_D128, "+d128", "-d128", FEAT_MAX, "", 0},
  179. {"dgh", AArch64::AEK_NONE, {}, {}, FEAT_DGH, "", 260},
  180. {"dit", AArch64::AEK_NONE, {}, {}, FEAT_DIT, "+dit", 180},
  181. {"dotprod", AArch64::AEK_DOTPROD, "+dotprod", "-dotprod", FEAT_DOTPROD, "+dotprod,+fp-armv8,+neon", 50},
  182. {"dpb", AArch64::AEK_NONE, {}, {}, FEAT_DPB, "+ccpp", 190},
  183. {"dpb2", AArch64::AEK_NONE, {}, {}, FEAT_DPB2, "+ccpp,+ccdp", 200},
  184. {"ebf16", AArch64::AEK_NONE, {}, {}, FEAT_EBF16, "+bf16", 290},
  185. {"f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm", FEAT_SVE_F32MM, "+sve,+f32mm,+fullfp16,+fp-armv8,+neon", 350},
  186. {"f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm", FEAT_SVE_F64MM, "+sve,+f64mm,+fullfp16,+fp-armv8,+neon", 360},
  187. {"fcma", AArch64::AEK_NONE, {}, {}, FEAT_FCMA, "+fp-armv8,+neon,+complxnum", 220},
  188. {"flagm", AArch64::AEK_FLAGM, "+flagm", "-flagm", FEAT_FLAGM, "+flagm", 20},
  189. {"flagm2", AArch64::AEK_NONE, {}, {}, FEAT_FLAGM2, "+flagm,+altnzcv", 30},
  190. {"fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8", FEAT_FP, "+fp-armv8,+neon", 90},
  191. {"fp16", AArch64::AEK_FP16, "+fullfp16", "-fullfp16", FEAT_FP16, "+fullfp16,+fp-armv8,+neon", 170},
  192. {"fp16fml", AArch64::AEK_FP16FML, "+fp16fml", "-fp16fml", FEAT_FP16FML, "+fp16fml,+fullfp16,+fp-armv8,+neon", 40},
  193. {"frintts", AArch64::AEK_NONE, {}, {}, FEAT_FRINTTS, "+fptoint", 250},
  194. {"hbc", AArch64::AEK_HBC, "+hbc", "-hbc", FEAT_MAX, "", 0},
  195. {"i8mm", AArch64::AEK_I8MM, "+i8mm", "-i8mm", FEAT_I8MM, "+i8mm", 270},
  196. {"ite", AArch64::AEK_ITE, "+ite", "-ite", FEAT_MAX, "", 0},
  197. {"jscvt", AArch64::AEK_NONE, {}, {}, FEAT_JSCVT, "+fp-armv8,+neon,+jsconv", 210},
  198. {"ls64_accdata", AArch64::AEK_NONE, {}, {}, FEAT_LS64_ACCDATA, "+ls64", 540},
  199. {"ls64_v", AArch64::AEK_NONE, {}, {}, FEAT_LS64_V, "", 530},
  200. {"ls64", AArch64::AEK_LS64, "+ls64", "-ls64", FEAT_LS64, "", 520},
  201. {"lse", AArch64::AEK_LSE, "+lse", "-lse", FEAT_LSE, "+lse", 80},
  202. {"lse128", AArch64::AEK_LSE128, "+lse128", "-lse128", FEAT_MAX, "", 0},
  203. {"memtag", AArch64::AEK_MTE, "+mte", "-mte", FEAT_MEMTAG, "", 440},
  204. {"memtag2", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG2, "+mte", 450},
  205. {"memtag3", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG3, "+mte", 460},
  206. {"mops", AArch64::AEK_MOPS, "+mops", "-mops", FEAT_MAX, "", 0},
  207. {"pauth", AArch64::AEK_PAUTH, "+pauth", "-pauth", FEAT_MAX, "", 0},
  208. {"pmull", AArch64::AEK_NONE, {}, {}, FEAT_PMULL, "+aes,+fp-armv8,+neon", 160},
  209. {"pmuv3", AArch64::AEK_PERFMON, "+perfmon", "-perfmon", FEAT_MAX, "", 0},
  210. {"predres", AArch64::AEK_PREDRES, "+predres", "-predres", FEAT_PREDRES, "+predres", 480},
  211. {"predres2", AArch64::AEK_SPECRES2, "+specres2", "-specres2", FEAT_MAX, "", 0},
  212. {"profile", AArch64::AEK_PROFILE, "+spe", "-spe", FEAT_MAX, "", 0},
  213. {"ras", AArch64::AEK_RAS, "+ras", "-ras", FEAT_MAX, "", 0},
  214. {"rasv2", AArch64::AEK_RASv2, "+rasv2", "-rasv2", FEAT_MAX, "", 0},
  215. {"rcpc", AArch64::AEK_RCPC, "+rcpc", "-rcpc", FEAT_RCPC, "+rcpc", 230},
  216. {"rcpc2", AArch64::AEK_NONE, {}, {}, FEAT_RCPC2, "+rcpc", 240},
  217. {"rcpc3", AArch64::AEK_RCPC3, "+rcpc3", "-rcpc3", FEAT_MAX, "", 0},
  218. {"rdm", AArch64::AEK_RDM, "+rdm", "-rdm", FEAT_RDM, "+rdm,+fp-armv8,+neon", 70},
  219. {"rng", AArch64::AEK_RAND, "+rand", "-rand", FEAT_RNG, "+rand", 10},
  220. {"rpres", AArch64::AEK_NONE, {}, {}, FEAT_RPRES, "", 300},
  221. {"sb", AArch64::AEK_SB, "+sb", "-sb", FEAT_SB, "+sb", 470},
  222. {"sha1", AArch64::AEK_NONE, {}, {}, FEAT_SHA1, "+fp-armv8,+neon", 120},
  223. {"sha2", AArch64::AEK_SHA2, "+sha2", "-sha2", FEAT_SHA2, "+sha2,+fp-armv8,+neon", 130},
  224. {"sha3", AArch64::AEK_SHA3, "+sha3", "-sha3", FEAT_SHA3, "+sha3,+sha2,+fp-armv8,+neon", 140},
  225. {"simd", AArch64::AEK_SIMD, "+neon", "-neon", FEAT_SIMD, "+fp-armv8,+neon", 100},
  226. {"sm4", AArch64::AEK_SM4, "+sm4", "-sm4", FEAT_SM4, "+sm4,+fp-armv8,+neon", 60},
  227. {"sme-f16f16", AArch64::AEK_SMEF16F16, "+sme-f16f16", "-sme-f16f16", FEAT_MAX, "", 0},
  228. {"sme-f64f64", AArch64::AEK_SMEF64F64, "+sme-f64f64", "-sme-f64f64", FEAT_SME_F64, "+sme,+sme-f64f64,+bf16", 560},
  229. {"sme-i16i64", AArch64::AEK_SMEI16I64, "+sme-i16i64", "-sme-i16i64", FEAT_SME_I64, "+sme,+sme-i16i64,+bf16", 570},
  230. {"sme", AArch64::AEK_SME, "+sme", "-sme", FEAT_SME, "+sme,+bf16", 430},
  231. {"sme2", AArch64::AEK_SME2, "+sme2", "-sme2", FEAT_SME2, "+sme2,+sme,+bf16", 580},
  232. {"sme2p1", AArch64::AEK_SME2p1, "+sme2p1", "-sme2p1", FEAT_MAX, "", 0},
  233. {"ssbs", AArch64::AEK_SSBS, "+ssbs", "-ssbs", FEAT_SSBS, "", 490},
  234. {"ssbs2", AArch64::AEK_NONE, {}, {}, FEAT_SSBS2, "+ssbs", 500},
  235. {"sve-bf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_BF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320},
  236. {"sve-ebf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_EBF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330},
  237. {"sve-i8mm", AArch64::AEK_NONE, {}, {}, FEAT_SVE_I8MM, "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340},
  238. {"sve", AArch64::AEK_SVE, "+sve", "-sve", FEAT_SVE, "+sve,+fullfp16,+fp-armv8,+neon", 310},
  239. {"sve2-aes", AArch64::AEK_SVE2AES, "+sve2-aes", "-sve2-aes", FEAT_SVE_AES, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 380},
  240. {"sve2-bitperm", AArch64::AEK_SVE2BITPERM, "+sve2-bitperm", "-sve2-bitperm", FEAT_SVE_BITPERM, "+sve2,+sve,+sve2-bitperm,+fullfp16,+fp-armv8,+neon", 400},
  241. {"sve2-pmull128", AArch64::AEK_NONE, {}, {}, FEAT_SVE_PMULL128, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390},
  242. {"sve2-sha3", AArch64::AEK_SVE2SHA3, "+sve2-sha3", "-sve2-sha3", FEAT_SVE_SHA3, "+sve2,+sve,+sve2-sha3,+fullfp16,+fp-armv8,+neon", 410},
  243. {"sve2-sm4", AArch64::AEK_SVE2SM4, "+sve2-sm4", "-sve2-sm4", FEAT_SVE_SM4, "+sve2,+sve,+sve2-sm4,+fullfp16,+fp-armv8,+neon", 420},
  244. {"sve2", AArch64::AEK_SVE2, "+sve2", "-sve2", FEAT_SVE2, "+sve2,+sve,+fullfp16,+fp-armv8,+neon", 370},
  245. {"sve2p1", AArch64::AEK_SVE2p1, "+sve2p1", "-sve2p1", FEAT_MAX, "", 0},
  246. {"the", AArch64::AEK_THE, "+the", "-the", FEAT_MAX, "", 0},
  247. {"tme", AArch64::AEK_TME, "+tme", "-tme", FEAT_MAX, "", 0},
  248. {"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550},
  249. // Special cases
  250. {"none", AArch64::AEK_NONE, {}, {}, FEAT_MAX, "", ExtensionInfo::MaxFMVPriority},
  251. {"invalid", AArch64::AEK_INVALID, {}, {}, FEAT_MAX, "", 0},
  252. };
  253. // clang-format on
  254. enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' };
  255. // Information about a specific architecture, e.g. V8.1-A
  256. struct ArchInfo {
  257. VersionTuple Version; // Architecture version, major + minor.
  258. ArchProfile Profile; // Architecuture profile
  259. StringRef Name; // Human readable name, e.g. "armv8.1-a"
  260. StringRef ArchFeature; // Command line feature flag, e.g. +v8a
  261. uint64_t DefaultExts; // bitfield of default extensions ArchExtKind
  262. bool operator==(const ArchInfo &Other) const {
  263. return this->Name == Other.Name;
  264. }
  265. bool operator!=(const ArchInfo &Other) const {
  266. return this->Name != Other.Name;
  267. }
  268. // Defines the following partial order, indicating when an architecture is
  269. // a superset of another:
  270. //
  271. // v9.4a > v9.3a > v9.3a > v9.3a > v9a;
  272. // v v v v v
  273. // v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a;
  274. //
  275. // v8r and INVALID have no relation to anything. This is used to
  276. // determine which features to enable for a given architecture. See
  277. // AArch64TargetInfo::setFeatureEnabled.
  278. bool implies(const ArchInfo &Other) const {
  279. if (this->Profile != Other.Profile)
  280. return false; // ARMV8R and INVALID
  281. if (this->Version.getMajor() == Other.Version.getMajor()) {
  282. return this->Version > Other.Version;
  283. }
  284. if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) {
  285. return this->Version.getMinor().value() + 5 >=
  286. Other.Version.getMinor().value();
  287. }
  288. return false;
  289. }
  290. // Return ArchFeature without the leading "+".
  291. StringRef getSubArch() const { return ArchFeature.substr(1); }
  292. // Search for ArchInfo by SubArch name
  293. static const ArchInfo &findBySubArch(StringRef SubArch);
  294. };
  295. // clang-format off
  296. inline constexpr ArchInfo INVALID = { VersionTuple{0, 0}, AProfile, "invalid", "+", (AArch64::AEK_NONE)};
  297. inline constexpr ArchInfo ARMV8A = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", (AArch64::AEK_FP | AArch64::AEK_SIMD), };
  298. inline constexpr ArchInfo ARMV8_1A = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts | AArch64::AEK_CRC | AArch64::AEK_LSE | AArch64::AEK_RDM)};
  299. inline constexpr ArchInfo ARMV8_2A = { VersionTuple{8, 2}, AProfile, "armv8.2-a", "+v8.2a", (ARMV8_1A.DefaultExts | AArch64::AEK_RAS)};
  300. inline constexpr ArchInfo ARMV8_3A = { VersionTuple{8, 3}, AProfile, "armv8.3-a", "+v8.3a", (ARMV8_2A.DefaultExts | AArch64::AEK_RCPC)};
  301. inline constexpr ArchInfo ARMV8_4A = { VersionTuple{8, 4}, AProfile, "armv8.4-a", "+v8.4a", (ARMV8_3A.DefaultExts | AArch64::AEK_DOTPROD)};
  302. inline constexpr ArchInfo ARMV8_5A = { VersionTuple{8, 5}, AProfile, "armv8.5-a", "+v8.5a", (ARMV8_4A.DefaultExts)};
  303. inline constexpr ArchInfo ARMV8_6A = { VersionTuple{8, 6}, AProfile, "armv8.6-a", "+v8.6a", (ARMV8_5A.DefaultExts | AArch64::AEK_BF16 | AArch64::AEK_I8MM)};
  304. inline constexpr ArchInfo ARMV8_7A = { VersionTuple{8, 7}, AProfile, "armv8.7-a", "+v8.7a", (ARMV8_6A.DefaultExts)};
  305. inline constexpr ArchInfo ARMV8_8A = { VersionTuple{8, 8}, AProfile, "armv8.8-a", "+v8.8a", (ARMV8_7A.DefaultExts | AArch64::AEK_MOPS | AArch64::AEK_HBC)};
  306. inline constexpr ArchInfo ARMV8_9A = { VersionTuple{8, 9}, AProfile, "armv8.9-a", "+v8.9a", (ARMV8_8A.DefaultExts | AArch64::AEK_SPECRES2 | AArch64::AEK_CSSC | AArch64::AEK_RASv2)};
  307. inline constexpr ArchInfo ARMV9A = { VersionTuple{9, 0}, AProfile, "armv9-a", "+v9a", (ARMV8_5A.DefaultExts | AArch64::AEK_FP16 | AArch64::AEK_SVE | AArch64::AEK_SVE2)};
  308. inline constexpr ArchInfo ARMV9_1A = { VersionTuple{9, 1}, AProfile, "armv9.1-a", "+v9.1a", (ARMV9A.DefaultExts | AArch64::AEK_BF16 | AArch64::AEK_I8MM)};
  309. inline constexpr ArchInfo ARMV9_2A = { VersionTuple{9, 2}, AProfile, "armv9.2-a", "+v9.2a", (ARMV9_1A.DefaultExts)};
  310. inline constexpr ArchInfo ARMV9_3A = { VersionTuple{9, 3}, AProfile, "armv9.3-a", "+v9.3a", (ARMV9_2A.DefaultExts | AArch64::AEK_MOPS | AArch64::AEK_HBC)};
  311. inline constexpr ArchInfo ARMV9_4A = { VersionTuple{9, 4}, AProfile, "armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts | AArch64::AEK_SPECRES2 | AArch64::AEK_CSSC | AArch64::AEK_RASv2)};
  312. // For v8-R, we do not enable crypto and align with GCC that enables a more minimal set of optional architecture extensions.
  313. inline constexpr ArchInfo ARMV8R = { VersionTuple{8, 0}, RProfile, "armv8-r", "+v8r", ((ARMV8_5A.DefaultExts ^ AArch64::AEK_LSE) | AArch64::AEK_SSBS | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SB), };
  314. // clang-format on
  315. // The set of all architectures
  316. static constexpr std::array<const ArchInfo *, 17> ArchInfos = {
  317. &INVALID, &ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A,
  318. &ARMV8_5A, &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A,
  319. &ARMV9_1A, &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV8R,
  320. };
  321. // Details of a specific CPU.
  322. struct CpuInfo {
  323. StringRef Name; // Name, as written for -mcpu.
  324. const ArchInfo &Arch;
  325. uint64_t DefaultExtensions; // Default extensions for this CPU. These will be
  326. // ORd with the architecture defaults.
  327. };
  328. inline constexpr CpuInfo CpuInfos[] = {
  329. {"cortex-a34", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  330. {"cortex-a35", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  331. {"cortex-a53", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  332. {"cortex-a55", ARMV8_2A,
  333. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  334. AArch64::AEK_RCPC)},
  335. {"cortex-a510", ARMV9A,
  336. (AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SB |
  337. AArch64::AEK_PAUTH | AArch64::AEK_MTE | AArch64::AEK_SSBS |
  338. AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
  339. AArch64::AEK_FP16FML)},
  340. {"cortex-a57", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  341. {"cortex-a65", ARMV8_2A,
  342. (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  343. AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  344. {"cortex-a65ae", ARMV8_2A,
  345. (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  346. AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  347. {"cortex-a72", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  348. {"cortex-a73", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  349. {"cortex-a75", ARMV8_2A,
  350. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  351. AArch64::AEK_RCPC)},
  352. {"cortex-a76", ARMV8_2A,
  353. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  354. AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  355. {"cortex-a76ae", ARMV8_2A,
  356. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  357. AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  358. {"cortex-a77", ARMV8_2A,
  359. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_RCPC |
  360. AArch64::AEK_DOTPROD | AArch64::AEK_SSBS)},
  361. {"cortex-a78", ARMV8_2A,
  362. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  363. AArch64::AEK_RCPC | AArch64::AEK_SSBS | AArch64::AEK_PROFILE)},
  364. {"cortex-a78c", ARMV8_2A,
  365. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  366. AArch64::AEK_RCPC | AArch64::AEK_SSBS | AArch64::AEK_PROFILE |
  367. AArch64::AEK_FLAGM | AArch64::AEK_PAUTH | AArch64::AEK_FP16FML)},
  368. {"cortex-a710", ARMV9A,
  369. (AArch64::AEK_MTE | AArch64::AEK_PAUTH | AArch64::AEK_FLAGM |
  370. AArch64::AEK_SB | AArch64::AEK_I8MM | AArch64::AEK_FP16FML |
  371. AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
  372. AArch64::AEK_BF16)},
  373. {"cortex-a715", ARMV9A,
  374. (AArch64::AEK_SB | AArch64::AEK_SSBS | AArch64::AEK_MTE |
  375. AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PAUTH |
  376. AArch64::AEK_I8MM | AArch64::AEK_PREDRES | AArch64::AEK_PERFMON |
  377. AArch64::AEK_PROFILE | AArch64::AEK_SVE | AArch64::AEK_SVE2BITPERM |
  378. AArch64::AEK_BF16 | AArch64::AEK_FLAGM)},
  379. {"cortex-r82", ARMV8R, (AArch64::AEK_LSE)},
  380. {"cortex-x1", ARMV8_2A,
  381. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  382. AArch64::AEK_RCPC | AArch64::AEK_SSBS | AArch64::AEK_PROFILE)},
  383. {"cortex-x1c", ARMV8_2A,
  384. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  385. AArch64::AEK_RCPC | AArch64::AEK_SSBS | AArch64::AEK_PAUTH |
  386. AArch64::AEK_PROFILE)},
  387. {"cortex-x2", ARMV9A,
  388. (AArch64::AEK_MTE | AArch64::AEK_BF16 | AArch64::AEK_I8MM |
  389. AArch64::AEK_PAUTH | AArch64::AEK_SSBS | AArch64::AEK_SB |
  390. AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
  391. AArch64::AEK_FP16FML)},
  392. {"cortex-x3", ARMV9A,
  393. (AArch64::AEK_SVE | AArch64::AEK_PERFMON | AArch64::AEK_PROFILE |
  394. AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_MTE |
  395. AArch64::AEK_SVE2BITPERM | AArch64::AEK_SB | AArch64::AEK_PAUTH |
  396. AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PREDRES |
  397. AArch64::AEK_FLAGM | AArch64::AEK_SSBS)},
  398. {"neoverse-e1", ARMV8_2A,
  399. (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  400. AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  401. {"neoverse-n1", ARMV8_2A,
  402. (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  403. AArch64::AEK_PROFILE | AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  404. {"neoverse-n2", ARMV8_5A,
  405. (AArch64::AEK_CRYPTO | AArch64::AEK_BF16 | AArch64::AEK_DOTPROD |
  406. AArch64::AEK_FP16 | AArch64::AEK_I8MM | AArch64::AEK_MTE |
  407. AArch64::AEK_SB | AArch64::AEK_SSBS | AArch64::AEK_SVE |
  408. AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM)},
  409. {"neoverse-512tvb", ARMV8_4A,
  410. (AArch64::AEK_CRYPTO | AArch64::AEK_SVE | AArch64::AEK_SSBS |
  411. AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_DOTPROD |
  412. AArch64::AEK_PROFILE | AArch64::AEK_RAND | AArch64::AEK_FP16FML |
  413. AArch64::AEK_I8MM)},
  414. {"neoverse-v1", ARMV8_4A,
  415. (AArch64::AEK_CRYPTO | AArch64::AEK_SVE | AArch64::AEK_SSBS |
  416. AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_DOTPROD |
  417. AArch64::AEK_PROFILE | AArch64::AEK_RAND | AArch64::AEK_FP16FML |
  418. AArch64::AEK_I8MM)},
  419. {"neoverse-v2", ARMV9A,
  420. (AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SSBS |
  421. AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_RAND |
  422. AArch64::AEK_DOTPROD | AArch64::AEK_PROFILE | AArch64::AEK_SVE2BITPERM |
  423. AArch64::AEK_FP16FML | AArch64::AEK_I8MM | AArch64::AEK_MTE)},
  424. {"cyclone", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_NONE)},
  425. {"apple-a7", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_NONE)},
  426. {"apple-a8", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_NONE)},
  427. {"apple-a9", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_NONE)},
  428. {"apple-a10", ARMV8A,
  429. (AArch64::AEK_CRYPTO | AArch64::AEK_CRC | AArch64::AEK_RDM)},
  430. {"apple-a11", ARMV8_2A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  431. {"apple-a12", ARMV8_3A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  432. {"apple-a13", ARMV8_4A,
  433. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  434. AArch64::AEK_SHA3)},
  435. {"apple-a14", ARMV8_5A,
  436. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  437. AArch64::AEK_SHA3)},
  438. {"apple-a15", ARMV8_5A,
  439. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  440. AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_I8MM)},
  441. {"apple-a16", ARMV8_5A,
  442. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  443. AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_I8MM)},
  444. {"apple-m1", ARMV8_5A,
  445. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  446. AArch64::AEK_SHA3)},
  447. {"apple-m2", ARMV8_5A,
  448. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  449. AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_I8MM)},
  450. {"apple-s4", ARMV8_3A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  451. {"apple-s5", ARMV8_3A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  452. {"exynos-m3", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  453. {"exynos-m4", ARMV8_2A,
  454. (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16)},
  455. {"exynos-m5", ARMV8_2A,
  456. (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16)},
  457. {"falkor", ARMV8A,
  458. (AArch64::AEK_CRYPTO | AArch64::AEK_CRC | AArch64::AEK_RDM)},
  459. {"saphira", ARMV8_3A, (AArch64::AEK_CRYPTO | AArch64::AEK_PROFILE)},
  460. {"kryo", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  461. {"thunderx2t99", ARMV8_1A, (AArch64::AEK_CRYPTO)},
  462. {"thunderx3t110", ARMV8_3A, (AArch64::AEK_CRYPTO)},
  463. {"thunderx", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  464. {"thunderxt88", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  465. {"thunderxt81", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  466. {"thunderxt83", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  467. {"tsv110", ARMV8_2A,
  468. (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  469. AArch64::AEK_FP16FML | AArch64::AEK_PROFILE)},
  470. {"a64fx", ARMV8_2A,
  471. (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_SVE)},
  472. {"carmel", ARMV8_2A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  473. {"ampere1", ARMV8_6A,
  474. (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
  475. AArch64::AEK_FP16 | AArch64::AEK_SB | AArch64::AEK_SSBS |
  476. AArch64::AEK_RAND)},
  477. {"ampere1a", ARMV8_6A,
  478. (AArch64::AEK_FP16 | AArch64::AEK_RAND | AArch64::AEK_SM4 |
  479. AArch64::AEK_SHA3 | AArch64::AEK_SHA2 | AArch64::AEK_AES |
  480. AArch64::AEK_MTE | AArch64::AEK_SB | AArch64::AEK_SSBS)},
  481. // Invalid CPU
  482. {"invalid", INVALID, (AArch64::AEK_INVALID)},
  483. };
  484. // An alias for a CPU.
  485. struct CpuAlias {
  486. StringRef Alias;
  487. StringRef Name;
  488. };
  489. inline constexpr CpuAlias CpuAliases[] = {{"grace", "neoverse-v2"}};
  490. bool getExtensionFeatures(uint64_t Extensions,
  491. std::vector<StringRef> &Features);
  492. StringRef getArchExtFeature(StringRef ArchExt);
  493. StringRef resolveCPUAlias(StringRef CPU);
  494. // Information by Name
  495. uint64_t getDefaultExtensions(StringRef CPU, const ArchInfo &AI);
  496. void getFeatureOption(StringRef Name, std::string &Feature);
  497. const ArchInfo &getArchForCpu(StringRef CPU);
  498. // Parser
  499. const ArchInfo &parseArch(StringRef Arch);
  500. ArchExtKind parseArchExt(StringRef ArchExt);
  501. // Given the name of a CPU or alias, return the correponding CpuInfo.
  502. const CpuInfo &parseCpu(StringRef Name);
  503. // Used by target parser tests
  504. void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values);
  505. bool isX18ReservedByDefault(const Triple &TT);
  506. uint64_t getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs);
  507. } // namespace AArch64
  508. } // namespace llvm
  509. #endif
  510. #ifdef __GNUC__
  511. #pragma GCC diagnostic pop
  512. #endif