brintos

brintos / llvm-project-archived public Read only

0
0
Text · 108.1 KiB · 92e2d77 Raw
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> &params) {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 &params) {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