Home | History | Annotate | Download | only in Support
      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>
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    258 TEST(TargetParserTest, ARMDefaultCPU) {
    259   for (unsigned i = 0; i < array_lengthof(ARMArch); i++)
    260     EXPECT_FALSE(ARM::getDefaultCPU(ARMArch[i]).empty());
    261 }
    262 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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