• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===----------- TargetParser.cpp - Target Parser -------------------------===//
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 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/Support/ARMBuildAttributes.h"
12 #include "llvm/Support/TargetParser.h"
13 #include "gtest/gtest.h"
14 #include <string>
15 
16 using namespace llvm;
17 
18 namespace {
19 static const unsigned kHWDivKinds[] = {
20 #define ARM_HW_DIV_NAME(NAME, ID) ID,
21 #include "llvm/Support/ARMTargetParser.def"
22 #undef ARM_HW_DIV_NAME
23 };
24 
25 static const unsigned kARMArchExtKinds[] = {
26 #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) ID,
27 #include "llvm/Support/ARMTargetParser.def"
28 #undef ARM_ARCH_EXT_NAME
29 };
30 
31 static const unsigned kAArch64ArchExtKinds[] = {
32 #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) ID,
33 #include "llvm/Support/AArch64TargetParser.def"
34 #undef AARCH64_ARCH_EXT_NAME
35 };
36 
37 template <typename T> struct ArchNames {
38   const char *Name;
39   unsigned DefaultFPU;
40   unsigned ArchBaseExtensions;
41   T ID;
42   ARMBuildAttrs::CPUArch ArchAttr;
43 };
44 ArchNames<AArch64::ArchKind> kAArch64ARCHNames[] = {
45 #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU,        \
46                      ARCH_BASE_EXT)                                            \
47   {NAME, ARM::ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
48 #include "llvm/Support/AArch64TargetParser.def"
49 #undef AARCH64_ARCH
50 };
51 ArchNames<ARM::ArchKind> kARMARCHNames[] = {
52 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU,            \
53                  ARCH_BASE_EXT)                                                \
54   {NAME, ARM::ARCH_FPU, ARCH_BASE_EXT, ARM::ID, ARCH_ATTR},
55 #include "llvm/Support/ARMTargetParser.def"
56 #undef ARM_ARCH
57 };
58 
59 template <typename T> struct CpuNames {
60   const char *Name;
61   T ID;
62   unsigned DefaultFPU;
63   unsigned DefaultExt;
64 };
65 CpuNames<AArch64::ArchKind> kAArch64CPUNames[] = {
66 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)       \
67   {NAME, AArch64::ArchKind::ID, ARM::DEFAULT_FPU, DEFAULT_EXT},
68 #include "llvm/Support/AArch64TargetParser.def"
69 #undef AARCH64_CPU_NAME
70 };
71 CpuNames<ARM::ArchKind> kARMCPUNames[] = {
72 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)           \
73   {NAME, ARM::ID, ARM::DEFAULT_FPU, DEFAULT_EXT},
74 #include "llvm/Support/ARMTargetParser.def"
75 #undef ARM_CPU_NAME
76 };
77 
78 const char *ARMArch[] = {
79     "armv2",        "armv2a",      "armv3",    "armv3m",       "armv4",
80     "armv4t",       "armv5",       "armv5t",   "armv5e",       "armv5te",
81     "armv5tej",     "armv6",       "armv6j",   "armv6k",       "armv6hl",
82     "armv6t2",      "armv6kz",     "armv6z",   "armv6zk",      "armv6-m",
83     "armv6m",       "armv6sm",     "armv6s-m", "armv7-a",      "armv7",
84     "armv7a",       "armv7hl",     "armv7l",   "armv7-r",      "armv7r",
85     "armv7-m",      "armv7m",      "armv7k",   "armv7s",       "armv7e-m",
86     "armv7em",      "armv8-a",     "armv8",    "armv8a",       "armv8.1-a",
87     "armv8.1a",     "armv8.2-a",   "armv8.2a", "armv8-m.base", "armv8m.base",
88     "armv8-m.main", "armv8m.main", "iwmmxt",   "iwmmxt2",      "xscale"};
89 
90 template <typename T, size_t N>
contains(const T (& array)[N],const T element)91 bool contains(const T (&array)[N], const T element) {
92   return std::find(std::begin(array), std::end(array), element) !=
93          std::end(array);
94 }
95 
TEST(TargetParserTest,ARMArchName)96 TEST(TargetParserTest, ARMArchName) {
97   for (ARM::ArchKind AK = static_cast<ARM::ArchKind>(0);
98        AK <= ARM::ArchKind::AK_LAST;
99        AK = static_cast<ARM::ArchKind>(static_cast<unsigned>(AK) + 1))
100     EXPECT_TRUE(AK == ARM::AK_LAST ? ARM::getArchName(AK).empty()
101                                    : !ARM::getArchName(AK).empty());
102 }
103 
TEST(TargetParserTest,ARMCPUAttr)104 TEST(TargetParserTest, ARMCPUAttr) {
105   for (ARM::ArchKind AK = static_cast<ARM::ArchKind>(0);
106        AK <= ARM::ArchKind::AK_LAST;
107        AK = static_cast<ARM::ArchKind>(static_cast<unsigned>(AK) + 1))
108     EXPECT_TRUE((AK == ARM::AK_INVALID || AK == ARM::AK_LAST)
109                     ? ARM::getCPUAttr(AK).empty()
110                     : !ARM::getCPUAttr(AK).empty());
111 }
112 
TEST(TargetParserTest,ARMSubArch)113 TEST(TargetParserTest, ARMSubArch) {
114   for (ARM::ArchKind AK = static_cast<ARM::ArchKind>(0);
115        AK <= ARM::ArchKind::AK_LAST;
116        AK = static_cast<ARM::ArchKind>(static_cast<unsigned>(AK) + 1))
117     EXPECT_TRUE((AK == ARM::AK_INVALID || AK == ARM::AK_IWMMXT ||
118                  AK == ARM::AK_IWMMXT2 || AK == ARM::AK_LAST)
119                     ? ARM::getSubArch(AK).empty()
120                     : !ARM::getSubArch(AK).empty());
121 }
122 
TEST(TargetParserTest,ARMFPUName)123 TEST(TargetParserTest, ARMFPUName) {
124   for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
125        FK <= ARM::FPUKind::FK_LAST;
126        FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
127     EXPECT_TRUE(FK == ARM::FK_LAST ? ARM::getFPUName(FK).empty()
128                                    : !ARM::getFPUName(FK).empty());
129 }
130 
TEST(TargetParserTest,ARMFPUVersion)131 TEST(TargetParserTest, ARMFPUVersion) {
132   for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
133        FK <= ARM::FPUKind::FK_LAST;
134        FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
135     if (FK == ARM::FK_LAST)
136       EXPECT_EQ(0, ARM::getFPUVersion(FK));
137     else
138       EXPECT_LE(0, ARM::getFPUVersion(FK));
139 }
140 
TEST(TargetParserTest,ARMFPUNeonSupportLevel)141 TEST(TargetParserTest, ARMFPUNeonSupportLevel) {
142   for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
143        FK <= ARM::FPUKind::FK_LAST;
144        FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
145     if (FK == ARM::FK_LAST)
146       EXPECT_EQ(0, ARM::getFPUNeonSupportLevel(FK));
147     else
148       EXPECT_LE(0, ARM::getFPUNeonSupportLevel(FK));
149 }
150 
TEST(TargetParserTest,ARMFPURestriction)151 TEST(TargetParserTest, ARMFPURestriction) {
152   for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
153        FK <= ARM::FPUKind::FK_LAST;
154        FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
155     if (FK == ARM::FK_LAST)
156       EXPECT_EQ(0, ARM::getFPURestriction(FK));
157     else
158       EXPECT_LE(0, ARM::getFPURestriction(FK));
159 }
160 
TEST(TargetParserTest,ARMDefaultFPU)161 TEST(TargetParserTest, ARMDefaultFPU) {
162   for (ARM::ArchKind AK = static_cast<ARM::ArchKind>(0);
163        AK < ARM::ArchKind::AK_LAST;
164        AK = static_cast<ARM::ArchKind>(static_cast<unsigned>(AK) + 1))
165     EXPECT_EQ(kARMARCHNames[AK].DefaultFPU,
166               ARM::getDefaultFPU(StringRef("generic"), AK));
167 
168   for (const auto &ARMCPUName : kARMCPUNames)
169     EXPECT_EQ(ARMCPUName.DefaultFPU, ARM::getDefaultFPU(ARMCPUName.Name, 0));
170 }
171 
TEST(TargetParserTest,ARMDefaultExtensions)172 TEST(TargetParserTest, ARMDefaultExtensions) {
173   for (ARM::ArchKind AK = static_cast<ARM::ArchKind>(0);
174        AK < ARM::ArchKind::AK_LAST;
175        AK = static_cast<ARM::ArchKind>(static_cast<unsigned>(AK) + 1))
176     EXPECT_EQ(kARMARCHNames[AK].ArchBaseExtensions,
177               ARM::getDefaultExtensions(StringRef("generic"), AK));
178 
179   for (const auto &ARMCPUName : kARMCPUNames) {
180     unsigned DefaultExt =
181         kARMARCHNames[ARMCPUName.ID].ArchBaseExtensions | ARMCPUName.DefaultExt;
182     EXPECT_EQ(DefaultExt, ARM::getDefaultExtensions(ARMCPUName.Name, 0));
183   }
184 }
185 
TEST(TargetParserTest,ARMExtensionFeatures)186 TEST(TargetParserTest, ARMExtensionFeatures) {
187   std::vector<const char *> Features;
188   unsigned Extensions = ARM::AEK_CRC | ARM::AEK_CRYPTO | ARM::AEK_DSP |
189                         ARM::AEK_HWDIVARM | ARM::AEK_HWDIV | ARM::AEK_MP |
190                         ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_RAS;
191 
192   for (unsigned i = 0; i <= Extensions; i++)
193     EXPECT_TRUE(i == 0 ? !ARM::getExtensionFeatures(i, Features)
194                        : ARM::getExtensionFeatures(i, Features));
195 }
196 
TEST(TargetParserTest,ARMFPUFeatures)197 TEST(TargetParserTest, ARMFPUFeatures) {
198   std::vector<const char *> Features;
199   for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
200        FK <= ARM::FPUKind::FK_LAST;
201        FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
202     EXPECT_TRUE((FK == ARM::FK_INVALID || FK >= ARM::FK_LAST)
203                     ? !ARM::getFPUFeatures(FK, Features)
204                     : ARM::getFPUFeatures(FK, Features));
205 }
206 
TEST(TargetParserTest,ARMArchAttr)207 TEST(TargetParserTest, ARMArchAttr) {
208   for (ARM::ArchKind AK = static_cast<ARM::ArchKind>(0);
209        AK <= ARM::ArchKind::AK_LAST;
210        AK = static_cast<ARM::ArchKind>(static_cast<unsigned>(AK) + 1))
211     EXPECT_TRUE(AK == ARM::AK_LAST
212                     ? (ARMBuildAttrs::CPUArch::Pre_v4 == ARM::getArchAttr(AK))
213                     : (kARMARCHNames[AK].ArchAttr == ARM::getArchAttr(AK)));
214 }
215 
TEST(TargetParserTest,ARMArchExtName)216 TEST(TargetParserTest, ARMArchExtName) {
217   for (ARM::ArchExtKind AEK = static_cast<ARM::ArchExtKind>(0);
218        AEK <= ARM::ArchExtKind::AEK_XSCALE;
219        AEK = static_cast<ARM::ArchExtKind>(static_cast<unsigned>(AEK) + 1))
220     EXPECT_TRUE(contains(kARMArchExtKinds, static_cast<unsigned>(AEK))
221                     ? !ARM::getArchExtName(AEK).empty()
222                     : ARM::getArchExtName(AEK).empty());
223 }
224 
TEST(TargetParserTest,ARMArchExtFeature)225 TEST(TargetParserTest, ARMArchExtFeature) {
226   const char *ArchExt[][4] = {{"crc", "nocrc", "+crc", "-crc"},
227                               {"crypto", "nocrypto", "+crypto", "-crypto"},
228                               {"dsp", "nodsp", "+dsp", "-dsp"},
229                               {"fp", "nofp", nullptr, nullptr},
230                               {"idiv", "noidiv", nullptr, nullptr},
231                               {"mp", "nomp", nullptr, nullptr},
232                               {"simd", "nosimd", nullptr, nullptr},
233                               {"sec", "nosec", nullptr, nullptr},
234                               {"virt", "novirt", nullptr, nullptr},
235                               {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
236                               {"ras", "noras", "+ras", "-ras"},
237                               {"os", "noos", nullptr, nullptr},
238                               {"iwmmxt", "noiwmmxt", nullptr, nullptr},
239                               {"iwmmxt2", "noiwmmxt2", nullptr, nullptr},
240                               {"maverick", "maverick", nullptr, nullptr},
241                               {"xscale", "noxscale", nullptr, nullptr}};
242 
243   for (unsigned i = 0; i < array_lengthof(ArchExt); i++) {
244     EXPECT_EQ(ArchExt[i][2], ARM::getArchExtFeature(ArchExt[i][0]));
245     EXPECT_EQ(ArchExt[i][3], ARM::getArchExtFeature(ArchExt[i][1]));
246   }
247 }
248 
TEST(TargetParserTest,ARMHWDivName)249 TEST(TargetParserTest, ARMHWDivName) {
250   for (ARM::ArchExtKind AEK = static_cast<ARM::ArchExtKind>(0);
251        AEK <= ARM::ArchExtKind::AEK_XSCALE;
252        AEK = static_cast<ARM::ArchExtKind>(static_cast<unsigned>(AEK) + 1))
253     EXPECT_TRUE(contains(kHWDivKinds, static_cast<unsigned>(AEK))
254                     ? !ARM::getHWDivName(AEK).empty()
255                     : ARM::getHWDivName(AEK).empty());
256 }
257 
TEST(TargetParserTest,ARMDefaultCPU)258 TEST(TargetParserTest, ARMDefaultCPU) {
259   for (unsigned i = 0; i < array_lengthof(ARMArch); i++)
260     EXPECT_FALSE(ARM::getDefaultCPU(ARMArch[i]).empty());
261 }
262 
TEST(TargetParserTest,ARMparseHWDiv)263 TEST(TargetParserTest, ARMparseHWDiv) {
264   const char *hwdiv[] = {"thumb", "arm", "arm,thumb", "thumb,arm"};
265 
266   for (unsigned i = 0; i < array_lengthof(hwdiv); i++)
267     EXPECT_NE(ARM::AEK_INVALID, ARM::parseHWDiv((StringRef)hwdiv[i]));
268 }
269 
TEST(TargetParserTest,ARMparseFPU)270 TEST(TargetParserTest, ARMparseFPU) {
271   const char *FPU[] = {"vfp",
272                        "vfpv2",
273                        "vfp2",
274                        "vfpv3",
275                        "vfp3",
276                        "vfpv3-fp16",
277                        "vfpv3-d16",
278                        "vfp3-d16",
279                        "vfpv3-d16-fp16",
280                        "vfpv3xd",
281                        "vfpv3xd-fp16",
282                        "vfpv4",
283                        "vfp4",
284                        "vfpv4-d16",
285                        "vfp4-d16",
286                        "fp4-dp-d16",
287                        "fpv4-dp-d16",
288                        "fpv4-sp-d16",
289                        "fp4-sp-d16",
290                        "vfpv4-sp-d16",
291                        "fpv5-d16",
292                        "fp5-dp-d16",
293                        "fpv5-dp-d16",
294                        "fpv5-sp-d16",
295                        "fp5-sp-d16",
296                        "fp-armv8",
297                        "neon",
298                        "neon-vfpv3",
299                        "neon-fp16",
300                        "neon-vfpv4",
301                        "neon-fp-armv8",
302                        "crypto-neon-fp-armv8",
303                        "softvfp"};
304 
305   for (unsigned i = 0; i < array_lengthof(FPU); i++)
306     EXPECT_NE(ARM::FK_INVALID, ARM::parseFPU((StringRef)FPU[i]));
307 }
308 
TEST(TargetParserTest,ARMparseArch)309 TEST(TargetParserTest, ARMparseArch) {
310   for (unsigned i = 0; i < array_lengthof(ARMArch); i++)
311     EXPECT_NE(ARM::AEK_INVALID, ARM::parseArch(ARMArch[i]));
312 }
313 
TEST(TargetParserTest,ARMparseArchExt)314 TEST(TargetParserTest, ARMparseArchExt) {
315   const char *ArchExt[] = {"none",     "crc",   "crypto", "dsp",    "fp",
316                            "idiv",     "mp",    "simd",   "sec",    "virt",
317                            "fp16",     "ras",   "os",     "iwmmxt", "iwmmxt2",
318                            "maverick", "xscale"};
319 
320   for (unsigned i = 0; i < array_lengthof(ArchExt); i++)
321     EXPECT_NE(ARM::AEK_INVALID, ARM::parseArchExt(ArchExt[i]));
322 }
323 
TEST(TargetParserTest,ARMparseCPUArch)324 TEST(TargetParserTest, ARMparseCPUArch) {
325   const char *CPU[] = {
326       "arm2",          "arm3",          "arm6",        "arm7m",
327       "arm8",          "arm810",        "strongarm",   "strongarm110",
328       "strongarm1100", "strongarm1110", "arm7tdmi",    "arm7tdmi-s",
329       "arm710t",       "arm720t",       "arm9",        "arm9tdmi",
330       "arm920",        "arm920t",       "arm922t",     "arm9312",
331       "arm940t",       "ep9312",        "arm10tdmi",   "arm1020t",
332       "arm9e",         "arm946e-s",     "arm966e-s",   "arm968e-s",
333       "arm10e",        "arm1020e",      "arm1022e",    "arm926ej-s",
334       "arm1136j-s",    "arm1136jf-s",   "arm1136jz-s", "arm1176j-s",
335       "arm1176jz-s",   "mpcore",        "mpcorenovfp", "arm1176jzf-s",
336       "arm1156t2-s",   "arm1156t2f-s",  "cortex-m0",   "cortex-m0plus",
337       "cortex-m1",     "sc000",         "cortex-a5",   "cortex-a7",
338       "cortex-a8",     "cortex-a9",     "cortex-a12",  "cortex-a15",
339       "cortex-a17",    "krait",         "cortex-r4",   "cortex-r4f",
340       "cortex-r5",     "cortex-r7",     "cortex-r8",   "sc300",
341       "cortex-m3",     "cortex-m4",     "cortex-m7",   "cortex-a32",
342       "cortex-a35",    "cortex-a53",    "cortex-a57",  "cortex-a72",
343       "cortex-a73",    "cyclone",       "exynos-m1",   "iwmmxt",
344       "xscale",        "swift"};
345 
346   for (const auto &ARMCPUName : kARMCPUNames)
347     EXPECT_TRUE(contains(CPU, ARMCPUName.Name)
348                     ? (ARM::AK_INVALID != ARM::parseCPUArch(ARMCPUName.Name))
349                     : (ARM::AK_INVALID == ARM::parseCPUArch(ARMCPUName.Name)));
350 }
351 
TEST(TargetParserTest,ARMparseArchEndianAndISA)352 TEST(TargetParserTest, ARMparseArchEndianAndISA) {
353   const char *Arch[] = {
354       "v2",    "v2a",    "v3",    "v3m",  "v4",   "v4t",  "v5",    "v5t",
355       "v5e",   "v5te",   "v5tej", "v6",   "v6j",  "v6k",  "v6hl",  "v6t2",
356       "v6kz",  "v6z",    "v6zk",  "v6-m", "v6m",  "v6sm", "v6s-m", "v7-a",
357       "v7",    "v7a",    "v7hl",  "v7l",  "v7-r", "v7r",  "v7-m",  "v7m",
358       "v7k",   "v7s",    "v7e-m", "v7em", "v8-a", "v8",   "v8a",   "v8.1-a",
359       "v8.1a", "v8.2-a", "v8.2a"};
360 
361   for (unsigned i = 0; i < array_lengthof(Arch); i++) {
362     std::string arm_1 = "armeb" + (std::string)(Arch[i]);
363     std::string arm_2 = "arm" + (std::string)(Arch[i]) + "eb";
364     std::string arm_3 = "arm" + (std::string)(Arch[i]);
365     std::string thumb_1 = "thumbeb" + (std::string)(Arch[i]);
366     std::string thumb_2 = "thumb" + (std::string)(Arch[i]) + "eb";
367     std::string thumb_3 = "thumb" + (std::string)(Arch[i]);
368 
369     EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian(arm_1));
370     EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian(arm_2));
371     EXPECT_EQ(ARM::EK_LITTLE, ARM::parseArchEndian(arm_3));
372 
373     EXPECT_EQ(ARM::IK_ARM, ARM::parseArchISA(arm_1));
374     EXPECT_EQ(ARM::IK_ARM, ARM::parseArchISA(arm_2));
375     EXPECT_EQ(ARM::IK_ARM, ARM::parseArchISA(arm_3));
376     if (i >= 4) {
377       EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian(thumb_1));
378       EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian(thumb_2));
379       EXPECT_EQ(ARM::EK_LITTLE, ARM::parseArchEndian(thumb_3));
380 
381       EXPECT_EQ(ARM::IK_THUMB, ARM::parseArchISA(thumb_1));
382       EXPECT_EQ(ARM::IK_THUMB, ARM::parseArchISA(thumb_2));
383       EXPECT_EQ(ARM::IK_THUMB, ARM::parseArchISA(thumb_3));
384     }
385   }
386 
387   EXPECT_EQ(ARM::EK_LITTLE, ARM::parseArchEndian("aarch64"));
388   EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian("aarch64_be"));
389 
390   EXPECT_EQ(ARM::IK_AARCH64, ARM::parseArchISA("aarch64"));
391   EXPECT_EQ(ARM::IK_AARCH64, ARM::parseArchISA("aarch64_be"));
392   EXPECT_EQ(ARM::IK_AARCH64, ARM::parseArchISA("arm64"));
393   EXPECT_EQ(ARM::IK_AARCH64, ARM::parseArchISA("arm64_be"));
394 }
395 
TEST(TargetParserTest,ARMparseArchProfile)396 TEST(TargetParserTest, ARMparseArchProfile) {
397   for (unsigned i = 0; i < array_lengthof(ARMArch); i++) {
398     switch (ARM::parseArch(ARMArch[i])) {
399     case ARM::AK_ARMV6M:
400     case ARM::AK_ARMV7M:
401     case ARM::AK_ARMV7EM:
402     case ARM::AK_ARMV8MMainline:
403     case ARM::AK_ARMV8MBaseline:
404       EXPECT_EQ(ARM::PK_M, ARM::parseArchProfile(ARMArch[i]));
405       continue;
406     case ARM::AK_ARMV7R:
407       EXPECT_EQ(ARM::PK_R, ARM::parseArchProfile(ARMArch[i]));
408       continue;
409     case ARM::AK_ARMV7A:
410     case ARM::AK_ARMV7K:
411     case ARM::AK_ARMV8A:
412     case ARM::AK_ARMV8_1A:
413     case ARM::AK_ARMV8_2A:
414       EXPECT_EQ(ARM::PK_A, ARM::parseArchProfile(ARMArch[i]));
415       continue;
416     }
417     EXPECT_EQ(ARM::PK_INVALID, ARM::parseArchProfile(ARMArch[i]));
418   }
419 }
420 
TEST(TargetParserTest,ARMparseArchVersion)421 TEST(TargetParserTest, ARMparseArchVersion) {
422   for (unsigned i = 0; i < array_lengthof(ARMArch); i++)
423     if (((std::string)ARMArch[i]).substr(0, 4) == "armv")
424       EXPECT_EQ((ARMArch[i][4] - 48), ARM::parseArchVersion(ARMArch[i]));
425     else
426       EXPECT_EQ(5, ARM::parseArchVersion(ARMArch[i]));
427 }
428 
TEST(TargetParserTest,AArch64DefaultFPU)429 TEST(TargetParserTest, AArch64DefaultFPU) {
430   for (unsigned AK = 0; AK < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
431        AK++)
432     EXPECT_EQ(kAArch64ARCHNames[AK].DefaultFPU,
433               AArch64::getDefaultFPU(StringRef("generic"), AK));
434 
435   for (const auto &AArch64CPUName : kAArch64CPUNames)
436     EXPECT_EQ(AArch64CPUName.DefaultFPU,
437               AArch64::getDefaultFPU(AArch64CPUName.Name,
438                                      static_cast<unsigned>(AArch64CPUName.ID)));
439 }
440 
TEST(TargetParserTest,AArch64DefaultExt)441 TEST(TargetParserTest, AArch64DefaultExt) {
442   for (unsigned AK = 0; AK < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
443        AK++)
444     EXPECT_EQ(kAArch64ARCHNames[AK].ArchBaseExtensions,
445               AArch64::getDefaultExtensions(StringRef("generic"), AK));
446 
447   for (const auto &AArch64CPUName : kAArch64CPUNames)
448     EXPECT_EQ(
449         AArch64CPUName.DefaultExt,
450         AArch64::getDefaultExtensions(
451             AArch64CPUName.Name, static_cast<unsigned>(AArch64CPUName.ID)));
452 }
453 
TEST(TargetParserTest,AArch64ExtensionFeatures)454 TEST(TargetParserTest, AArch64ExtensionFeatures) {
455   std::vector<const char *> Features;
456   unsigned Extensions = AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
457                         AArch64::AEK_FP | AArch64::AEK_SIMD |
458                         AArch64::AEK_FP16 | AArch64::AEK_PROFILE |
459                         AArch64::AEK_RAS;
460 
461   for (unsigned i = 0; i <= Extensions; i++)
462     EXPECT_TRUE(i == 0 ? !AArch64::getExtensionFeatures(i, Features)
463                        : AArch64::getExtensionFeatures(i, Features));
464 }
465 
TEST(TargetParserTest,AArch64ArchFeatures)466 TEST(TargetParserTest, AArch64ArchFeatures) {
467   std::vector<const char *> Features;
468 
469   for (unsigned AK = 0; AK < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
470        AK++)
471     EXPECT_TRUE((AK == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
472                  AK == static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
473                     ? !AArch64::getArchFeatures(AK, Features)
474                     : AArch64::getArchFeatures(AK, Features));
475 }
476 
TEST(TargetParserTest,AArch64ArchName)477 TEST(TargetParserTest, AArch64ArchName) {
478   for (unsigned AK = 0; AK < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
479        AK++)
480     EXPECT_TRUE(AK == static_cast<unsigned>(AArch64::ArchKind::AK_LAST)
481                     ? AArch64::getArchName(AK).empty()
482                     : !AArch64::getArchName(AK).empty());
483 }
484 
TEST(TargetParserTest,AArch64CPUAttr)485 TEST(TargetParserTest, AArch64CPUAttr) {
486   for (unsigned AK = 0; AK < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
487        AK++)
488     EXPECT_TRUE((AK == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
489                  AK == static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
490                     ? AArch64::getCPUAttr(AK).empty()
491                     : !AArch64::getCPUAttr(AK).empty());
492 }
493 
TEST(TargetParserTest,AArch64SubArch)494 TEST(TargetParserTest, AArch64SubArch) {
495   for (unsigned AK = 0; AK < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
496        AK++)
497     EXPECT_TRUE((AK == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
498                  AK == static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
499                     ? AArch64::getSubArch(AK).empty()
500                     : !AArch64::getSubArch(AK).empty());
501 }
502 
TEST(TargetParserTest,AArch64ArchAttr)503 TEST(TargetParserTest, AArch64ArchAttr) {
504   for (unsigned AK = 0; AK < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
505        AK++)
506     EXPECT_TRUE(
507         AK == static_cast<unsigned>(AArch64::ArchKind::AK_LAST)
508             ? (ARMBuildAttrs::CPUArch::v8_A == AArch64::getArchAttr(AK))
509             : (kAArch64ARCHNames[AK].ArchAttr == AArch64::getArchAttr(AK)));
510 }
511 
TEST(TargetParserTest,AArch64ArchExtName)512 TEST(TargetParserTest, AArch64ArchExtName) {
513   for (AArch64::ArchExtKind AEK = static_cast<AArch64::ArchExtKind>(0);
514        AEK <= AArch64::ArchExtKind::AEK_RAS;
515        AEK = static_cast<AArch64::ArchExtKind>(static_cast<unsigned>(AEK) + 1))
516     EXPECT_TRUE(contains(kAArch64ArchExtKinds, static_cast<unsigned>(AEK))
517                     ? !AArch64::getArchExtName(AEK).empty()
518                     : AArch64::getArchExtName(AEK).empty());
519 }
520 
TEST(TargetParserTest,AArch64ArchExtFeature)521 TEST(TargetParserTest, AArch64ArchExtFeature) {
522   const char *ArchExt[][4] = {{"crc", "nocrc", "+crc", "-crc"},
523                               {"crypto", "nocrypto", "+crypto", "-crypto"},
524                               {"fp", "nofp", "+fp-armv8", "-fp-armv8"},
525                               {"simd", "nosimd", "+neon", "-neon"},
526                               {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
527                               {"profile", "noprofile", "+spe", "-spe"},
528                               {"ras", "noras", "+ras", "-ras"}};
529 
530   for (unsigned i = 0; i < array_lengthof(ArchExt); i++) {
531     EXPECT_EQ(ArchExt[i][2], AArch64::getArchExtFeature(ArchExt[i][0]));
532     EXPECT_EQ(ArchExt[i][3], AArch64::getArchExtFeature(ArchExt[i][1]));
533   }
534 }
535 
TEST(TargetParserTest,AArch64DefaultCPU)536 TEST(TargetParserTest, AArch64DefaultCPU) {
537   const char *Arch[] = {"armv8a",    "armv8-a",  "armv8",    "armv8.1a",
538                         "armv8.1-a", "armv8.2a", "armv8.2-a"};
539 
540   for (unsigned i = 0; i < array_lengthof(Arch); i++)
541     EXPECT_FALSE(AArch64::getDefaultCPU(Arch[i]).empty());
542 }
543 
TEST(TargetParserTest,AArch64parseArch)544 TEST(TargetParserTest, AArch64parseArch) {
545   const char *Arch[] = {"armv8",     "armv8a",   "armv8-a",  "armv8.1a",
546                         "armv8.1-a", "armv8.2a", "armv8.2-a"};
547 
548   for (unsigned i = 0; i < array_lengthof(Arch); i++)
549     EXPECT_NE(static_cast<unsigned>(AArch64::ArchKind::AK_INVALID),
550               AArch64::parseArch(Arch[i]));
551   EXPECT_EQ(static_cast<unsigned>(AArch64::ArchKind::AK_INVALID),
552             AArch64::parseArch("aarch64"));
553   EXPECT_EQ(static_cast<unsigned>(AArch64::ArchKind::AK_INVALID),
554             AArch64::parseArch("arm64"));
555 }
556 
TEST(TargetParserTest,AArch64parseArchExt)557 TEST(TargetParserTest, AArch64parseArchExt) {
558   const char *ArchExt[] = {"none", "crc",  "crypto",  "fp",
559                            "simd", "fp16", "profile", "ras"};
560 
561   for (unsigned i = 0; i < array_lengthof(ArchExt); i++)
562     EXPECT_NE(AArch64::AEK_INVALID, AArch64::parseArchExt(ArchExt[i]));
563 }
564 
TEST(TargetParserTest,AArch64parseCPUArch)565 TEST(TargetParserTest, AArch64parseCPUArch) {
566   const char *CPU[] = {"cortex-a35", "cortex-a53", "cortex-a57",
567                        "cortex-a72", "cortex-a73", "cyclone",
568                        "exynos-m1",  "kryo",       "vulcan"};
569 
570   for (const auto &AArch64CPUName : kAArch64CPUNames)
571     EXPECT_TRUE(contains(CPU, AArch64CPUName.Name)
572                     ? (static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) !=
573                        AArch64::parseCPUArch(AArch64CPUName.Name))
574                     : (static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ==
575                        AArch64::parseCPUArch(AArch64CPUName.Name)));
576 }
577 }
578