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