ARMTargetParser.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- ARMTargetParser - Parser for ARM target 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 ARM hardware features
  15. // such as FPU/CPU/ARCH/extensions and specific support such as HWDIV.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_SUPPORT_ARMTARGETPARSER_H
  19. #define LLVM_SUPPORT_ARMTARGETPARSER_H
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/Support/ARMBuildAttributes.h"
  22. #include <vector>
  23. namespace llvm {
  24. class Triple;
  25. namespace ARM {
  26. // Arch extension modifiers for CPUs.
  27. // Note that this is not the same as the AArch64 list
  28. enum ArchExtKind : uint64_t {
  29. AEK_INVALID = 0,
  30. AEK_NONE = 1,
  31. AEK_CRC = 1 << 1,
  32. AEK_CRYPTO = 1 << 2,
  33. AEK_FP = 1 << 3,
  34. AEK_HWDIVTHUMB = 1 << 4,
  35. AEK_HWDIVARM = 1 << 5,
  36. AEK_MP = 1 << 6,
  37. AEK_SIMD = 1 << 7,
  38. AEK_SEC = 1 << 8,
  39. AEK_VIRT = 1 << 9,
  40. AEK_DSP = 1 << 10,
  41. AEK_FP16 = 1 << 11,
  42. AEK_RAS = 1 << 12,
  43. AEK_DOTPROD = 1 << 13,
  44. AEK_SHA2 = 1 << 14,
  45. AEK_AES = 1 << 15,
  46. AEK_FP16FML = 1 << 16,
  47. AEK_SB = 1 << 17,
  48. AEK_FP_DP = 1 << 18,
  49. AEK_LOB = 1 << 19,
  50. AEK_BF16 = 1 << 20,
  51. AEK_I8MM = 1 << 21,
  52. AEK_CDECP0 = 1 << 22,
  53. AEK_CDECP1 = 1 << 23,
  54. AEK_CDECP2 = 1 << 24,
  55. AEK_CDECP3 = 1 << 25,
  56. AEK_CDECP4 = 1 << 26,
  57. AEK_CDECP5 = 1 << 27,
  58. AEK_CDECP6 = 1 << 28,
  59. AEK_CDECP7 = 1 << 29,
  60. AEK_PACBTI = 1 << 30,
  61. // Unsupported extensions.
  62. AEK_OS = 1ULL << 59,
  63. AEK_IWMMXT = 1ULL << 60,
  64. AEK_IWMMXT2 = 1ULL << 61,
  65. AEK_MAVERICK = 1ULL << 62,
  66. AEK_XSCALE = 1ULL << 63,
  67. };
  68. // List of Arch Extension names.
  69. // FIXME: TableGen this.
  70. struct ExtName {
  71. const char *NameCStr;
  72. size_t NameLength;
  73. uint64_t ID;
  74. const char *Feature;
  75. const char *NegFeature;
  76. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  77. };
  78. const ExtName ARCHExtNames[] = {
  79. #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
  80. {NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE},
  81. #include "ARMTargetParser.def"
  82. };
  83. // List of HWDiv names (use getHWDivSynonym) and which architectural
  84. // features they correspond to (use getHWDivFeatures).
  85. // FIXME: TableGen this.
  86. const struct {
  87. const char *NameCStr;
  88. size_t NameLength;
  89. uint64_t ID;
  90. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  91. } HWDivNames[] = {
  92. #define ARM_HW_DIV_NAME(NAME, ID) {NAME, sizeof(NAME) - 1, ID},
  93. #include "ARMTargetParser.def"
  94. };
  95. // Arch names.
  96. enum class ArchKind {
  97. #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID,
  98. #include "ARMTargetParser.def"
  99. };
  100. // List of CPU names and their arches.
  101. // The same CPU can have multiple arches and can be default on multiple arches.
  102. // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
  103. // When this becomes table-generated, we'd probably need two tables.
  104. // FIXME: TableGen this.
  105. template <typename T> struct CpuNames {
  106. const char *NameCStr;
  107. size_t NameLength;
  108. T ArchID;
  109. bool Default; // is $Name the default CPU for $ArchID ?
  110. uint64_t DefaultExtensions;
  111. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  112. };
  113. const CpuNames<ArchKind> CPUNames[] = {
  114. #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
  115. {NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT},
  116. #include "ARMTargetParser.def"
  117. };
  118. // FPU names.
  119. enum FPUKind {
  120. #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) KIND,
  121. #include "ARMTargetParser.def"
  122. FK_LAST
  123. };
  124. // FPU Version
  125. enum class FPUVersion {
  126. NONE,
  127. VFPV2,
  128. VFPV3,
  129. VFPV3_FP16,
  130. VFPV4,
  131. VFPV5,
  132. VFPV5_FULLFP16,
  133. };
  134. // An FPU name restricts the FPU in one of three ways:
  135. enum class FPURestriction {
  136. None = 0, ///< No restriction
  137. D16, ///< Only 16 D registers
  138. SP_D16 ///< Only single-precision instructions, with 16 D registers
  139. };
  140. // An FPU name implies one of three levels of Neon support:
  141. enum class NeonSupportLevel {
  142. None = 0, ///< No Neon
  143. Neon, ///< Neon
  144. Crypto ///< Neon with Crypto
  145. };
  146. // ISA kinds.
  147. enum class ISAKind { INVALID = 0, ARM, THUMB, AARCH64 };
  148. // Endianness
  149. // FIXME: BE8 vs. BE32?
  150. enum class EndianKind { INVALID = 0, LITTLE, BIG };
  151. // v6/v7/v8 Profile
  152. enum class ProfileKind { INVALID = 0, A, R, M };
  153. // List of canonical FPU names (use getFPUSynonym) and which architectural
  154. // features they correspond to (use getFPUFeatures).
  155. // FIXME: TableGen this.
  156. // The entries must appear in the order listed in ARM::FPUKind for correct
  157. // indexing
  158. struct FPUName {
  159. const char *NameCStr;
  160. size_t NameLength;
  161. FPUKind ID;
  162. FPUVersion FPUVer;
  163. NeonSupportLevel NeonSupport;
  164. FPURestriction Restriction;
  165. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  166. };
  167. static const FPUName FPUNames[] = {
  168. #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
  169. {NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION},
  170. #include "llvm/Support/ARMTargetParser.def"
  171. };
  172. // List of canonical arch names (use getArchSynonym).
  173. // This table also provides the build attribute fields for CPU arch
  174. // and Arch ID, according to the Addenda to the ARM ABI, chapters
  175. // 2.4 and 2.3.5.2 respectively.
  176. // FIXME: SubArch values were simplified to fit into the expectations
  177. // of the triples and are not conforming with their official names.
  178. // Check to see if the expectation should be changed.
  179. // FIXME: TableGen this.
  180. template <typename T> struct ArchNames {
  181. const char *NameCStr;
  182. size_t NameLength;
  183. const char *CPUAttrCStr;
  184. size_t CPUAttrLength;
  185. const char *SubArchCStr;
  186. size_t SubArchLength;
  187. unsigned DefaultFPU;
  188. uint64_t ArchBaseExtensions;
  189. T ID;
  190. ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
  191. StringRef getName() const { return StringRef(NameCStr, NameLength); }
  192. // CPU class in build attributes.
  193. StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
  194. // Sub-Arch name.
  195. StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
  196. };
  197. static const ArchNames<ArchKind> ARCHNames[] = {
  198. #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, \
  199. ARCH_BASE_EXT) \
  200. {NAME, sizeof(NAME) - 1, \
  201. CPU_ATTR, sizeof(CPU_ATTR) - 1, \
  202. SUB_ARCH, sizeof(SUB_ARCH) - 1, \
  203. ARCH_FPU, ARCH_BASE_EXT, \
  204. ArchKind::ID, ARCH_ATTR},
  205. #include "llvm/Support/ARMTargetParser.def"
  206. };
  207. // Information by ID
  208. StringRef getFPUName(unsigned FPUKind);
  209. FPUVersion getFPUVersion(unsigned FPUKind);
  210. NeonSupportLevel getFPUNeonSupportLevel(unsigned FPUKind);
  211. FPURestriction getFPURestriction(unsigned FPUKind);
  212. // FIXME: These should be moved to TargetTuple once it exists
  213. bool getFPUFeatures(unsigned FPUKind, std::vector<StringRef> &Features);
  214. bool getHWDivFeatures(uint64_t HWDivKind, std::vector<StringRef> &Features);
  215. bool getExtensionFeatures(uint64_t Extensions,
  216. std::vector<StringRef> &Features);
  217. StringRef getArchName(ArchKind AK);
  218. unsigned getArchAttr(ArchKind AK);
  219. StringRef getCPUAttr(ArchKind AK);
  220. StringRef getSubArch(ArchKind AK);
  221. StringRef getArchExtName(uint64_t ArchExtKind);
  222. StringRef getArchExtFeature(StringRef ArchExt);
  223. bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, StringRef ArchExt,
  224. std::vector<StringRef> &Features,
  225. unsigned &ArgFPUKind);
  226. // Information by Name
  227. unsigned getDefaultFPU(StringRef CPU, ArchKind AK);
  228. uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK);
  229. StringRef getDefaultCPU(StringRef Arch);
  230. StringRef getCanonicalArchName(StringRef Arch);
  231. StringRef getFPUSynonym(StringRef FPU);
  232. StringRef getArchSynonym(StringRef Arch);
  233. // Parser
  234. uint64_t parseHWDiv(StringRef HWDiv);
  235. unsigned parseFPU(StringRef FPU);
  236. ArchKind parseArch(StringRef Arch);
  237. uint64_t parseArchExt(StringRef ArchExt);
  238. ArchKind parseCPUArch(StringRef CPU);
  239. ISAKind parseArchISA(StringRef Arch);
  240. EndianKind parseArchEndian(StringRef Arch);
  241. ProfileKind parseArchProfile(StringRef Arch);
  242. unsigned parseArchVersion(StringRef Arch);
  243. void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values);
  244. StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU);
  245. } // namespace ARM
  246. } // namespace llvm
  247. #endif
  248. #ifdef __GNUC__
  249. #pragma GCC diagnostic pop
  250. #endif