2353 lines · cpp
1//===----------- TargetParser.cpp - Target Parser -------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/TargetParser/TargetParser.h"10#include "llvm/ADT/STLExtras.h"11#include "llvm/ADT/StringExtras.h"12#include "llvm/ADT/StringMap.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/Support/ARMBuildAttributes.h"15#include "llvm/Support/Debug.h"16#include "llvm/Support/FormatVariadic.h"17#include "llvm/TargetParser/AArch64TargetParser.h"18#include "llvm/TargetParser/ARMTargetParser.h"19#include "llvm/TargetParser/ARMTargetParserCommon.h"20#include "llvm/TargetParser/Triple.h"21#include "gmock/gmock.h"22#include "gtest/gtest.h"23#include <optional>24#include <sstream>25#include <string>26 27using namespace llvm;28 29using ::testing::Contains;30using ::testing::StrEq;31 32namespace {33const char *ARMArch[] = {34 "armv4", "armv4t", "armv5", "armv5t", "armv5e",35 "armv5te", "armv5tej", "armv6", "armv6j", "armv6k",36 "armv6hl", "armv6t2", "armv6kz", "armv6z", "armv6zk",37 "armv6-m", "armv6m", "armv6sm", "armv6s-m", "armv7-a",38 "armv7", "armv7a", "armv7ve", "armv7hl", "armv7l",39 "armv7-r", "armv7r", "armv7-m", "armv7m", "armv7k",40 "armv7s", "armv7e-m", "armv7em", "armv8-a", "armv8",41 "armv8a", "armv8l", "armv8.1-a", "armv8.1a", "armv8.2-a",42 "armv8.2a", "armv8.3-a", "armv8.3a", "armv8.4-a", "armv8.4a",43 "armv8.5-a", "armv8.5a", "armv8.6-a", "armv8.6a", "armv8.7-a",44 "armv8.7a", "armv8.8-a", "armv8.8a", "armv8.9-a", "armv8.9a",45 "armv8-r", "armv8r", "armv8-m.base", "armv8m.base", "armv8-m.main",46 "armv8m.main", "iwmmxt", "iwmmxt2", "xscale", "armv8.1-m.main",47 "armv9-a", "armv9", "armv9a", "armv9.1-a", "armv9.1a",48 "armv9.2-a", "armv9.2a", "armv9.3-a", "armv9.3a", "armv9.4-a",49 "armv9.4a", "armv9.5-a", "armv9.5a", "armv9.6a", "armv9.6-a",50 "armv9.7a", "armv9.7-a",51};52 53std::string FormatExtensionFlags(int64_t Flags) {54 std::vector<StringRef> Features;55 56 if (Flags & ARM::AEK_NONE)57 Features.push_back("none");58 ARM::getExtensionFeatures(Flags, Features);59 60 // The target parser also includes every extension you don't have.61 // E.g. if AEK_CRC is not set then it adds "-crc". Not useful here.62 llvm::erase_if(63 Features, [](StringRef extension) { return extension.starts_with("-"); });64 65 return llvm::join(Features, ", ");66}67 68std::string SerializeExtensionFlags(AArch64::ExtensionBitset Flags) {69 std::string SerializedFlags;70 std::ostringstream ss;71 int HexValue = 0;72 for (unsigned int i = 0; i < AArch64::AEK_NUM_EXTENSIONS; i++) {73 HexValue <<= 1;74 HexValue |= (int)Flags[i];75 if ((i + 1) % 4 == 0) {76 ss << std::hex << HexValue;77 HexValue = 0;78 }79 }80 // check if there are remainig unhandled bits81 if ((AArch64::AEK_NUM_EXTENSIONS % 4) != 0)82 ss << std::hex << HexValue;83 84 SerializedFlags = ss.str();85 return SerializedFlags;86}87 88template <ARM::ISAKind ISAKind> struct AssertSameExtensionFlags {89 AssertSameExtensionFlags(StringRef CPUName) : CPUName(CPUName) {}90 91 testing::AssertionResult operator()(const char *m_expr, const char *n_expr,92 uint64_t ExpectedFlags,93 uint64_t GotFlags) {94 if (ExpectedFlags == GotFlags)95 return testing::AssertionSuccess();96 97 return testing::AssertionFailure()98 << llvm::formatv("CPU: {4}\n"99 "Expected extension flags: {0} ({1:x})\n"100 " Got extension flags: {2} ({3:x})\n"101 " Diff: {5} ({6:x})\n",102 FormatExtensionFlags(ExpectedFlags), ExpectedFlags,103 FormatExtensionFlags(GotFlags), GotFlags, CPUName,104 FormatExtensionFlags(ExpectedFlags ^ GotFlags));105 }106private:107 StringRef CPUName;108};109 110template <typename T> struct ARMCPUTestParams {111 ARMCPUTestParams(StringRef CPUName, StringRef ExpectedArch,112 StringRef ExpectedFPU, T ExpectedFlags, StringRef CPUAttr)113 : CPUName(CPUName), ExpectedArch(ExpectedArch), ExpectedFPU(ExpectedFPU),114 ExpectedFlags(ExpectedFlags), CPUAttr(CPUAttr) {}115 116 friend std::ostream &operator<<(std::ostream &os,117 const ARMCPUTestParams<T> ¶ms) {118 os << "\"" << params.CPUName.str() << "\", \"" << params.ExpectedArch.str()119 << "\", \"" << params.ExpectedFPU.str() << "\", 0x";120 if constexpr (std::is_same<T, uint64_t>::value)121 os << std::hex << params.ExpectedFlags;122 else123 os << SerializeExtensionFlags(params.ExpectedFlags);124 os << ", \"" << params.CPUAttr.str() << "\"";125 return os;126 }127 128 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name129 /// human-readable.130 ///131 /// https://github.com/google/googletest/blob/main/docs/advanced.md#specifying-names-for-value-parameterized-test-parameters132 static std::string PrintToStringParamName(133 const testing::TestParamInfo<ARMCPUTestParams<T>> &Info) {134 std::string Name = Info.param.CPUName.str();135 for (char &C : Name)136 if (!std::isalnum(C))137 C = '_';138 return Name;139 }140 141 StringRef CPUName;142 StringRef ExpectedArch;143 StringRef ExpectedFPU;144 T ExpectedFlags;145 StringRef CPUAttr;146};147 148class ARMCPUTestFixture149 : public ::testing::TestWithParam<ARMCPUTestParams<uint64_t>> {};150 151TEST_P(ARMCPUTestFixture, ARMCPUTests) {152 auto params = GetParam();153 154 ARM::ArchKind AK = ARM::parseCPUArch(params.CPUName);155 EXPECT_EQ(params.ExpectedArch, ARM::getArchName(AK));156 157 ARM::FPUKind FPUKind = ARM::getDefaultFPU(params.CPUName, AK);158 EXPECT_EQ(params.ExpectedFPU, ARM::getFPUName(FPUKind));159 160 uint64_t default_extensions = ARM::getDefaultExtensions(params.CPUName, AK);161 EXPECT_PRED_FORMAT2(162 AssertSameExtensionFlags<ARM::ISAKind::ARM>(params.CPUName),163 params.ExpectedFlags, default_extensions);164 165 EXPECT_EQ(params.CPUAttr, ARM::getCPUAttr(AK));166}167 168// Note that we include ARM::AEK_NONE even when there are other extensions169// we expect. This is because the default extensions for a CPU are the sum170// of the default extensions for its architecture and for the CPU.171// So if a CPU has no extra extensions, it adds AEK_NONE.172INSTANTIATE_TEST_SUITE_P(173 ARMCPUTestsPart1, ARMCPUTestFixture,174 ::testing::Values(175 ARMCPUTestParams<uint64_t>("invalid", "invalid", "invalid",176 ARM::AEK_NONE, ""),177 ARMCPUTestParams<uint64_t>("generic", "invalid", "none", ARM::AEK_NONE,178 ""),179 180 ARMCPUTestParams<uint64_t>("arm8", "armv4", "none", ARM::AEK_NONE, "4"),181 ARMCPUTestParams<uint64_t>("arm810", "armv4", "none", ARM::AEK_NONE,182 "4"),183 ARMCPUTestParams<uint64_t>("strongarm", "armv4", "none", ARM::AEK_NONE,184 "4"),185 ARMCPUTestParams<uint64_t>("strongarm110", "armv4", "none",186 ARM::AEK_NONE, "4"),187 ARMCPUTestParams<uint64_t>("strongarm1100", "armv4", "none",188 ARM::AEK_NONE, "4"),189 ARMCPUTestParams<uint64_t>("strongarm1110", "armv4", "none",190 ARM::AEK_NONE, "4"),191 ARMCPUTestParams<uint64_t>("arm7tdmi", "armv4t", "none", ARM::AEK_NONE,192 "4T"),193 ARMCPUTestParams<uint64_t>("arm7tdmi-s", "armv4t", "none",194 ARM::AEK_NONE, "4T"),195 ARMCPUTestParams<uint64_t>("arm710t", "armv4t", "none", ARM::AEK_NONE,196 "4T"),197 ARMCPUTestParams<uint64_t>("arm720t", "armv4t", "none", ARM::AEK_NONE,198 "4T"),199 ARMCPUTestParams<uint64_t>("arm9", "armv4t", "none", ARM::AEK_NONE,200 "4T"),201 ARMCPUTestParams<uint64_t>("arm9tdmi", "armv4t", "none", ARM::AEK_NONE,202 "4T"),203 ARMCPUTestParams<uint64_t>("arm920", "armv4t", "none", ARM::AEK_NONE,204 "4T"),205 ARMCPUTestParams<uint64_t>("arm920t", "armv4t", "none", ARM::AEK_NONE,206 "4T"),207 ARMCPUTestParams<uint64_t>("arm922t", "armv4t", "none", ARM::AEK_NONE,208 "4T"),209 ARMCPUTestParams<uint64_t>("arm940t", "armv4t", "none", ARM::AEK_NONE,210 "4T"),211 ARMCPUTestParams<uint64_t>("ep9312", "armv4t", "none", ARM::AEK_NONE,212 "4T"),213 ARMCPUTestParams<uint64_t>("arm10tdmi", "armv5t", "none", ARM::AEK_NONE,214 "5T"),215 ARMCPUTestParams<uint64_t>("arm1020t", "armv5t", "none", ARM::AEK_NONE,216 "5T"),217 ARMCPUTestParams<uint64_t>("arm9e", "armv5te", "none",218 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),219 ARMCPUTestParams<uint64_t>("arm946e-s", "armv5te", "none",220 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),221 ARMCPUTestParams<uint64_t>("arm966e-s", "armv5te", "none",222 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),223 ARMCPUTestParams<uint64_t>("arm968e-s", "armv5te", "none",224 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),225 ARMCPUTestParams<uint64_t>("arm10e", "armv5te", "none",226 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),227 ARMCPUTestParams<uint64_t>("arm1020e", "armv5te", "none",228 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),229 ARMCPUTestParams<uint64_t>("arm1022e", "armv5te", "none",230 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),231 ARMCPUTestParams<uint64_t>("arm926ej-s", "armv5tej", "none",232 ARM::AEK_NONE | ARM::AEK_DSP, "5TEJ"),233 ARMCPUTestParams<uint64_t>("arm1136j-s", "armv6", "none",234 ARM::AEK_NONE | ARM::AEK_DSP, "6"),235 ARMCPUTestParams<uint64_t>("arm1136jf-s", "armv6", "vfpv2",236 ARM::AEK_NONE | ARM::AEK_DSP, "6"),237 ARMCPUTestParams<uint64_t>("arm1176jz-s", "armv6kz", "none",238 ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP,239 "6KZ"),240 ARMCPUTestParams<uint64_t>("mpcore", "armv6k", "vfpv2",241 ARM::AEK_NONE | ARM::AEK_DSP, "6K"),242 ARMCPUTestParams<uint64_t>("mpcorenovfp", "armv6k", "none",243 ARM::AEK_NONE | ARM::AEK_DSP, "6K"),244 ARMCPUTestParams<uint64_t>("arm1176jzf-s", "armv6kz", "vfpv2",245 ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP,246 "6KZ"),247 ARMCPUTestParams<uint64_t>("arm1156t2-s", "armv6t2", "none",248 ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),249 ARMCPUTestParams<uint64_t>("arm1156t2f-s", "armv6t2", "vfpv2",250 ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),251 ARMCPUTestParams<uint64_t>("cortex-m0", "armv6-m", "none",252 ARM::AEK_NONE, "6-M"),253 ARMCPUTestParams<uint64_t>("cortex-m0plus", "armv6-m", "none",254 ARM::AEK_NONE, "6-M"),255 ARMCPUTestParams<uint64_t>("cortex-m1", "armv6-m", "none",256 ARM::AEK_NONE, "6-M"),257 ARMCPUTestParams<uint64_t>("sc000", "armv6-m", "none", ARM::AEK_NONE,258 "6-M"),259 ARMCPUTestParams<uint64_t>("cortex-a5", "armv7-a", "neon-vfpv4",260 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP,261 "7-A"),262 ARMCPUTestParams<uint64_t>("cortex-a7", "armv7-a", "neon-vfpv4",263 ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM |264 ARM::AEK_MP | ARM::AEK_SEC |265 ARM::AEK_VIRT | ARM::AEK_DSP,266 "7-A"),267 ARMCPUTestParams<uint64_t>("cortex-a8", "armv7-a", "neon",268 ARM::AEK_SEC | ARM::AEK_DSP, "7-A")),269 ARMCPUTestParams<uint64_t>::PrintToStringParamName);270 271// gtest in llvm has a limit of 50 test cases when using ::Values so we split272// them into 2 blocks273INSTANTIATE_TEST_SUITE_P(274 ARMCPUTestsPart2, ARMCPUTestFixture,275 ::testing::Values(276 ARMCPUTestParams<uint64_t>("cortex-a9", "armv7-a", "neon-fp16",277 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP,278 "7-A"),279 ARMCPUTestParams<uint64_t>("cortex-a12", "armv7-a", "neon-vfpv4",280 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |281 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |282 ARM::AEK_DSP,283 "7-A"),284 ARMCPUTestParams<uint64_t>("cortex-a15", "armv7-a", "neon-vfpv4",285 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |286 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |287 ARM::AEK_DSP,288 "7-A"),289 ARMCPUTestParams<uint64_t>("cortex-a17", "armv7-a", "neon-vfpv4",290 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |291 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |292 ARM::AEK_DSP,293 "7-A"),294 ARMCPUTestParams<uint64_t>("krait", "armv7-a", "neon-vfpv4",295 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |296 ARM::AEK_DSP,297 "7-A"),298 ARMCPUTestParams<uint64_t>("cortex-r4", "armv7-r", "none",299 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |300 ARM::AEK_DSP,301 "7-R"),302 ARMCPUTestParams<uint64_t>("cortex-r4f", "armv7-r", "vfpv3-d16",303 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |304 ARM::AEK_DSP,305 "7-R"),306 ARMCPUTestParams<uint64_t>("cortex-r5", "armv7-r", "vfpv3-d16",307 ARM::AEK_MP | ARM::AEK_HWDIVARM |308 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,309 "7-R"),310 ARMCPUTestParams<uint64_t>("cortex-r7", "armv7-r", "vfpv3-d16-fp16",311 ARM::AEK_MP | ARM::AEK_HWDIVARM |312 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,313 "7-R"),314 ARMCPUTestParams<uint64_t>("cortex-r8", "armv7-r", "vfpv3-d16-fp16",315 ARM::AEK_MP | ARM::AEK_HWDIVARM |316 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,317 "7-R"),318 ARMCPUTestParams<uint64_t>("cortex-r52", "armv8-r", "neon-fp-armv8",319 ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP |320 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |321 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,322 "8-R"),323 ARMCPUTestParams<uint64_t>("cortex-r52plus", "armv8-r", "neon-fp-armv8",324 ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP |325 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |326 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,327 "8-R"),328 ARMCPUTestParams<uint64_t>("sc300", "armv7-m", "none",329 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),330 ARMCPUTestParams<uint64_t>("cortex-m3", "armv7-m", "none",331 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),332 ARMCPUTestParams<uint64_t>("cortex-m4", "armv7e-m", "fpv4-sp-d16",333 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |334 ARM::AEK_DSP,335 "7E-M"),336 ARMCPUTestParams<uint64_t>("cortex-m7", "armv7e-m", "fpv5-d16",337 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |338 ARM::AEK_DSP,339 "7E-M"),340 ARMCPUTestParams<uint64_t>("cortex-a32", "armv8-a",341 "crypto-neon-fp-armv8",342 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |343 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |344 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,345 "8-A"),346 ARMCPUTestParams<uint64_t>("cortex-a35", "armv8-a",347 "crypto-neon-fp-armv8",348 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |349 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |350 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,351 "8-A"),352 ARMCPUTestParams<uint64_t>("cortex-a53", "armv8-a",353 "crypto-neon-fp-armv8",354 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |355 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |356 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,357 "8-A"),358 ARMCPUTestParams<uint64_t>(359 "cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",360 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |361 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |362 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,363 "8.2-A"),364 ARMCPUTestParams<uint64_t>("cortex-a57", "armv8-a",365 "crypto-neon-fp-armv8",366 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |367 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |368 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,369 "8-A"),370 ARMCPUTestParams<uint64_t>("cortex-a72", "armv8-a",371 "crypto-neon-fp-armv8",372 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |373 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |374 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,375 "8-A"),376 ARMCPUTestParams<uint64_t>("cortex-a73", "armv8-a",377 "crypto-neon-fp-armv8",378 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |379 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |380 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,381 "8-A"),382 ARMCPUTestParams<uint64_t>(383 "cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",384 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |385 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |386 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,387 "8.2-A"),388 ARMCPUTestParams<uint64_t>(389 "cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",390 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |391 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |392 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,393 "8.2-A"),394 ARMCPUTestParams<uint64_t>(395 "cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",396 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |397 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |398 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,399 "8.2-A"),400 ARMCPUTestParams<uint64_t>(401 "cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8",402 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |403 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC |404 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD,405 "8.2-A"),406 ARMCPUTestParams<uint64_t>("cortex-a510", "armv9-a", "neon-fp-armv8",407 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |408 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |409 ARM::AEK_DSP | ARM::AEK_CRC |410 ARM::AEK_RAS | ARM::AEK_DOTPROD |411 ARM::AEK_FP16FML | ARM::AEK_BF16 |412 ARM::AEK_I8MM | ARM::AEK_SB,413 "9-A"),414 ARMCPUTestParams<uint64_t>("cortex-a710", "armv9-a", "neon-fp-armv8",415 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |416 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |417 ARM::AEK_DSP | ARM::AEK_CRC |418 ARM::AEK_RAS | ARM::AEK_DOTPROD |419 ARM::AEK_FP16FML | ARM::AEK_BF16 |420 ARM::AEK_I8MM | ARM::AEK_SB,421 "9-A"),422 ARMCPUTestParams<uint64_t>(423 "cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",424 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |425 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |426 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,427 "8.2-A"),428 ARMCPUTestParams<uint64_t>(429 "cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",430 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_SEC | ARM::AEK_MP |431 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |432 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS,433 "8.2-A"),434 ARMCPUTestParams<uint64_t>(435 "cortex-a78ae", "armv8.2-a", "crypto-neon-fp-armv8",436 ARM::AEK_RAS | ARM::AEK_DOTPROD | ARM::AEK_SEC | ARM::AEK_MP |437 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |438 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS,439 "8.2-A"),440 ARMCPUTestParams<uint64_t>(441 "cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",442 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD | ARM::AEK_SEC |443 ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |444 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC,445 "8.2-A"),446 ARMCPUTestParams<uint64_t>(447 "cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",448 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD | ARM::AEK_SEC |449 ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |450 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC,451 "8.2-A"),452 ARMCPUTestParams<uint64_t>(453 "neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",454 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |455 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |456 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,457 "8.2-A"),458 ARMCPUTestParams<uint64_t>(459 "neoverse-n2", "armv9-a", "neon-fp-armv8",460 ARM::AEK_CRC | ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM |461 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_DSP |462 ARM::AEK_BF16 | ARM::AEK_DOTPROD | ARM::AEK_RAS |463 ARM::AEK_I8MM | ARM::AEK_FP16FML | ARM::AEK_SB,464 "9-A"),465 ARMCPUTestParams<uint64_t>(466 "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",467 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |468 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC |469 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_BF16 | ARM::AEK_DOTPROD,470 "8.4-A"),471 ARMCPUTestParams<uint64_t>("cyclone", "armv8-a", "crypto-neon-fp-armv8",472 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |473 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |474 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,475 "8-A"),476 ARMCPUTestParams<uint64_t>("exynos-m3", "armv8-a",477 "crypto-neon-fp-armv8",478 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |479 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |480 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,481 "8-A"),482 ARMCPUTestParams<uint64_t>(483 "exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",484 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |485 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |486 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,487 "8.2-A"),488 ARMCPUTestParams<uint64_t>(489 "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",490 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |491 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |492 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,493 "8.2-A"),494 ARMCPUTestParams<uint64_t>("cortex-m23", "armv8-m.base", "none",495 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB,496 "8-M.Baseline"),497 ARMCPUTestParams<uint64_t>("cortex-m33", "armv8-m.main", "fpv5-sp-d16",498 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,499 "8-M.Mainline"),500 ARMCPUTestParams<uint64_t>("star-mc1", "armv8-m.main", "fpv5-sp-d16",501 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,502 "8-M.Mainline"),503 ARMCPUTestParams<uint64_t>("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",504 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,505 "8-M.Mainline"),506 ARMCPUTestParams<uint64_t>(507 "cortex-m55", "armv8.1-m.main", "fp-armv8-fullfp16-d16",508 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |509 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16,510 "8.1-M.Mainline"),511 ARMCPUTestParams<uint64_t>(512 "cortex-m85", "armv8.1-m.main", "fp-armv8-fullfp16-d16",513 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |514 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI,515 "8.1-M.Mainline"),516 ARMCPUTestParams<uint64_t>(517 "cortex-m52", "armv8.1-m.main", "fp-armv8-fullfp16-d16",518 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |519 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI,520 "8.1-M.Mainline"),521 ARMCPUTestParams<uint64_t>(522 "star-mc3", "armv8.1-m.main", "fp-armv8-fullfp16-d16",523 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_MVE | ARM::AEK_FP |524 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI,525 "8.1-M.Mainline"),526 ARMCPUTestParams<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE,527 "iwmmxt"),528 ARMCPUTestParams<uint64_t>("xscale", "xscale", "none", ARM::AEK_NONE,529 "xscale"),530 ARMCPUTestParams<uint64_t>("swift", "armv7s", "neon-vfpv4",531 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |532 ARM::AEK_DSP,533 "7-S")),534 ARMCPUTestParams<uint64_t>::PrintToStringParamName);535 536static constexpr unsigned NumARMCPUArchs = 95;537 538TEST(TargetParserTest, testARMCPUArchList) {539 SmallVector<StringRef, NumARMCPUArchs> List;540 ARM::fillValidCPUArchList(List);541 542 // No list exists for these in this test suite, so ensure all are543 // valid, and match the expected 'magic' count.544 EXPECT_EQ(List.size(), NumARMCPUArchs);545 for (StringRef CPU : List) {546 EXPECT_NE(ARM::parseCPUArch(CPU), ARM::ArchKind::INVALID);547 }548}549 550TEST(TargetParserTest, testInvalidARMArch) {551 auto InvalidArchStrings = {"armv", "armv99", "noarm"};552 for (const char *InvalidArch : InvalidArchStrings)553 EXPECT_EQ(ARM::parseArch(InvalidArch), ARM::ArchKind::INVALID);554}555 556bool testARMArch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,557 unsigned ArchAttr) {558 ARM::ArchKind AK = ARM::parseArch(Arch);559 bool Result = (AK != ARM::ArchKind::INVALID);560 Result &= ARM::getDefaultCPU(Arch) == DefaultCPU;561 Result &= ARM::getSubArch(AK) == SubArch;562 Result &= (ARM::getArchAttr(AK) == ArchAttr);563 return Result;564}565 566TEST(TargetParserTest, testARMArch) {567 EXPECT_TRUE(568 testARMArch("armv4", "strongarm", "v4", ARMBuildAttrs::CPUArch::v4));569 EXPECT_TRUE(570 testARMArch("armv4t", "arm7tdmi", "v4t", ARMBuildAttrs::CPUArch::v4T));571 EXPECT_TRUE(572 testARMArch("armv5t", "arm10tdmi", "v5", ARMBuildAttrs::CPUArch::v5T));573 EXPECT_TRUE(574 testARMArch("armv5te", "arm1022e", "v5e", ARMBuildAttrs::CPUArch::v5TE));575 EXPECT_TRUE(testARMArch("armv5tej", "arm926ej-s", "v5e",576 ARMBuildAttrs::CPUArch::v5TEJ));577 EXPECT_TRUE(578 testARMArch("armv6", "arm1136jf-s", "v6", ARMBuildAttrs::CPUArch::v6));579 EXPECT_TRUE(580 testARMArch("armv6k", "mpcore", "v6k", ARMBuildAttrs::CPUArch::v6K));581 EXPECT_TRUE(testARMArch("armv6t2", "arm1156t2-s", "v6t2",582 ARMBuildAttrs::CPUArch::v6T2));583 EXPECT_TRUE(testARMArch("armv6kz", "arm1176jzf-s", "v6kz",584 ARMBuildAttrs::CPUArch::v6KZ));585 EXPECT_TRUE(586 testARMArch("armv6-m", "cortex-m0", "v6m", ARMBuildAttrs::CPUArch::v6_M));587 EXPECT_TRUE(588 testARMArch("armv7-a", "generic", "v7", ARMBuildAttrs::CPUArch::v7));589 EXPECT_TRUE(590 testARMArch("armv7ve", "generic", "v7ve", ARMBuildAttrs::CPUArch::v7));591 EXPECT_TRUE(592 testARMArch("armv7-r", "cortex-r4", "v7r", ARMBuildAttrs::CPUArch::v7));593 EXPECT_TRUE(594 testARMArch("armv7-m", "cortex-m3", "v7m", ARMBuildAttrs::CPUArch::v7));595 EXPECT_TRUE(testARMArch("armv7e-m", "cortex-m4", "v7em",596 ARMBuildAttrs::CPUArch::v7E_M));597 EXPECT_TRUE(598 testARMArch("armv8-a", "generic", "v8a", ARMBuildAttrs::CPUArch::v8_A));599 EXPECT_TRUE(testARMArch("armv8.1-a", "generic", "v8.1a",600 ARMBuildAttrs::CPUArch::v8_A));601 EXPECT_TRUE(testARMArch("armv8.2-a", "generic", "v8.2a",602 ARMBuildAttrs::CPUArch::v8_A));603 EXPECT_TRUE(testARMArch("armv8.3-a", "generic", "v8.3a",604 ARMBuildAttrs::CPUArch::v8_A));605 EXPECT_TRUE(testARMArch("armv8.4-a", "generic", "v8.4a",606 ARMBuildAttrs::CPUArch::v8_A));607 EXPECT_TRUE(testARMArch("armv8.5-a", "generic", "v8.5a",608 ARMBuildAttrs::CPUArch::v8_A));609 EXPECT_TRUE(testARMArch("armv8.6-a", "generic", "v8.6a",610 ARMBuildAttrs::CPUArch::v8_A));611 EXPECT_TRUE(testARMArch("armv8.7-a", "generic", "v8.7a",612 ARMBuildAttrs::CPUArch::v8_A));613 EXPECT_TRUE(testARMArch("armv8.8-a", "generic", "v8.8a",614 ARMBuildAttrs::CPUArch::v8_A));615 EXPECT_TRUE(testARMArch("armv8.9-a", "generic", "v8.9a",616 ARMBuildAttrs::CPUArch::v8_A));617 EXPECT_TRUE(618 testARMArch("armv9-a", "generic", "v9a", ARMBuildAttrs::CPUArch::v9_A));619 EXPECT_TRUE(testARMArch("armv9.1-a", "generic", "v9.1a",620 ARMBuildAttrs::CPUArch::v9_A));621 EXPECT_TRUE(testARMArch("armv9.2-a", "generic", "v9.2a",622 ARMBuildAttrs::CPUArch::v9_A));623 EXPECT_TRUE(testARMArch("armv9.3-a", "generic", "v9.3a",624 ARMBuildAttrs::CPUArch::v9_A));625 EXPECT_TRUE(testARMArch("armv9.4-a", "generic", "v9.4a",626 ARMBuildAttrs::CPUArch::v9_A));627 EXPECT_TRUE(testARMArch("armv9.5-a", "generic", "v9.5a",628 ARMBuildAttrs::CPUArch::v9_A));629 EXPECT_TRUE(testARMArch("armv9.6-a", "generic", "v9.6a",630 ARMBuildAttrs::CPUArch::v9_A));631 EXPECT_TRUE(testARMArch("armv9.7-a", "generic", "v9.7a",632 ARMBuildAttrs::CPUArch::v9_A));633 EXPECT_TRUE(634 testARMArch("armv8-r", "generic", "v8r", ARMBuildAttrs::CPUArch::v8_R));635 EXPECT_TRUE(testARMArch("armv8-m.base", "generic", "v8m.base",636 ARMBuildAttrs::CPUArch::v8_M_Base));637 EXPECT_TRUE(testARMArch("armv8-m.main", "generic", "v8m.main",638 ARMBuildAttrs::CPUArch::v8_M_Main));639 EXPECT_TRUE(testARMArch("armv8.1-m.main", "generic", "v8.1m.main",640 ARMBuildAttrs::CPUArch::v8_1_M_Main));641 EXPECT_TRUE(642 testARMArch("iwmmxt", "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE));643 EXPECT_TRUE(644 testARMArch("iwmmxt2", "generic", "", ARMBuildAttrs::CPUArch::v5TE));645 EXPECT_TRUE(646 testARMArch("xscale", "xscale", "v5e", ARMBuildAttrs::CPUArch::v5TE));647 EXPECT_TRUE(648 testARMArch("armv7s", "swift", "v7s", ARMBuildAttrs::CPUArch::v7));649 EXPECT_TRUE(650 testARMArch("armv7k", "generic", "v7k", ARMBuildAttrs::CPUArch::v7));651}652 653bool testARMExtension(StringRef CPUName, ARM::ArchKind ArchKind,654 StringRef ArchExt) {655 return ARM::getDefaultExtensions(CPUName, ArchKind) &656 ARM::parseArchExt(ArchExt);657}658 659TEST(TargetParserTest, testARMExtension) {660 EXPECT_FALSE(testARMExtension("strongarm", ARM::ArchKind::INVALID, "dsp"));661 EXPECT_FALSE(testARMExtension("arm7tdmi", ARM::ArchKind::INVALID, "dsp"));662 EXPECT_FALSE(testARMExtension("arm10tdmi", ARM::ArchKind::INVALID, "simd"));663 EXPECT_FALSE(testARMExtension("arm1022e", ARM::ArchKind::INVALID, "simd"));664 EXPECT_FALSE(testARMExtension("arm926ej-s", ARM::ArchKind::INVALID, "simd"));665 EXPECT_FALSE(666 testARMExtension("arm1136jf-s", ARM::ArchKind::INVALID, "crypto"));667 EXPECT_FALSE(668 testARMExtension("arm1156t2-s", ARM::ArchKind::INVALID, "crypto"));669 EXPECT_FALSE(670 testARMExtension("arm1176jzf-s", ARM::ArchKind::INVALID, "crypto"));671 EXPECT_FALSE(testARMExtension("cortex-m0", ARM::ArchKind::INVALID, "crypto"));672 EXPECT_FALSE(testARMExtension("cortex-a8", ARM::ArchKind::INVALID, "crypto"));673 EXPECT_FALSE(testARMExtension("cortex-r4", ARM::ArchKind::INVALID, "crypto"));674 EXPECT_FALSE(testARMExtension("cortex-m3", ARM::ArchKind::INVALID, "crypto"));675 EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID, "ras"));676 EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID, "fp16"));677 EXPECT_TRUE(testARMExtension("cortex-a55", ARM::ArchKind::INVALID, "fp16"));678 EXPECT_FALSE(679 testARMExtension("cortex-a55", ARM::ArchKind::INVALID, "fp16fml"));680 EXPECT_TRUE(testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16"));681 EXPECT_FALSE(682 testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16fml"));683 EXPECT_FALSE(testARMExtension("cortex-r52", ARM::ArchKind::INVALID, "ras"));684 EXPECT_FALSE(685 testARMExtension("cortex-r52plus", ARM::ArchKind::INVALID, "ras"));686 EXPECT_FALSE(testARMExtension("iwmmxt", ARM::ArchKind::INVALID, "crc"));687 EXPECT_FALSE(testARMExtension("xscale", ARM::ArchKind::INVALID, "crc"));688 EXPECT_FALSE(testARMExtension("swift", ARM::ArchKind::INVALID, "crc"));689 690 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4, "dsp"));691 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4T, "dsp"));692 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5T, "simd"));693 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TE, "simd"));694 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TEJ, "simd"));695 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6, "crypto"));696 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6K, "crypto"));697 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6T2, "crypto"));698 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6KZ, "crypto"));699 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6M, "crypto"));700 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7A, "crypto"));701 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7R, "crypto"));702 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7M, "crypto"));703 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7EM, "crypto"));704 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A, "ras"));705 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A, "ras"));706 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "profile"));707 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16"));708 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16fml"));709 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16"));710 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16fml"));711 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16"));712 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16fml"));713 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8R, "ras"));714 EXPECT_FALSE(715 testARMExtension("generic", ARM::ArchKind::ARMV8MBaseline, "crc"));716 EXPECT_FALSE(717 testARMExtension("generic", ARM::ArchKind::ARMV8MMainline, "crc"));718 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT, "crc"));719 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT2, "crc"));720 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::XSCALE, "crc"));721 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7S, "crypto"));722 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7K, "crypto"));723}724 725TEST(TargetParserTest, ARMFPUVersion) {726 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);727 FK <= ARM::FPUKind::FK_LAST;728 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))729 if (FK == ARM::FK_LAST || ARM::getFPUName(FK) == "invalid" ||730 ARM::getFPUName(FK) == "none" || ARM::getFPUName(FK) == "softvfp")731 EXPECT_EQ(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));732 else733 EXPECT_NE(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));734}735 736TEST(TargetParserTest, ARMFPUNeonSupportLevel) {737 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);738 FK <= ARM::FPUKind::FK_LAST;739 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))740 if (FK == ARM::FK_LAST || !ARM::getFPUName(FK).contains("neon"))741 EXPECT_EQ(ARM::NeonSupportLevel::None, ARM::getFPUNeonSupportLevel(FK));742 else743 EXPECT_NE(ARM::NeonSupportLevel::None, ARM::getFPUNeonSupportLevel(FK));744}745 746TEST(TargetParserTest, ARMFPURestriction) {747 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);748 FK <= ARM::FPUKind::FK_LAST;749 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) {750 if (FK == ARM::FK_LAST || (!ARM::getFPUName(FK).contains("d16") &&751 !ARM::getFPUName(FK).contains("vfpv3xd")))752 EXPECT_EQ(ARM::FPURestriction::None, ARM::getFPURestriction(FK));753 else754 EXPECT_NE(ARM::FPURestriction::None, ARM::getFPURestriction(FK));755 }756}757 758TEST(TargetParserTest, ARMExtensionFeatures) {759 std::map<uint64_t, std::vector<StringRef>> Extensions;760 761 for (auto &Ext : ARM::ARCHExtNames) {762 if (!Ext.Feature.empty() && !Ext.NegFeature.empty())763 Extensions[Ext.ID] = {Ext.Feature, Ext.NegFeature};764 }765 766 Extensions[ARM::AEK_HWDIVARM] = {"+hwdiv-arm", "-hwdiv-arm"};767 Extensions[ARM::AEK_HWDIVTHUMB] = {"+hwdiv", "-hwdiv"};768 769 std::vector<StringRef> Features;770 771 EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID, Features));772 773 for (auto &E : Extensions) {774 // test +extension775 Features.clear();776 ARM::getExtensionFeatures(E.first, Features);777 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(0)));778 EXPECT_EQ(Extensions.size(), Features.size());779 780 // test -extension781 Features.clear();782 ARM::getExtensionFeatures(~E.first, Features);783 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(1)));784 EXPECT_EQ(Extensions.size(), Features.size());785 }786}787 788TEST(TargetParserTest, ARMFPUFeatures) {789 std::vector<StringRef> Features;790 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);791 FK <= ARM::FPUKind::FK_LAST;792 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) {793 if (FK == ARM::FK_INVALID || FK >= ARM::FK_LAST)794 EXPECT_FALSE(ARM::getFPUFeatures(FK, Features));795 else796 EXPECT_TRUE(ARM::getFPUFeatures(FK, Features));797 }798}799 800TEST(TargetParserTest, ARMArchExtFeature) {801 const char *ArchExt[][4] = {{"crc", "nocrc", "+crc", "-crc"},802 {"crypto", "nocrypto", "+crypto", "-crypto"},803 {"dsp", "nodsp", "+dsp", "-dsp"},804 {"fp", "nofp", nullptr, nullptr},805 {"idiv", "noidiv", nullptr, nullptr},806 {"mp", "nomp", nullptr, nullptr},807 {"simd", "nosimd", "+neon", "-neon"},808 {"sec", "nosec", nullptr, nullptr},809 {"virt", "novirt", nullptr, nullptr},810 {"fp16", "nofp16", "+fullfp16", "-fullfp16"},811 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},812 {"ras", "noras", "+ras", "-ras"},813 {"dotprod", "nodotprod", "+dotprod", "-dotprod"},814 {"os", "noos", nullptr, nullptr},815 {"iwmmxt", "noiwmmxt", nullptr, nullptr},816 {"iwmmxt2", "noiwmmxt2", nullptr, nullptr},817 {"maverick", "maverick", nullptr, nullptr},818 {"xscale", "noxscale", nullptr, nullptr},819 {"sb", "nosb", "+sb", "-sb"},820 {"i8mm", "noi8mm", "+i8mm", "-i8mm"},821 {"mve", "nomve", "+mve", "-mve"},822 {"mve.fp", "nomve.fp", "+mve.fp", "-mve.fp"}};823 824 for (unsigned i = 0; i < std::size(ArchExt); i++) {825 EXPECT_EQ(StringRef(ArchExt[i][2]), ARM::getArchExtFeature(ArchExt[i][0]));826 EXPECT_EQ(StringRef(ArchExt[i][3]), ARM::getArchExtFeature(ArchExt[i][1]));827 }828}829 830static bool831testArchExtDependency(const char *ArchExt,832 const std::initializer_list<const char *> &Expected) {833 std::vector<StringRef> Features;834 ARM::FPUKind FPUKind;835 836 if (!ARM::appendArchExtFeatures("", ARM::ArchKind::ARMV8_1MMainline, ArchExt,837 Features, FPUKind))838 return false;839 840 return llvm::all_of(Expected, [&](StringRef Ext) {841 return llvm::is_contained(Features, Ext);842 });843}844 845TEST(TargetParserTest, ARMArchExtDependencies) {846 EXPECT_TRUE(testArchExtDependency("mve", {"+mve", "+dsp"}));847 EXPECT_TRUE(testArchExtDependency("mve.fp", {"+mve.fp", "+mve", "+dsp"}));848 EXPECT_TRUE(testArchExtDependency("nodsp", {"-dsp", "-mve", "-mve.fp"}));849 EXPECT_TRUE(testArchExtDependency("nomve", {"-mve", "-mve.fp"}));850}851 852TEST(TargetParserTest, ARMparseHWDiv) {853 const char *hwdiv[] = {"thumb", "arm", "arm,thumb", "thumb,arm"};854 855 for (unsigned i = 0; i < std::size(hwdiv); i++)856 EXPECT_NE(ARM::AEK_INVALID, ARM::parseHWDiv((StringRef)hwdiv[i]));857}858 859TEST(TargetParserTest, ARMparseArchEndianAndISA) {860 const char *Arch[] = {861 "v2", "v2a", "v3", "v3m", "v4", "v4t",862 "v5", "v5t", "v5e", "v5te", "v5tej", "v6",863 "v6j", "v6k", "v6hl", "v6t2", "v6kz", "v6z",864 "v6zk", "v6-m", "v6m", "v6sm", "v6s-m", "v7-a",865 "v7", "v7a", "v7ve", "v7hl", "v7l", "v7-r",866 "v7r", "v7-m", "v7m", "v7k", "v7s", "v7e-m",867 "v7em", "v8-a", "v8", "v8a", "v8l", "v8.1-a",868 "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8.4-a",869 "v8.4a", "v8.5-a", "v8.5a", "v8.6-a", "v8.6a", "v8.7-a",870 "v8.7a", "v8.8-a", "v8.8a", "v8-r", "v8m.base", "v8m.main",871 "v8.1m.main"};872 873 for (unsigned i = 0; i < std::size(Arch); i++) {874 std::string arm_1 = "armeb" + (std::string)(Arch[i]);875 std::string arm_2 = "arm" + (std::string)(Arch[i]) + "eb";876 std::string arm_3 = "arm" + (std::string)(Arch[i]);877 std::string thumb_1 = "thumbeb" + (std::string)(Arch[i]);878 std::string thumb_2 = "thumb" + (std::string)(Arch[i]) + "eb";879 std::string thumb_3 = "thumb" + (std::string)(Arch[i]);880 881 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_1));882 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_2));883 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(arm_3));884 885 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_1));886 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_2));887 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_3));888 if (i >= 4) {889 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_1));890 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_2));891 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(thumb_3));892 893 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_1));894 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_2));895 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_3));896 }897 }898 899 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("aarch64"));900 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("arm64_32"));901 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian("aarch64_be"));902 903 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64"));904 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_be"));905 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64"));906 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_be"));907 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_32"));908 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_32"));909}910 911TEST(TargetParserTest, ARMparseArchProfile) {912 for (unsigned i = 0; i < std::size(ARMArch); i++) {913 switch (ARM::parseArch(ARMArch[i])) {914 case ARM::ArchKind::ARMV6M:915 case ARM::ArchKind::ARMV7M:916 case ARM::ArchKind::ARMV7EM:917 case ARM::ArchKind::ARMV8MMainline:918 case ARM::ArchKind::ARMV8MBaseline:919 case ARM::ArchKind::ARMV8_1MMainline:920 EXPECT_EQ(ARM::ProfileKind::M, ARM::parseArchProfile(ARMArch[i]));921 break;922 case ARM::ArchKind::ARMV7R:923 case ARM::ArchKind::ARMV8R:924 EXPECT_EQ(ARM::ProfileKind::R, ARM::parseArchProfile(ARMArch[i]));925 break;926 case ARM::ArchKind::ARMV7A:927 case ARM::ArchKind::ARMV7VE:928 case ARM::ArchKind::ARMV7K:929 case ARM::ArchKind::ARMV8A:930 case ARM::ArchKind::ARMV8_1A:931 case ARM::ArchKind::ARMV8_2A:932 case ARM::ArchKind::ARMV8_3A:933 case ARM::ArchKind::ARMV8_4A:934 case ARM::ArchKind::ARMV8_5A:935 case ARM::ArchKind::ARMV8_6A:936 case ARM::ArchKind::ARMV8_7A:937 case ARM::ArchKind::ARMV8_8A:938 case ARM::ArchKind::ARMV8_9A:939 case ARM::ArchKind::ARMV9A:940 case ARM::ArchKind::ARMV9_1A:941 case ARM::ArchKind::ARMV9_2A:942 case ARM::ArchKind::ARMV9_3A:943 case ARM::ArchKind::ARMV9_4A:944 case ARM::ArchKind::ARMV9_5A:945 case ARM::ArchKind::ARMV9_6A:946 case ARM::ArchKind::ARMV9_7A:947 EXPECT_EQ(ARM::ProfileKind::A, ARM::parseArchProfile(ARMArch[i]));948 break;949 default:950 EXPECT_EQ(ARM::ProfileKind::INVALID, ARM::parseArchProfile(ARMArch[i]));951 break;952 }953 }954}955 956TEST(TargetParserTest, ARMparseArchVersion) {957 for (unsigned i = 0; i < std::size(ARMArch); i++)958 if (((std::string)ARMArch[i]).substr(0, 4) == "armv")959 EXPECT_EQ((ARMArch[i][4] - 48u), ARM::parseArchVersion(ARMArch[i]));960 else961 EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch[i]));962}963 964TEST(TargetParserTest, getARMCPUForArch) {965 // Platform specific defaults.966 {967 llvm::Triple Triple("arm--openbsd");968 EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple));969 }970 {971 llvm::Triple Triple("armv6-unknown-freebsd");972 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple));973 }974 {975 llvm::Triple Triple("thumbv6-unknown-freebsd");976 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple));977 }978 {979 llvm::Triple Triple("armebv6-unknown-freebsd");980 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple));981 }982 {983 llvm::Triple Triple("arm--win32");984 EXPECT_EQ("cortex-a9", ARM::getARMCPUForArch(Triple));985 EXPECT_EQ("generic", ARM::getARMCPUForArch(Triple, "armv8-a"));986 }987 // Some alternative architectures988 {989 llvm::Triple Triple("armv7k-apple-ios9");990 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple));991 }992 {993 llvm::Triple Triple("armv7k-apple-watchos3");994 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple));995 }996 {997 llvm::Triple Triple("armv7k-apple-tvos9");998 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple));999 }1000 // armeb is permitted, but armebeb is not1001 {1002 llvm::Triple Triple("armeb-none-eabi");1003 EXPECT_EQ("arm7tdmi", ARM::getARMCPUForArch(Triple));1004 }1005 {1006 llvm::Triple Triple("armebeb-none-eabi");1007 EXPECT_EQ("", ARM::getARMCPUForArch(Triple));1008 }1009 {1010 llvm::Triple Triple("armebv6eb-none-eabi");1011 EXPECT_EQ("", ARM::getARMCPUForArch(Triple));1012 }1013 // xscaleeb is permitted, but armebxscale is not1014 {1015 llvm::Triple Triple("xscaleeb-none-eabi");1016 EXPECT_EQ("xscale", ARM::getARMCPUForArch(Triple));1017 }1018 {1019 llvm::Triple Triple("armebxscale-none-eabi");1020 EXPECT_EQ("", ARM::getARMCPUForArch(Triple));1021 }1022}1023 1024TEST(TargetParserTest, ARMPrintSupportedExtensions) {1025 std::string expected =1026 "All available -march extensions for ARM\n\n"1027 " Name Description\n"1028 " crc This is a long dummy description\n"1029 " crypto\n"1030 " sha2\n";1031 1032 StringMap<StringRef> DummyMap;1033 DummyMap["crc"] = "This is a long dummy description";1034 1035 outs().flush();1036 testing::internal::CaptureStdout();1037 ARM::PrintSupportedExtensions(DummyMap);1038 outs().flush();1039 std::string captured = testing::internal::GetCapturedStdout();1040 1041 // Check that the start of the output is as expected.1042 EXPECT_EQ(0ULL, captured.find(expected));1043 1044 // Should not include "none" or "invalid".1045 EXPECT_EQ(std::string::npos, captured.find("none"));1046 EXPECT_EQ(std::string::npos, captured.find("invalid"));1047 // Should not include anything that lacks a feature name. Checking a few here1048 // but not all as if one is hidden correctly the rest should be.1049 EXPECT_EQ(std::string::npos, captured.find("maverick"));1050 EXPECT_EQ(std::string::npos, captured.find("xscale"));1051}1052 1053struct AArch64CPUTestParams1054 : public ARMCPUTestParams<AArch64::ExtensionBitset> {1055 AArch64CPUTestParams(StringRef CPUName, StringRef ExpectedArch)1056 : ARMCPUTestParams<AArch64::ExtensionBitset>(CPUName, ExpectedArch,1057 /*ignored*/ "", {},1058 /*ignored*/ "") {}1059 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name1060 /// human-readable.1061 ///1062 /// https://github.com/google/googletest/blob/main/docs/advanced.md#specifying-names-for-value-parameterized-test-parameters1063 static std::string PrintToStringParamName(1064 const testing::TestParamInfo<AArch64CPUTestParams> &Info) {1065 std::string Name = Info.param.CPUName.str();1066 for (char &C : Name)1067 if (!std::isalnum(C))1068 C = '_';1069 return Name;1070 }1071};1072 1073class AArch64CPUTestFixture1074 : public ::testing::TestWithParam<AArch64CPUTestParams> {};1075 1076TEST_P(AArch64CPUTestFixture, testAArch64CPU) {1077 auto params = GetParam();1078 1079 const std::optional<AArch64::CpuInfo> Cpu = AArch64::parseCpu(params.CPUName);1080 EXPECT_TRUE(Cpu);1081 EXPECT_EQ(params.ExpectedArch, Cpu->Arch.Name);1082}1083 1084INSTANTIATE_TEST_SUITE_P(1085 AArch64CPUTests, AArch64CPUTestFixture,1086 ::testing::Values(AArch64CPUTestParams("cortex-a34", "armv8-a"),1087 AArch64CPUTestParams("cortex-a35", "armv8-a"),1088 AArch64CPUTestParams("cortex-a320", "armv9.2-a"),1089 AArch64CPUTestParams("cortex-a53", "armv8-a"),1090 AArch64CPUTestParams("cortex-a55", "armv8.2-a"),1091 AArch64CPUTestParams("cortex-a510", "armv9-a"),1092 AArch64CPUTestParams("cortex-a520", "armv9.2-a"),1093 AArch64CPUTestParams("cortex-a520ae", "armv9.2-a"),1094 AArch64CPUTestParams("cortex-a57", "armv8-a"),1095 AArch64CPUTestParams("cortex-a65", "armv8.2-a"),1096 AArch64CPUTestParams("cortex-a65ae", "armv8.2-a"),1097 AArch64CPUTestParams("cortex-a72", "armv8-a"),1098 AArch64CPUTestParams("cortex-a73", "armv8-a"),1099 AArch64CPUTestParams("cortex-a75", "armv8.2-a"),1100 AArch64CPUTestParams("cortex-a76", "armv8.2-a"),1101 AArch64CPUTestParams("cortex-a76ae", "armv8.2-a"),1102 AArch64CPUTestParams("cortex-a77", "armv8.2-a"),1103 AArch64CPUTestParams("cortex-a78", "armv8.2-a"),1104 AArch64CPUTestParams("cortex-a78ae", "armv8.2-a"),1105 AArch64CPUTestParams("cortex-a78c", "armv8.2-a"),1106 AArch64CPUTestParams("cortex-a710", "armv9-a"),1107 AArch64CPUTestParams("cortex-a715", "armv9-a"),1108 AArch64CPUTestParams("cortex-a720", "armv9.2-a"),1109 AArch64CPUTestParams("cortex-a720ae", "armv9.2-a"),1110 AArch64CPUTestParams("cortex-a725", "armv9.2-a"),1111 AArch64CPUTestParams("neoverse-v1", "armv8.4-a"),1112 AArch64CPUTestParams("neoverse-v2", "armv9-a"),1113 AArch64CPUTestParams("neoverse-v3", "armv9.2-a"),1114 AArch64CPUTestParams("neoverse-v3ae", "armv9.2-a"),1115 AArch64CPUTestParams("cortex-r82", "armv8-r"),1116 AArch64CPUTestParams("cortex-r82ae", "armv8-r"),1117 AArch64CPUTestParams("cortex-x1", "armv8.2-a"),1118 AArch64CPUTestParams("cortex-x1c", "armv8.2-a"),1119 AArch64CPUTestParams("cortex-x2", "armv9-a"),1120 AArch64CPUTestParams("cortex-x3", "armv9-a"),1121 AArch64CPUTestParams("cortex-x4", "armv9.2-a"),1122 AArch64CPUTestParams("cortex-x925", "armv9.2-a"),1123 AArch64CPUTestParams("cyclone", "armv8-a"),1124 AArch64CPUTestParams("apple-a7", "armv8-a"),1125 AArch64CPUTestParams("apple-a8", "armv8-a"),1126 AArch64CPUTestParams("apple-a9", "armv8-a"),1127 AArch64CPUTestParams("apple-a10", "armv8-a"),1128 AArch64CPUTestParams("apple-a11", "armv8.2-a"),1129 AArch64CPUTestParams("apple-a12", "armv8.3-a"),1130 AArch64CPUTestParams("apple-s4", "armv8.3-a"),1131 AArch64CPUTestParams("apple-s5", "armv8.3-a"),1132 AArch64CPUTestParams("apple-a13", "armv8.4-a"),1133 AArch64CPUTestParams("apple-s6", "armv8.4-a"),1134 AArch64CPUTestParams("apple-s7", "armv8.4-a"),1135 AArch64CPUTestParams("apple-s8", "armv8.4-a"),1136 AArch64CPUTestParams("apple-a14", "armv8.4-a"),1137 AArch64CPUTestParams("apple-m1", "armv8.4-a"),1138 AArch64CPUTestParams("apple-a15", "armv8.6-a"),1139 AArch64CPUTestParams("apple-m2", "armv8.6-a"),1140 AArch64CPUTestParams("apple-a16", "armv8.6-a"),1141 AArch64CPUTestParams("apple-m3", "armv8.6-a"),1142 AArch64CPUTestParams("apple-s9", "armv8.6-a"),1143 AArch64CPUTestParams("apple-s10", "armv8.6-a"),1144 AArch64CPUTestParams("apple-a17", "armv8.6-a"),1145 AArch64CPUTestParams("apple-m4", "armv8.7-a"),1146 AArch64CPUTestParams("apple-a18", "armv8.7-a"),1147 AArch64CPUTestParams("exynos-m3", "armv8-a"),1148 AArch64CPUTestParams("exynos-m4", "armv8.2-a"),1149 AArch64CPUTestParams("exynos-m5", "armv8.2-a"),1150 AArch64CPUTestParams("falkor", "armv8-a"),1151 AArch64CPUTestParams("kryo", "armv8-a"),1152 AArch64CPUTestParams("neoverse-e1", "armv8.2-a"),1153 AArch64CPUTestParams("neoverse-n1", "armv8.2-a"),1154 AArch64CPUTestParams("neoverse-n2", "armv9-a"),1155 AArch64CPUTestParams("neoverse-n3", "armv9.2-a"),1156 AArch64CPUTestParams("ampere1", "armv8.6-a"),1157 AArch64CPUTestParams("ampere1a", "armv8.6-a"),1158 AArch64CPUTestParams("ampere1b", "armv8.7-a"),1159 AArch64CPUTestParams("neoverse-512tvb", "armv8.4-a"),1160 AArch64CPUTestParams("thunderx2t99", "armv8.1-a"),1161 AArch64CPUTestParams("thunderx3t110", "armv8.3-a"),1162 AArch64CPUTestParams("thunderx", "armv8-a"),1163 AArch64CPUTestParams("thunderxt81", "armv8-a"),1164 AArch64CPUTestParams("thunderxt83", "armv8-a"),1165 AArch64CPUTestParams("thunderxt88", "armv8-a"),1166 AArch64CPUTestParams("tsv110", "armv8.2-a"),1167 AArch64CPUTestParams("a64fx", "armv8.2-a"),1168 AArch64CPUTestParams("fujitsu-monaka", "armv9.3-a"),1169 AArch64CPUTestParams("carmel", "armv8.2-a"),1170 AArch64CPUTestParams("gb10", "armv9.2-a"),1171 AArch64CPUTestParams("grace", "armv9-a"),1172 AArch64CPUTestParams("olympus", "armv9.2-a"),1173 AArch64CPUTestParams("saphira", "armv8.4-a"),1174 AArch64CPUTestParams("oryon-1", "armv8.6-a")),1175 AArch64CPUTestParams::PrintToStringParamName);1176 1177struct AArch64CPUAliasTestParams {1178 AArch64CPUAliasTestParams(std::vector<StringRef> Aliases)1179 : Aliases(Aliases) {}1180 1181 friend std::ostream &operator<<(std::ostream &os,1182 const AArch64CPUAliasTestParams ¶ms) {1183 raw_os_ostream oss(os);1184 interleave(params.Aliases, oss, ", ");1185 return os;1186 }1187 1188 /// Print a gtest-compatible facsimile of the first cpu (the aliasee), to make1189 /// the test's name human-readable.1190 static std::string PrintToStringParamName(1191 const testing::TestParamInfo<AArch64CPUAliasTestParams> &Info) {1192 std::string Name = Info.param.Aliases.front().str();1193 for (char &C : Name)1194 if (!std::isalnum(C))1195 C = '_';1196 return Name;1197 }1198 1199 std::vector<StringRef> Aliases;1200};1201 1202class AArch64CPUAliasTestFixture1203 : public ::testing::TestWithParam<AArch64CPUAliasTestParams> {};1204 1205static std::string aarch64FeaturesFromBits(AArch64::ExtensionBitset BitFlags) {1206 std::vector<StringRef> Flags;1207 bool OK = AArch64::getExtensionFeatures(BitFlags, Flags);1208 assert(OK);1209 (void)OK;1210 std::string S;1211 raw_string_ostream OS(S);1212 interleave(Flags, OS, ", ");1213 return OS.str();1214}1215 1216TEST_P(AArch64CPUAliasTestFixture, testCPUAlias) {1217 AArch64CPUAliasTestParams params = GetParam();1218 1219 StringRef MainName = params.Aliases[0];1220 const std::optional<AArch64::CpuInfo> Cpu = AArch64::parseCpu(MainName);1221 const AArch64::ArchInfo &MainAI = Cpu->Arch;1222 AArch64::ExtensionBitset MainFlags = Cpu->getImpliedExtensions();1223 1224 for (size_t I = 1, E = params.Aliases.size(); I != E; ++I) {1225 StringRef OtherName = params.Aliases[I];1226 const std::optional<AArch64::CpuInfo> OtherCpu =1227 AArch64::parseCpu(OtherName);1228 const AArch64::ArchInfo &OtherAI = OtherCpu->Arch;1229 1230 EXPECT_EQ(MainAI.Version, OtherAI.Version)1231 << MainName << " vs " << OtherName;1232 EXPECT_EQ(MainAI.Name, OtherAI.Name) << MainName << " vs " << OtherName;1233 EXPECT_EQ(MainAI.Profile, OtherAI.Profile)1234 << MainName << " vs " << OtherName;1235 EXPECT_EQ(MainAI.DefaultExts, OtherAI.DefaultExts)1236 << MainName << " vs " << OtherName;1237 EXPECT_EQ(MainAI, OtherAI) << MainName << " vs " << OtherName;1238 1239 AArch64::ExtensionBitset OtherFlags = OtherCpu->getImpliedExtensions();1240 1241 EXPECT_EQ(MainFlags, OtherFlags) << MainName << " vs " << OtherName;1242 1243 EXPECT_EQ(aarch64FeaturesFromBits(MainFlags),1244 aarch64FeaturesFromBits(OtherFlags))1245 << MainName << " vs " << OtherName << "\n Diff: "1246 << (aarch64FeaturesFromBits(MainFlags ^ OtherFlags));1247 }1248}1249 1250INSTANTIATE_TEST_SUITE_P(1251 AArch64CPUAliasTests, AArch64CPUAliasTestFixture,1252 ::testing::Values(AArch64CPUAliasTestParams({"neoverse-n2", "cobalt-100"}),1253 AArch64CPUAliasTestParams({"apple-a7", "cyclone",1254 "apple-a8", "apple-a9"}),1255 AArch64CPUAliasTestParams({"apple-a12", "apple-s4",1256 "apple-s5"}),1257 AArch64CPUAliasTestParams({"apple-a13", "apple-s6",1258 "apple-s7", "apple-s8"}),1259 AArch64CPUAliasTestParams({"apple-a14", "apple-m1"}),1260 AArch64CPUAliasTestParams({"apple-a15", "apple-m2"}),1261 AArch64CPUAliasTestParams({"apple-a16", "apple-m3",1262 "apple-s9", "apple-s10"}),1263 AArch64CPUAliasTestParams({"apple-m4", "apple-a18"})),1264 AArch64CPUAliasTestParams::PrintToStringParamName);1265 1266// Note: number of CPUs includes aliases.1267static constexpr unsigned NumAArch64CPUArchs = 91;1268 1269TEST(TargetParserTest, testAArch64CPUArchList) {1270 SmallVector<StringRef, NumAArch64CPUArchs> List;1271 AArch64::fillValidCPUArchList(List);1272 1273 // No list exists for these in this test suite, so ensure all are1274 // valid, and match the expected 'magic' count.1275 EXPECT_EQ(List.size(), NumAArch64CPUArchs);1276 for (StringRef CPU : List) {1277 EXPECT_TRUE(AArch64::parseCpu(CPU));1278 }1279}1280 1281bool testAArch64Arch(StringRef Arch) {1282 const AArch64::ArchInfo *AI = AArch64::parseArch(Arch);1283 return AI != nullptr;1284}1285 1286TEST(TargetParserTest, testAArch64Arch) {1287 EXPECT_TRUE(testAArch64Arch("armv8-a"));1288 EXPECT_TRUE(testAArch64Arch("armv8.1-a"));1289 EXPECT_TRUE(testAArch64Arch("armv8.2-a"));1290 EXPECT_TRUE(testAArch64Arch("armv8.3-a"));1291 EXPECT_TRUE(testAArch64Arch("armv8.4-a"));1292 EXPECT_TRUE(testAArch64Arch("armv8.5-a"));1293 EXPECT_TRUE(testAArch64Arch("armv8.6-a"));1294 EXPECT_TRUE(testAArch64Arch("armv8.7-a"));1295 EXPECT_TRUE(testAArch64Arch("armv8.8-a"));1296 EXPECT_TRUE(testAArch64Arch("armv8.9-a"));1297 EXPECT_TRUE(testAArch64Arch("armv9-a"));1298 EXPECT_TRUE(testAArch64Arch("armv9.1-a"));1299 EXPECT_TRUE(testAArch64Arch("armv9.2-a"));1300 EXPECT_TRUE(testAArch64Arch("armv9.3-a"));1301 EXPECT_TRUE(testAArch64Arch("armv9.4-a"));1302 EXPECT_TRUE(testAArch64Arch("armv9.5-a"));1303 EXPECT_TRUE(testAArch64Arch("armv9.6-a"));1304 EXPECT_TRUE(testAArch64Arch("armv9.7-a"));1305}1306 1307bool testAArch64Extension(StringRef CPUName, StringRef ArchExt) {1308 std::optional<AArch64::ExtensionInfo> Extension =1309 AArch64::parseArchExtension(ArchExt);1310 if (!Extension)1311 return false;1312 std::optional<AArch64::CpuInfo> CpuInfo = AArch64::parseCpu(CPUName);1313 return CpuInfo->getImpliedExtensions().test(Extension->ID);1314}1315 1316bool testAArch64Extension(const AArch64::ArchInfo &AI, StringRef ArchExt) {1317 std::optional<AArch64::ExtensionInfo> Extension =1318 AArch64::parseArchExtension(ArchExt);1319 if (!Extension)1320 return false;1321 return AI.DefaultExts.test(Extension->ID);1322}1323 1324TEST(TargetParserTest, testAArch64Extension) {1325 EXPECT_FALSE(testAArch64Extension("cortex-a34", "ras"));1326 EXPECT_FALSE(testAArch64Extension("cortex-a35", "ras"));1327 EXPECT_FALSE(testAArch64Extension("cortex-a53", "ras"));1328 EXPECT_TRUE(testAArch64Extension("cortex-a55", "ras"));1329 EXPECT_TRUE(testAArch64Extension("cortex-a55", "fp16"));1330 EXPECT_FALSE(testAArch64Extension("cortex-a55", "fp16fml"));1331 EXPECT_TRUE(testAArch64Extension("cortex-a55", "dotprod"));1332 EXPECT_FALSE(testAArch64Extension("cortex-a57", "ras"));1333 EXPECT_FALSE(testAArch64Extension("cortex-a72", "ras"));1334 EXPECT_FALSE(testAArch64Extension("cortex-a73", "ras"));1335 EXPECT_TRUE(testAArch64Extension("cortex-a75", "ras"));1336 EXPECT_TRUE(testAArch64Extension("cortex-a75", "fp16"));1337 EXPECT_FALSE(testAArch64Extension("cortex-a75", "fp16fml"));1338 EXPECT_TRUE(testAArch64Extension("cortex-a75", "dotprod"));1339 EXPECT_TRUE(testAArch64Extension("cortex-r82", "ras"));1340 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16"));1341 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16fml"));1342 EXPECT_TRUE(testAArch64Extension("cortex-r82", "dotprod"));1343 EXPECT_TRUE(testAArch64Extension("cortex-r82", "lse"));1344 EXPECT_FALSE(testAArch64Extension("cyclone", "ras"));1345 EXPECT_FALSE(testAArch64Extension("exynos-m3", "ras"));1346 EXPECT_TRUE(testAArch64Extension("exynos-m4", "dotprod"));1347 EXPECT_TRUE(testAArch64Extension("exynos-m4", "fp16"));1348 EXPECT_TRUE(testAArch64Extension("exynos-m4", "lse"));1349 EXPECT_TRUE(testAArch64Extension("exynos-m4", "ras"));1350 EXPECT_TRUE(testAArch64Extension("exynos-m4", "rdm"));1351 EXPECT_TRUE(testAArch64Extension("exynos-m5", "dotprod"));1352 EXPECT_TRUE(testAArch64Extension("exynos-m5", "fp16"));1353 EXPECT_TRUE(testAArch64Extension("exynos-m5", "lse"));1354 EXPECT_TRUE(testAArch64Extension("exynos-m5", "ras"));1355 EXPECT_TRUE(testAArch64Extension("exynos-m5", "rdm"));1356 EXPECT_TRUE(testAArch64Extension("falkor", "rdm"));1357 EXPECT_FALSE(testAArch64Extension("kryo", "ras"));1358 EXPECT_TRUE(testAArch64Extension("saphira", "crc"));1359 EXPECT_TRUE(testAArch64Extension("saphira", "lse"));1360 EXPECT_TRUE(testAArch64Extension("saphira", "rdm"));1361 EXPECT_TRUE(testAArch64Extension("saphira", "ras"));1362 EXPECT_TRUE(testAArch64Extension("saphira", "rcpc"));1363 EXPECT_TRUE(testAArch64Extension("saphira", "profile"));1364 EXPECT_FALSE(testAArch64Extension("saphira", "fp16"));1365 EXPECT_FALSE(testAArch64Extension("thunderx2t99", "ras"));1366 EXPECT_FALSE(testAArch64Extension("thunderx", "lse"));1367 EXPECT_FALSE(testAArch64Extension("thunderxt81", "lse"));1368 EXPECT_FALSE(testAArch64Extension("thunderxt83", "lse"));1369 EXPECT_FALSE(testAArch64Extension("thunderxt88", "lse"));1370 EXPECT_TRUE(testAArch64Extension("tsv110", "aes"));1371 EXPECT_TRUE(testAArch64Extension("tsv110", "sha2"));1372 EXPECT_FALSE(testAArch64Extension("tsv110", "sha3"));1373 EXPECT_FALSE(testAArch64Extension("tsv110", "sm4"));1374 EXPECT_TRUE(testAArch64Extension("tsv110", "ras"));1375 EXPECT_TRUE(testAArch64Extension("tsv110", "profile"));1376 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16"));1377 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16fml"));1378 EXPECT_TRUE(testAArch64Extension("tsv110", "dotprod"));1379 EXPECT_TRUE(testAArch64Extension("tsv110", "jscvt"));1380 EXPECT_TRUE(testAArch64Extension("tsv110", "fcma"));1381 EXPECT_TRUE(testAArch64Extension("a64fx", "fp16"));1382 EXPECT_TRUE(testAArch64Extension("a64fx", "sve"));1383 EXPECT_FALSE(testAArch64Extension("a64fx", "sve2"));1384 EXPECT_TRUE(testAArch64Extension("carmel", "aes"));1385 EXPECT_TRUE(testAArch64Extension("carmel", "sha2"));1386 EXPECT_TRUE(testAArch64Extension("carmel", "fp16"));1387 1388 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8A, "ras"));1389 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_1A, "ras"));1390 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "profile"));1391 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16"));1392 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16fml"));1393 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16"));1394 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16fml"));1395 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16"));1396 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16fml"));1397}1398 1399TEST(TargetParserTest, AArch64ExtensionFeatures) {1400 std::vector<uint64_t> Extensions = {1401 AArch64::AEK_CRC, AArch64::AEK_LSE,1402 AArch64::AEK_RDM, AArch64::AEK_CRYPTO,1403 AArch64::AEK_SM4, AArch64::AEK_SHA3,1404 AArch64::AEK_SHA2, AArch64::AEK_AES,1405 AArch64::AEK_DOTPROD, AArch64::AEK_FP,1406 AArch64::AEK_SIMD, AArch64::AEK_FP16,1407 AArch64::AEK_FP16FML, AArch64::AEK_PROFILE,1408 AArch64::AEK_RAS, AArch64::AEK_SVE,1409 AArch64::AEK_SVE2, AArch64::AEK_SVE2AES,1410 AArch64::AEK_SVE2SM4, AArch64::AEK_SVE2SHA3,1411 AArch64::AEK_SVE2BITPERM, AArch64::AEK_RCPC,1412 AArch64::AEK_RAND, AArch64::AEK_MTE,1413 AArch64::AEK_SSBS, AArch64::AEK_SB,1414 AArch64::AEK_PREDRES, AArch64::AEK_BF16,1415 AArch64::AEK_I8MM, AArch64::AEK_F32MM,1416 AArch64::AEK_LS64, AArch64::AEK_BRBE,1417 AArch64::AEK_PAUTH, AArch64::AEK_FLAGM,1418 AArch64::AEK_SME, AArch64::AEK_SMEF64F64,1419 AArch64::AEK_SMEI16I64, AArch64::AEK_SME2,1420 AArch64::AEK_HBC, AArch64::AEK_MOPS,1421 AArch64::AEK_PERFMON, AArch64::AEK_SVE2P1,1422 AArch64::AEK_SME2P1, AArch64::AEK_SMEB16B16,1423 AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC,1424 AArch64::AEK_RCPC3, AArch64::AEK_THE,1425 AArch64::AEK_D128, AArch64::AEK_LSE128,1426 AArch64::AEK_SPECRES2, AArch64::AEK_RASV2,1427 AArch64::AEK_ITE, AArch64::AEK_GCS,1428 AArch64::AEK_FAMINMAX, AArch64::AEK_FP8FMA,1429 AArch64::AEK_SSVE_FP8FMA, AArch64::AEK_FP8DOT2,1430 AArch64::AEK_SSVE_FP8DOT2, AArch64::AEK_FP8DOT4,1431 AArch64::AEK_SSVE_FP8DOT4, AArch64::AEK_LUT,1432 AArch64::AEK_SME_LUTV2, AArch64::AEK_SMEF8F16,1433 AArch64::AEK_SMEF8F32, AArch64::AEK_SMEFA64,1434 AArch64::AEK_CPA, AArch64::AEK_PAUTHLR,1435 AArch64::AEK_TLBIW, AArch64::AEK_JSCVT,1436 AArch64::AEK_FCMA, AArch64::AEK_FP8,1437 AArch64::AEK_SVEB16B16, AArch64::AEK_SVE2P2,1438 AArch64::AEK_SME2P2, AArch64::AEK_SVE_BFSCALE,1439 AArch64::AEK_SVE_F16F32MM, AArch64::AEK_SVE_AES2,1440 AArch64::AEK_SSVE_AES, AArch64::AEK_F8F32MM,1441 AArch64::AEK_F8F16MM, AArch64::AEK_LSFE,1442 AArch64::AEK_FPRCVT, AArch64::AEK_CMPBR,1443 AArch64::AEK_LSUI, AArch64::AEK_OCCMO,1444 AArch64::AEK_PCDPHINT, AArch64::AEK_POPS,1445 AArch64::AEK_SVEAES, AArch64::AEK_SME_MOP4,1446 AArch64::AEK_SME_TMOP, AArch64::AEK_SVEBITPERM,1447 AArch64::AEK_SSVE_BITPERM, AArch64::AEK_SVESHA3,1448 AArch64::AEK_SVESM4, AArch64::AEK_CMH,1449 AArch64::AEK_LSCP, AArch64::AEK_TLBID,1450 AArch64::AEK_MPAMV2, AArch64::AEK_MTETC,1451 AArch64::AEK_GCIE, AArch64::AEK_SME2P3,1452 AArch64::AEK_SVE2P3, AArch64::AEK_SVE_B16MM,1453 AArch64::AEK_F16MM, AArch64::AEK_F16F32DOT,1454 AArch64::AEK_F16F32MM, AArch64::AEK_MOPS_GO,1455 AArch64::AEK_POE2, AArch64::AEK_TEV,1456 AArch64::AEK_BTIE, AArch64::AEK_F64MM,1457 };1458 1459 std::vector<StringRef> Features;1460 1461 AArch64::ExtensionBitset ExtVal;1462 for (auto Ext : Extensions)1463 ExtVal.set(Ext);1464 1465 // Test an empty set of features.1466 EXPECT_TRUE(AArch64::getExtensionFeatures({}, Features));1467 EXPECT_TRUE(Features.size() == 0);1468 1469 AArch64::getExtensionFeatures(ExtVal, Features);1470 EXPECT_EQ(Extensions.size(), Features.size());1471 1472 EXPECT_TRUE(llvm::is_contained(Features, "+crc"));1473 EXPECT_TRUE(llvm::is_contained(Features, "+lse"));1474 EXPECT_TRUE(llvm::is_contained(Features, "+rdm"));1475 EXPECT_TRUE(llvm::is_contained(Features, "+crypto"));1476 EXPECT_TRUE(llvm::is_contained(Features, "+sm4"));1477 EXPECT_TRUE(llvm::is_contained(Features, "+sha3"));1478 EXPECT_TRUE(llvm::is_contained(Features, "+sha2"));1479 EXPECT_TRUE(llvm::is_contained(Features, "+aes"));1480 EXPECT_TRUE(llvm::is_contained(Features, "+dotprod"));1481 EXPECT_TRUE(llvm::is_contained(Features, "+fp-armv8"));1482 EXPECT_TRUE(llvm::is_contained(Features, "+neon"));1483 EXPECT_TRUE(llvm::is_contained(Features, "+fullfp16"));1484 EXPECT_TRUE(llvm::is_contained(Features, "+fp16fml"));1485 EXPECT_TRUE(llvm::is_contained(Features, "+spe"));1486 EXPECT_TRUE(llvm::is_contained(Features, "+ras"));1487 EXPECT_TRUE(llvm::is_contained(Features, "+sve"));1488 EXPECT_TRUE(llvm::is_contained(Features, "+sve-b16b16"));1489 EXPECT_TRUE(llvm::is_contained(Features, "+sve-bfscale"));1490 EXPECT_TRUE(llvm::is_contained(Features, "+sve-f16f32mm"));1491 EXPECT_TRUE(llvm::is_contained(Features, "+sve2"));1492 EXPECT_TRUE(llvm::is_contained(Features, "+sve-aes"));1493 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-aes"));1494 EXPECT_TRUE(llvm::is_contained(Features, "+sve-sm4"));1495 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sm4"));1496 EXPECT_TRUE(llvm::is_contained(Features, "+sve-sha3"));1497 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sha3"));1498 EXPECT_TRUE(llvm::is_contained(Features, "+sve-bitperm"));1499 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-bitperm"));1500 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-bitperm"));1501 EXPECT_TRUE(llvm::is_contained(Features, "+sve-aes2"));1502 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-aes"));1503 EXPECT_TRUE(llvm::is_contained(Features, "+sve2p1"));1504 EXPECT_TRUE(llvm::is_contained(Features, "+sve2p2"));1505 EXPECT_TRUE(llvm::is_contained(Features, "+rcpc"));1506 EXPECT_TRUE(llvm::is_contained(Features, "+rand"));1507 EXPECT_TRUE(llvm::is_contained(Features, "+mte"));1508 EXPECT_TRUE(llvm::is_contained(Features, "+ssbs"));1509 EXPECT_TRUE(llvm::is_contained(Features, "+sb"));1510 EXPECT_TRUE(llvm::is_contained(Features, "+predres"));1511 EXPECT_TRUE(llvm::is_contained(Features, "+bf16"));1512 EXPECT_TRUE(llvm::is_contained(Features, "+i8mm"));1513 EXPECT_TRUE(llvm::is_contained(Features, "+f32mm"));1514 EXPECT_TRUE(llvm::is_contained(Features, "+f64mm"));1515 EXPECT_TRUE(llvm::is_contained(Features, "+ls64"));1516 EXPECT_TRUE(llvm::is_contained(Features, "+brbe"));1517 EXPECT_TRUE(llvm::is_contained(Features, "+pauth"));1518 EXPECT_TRUE(llvm::is_contained(Features, "+flagm"));1519 EXPECT_TRUE(llvm::is_contained(Features, "+sme"));1520 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f64f64"));1521 EXPECT_TRUE(llvm::is_contained(Features, "+sme-i16i64"));1522 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f16f16"));1523 EXPECT_TRUE(llvm::is_contained(Features, "+sme2"));1524 EXPECT_TRUE(llvm::is_contained(Features, "+sme-b16b16"));1525 EXPECT_TRUE(llvm::is_contained(Features, "+sme2p1"));1526 EXPECT_TRUE(llvm::is_contained(Features, "+sme2p2"));1527 EXPECT_TRUE(llvm::is_contained(Features, "+hbc"));1528 EXPECT_TRUE(llvm::is_contained(Features, "+mops"));1529 EXPECT_TRUE(llvm::is_contained(Features, "+perfmon"));1530 EXPECT_TRUE(llvm::is_contained(Features, "+cssc"));1531 EXPECT_TRUE(llvm::is_contained(Features, "+rcpc3"));1532 EXPECT_TRUE(llvm::is_contained(Features, "+the"));1533 EXPECT_TRUE(llvm::is_contained(Features, "+d128"));1534 EXPECT_TRUE(llvm::is_contained(Features, "+lse128"));1535 EXPECT_TRUE(llvm::is_contained(Features, "+specres2"));1536 EXPECT_TRUE(llvm::is_contained(Features, "+ite"));1537 EXPECT_TRUE(llvm::is_contained(Features, "+gcs"));1538 EXPECT_TRUE(llvm::is_contained(Features, "+fp8"));1539 EXPECT_TRUE(llvm::is_contained(Features, "+faminmax"));1540 EXPECT_TRUE(llvm::is_contained(Features, "+fp8fma"));1541 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8fma"));1542 EXPECT_TRUE(llvm::is_contained(Features, "+fp8dot2"));1543 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8dot2"));1544 EXPECT_TRUE(llvm::is_contained(Features, "+fp8dot4"));1545 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8dot4"));1546 EXPECT_TRUE(llvm::is_contained(Features, "+f8f32mm"));1547 EXPECT_TRUE(llvm::is_contained(Features, "+f8f16mm"));1548 EXPECT_TRUE(llvm::is_contained(Features, "+lut"));1549 EXPECT_TRUE(llvm::is_contained(Features, "+sme-lutv2"));1550 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f8f16"));1551 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f8f32"));1552 EXPECT_TRUE(llvm::is_contained(Features, "+sme-fa64"));1553 EXPECT_TRUE(llvm::is_contained(Features, "+cpa"));1554 EXPECT_TRUE(llvm::is_contained(Features, "+pauth-lr"));1555 EXPECT_TRUE(llvm::is_contained(Features, "+tlbiw"));1556 EXPECT_TRUE(llvm::is_contained(Features, "+jsconv"));1557 EXPECT_TRUE(llvm::is_contained(Features, "+complxnum"));1558 EXPECT_TRUE(llvm::is_contained(Features, "+lsfe"));1559 EXPECT_TRUE(llvm::is_contained(Features, "+fprcvt"));1560 EXPECT_TRUE(llvm::is_contained(Features, "+cmpbr"));1561 EXPECT_TRUE(llvm::is_contained(Features, "+lsui"));1562 EXPECT_TRUE(llvm::is_contained(Features, "+occmo"));1563 EXPECT_TRUE(llvm::is_contained(Features, "+pcdphint"));1564 EXPECT_TRUE(llvm::is_contained(Features, "+pops"));1565 EXPECT_TRUE(llvm::is_contained(Features, "+sme-mop4"));1566 EXPECT_TRUE(llvm::is_contained(Features, "+sme-tmop"));1567 EXPECT_TRUE(llvm::is_contained(Features, "+cmh"));1568 EXPECT_TRUE(llvm::is_contained(Features, "+lscp"));1569 EXPECT_TRUE(llvm::is_contained(Features, "+tlbid"));1570 EXPECT_TRUE(llvm::is_contained(Features, "+mpamv2"));1571 EXPECT_TRUE(llvm::is_contained(Features, "+mtetc"));1572 EXPECT_TRUE(llvm::is_contained(Features, "+gcie"));1573 EXPECT_TRUE(llvm::is_contained(Features, "+sme2p3"));1574 EXPECT_TRUE(llvm::is_contained(Features, "+sve2p3"));1575 EXPECT_TRUE(llvm::is_contained(Features, "+sve-b16mm"));1576 EXPECT_TRUE(llvm::is_contained(Features, "+f16mm"));1577 EXPECT_TRUE(llvm::is_contained(Features, "+f16f32dot"));1578 EXPECT_TRUE(llvm::is_contained(Features, "+f16f32mm"));1579 EXPECT_TRUE(llvm::is_contained(Features, "+mops-go"));1580 EXPECT_TRUE(llvm::is_contained(Features, "+poe2"));1581 EXPECT_TRUE(llvm::is_contained(Features, "+tev"));1582 EXPECT_TRUE(llvm::is_contained(Features, "+btie"));1583 1584 // Assuming we listed every extension above, this should produce the same1585 // result.1586 std::vector<StringRef> AllFeatures;1587 EXPECT_TRUE(AArch64::getExtensionFeatures(ExtVal, AllFeatures));1588 EXPECT_THAT(Features, ::testing::ContainerEq(AllFeatures));1589}1590 1591TEST(TargetParserTest, AArch64ArchFeatures) {1592 EXPECT_EQ(AArch64::ARMV8A.ArchFeature, "+v8a");1593 EXPECT_EQ(AArch64::ARMV8_1A.ArchFeature, "+v8.1a");1594 EXPECT_EQ(AArch64::ARMV8_2A.ArchFeature, "+v8.2a");1595 EXPECT_EQ(AArch64::ARMV8_3A.ArchFeature, "+v8.3a");1596 EXPECT_EQ(AArch64::ARMV8_4A.ArchFeature, "+v8.4a");1597 EXPECT_EQ(AArch64::ARMV8_5A.ArchFeature, "+v8.5a");1598 EXPECT_EQ(AArch64::ARMV8_6A.ArchFeature, "+v8.6a");1599 EXPECT_EQ(AArch64::ARMV8_7A.ArchFeature, "+v8.7a");1600 EXPECT_EQ(AArch64::ARMV8_8A.ArchFeature, "+v8.8a");1601 EXPECT_EQ(AArch64::ARMV8_9A.ArchFeature, "+v8.9a");1602 EXPECT_EQ(AArch64::ARMV9A.ArchFeature, "+v9a");1603 EXPECT_EQ(AArch64::ARMV9_1A.ArchFeature, "+v9.1a");1604 EXPECT_EQ(AArch64::ARMV9_2A.ArchFeature, "+v9.2a");1605 EXPECT_EQ(AArch64::ARMV9_3A.ArchFeature, "+v9.3a");1606 EXPECT_EQ(AArch64::ARMV9_4A.ArchFeature, "+v9.4a");1607 EXPECT_EQ(AArch64::ARMV9_5A.ArchFeature, "+v9.5a");1608 EXPECT_EQ(AArch64::ARMV9_6A.ArchFeature, "+v9.6a");1609 EXPECT_EQ(AArch64::ARMV9_7A.ArchFeature, "+v9.7a");1610 EXPECT_EQ(AArch64::ARMV8R.ArchFeature, "+v8r");1611}1612 1613TEST(TargetParserTest, AArch64ArchPartialOrder) {1614 for (const auto *A : AArch64::ArchInfos) {1615 EXPECT_EQ(*A, *A);1616 1617 // v8r has no relation to other valid architectures1618 if (*A != AArch64::ARMV8R) {1619 EXPECT_FALSE(A->implies(AArch64::ARMV8R));1620 EXPECT_FALSE(AArch64::ARMV8R.implies(*A));1621 }1622 }1623 1624 for (const auto *A : {1625 &AArch64::ARMV8_1A,1626 &AArch64::ARMV8_2A,1627 &AArch64::ARMV8_3A,1628 &AArch64::ARMV8_4A,1629 &AArch64::ARMV8_5A,1630 &AArch64::ARMV8_6A,1631 &AArch64::ARMV8_7A,1632 &AArch64::ARMV8_8A,1633 &AArch64::ARMV8_9A,1634 })1635 EXPECT_TRUE(A->implies(AArch64::ARMV8A));1636 1637 for (const auto *A :1638 {&AArch64::ARMV9_1A, &AArch64::ARMV9_2A, &AArch64::ARMV9_3A,1639 &AArch64::ARMV9_4A, &AArch64::ARMV9_5A, &AArch64::ARMV9_6A,1640 &AArch64::ARMV9_7A})1641 EXPECT_TRUE(A->implies(AArch64::ARMV9A));1642 1643 EXPECT_TRUE(AArch64::ARMV8_1A.implies(AArch64::ARMV8A));1644 EXPECT_TRUE(AArch64::ARMV8_2A.implies(AArch64::ARMV8_1A));1645 EXPECT_TRUE(AArch64::ARMV8_3A.implies(AArch64::ARMV8_2A));1646 EXPECT_TRUE(AArch64::ARMV8_4A.implies(AArch64::ARMV8_3A));1647 EXPECT_TRUE(AArch64::ARMV8_5A.implies(AArch64::ARMV8_4A));1648 EXPECT_TRUE(AArch64::ARMV8_6A.implies(AArch64::ARMV8_5A));1649 EXPECT_TRUE(AArch64::ARMV8_7A.implies(AArch64::ARMV8_6A));1650 EXPECT_TRUE(AArch64::ARMV8_8A.implies(AArch64::ARMV8_7A));1651 EXPECT_TRUE(AArch64::ARMV8_9A.implies(AArch64::ARMV8_8A));1652 1653 EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV9A));1654 EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV9_1A));1655 EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV9_2A));1656 EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV9_3A));1657 EXPECT_TRUE(AArch64::ARMV9_5A.implies(AArch64::ARMV9_4A));1658 EXPECT_TRUE(AArch64::ARMV9_6A.implies(AArch64::ARMV9_5A));1659 EXPECT_TRUE(AArch64::ARMV9_7A.implies(AArch64::ARMV9_6A));1660 1661 EXPECT_TRUE(AArch64::ARMV9A.implies(AArch64::ARMV8_5A));1662 EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV8_6A));1663 EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV8_7A));1664 EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV8_8A));1665 EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV8_9A));1666}1667 1668TEST(TargetParserTest, AArch64ArchExtFeature) {1669 const char *ArchExt[][4] = {1670 {"crc", "nocrc", "+crc", "-crc"},1671 {"crypto", "nocrypto", "+crypto", "-crypto"},1672 {"flagm", "noflagm", "+flagm", "-flagm"},1673 {"fp", "nofp", "+fp-armv8", "-fp-armv8"},1674 {"simd", "nosimd", "+neon", "-neon"},1675 {"fp16", "nofp16", "+fullfp16", "-fullfp16"},1676 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},1677 {"profile", "noprofile", "+spe", "-spe"},1678 {"ras", "noras", "+ras", "-ras"},1679 {"lse", "nolse", "+lse", "-lse"},1680 {"rdm", "nordm", "+rdm", "-rdm"},1681 {"sve", "nosve", "+sve", "-sve"},1682 {"sve-b16b16", "nosve-b16b16", "+sve-b16b16", "-sve-b16b16"},1683 {"sve-bfscale", "nosve-bfscale", "+sve-bfscale", "-sve-bfscale"},1684 {"sve-f16f32mm", "nosve-f16f32mm", "+sve-f16f32mm", "-sve-f16f32mm"},1685 {"sve2", "nosve2", "+sve2", "-sve2"},1686 {"sve-aes", "nosve-aes", "+sve-aes", "-sve-aes"},1687 {"sve-sm4", "nosve-sm4", "+sve-sm4", "-sve-sm4"},1688 {"sve-sha3", "nosve-sha3", "+sve-sha3", "-sve-sha3"},1689 {"sve2-aes", "nosve2-aes", "+sve2-aes", "-sve2-aes"},1690 {"sve2-sm4", "nosve2-sm4", "+sve2-sm4", "-sve2-sm4"},1691 {"sve2-sha3", "nosve2-sha3", "+sve2-sha3", "-sve2-sha3"},1692 {"sve2p1", "nosve2p1", "+sve2p1", "-sve2p1"},1693 {"sve2p2", "nosve2p2", "+sve2p2", "-sve2p2"},1694 {"sve-bitperm", "nosve-bitperm", "+sve-bitperm", "-sve-bitperm"},1695 {"ssve-bitperm", "nossve-bitperm", "+ssve-bitperm", "-ssve-bitperm"},1696 {"sve2-bitperm", "nosve2-bitperm", "+sve2-bitperm", "-sve2-bitperm"},1697 {"sve-aes2", "nosve-aes2", "+sve-aes2", "-sve-aes2"},1698 {"ssve-aes", "nossve-aes", "+ssve-aes", "-ssve-aes"},1699 {"dotprod", "nodotprod", "+dotprod", "-dotprod"},1700 {"rcpc", "norcpc", "+rcpc", "-rcpc"},1701 {"rng", "norng", "+rand", "-rand"},1702 {"memtag", "nomemtag", "+mte", "-mte"},1703 {"pauth", "nopauth", "+pauth", "-pauth"},1704 {"ssbs", "nossbs", "+ssbs", "-ssbs"},1705 {"sb", "nosb", "+sb", "-sb"},1706 {"predres", "nopredres", "+predres", "-predres"},1707 {"i8mm", "noi8mm", "+i8mm", "-i8mm"},1708 {"f32mm", "nof32mm", "+f32mm", "-f32mm"},1709 {"f64mm", "nof64mm", "+f64mm", "-f64mm"},1710 {"f8f32mm", "nof8f32mm", "+f8f32mm", "-f8f32mm"},1711 {"f8f16mm", "nof8f16mm", "+f8f16mm", "-f8f16mm"},1712 {"sme", "nosme", "+sme", "-sme"},1713 {"sme-fa64", "nosme-fa64", "+sme-fa64", "-sme-fa64"},1714 {"sme-f64f64", "nosme-f64f64", "+sme-f64f64", "-sme-f64f64"},1715 {"sme-i16i64", "nosme-i16i64", "+sme-i16i64", "-sme-i16i64"},1716 {"sme-f16f16", "nosme-f16f16", "+sme-f16f16", "-sme-f16f16"},1717 {"sme2", "nosme2", "+sme2", "-sme2"},1718 {"sme-b16b16", "nosme-b16b16", "+sme-b16b16", "-sme-b16b16"},1719 {"sme2p1", "nosme2p1", "+sme2p1", "-sme2p1"},1720 {"sme2p2", "nosme2p2", "+sme2p2", "-sme2p2"},1721 {"hbc", "nohbc", "+hbc", "-hbc"},1722 {"mops", "nomops", "+mops", "-mops"},1723 {"pmuv3", "nopmuv3", "+perfmon", "-perfmon"},1724 {"predres2", "nopredres2", "+specres2", "-specres2"},1725 {"rasv2", "norasv2", "+rasv2", "-rasv2"},1726 {"gcs", "nogcs", "+gcs", "-gcs"},1727 {"fp8", "nofp8", "+fp8", "-fp8"},1728 {"faminmax", "nofaminmax", "+faminmax", "-faminmax"},1729 {"fp8fma", "nofp8fma", "+fp8fma", "-fp8fma"},1730 {"ssve-fp8fma", "nossve-fp8fma", "+ssve-fp8fma", "-ssve-fp8fma"},1731 {"fp8dot2", "nofp8dot2", "+fp8dot2", "-fp8dot2"},1732 {"ssve-fp8dot2", "nossve-fp8dot2", "+ssve-fp8dot2", "-ssve-fp8dot2"},1733 {"fp8dot4", "nofp8dot4", "+fp8dot4", "-fp8dot4"},1734 {"ssve-fp8dot4", "nossve-fp8dot4", "+ssve-fp8dot4", "-ssve-fp8dot4"},1735 {"lut", "nolut", "+lut", "-lut"},1736 {"sme-lutv2", "nosme-lutv2", "+sme-lutv2", "-sme-lutv2"},1737 {"sme-f8f16", "nosme-f8f16", "+sme-f8f16", "-sme-f8f16"},1738 {"sme-f8f32", "nosme-f8f32", "+sme-f8f32", "-sme-f8f32"},1739 {"lsfe", "nolsfe", "+lsfe", "-lsfe"},1740 {"fprcvt", "nofprcvt", "+fprcvt", "-fprcvt"},1741 {"cmpbr", "nocmpbr", "+cmpbr", "-cmpbr"},1742 {"lsui", "nolsui", "+lsui", "-lsui"},1743 {"occmo", "nooccmo", "+occmo", "-occmo"},1744 {"pcdphint", "nopcdphint", "+pcdphint", "-pcdphint"},1745 {"pops", "nopops", "+pops", "-pops"},1746 {"sme-mop4", "nosme-mop4", "+sme-mop4", "-sme-mop4"},1747 {"sme-tmop", "nosme-tmop", "+sme-tmop", "-sme-tmop"},1748 {"cmh", "nocmh", "+cmh", "-cmh"},1749 {"lscp", "nolscp", "+lscp", "-lscp"},1750 {"tlbid", "notlbid", "+tlbid", "-tlbid"},1751 {"mpamv2", "nompamv2", "+mpamv2", "-mpamv2"},1752 {"mtetc", "nomtetc", "+mtetc", "-mtetc"},1753 {"gcie", "nogcie", "+gcie", "-gcie"},1754 {"sme2p3", "nosme2p3", "+sme2p3", "-sme2p3"},1755 {"sve2p3", "nosve2p3", "+sve2p3", "-sve2p3"},1756 {"sve-b16mm", "nosve-b16mm", "+sve-b16mm", "-sve-b16mm"},1757 {"f16mm", "nof16mm", "+f16mm", "-f16mm"},1758 {"f16f32dot", "nof16f32dot", "+f16f32dot", "-f16f32dot"},1759 {"f16f32mm", "nof16f32mm", "+f16f32mm", "-f16f32mm"},1760 {"mops-go", "nomops-go", "+mops-go", "-mops-go"},1761 {"poe2", "nopoe2", "+poe2", "-poe2"},1762 {"tev", "notev", "+tev", "-tev"},1763 {"btie", "nobtie", "+btie", "-btie"},1764 };1765 1766 for (unsigned i = 0; i < std::size(ArchExt); i++) {1767 EXPECT_EQ(StringRef(ArchExt[i][2]),1768 AArch64::getArchExtFeature(ArchExt[i][0]));1769 EXPECT_EQ(StringRef(ArchExt[i][3]),1770 AArch64::getArchExtFeature(ArchExt[i][1]));1771 }1772}1773 1774TEST(TargetParserTest, AArch64PrintSupportedExtensions) {1775 std::string expected = "All available -march extensions for AArch64\n\n"1776 " Name Architecture Feature(s) "1777 " Description\n";1778 1779 outs().flush();1780 testing::internal::CaptureStdout();1781 AArch64::PrintSupportedExtensions();1782 outs().flush();1783 std::string captured = testing::internal::GetCapturedStdout();1784 1785 // Check that the start of the output is as expected.1786 EXPECT_EQ(0ULL, captured.find(expected));1787 1788 // Should not include "none".1789 EXPECT_EQ(std::string::npos, captured.find("none"));1790 // Should not include anything that lacks a feature name. Checking a few here1791 // but not all as if one is hidden correctly the rest should be.1792 EXPECT_EQ(std::string::npos, captured.find("memtag3"));1793 EXPECT_EQ(std::string::npos, captured.find("sha1"));1794 EXPECT_EQ(std::string::npos, captured.find("ssbs2"));1795}1796 1797struct AArch64ExtensionDependenciesBaseArchTestParams {1798 const llvm::AArch64::ArchInfo &Arch;1799 std::vector<StringRef> Modifiers;1800 std::vector<StringRef> ExpectedPos;1801 std::vector<StringRef> ExpectedNeg;1802};1803 1804class AArch64ExtensionDependenciesBaseArchTestFixture1805 : public ::testing::TestWithParam<1806 AArch64ExtensionDependenciesBaseArchTestParams> {};1807 1808struct AArch64ExtensionDependenciesBaseCPUTestParams {1809 StringRef CPUName;1810 std::vector<StringRef> Modifiers;1811 std::vector<StringRef> ExpectedPos;1812 std::vector<StringRef> ExpectedNeg;1813};1814 1815class AArch64ExtensionDependenciesBaseCPUTestFixture1816 : public ::testing::TestWithParam<1817 AArch64ExtensionDependenciesBaseCPUTestParams> {};1818 1819TEST_P(AArch64ExtensionDependenciesBaseArchTestFixture,1820 AArch64ExtensionDependenciesBaseArch) {1821 auto Params = GetParam();1822 1823 llvm::AArch64::ExtensionSet Extensions;1824 Extensions.addArchDefaults(Params.Arch);1825 for (auto M : Params.Modifiers) {1826 bool success = Extensions.parseModifier(M);1827 EXPECT_TRUE(success);1828 }1829 std::vector<StringRef> Features;1830 Extensions.toLLVMFeatureList(Features);1831 1832 for (auto E : Params.ExpectedPos) {1833 std::string PosString = "+";1834 PosString += E;1835 std::string NegString = "-";1836 NegString += E;1837 ASSERT_THAT(Features, Contains(StrEq(PosString)));1838 ASSERT_THAT(Features, Not(Contains(StrEq(NegString))));1839 }1840 1841 for (auto E : Params.ExpectedNeg) {1842 std::string PosString = "+";1843 PosString += E;1844 ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));1845 // Features default to off, so the negative string is not expected in many1846 // cases.1847 }1848}1849 1850TEST_P(AArch64ExtensionDependenciesBaseCPUTestFixture,1851 AArch64ExtensionDependenciesBaseCPU) {1852 auto Params = GetParam();1853 1854 llvm::AArch64::ExtensionSet Extensions;1855 const std::optional<llvm::AArch64::CpuInfo> CPU =1856 llvm::AArch64::parseCpu(Params.CPUName);1857 EXPECT_TRUE(CPU);1858 Extensions.addCPUDefaults(*CPU);1859 for (auto M : Params.Modifiers) {1860 bool success = Extensions.parseModifier(M);1861 EXPECT_TRUE(success);1862 }1863 std::vector<StringRef> Features;1864 Extensions.toLLVMFeatureList(Features);1865 1866 for (auto E : Params.ExpectedPos) {1867 std::string PosString = "+";1868 PosString += E;1869 std::string NegString = "-";1870 NegString += E;1871 ASSERT_THAT(Features, Contains(StrEq(PosString)));1872 ASSERT_THAT(Features, Not(Contains(StrEq(NegString))));1873 }1874 1875 for (auto E : Params.ExpectedNeg) {1876 std::string PosString = "+";1877 PosString += E;1878 ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));1879 // Features default to off, so the negative string is not expected in many1880 // cases.1881 }1882}1883 1884TEST(TargetParserTest, testAArch64ReconstructFromParsedFeatures) {1885 AArch64::ExtensionSet Extensions;1886 std::vector<std::string> FeatureOptions = {1887 "-sve2", "-Baz", "+sve", "+FooBar", "+sve2", "+neon", "-sve",1888 };1889 std::vector<std::string> NonExtensions;1890 Extensions.reconstructFromParsedFeatures(FeatureOptions, NonExtensions);1891 1892 std::vector<std::string> NonExtensionsExpected = {"-Baz", "+FooBar"};1893 ASSERT_THAT(NonExtensions, testing::ContainerEq(NonExtensionsExpected));1894 std::vector<StringRef> Features;1895 Extensions.toLLVMFeatureList(Features);1896 std::vector<StringRef> FeaturesExpected = {"+neon", "-sve", "+sve2"};1897 ASSERT_THAT(Features, testing::ContainerEq(FeaturesExpected));1898}1899 1900AArch64ExtensionDependenciesBaseArchTestParams1901 AArch64ExtensionDependenciesArchData[] = {1902 // Base architecture features1903 {AArch64::ARMV8A, {}, {"v8a", "fp-armv8", "neon"}, {}},1904 {AArch64::ARMV8_1A,1905 {},1906 {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"},1907 {}},1908 {AArch64::ARMV9_5A, {}, {"v9.5a", "mops", "cpa"}, {}},1909 1910 // Positive modifiers1911 {AArch64::ARMV8A, {"fp16"}, {"fullfp16"}, {}},1912 {AArch64::ARMV8A, {"dotprod"}, {"dotprod"}, {}},1913 1914 // Negative modifiers1915 {AArch64::ARMV8A, {"nofp"}, {"v8a"}, {"fp-armv8", "neon"}},1916 1917 // Mixed modifiers1918 {AArch64::ARMV8A,1919 {"fp16", "nofp16"},1920 {"v8a", "fp-armv8", "neon"},1921 {"fullfp16"}},1922 {AArch64::ARMV8A,1923 {"fp16", "nofp"},1924 {"v8a"},1925 {"fp-armv8", "neon", "fullfp16"}},1926 1927 // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp1928 {AArch64::ARMV8A,1929 {"nofp", "sve2", "sve-bitperm"},1930 {"fp-armv8", "fullfp16", "sve", "sve2", "sve-bitperm"},1931 {}},1932 {AArch64::ARMV8A,1933 {"sve2", "sve-bitperm", "nofp16"},1934 {"fp-armv8"},1935 {"full-fp16", "sve", "sve2", "sve-bitperm"}},1936 1937 // Meaning of +crypto varies with base architecture.1938 {AArch64::ARMV8A, {"crypto"}, {"aes", "sha2"}, {}},1939 {AArch64::ARMV8_4A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},1940 {AArch64::ARMV9A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},1941 1942 // -crypto always disables all crypto features, even if it wouldn't1943 // enable them.1944 {AArch64::ARMV8A,1945 {"aes", "sha2", "sha3", "sm4", "nocrypto"},1946 {},1947 {"aes", "sha2", "sha3", "sm4"}},1948 {AArch64::ARMV8_4A,1949 {"aes", "sha2", "sha3", "sm4", "nocrypto"},1950 {},1951 {"aes", "sha2", "sha3", "sm4"}},1952 1953 // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+1954 {AArch64::ARMV8_3A, {"fp16"}, {"fullfp16"}, {"fp16fml"}},1955 {AArch64::ARMV9A, {"fp16"}, {"fullfp16"}, {"fp16fml"}},1956 {AArch64::ARMV8_4A, {"fp16"}, {"fullfp16", "fp16fml"}, {}},1957 1958 // fp -> fp161959 {AArch64::ARMV8A, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}},1960 {AArch64::ARMV8A, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}},1961 1962 // fp -> simd1963 {AArch64::ARMV8A, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}},1964 {AArch64::ARMV8A, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}},1965 1966 // fp -> jscvt1967 {AArch64::ARMV8A, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}},1968 {AArch64::ARMV8A, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}},1969 1970 // fp -> lsfe1971 {AArch64::ARMV9_6A, {"nofp", "lsfe"}, {"fp-armv8", "lsfe"}, {}},1972 {AArch64::ARMV9_6A, {"lsfe", "nofp"}, {}, {"fp-armv8", "lsfe"}},1973 1974 // fp -> fprcvt1975 {AArch64::ARMV9_6A, {"nofp", "fprcvt"}, {"fp-armv8", "fprcvt"}, {}},1976 {AArch64::ARMV9_6A, {"fprcvt", "nofp"}, {}, {"fp-armv8", "fprcvt"}},1977 1978 // simd -> {aes, sha2, sha3, sm4, f8f16mm, f8f32mm, faminmax, lut, fp8,1979 // f16f32dot, f16f32mm}1980 {AArch64::ARMV8A, {"nosimd", "aes"}, {"neon", "aes"}, {}},1981 {AArch64::ARMV8A, {"aes", "nosimd"}, {}, {"neon", "aes"}},1982 {AArch64::ARMV8A, {"nosimd", "sha2"}, {"neon", "sha2"}, {}},1983 {AArch64::ARMV8A, {"sha2", "nosimd"}, {}, {"neon", "sha2"}},1984 {AArch64::ARMV8A, {"nosimd", "sha3"}, {"neon", "sha3"}, {}},1985 {AArch64::ARMV8A, {"sha3", "nosimd"}, {}, {"neon", "sha3"}},1986 {AArch64::ARMV8A, {"nosimd", "sm4"}, {"neon", "sm4"}, {}},1987 {AArch64::ARMV8A, {"sm4", "nosimd"}, {}, {"neon", "sm4"}},1988 {AArch64::ARMV9_6A, {"nosimd", "f8f16mm"}, {"neon", "f8f16mm"}, {}},1989 {AArch64::ARMV9_6A, {"f8f16mm", "nosimd"}, {}, {"neon", "f8f16mm"}},1990 {AArch64::ARMV9_6A, {"nosimd", "f8f32mm"}, {"neon", "f8f32mm"}, {}},1991 {AArch64::ARMV9_6A, {"f8f32mm", "nosimd"}, {}, {"neon", "f8f32mm"}},1992 {AArch64::ARMV9_6A, {"faminmax", "nosimd"}, {}, {"neon", "faminmax"}},1993 {AArch64::ARMV9_6A, {"nosimd", "faminmax"}, {"neon", "faminmax"}, {}},1994 {AArch64::ARMV9_6A, {"lut", "nosimd"}, {}, {"neon", "lut"}},1995 {AArch64::ARMV9_6A, {"nosimd", "lut"}, {"neon", "lut"}, {}},1996 {AArch64::ARMV9_6A, {"fp8", "nosimd"}, {}, {"neon", "fp8"}},1997 {AArch64::ARMV9_6A, {"nosimd", "fp8"}, {"neon", "fp8"}, {}},1998 {AArch64::ARMV9_7A, {"nosimd", "f16f32mm"}, {"neon", "f16f32mm"}, {}},1999 {AArch64::ARMV9_7A, {"f16f32mm", "nosimd"}, {}, {"neon", "f16f32mm"}},2000 {AArch64::ARMV9_7A, {"nosimd", "f16f32dot"}, {"neon", "f16f32dot"}, {}},2001 {AArch64::ARMV9_7A, {"f16f32dot", "nosimd"}, {}, {"neon", "f16f32dot"}},2002 2003 // fp8 -> {fp8dot4, fp8dot2}2004 {AArch64::ARMV9_6A, {"nofp8", "fp8dot4"}, {"fp8", "fp8dot4"}, {}},2005 {AArch64::ARMV9_6A, {"fp8dot4", "nofp8"}, {}, {"fp8", "fp8dot4"}},2006 {AArch64::ARMV9_6A, {"nofp8", "fp8dot2"}, {"fp8", "fp8dot2"}, {}},2007 {AArch64::ARMV9_6A, {"fp8dot2", "nofp8"}, {}, {"fp8", "fp8dot2"}},2008 2009 // simd -> {rdm, dotprod, fcma}2010 {AArch64::ARMV8A, {"nosimd", "rdm"}, {"neon", "rdm"}, {}},2011 {AArch64::ARMV8A, {"rdm", "nosimd"}, {}, {"neon", "rdm"}},2012 {AArch64::ARMV8A, {"nosimd", "dotprod"}, {"neon", "dotprod"}, {}},2013 {AArch64::ARMV8A, {"dotprod", "nosimd"}, {}, {"neon", "dotprod"}},2014 {AArch64::ARMV8A, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}},2015 {AArch64::ARMV8A, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}},2016 2017 // fp16 -> {fp16fml, sve, f16f32dot, f16f32mm, f16mm}2018 {AArch64::ARMV8A, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}},2019 {AArch64::ARMV8A, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}},2020 {AArch64::ARMV8A, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}},2021 {AArch64::ARMV8A, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}},2022 {AArch64::ARMV9_7A, {"nofp16", "f16mm"}, {"fullfp16", "f16mm"}, {}},2023 {AArch64::ARMV9_7A, {"f16mm", "nofp16"}, {}, {"fullfp16", "f16mm"}},2024 {AArch64::ARMV9_7A,2025 {"nofp16", "f16f32mm"},2026 {"fullfp16", "f16f32mm"},2027 {}},2028 {AArch64::ARMV9_7A,2029 {"f16f32mm", "nofp16"},2030 {},2031 {"fullfp16", "f16f32mm"}},2032 {AArch64::ARMV9_7A,2033 {"nofp16", "f16f32dot"},2034 {"fullfp16", "f16f32dot"},2035 {}},2036 {AArch64::ARMV9_7A,2037 {"f16f32dot", "nofp16"},2038 {},2039 {"fullfp16", "f16f32dot"}},2040 2041 // bf16 -> {sme}2042 {AArch64::ARMV8A, {"nobf16", "sme"}, {"bf16", "sme"}, {}},2043 {AArch64::ARMV8A, {"sme", "nobf16"}, {}, {"bf16", "sme"}},2044 2045 // sve -> {sve2, f32mm, f64mm, sve-f16f32mm, sve-b16mm}2046 {AArch64::ARMV8A, {"nosve", "sve2"}, {"sve", "sve2"}, {}},2047 {AArch64::ARMV8A, {"sve2", "nosve"}, {}, {"sve", "sve2"}},2048 {AArch64::ARMV8A, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}},2049 {AArch64::ARMV8A, {"f32mm", "nosve"}, {}, {"sve", "f32mm"}},2050 {AArch64::ARMV8A, {"nosve", "f64mm"}, {"sve", "f64mm"}, {}},2051 {AArch64::ARMV8A, {"f64mm", "nosve"}, {}, {"sve", "f64mm"}},2052 {AArch64::ARMV9_6A,2053 {"nosve", "sve-f16f32mm"},2054 {"sve", "sve-f16f32mm"},2055 {}},2056 {AArch64::ARMV9_6A,2057 {"sve-f16f32mm", "nosve"},2058 {},2059 {"sve", "sve-f16f32mm"}},2060 {AArch64::ARMV9_7A, {"nosve", "sve-b16mm"}, {"sve", "sve-b16mm"}, {}},2061 {AArch64::ARMV9_7A, {"sve-b16mm", "nosve"}, {}, {"sve", "sve-b16mm"}},2062 2063 // aes -> {sve-aes}2064 {AArch64::ARMV8A, {"noaes", "sve-aes"}, {"aes", "sve-aes"}, {}},2065 {AArch64::ARMV8A, {"sve-aes", "noaes"}, {}, {"aes", "sve-aes"}},2066 2067 // sve2 -> {sve2p1, sve2-bitperm, sve2-sha3, sve2-sm4, sve2-aes}2068 {AArch64::ARMV8A, {"nosve2", "sve2p1"}, {"sve2", "sve2p1"}, {}},2069 {AArch64::ARMV8A, {"sve2p1", "nosve2"}, {}, {"sve2", "sve2p1"}},2070 {AArch64::ARMV8A,2071 {"nosve2", "sve2-bitperm"},2072 {"sve2", "sve-bitperm"},2073 {}},2074 {AArch64::ARMV8A,2075 {"sve2-bitperm", "nosve2"},2076 {"sve"},2077 {"sve-bitperm", "sve2", "sve2-bitperm"}},2078 {AArch64::ARMV8A,2079 {"ssve-bitperm", "nosve-bitperm"},2080 {"sme"},2081 {"ssve-bitperm", "sve-bitperm"}},2082 {AArch64::ARMV8A,2083 {"nosve-bitperm", "ssve-bitperm"},2084 {"sve-bitperm", "sve-bitperm"},2085 {""}},2086 {AArch64::ARMV8A, {"nosve2", "sve2-sha3"}, {"sve2", "sve2-sha3"}, {}},2087 {AArch64::ARMV8A, {"sve2-sha3", "nosve2"}, {}, {"sve2", "sve2-sha3"}},2088 {AArch64::ARMV8A, {"nosve2", "sve2-sm4"}, {"sve2", "sve2-sm4"}, {}},2089 {AArch64::ARMV8A, {"sve2-sm4", "nosve2"}, {}, {"sve2", "sve2-sm4"}},2090 {AArch64::ARMV8A, {"nosve2", "sve2-aes"}, {"sve2", "sve2-aes"}, {}},2091 {AArch64::ARMV8A, {"sve2-aes", "nosve2"}, {}, {"sve2", "sve2-aes"}},2092 2093 // sve-b16b16 -> {sme-b16b16}2094 {AArch64::ARMV9_4A,2095 {"nosve-b16b16", "sme-b16b16"},2096 {"sve-b16b16", "sme-b16b16"},2097 {}},2098 {AArch64::ARMV9_4A,2099 {"sme-b16b16", "nosve-b16b16"},2100 {},2101 {"sve-b16b16", "sme-b16b16"}},2102 2103 // sve2p1 -> {sve2p2}2104 {AArch64::ARMV9_6A, {"nosve2p1", "sve2p2"}, {"sve2p1", "sve2p2"}, {}},2105 {AArch64::ARMV9_6A, {"sve2p2", "nosve2p1"}, {}, {"sve2p1", "sve2p2"}},2106 2107 // sve2p2 -> {sve2p3}2108 {AArch64::ARMV9_7A, {"nosve2p2", "sve2p3"}, {"sve2p2", "sve2p3"}, {}},2109 {AArch64::ARMV9_7A, {"sve2p3", "nosve2p2"}, {}, {"sve2p2", "sve2p3"}},2110 2111 // sme -> {sme2, sme-f16f16, sme-f64f64, sme-i16i64, sme-fa64}2112 {AArch64::ARMV8A, {"nosme", "sme2"}, {"sme", "sme2"}, {}},2113 {AArch64::ARMV8A, {"sme2", "nosme"}, {}, {"sme", "sme2"}},2114 {AArch64::ARMV8A, {"nosme", "sme-f16f16"}, {"sme", "sme-f16f16"}, {}},2115 {AArch64::ARMV8A, {"sme-f16f16", "nosme"}, {}, {"sme", "sme-f16f16"}},2116 {AArch64::ARMV8A, {"nosme", "sme-f64f64"}, {"sme", "sme-f64f64"}, {}},2117 {AArch64::ARMV8A, {"sme-f64f64", "nosme"}, {}, {"sme", "sme-f64f64"}},2118 {AArch64::ARMV8A, {"nosme", "sme-i16i64"}, {"sme", "sme-i16i64"}, {}},2119 {AArch64::ARMV8A, {"sme-i16i64", "nosme"}, {}, {"sme", "sme-i16i64"}},2120 {AArch64::ARMV8A, {"nosme", "sme-fa64"}, {"sme", "sme-fa64"}, {}},2121 {AArch64::ARMV8A, {"sme-fa64", "nosme"}, {}, {"sme", "sme-fa64"}},2122 2123 // sme2 -> {sme2p1, ssve-fp8fma, ssve-fp8dot2, ssve-fp8dot4, sme-f8f16,2124 // sme-f8f32, sme-b16b16, ssve-aes}2125 {AArch64::ARMV8A, {"nosme2", "sme2p1"}, {"sme2", "sme2p1"}, {}},2126 {AArch64::ARMV8A, {"sme2p1", "nosme2"}, {}, {"sme2", "sme2p1"}},2127 {AArch64::ARMV8A,2128 {"nosme2", "ssve-fp8fma"},2129 {"sme2", "ssve-fp8fma"},2130 {}},2131 {AArch64::ARMV8A,2132 {"ssve-fp8fma", "nosme2"},2133 {},2134 {"sme2", "ssve-fp8fma"}},2135 {AArch64::ARMV8A,2136 {"nosme2", "ssve-fp8dot2"},2137 {"sme2", "ssve-fp8dot2"},2138 {}},2139 {AArch64::ARMV8A,2140 {"ssve-fp8dot2", "nosme2"},2141 {},2142 {"sme2", "ssve-fp8dot2"}},2143 {AArch64::ARMV8A,2144 {"nosme2", "ssve-fp8dot4"},2145 {"sme2", "ssve-fp8dot4"},2146 {}},2147 {AArch64::ARMV8A,2148 {"ssve-fp8dot4", "nosme2"},2149 {},2150 {"sme2", "ssve-fp8dot4"}},2151 {AArch64::ARMV8A, {"nosme2", "sme-f8f16"}, {"sme2", "sme-f8f16"}, {}},2152 {AArch64::ARMV8A, {"sme-f8f16", "nosme2"}, {}, {"sme2", "sme-f8f16"}},2153 {AArch64::ARMV8A, {"nosme2", "sme-f8f32"}, {"sme2", "sme-f8f32"}, {}},2154 {AArch64::ARMV8A, {"sme-f8f32", "nosme2"}, {}, {"sme2", "sme-f8f32"}},2155 {AArch64::ARMV8A, {"nosme2", "sme-b16b16"}, {"sme2", "sme-b16b16"}, {}},2156 {AArch64::ARMV8A, {"sme-b16b16", "nosme2"}, {}, {"sme2", "sme-b16b16"}},2157 {AArch64::ARMV9_6A, {"nosme2", "ssve-aes"}, {"sme2", "ssve-aes"}, {}},2158 {AArch64::ARMV9_6A, {"ssve-aes", "nosme2"}, {}, {"ssve-aes", "sme2"}},2159 2160 // sme2p1 -> {sme2p2}2161 {AArch64::ARMV9_6A, {"nosme2p1", "sme2p2"}, {"sme2p2", "sme2p1"}, {}},2162 {AArch64::ARMV9_6A, {"sme2p2", "nosme2p1"}, {}, {"sme2p1", "sme2p2"}},2163 2164 // sme2p2 -> {sme2p3}2165 {AArch64::ARMV9_7A, {"nosme2p2", "sme2p3"}, {"sme2p3", "sme2p2"}, {}},2166 {AArch64::ARMV9_7A, {"sme2p3", "nosme2p2"}, {}, {"sme2p2", "sme2p3"}},2167 2168 // fp8 -> {sme-f8f16, sme-f8f32, f8f16mm, f8f32mm, fp8dot4, fp8dot2,2169 // ssve-fp8dot4, ssve-fp8dot2}2170 {AArch64::ARMV8A, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}},2171 {AArch64::ARMV8A, {"sme-f8f16", "nofp8"}, {}, {"fp8", "sme-f8f16"}},2172 {AArch64::ARMV8A, {"nofp8", "sme-f8f32"}, {"fp8", "sme-f8f32"}, {}},2173 {AArch64::ARMV8A, {"sme-f8f32", "nofp8"}, {}, {"fp8", "sme-f8f32"}},2174 {AArch64::ARMV9_6A, {"nofp8", "f8f16mm"}, {"fp8", "f8f16mm"}, {}},2175 {AArch64::ARMV9_6A, {"f8f16mm", "nofp8"}, {}, {"fp8", "f8f16mm"}},2176 {AArch64::ARMV9_6A, {"nofp8", "f8f32mm"}, {"fp8", "f8f32mm"}, {}},2177 {AArch64::ARMV9_6A, {"f8f32mm", "nofp8"}, {}, {"fp8", "f8f32mm"}},2178 {AArch64::ARMV9_6A, {"nofp8", "fp8dot4"}, {"fp8", "fp8dot4"}, {}},2179 {AArch64::ARMV9_6A, {"fp8dot4", "nofp8"}, {}, {"fp8", "fp8dot4"}},2180 {AArch64::ARMV9_6A, {"nofp8", "fp8dot2"}, {"fp8", "fp8dot2"}, {}},2181 {AArch64::ARMV9_6A, {"fp8dot2", "nofp8"}, {}, {"fp8", "fp8dot2"}},2182 {AArch64::ARMV9_6A,2183 {"nofp8", "ssve-fp8dot4"},2184 {"fp8", "ssve-fp8dot4"},2185 {}},2186 {AArch64::ARMV9_6A,2187 {"ssve-fp8dot4", "nofp8"},2188 {},2189 {"fp8", "ssve-fp8dot4"}},2190 {AArch64::ARMV9_6A,2191 {"nofp8", "ssve-fp8dot2"},2192 {"fp8", "ssve-fp8dot2"},2193 {}},2194 {AArch64::ARMV9_6A,2195 {"ssve-fp8dot2", "nofp8"},2196 {},2197 {"fp8", "ssve-fp8dot2"}},2198 2199 // lse -> lse1282200 {AArch64::ARMV8A, {"nolse", "lse128"}, {"lse", "lse128"}, {}},2201 {AArch64::ARMV8A, {"lse128", "nolse"}, {}, {"lse", "lse128"}},2202 2203 // predres -> predres22204 {AArch64::ARMV8A,2205 {"nopredres", "predres2"},2206 {"predres", "specres2"},2207 {}},2208 {AArch64::ARMV8A,2209 {"predres2", "nopredres"},2210 {},2211 {"predres", "specres2"}},2212 2213 // ras -> ras22214 {AArch64::ARMV8A, {"noras", "rasv2"}, {"ras", "rasv2"}, {}},2215 {AArch64::ARMV8A, {"rasv2", "noras"}, {}, {"ras", "rasv2"}},2216 2217 // rcpc -> rcpc32218 {AArch64::ARMV8A, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}},2219 {AArch64::ARMV8A, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}},2220 2221 // sve-aes -> {ssve-aes, sve2-aes}2222 {AArch64::ARMV9_6A,2223 {"nosve-aes", "ssve-aes"},2224 {"sve-aes", "ssve-aes"},2225 {}},2226 {AArch64::ARMV9_6A,2227 {"ssve-aes", "nosve-aes"},2228 {},2229 {"ssve-aes", "sve-aes"}},2230 {AArch64::ARMV9_6A,2231 {"nosve-aes", "sve2-aes"},2232 {"sve2-aes", "sve-aes"},2233 {}},2234 {AArch64::ARMV9_6A,2235 {"sve2-aes", "nosve-aes"},2236 {},2237 {"sve2-aes", "sve-aes"}},2238 2239 // -sve2-aes should disable sve-aes (only)2240 {AArch64::ARMV9_6A,2241 {"sve2", "sve-aes", "nosve2-aes"},2242 {"sve2"},2243 {"sve2-aes", "sve-aes"}},2244 2245 // -sve2-sm4 should disable sve-sm4 (only)2246 {AArch64::ARMV9_6A,2247 {"sve2", "sve-sm4", "nosve2-sm4"},2248 {"sve2"},2249 {"sve2-sm4", "sve-sm4"}},2250 2251 // -sve2-sha3 should disable sve-sha3 (only)2252 {AArch64::ARMV9_6A,2253 {"sve2", "sve-sha3", "nosve2-sha3"},2254 {"sve2"},2255 {"sve2-sha3", "sve-sha3"}},2256 2257 // sme-tmop -> sme2258 {AArch64::ARMV8A, {"nosme2", "sme-tmop"}, {"sme2", "sme-tmop"}, {}},2259 {AArch64::ARMV8A, {"sme-tmop", "nosme2"}, {}, {"sme2", "sme-tmop"}},2260 2261 // sme-mop4 -> sme2262 {AArch64::ARMV8A, {"nosme", "sme-mop4"}, {"sme", "sme-mop4"}, {}},2263 {AArch64::ARMV8A, {"sme-mop4", "nosme"}, {}, {"sme", "sme-mop4"}}};2264 2265INSTANTIATE_TEST_SUITE_P(2266 AArch64ExtensionDependenciesBaseArch,2267 AArch64ExtensionDependenciesBaseArchTestFixture,2268 ::testing::ValuesIn(AArch64ExtensionDependenciesArchData));2269 2270AArch64ExtensionDependenciesBaseCPUTestParams2271 AArch64ExtensionDependenciesCPUData[] = {2272 // Base CPU features2273 {"cortex-a57",2274 {},2275 {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"},2276 {}},2277 {"cortex-r82",2278 {},2279 {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse",2280 "ras", "rcpc", "rdm", "sb", "neon", "ssbs"},2281 {}},2282 {"cortex-a520",2283 {},2284 {"v9.2a", "bf16", "crc", "dotprod", "flagm", "fp-armv8",2285 "fullfp16", "fp16fml", "i8mm", "lse", "mte", "pauth",2286 "perfmon", "predres", "ras", "rcpc", "rdm", "sb",2287 "neon", "ssbs", "sve", "sve-bitperm", "sve2"},2288 {}},2289 2290 // Negative modifiers2291 {"cortex-r82",2292 {"nofp"},2293 {"v8r", "crc", "lse", "ras", "rcpc", "sb", "ssbs"},2294 {"fp-armv8", "neon", "fullfp16", "fp16fml", "dotprod", "rdm"}},2295};2296 2297INSTANTIATE_TEST_SUITE_P(2298 AArch64ExtensionDependenciesBaseCPU,2299 AArch64ExtensionDependenciesBaseCPUTestFixture,2300 ::testing::ValuesIn(AArch64ExtensionDependenciesCPUData));2301 2302struct CheckFindSinglePrecisionFpuTest {2303 StringRef Cpu;2304 ARM::ArchKind Arch;2305 StringRef Archext;2306 std::vector<StringRef> Features;2307 ARM::FPUKind Fpu;2308 ARM::FPUKind Output;2309};2310 2311TEST(TargetParserTest, checkFindSinglePrecisionFPU) {2312 CheckFindSinglePrecisionFpuTest tests[] = {2313 {"cortex-r4f",2314 ARM::ArchKind::ARMV7R,2315 "nofp.dp",2316 {},2317 ARM::FK_INVALID,2318 ARM::FK_VFPV3XD},2319 {"cortex-r7",2320 ARM::ArchKind::ARMV7R,2321 "nofp.dp",2322 {},2323 ARM::FK_INVALID,2324 ARM::FK_VFPV3XD_FP16},2325 {"cortex-a7",2326 ARM::ArchKind::ARMV7A,2327 "nofp.dp",2328 {},2329 ARM::FK_INVALID,2330 ARM::FK_FPV4_SP_D16},2331 {"cortex-r52",2332 ARM::ArchKind::ARMV8R,2333 "nofp.dp",2334 {},2335 ARM::FK_INVALID,2336 ARM::FK_FPV5_SP_D16},2337 {"cortex-m55",2338 ARM::ArchKind::ARMV8_1MMainline,2339 "nofp.dp",2340 {},2341 ARM::FK_INVALID,2342 ARM::FK_FP_ARMV8_FULLFP16_SP_D16}};2343 2344 for (auto X : tests) {2345 ARM::FPUKind FPU = X.Fpu;2346 EXPECT_TRUE(2347 ARM::appendArchExtFeatures(X.Cpu, X.Arch, X.Archext, X.Features, FPU));2348 EXPECT_EQ(FPU, X.Output);2349 }2350}2351 2352} // namespace2353