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