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