Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- AArch64TargetParser - Parser for AArch64 features -------*- C++ -*-===//
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements a target parser to recognise AArch64 hardware features
  10. // such as FPU/CPU/ARCH and extension names.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
  15. #define LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
  16.  
  17. #include "llvm/ADT/ArrayRef.h"
  18. #include "llvm/ADT/StringRef.h"
  19. #include "llvm/Support/VersionTuple.h"
  20. #include <array>
  21. #include <vector>
  22.  
  23. namespace llvm {
  24.  
  25. class Triple;
  26.  
  27. namespace AArch64 {
  28. enum CPUFeatures {
  29.   FEAT_RNG,
  30.   FEAT_FLAGM,
  31.   FEAT_FLAGM2,
  32.   FEAT_FP16FML,
  33.   FEAT_DOTPROD,
  34.   FEAT_SM4,
  35.   FEAT_RDM,
  36.   FEAT_LSE,
  37.   FEAT_FP,
  38.   FEAT_SIMD,
  39.   FEAT_CRC,
  40.   FEAT_SHA1,
  41.   FEAT_SHA2,
  42.   FEAT_SHA3,
  43.   FEAT_AES,
  44.   FEAT_PMULL,
  45.   FEAT_FP16,
  46.   FEAT_DIT,
  47.   FEAT_DPB,
  48.   FEAT_DPB2,
  49.   FEAT_JSCVT,
  50.   FEAT_FCMA,
  51.   FEAT_RCPC,
  52.   FEAT_RCPC2,
  53.   FEAT_FRINTTS,
  54.   FEAT_DGH,
  55.   FEAT_I8MM,
  56.   FEAT_BF16,
  57.   FEAT_EBF16,
  58.   FEAT_RPRES,
  59.   FEAT_SVE,
  60.   FEAT_SVE_BF16,
  61.   FEAT_SVE_EBF16,
  62.   FEAT_SVE_I8MM,
  63.   FEAT_SVE_F32MM,
  64.   FEAT_SVE_F64MM,
  65.   FEAT_SVE2,
  66.   FEAT_SVE_AES,
  67.   FEAT_SVE_PMULL128,
  68.   FEAT_SVE_BITPERM,
  69.   FEAT_SVE_SHA3,
  70.   FEAT_SVE_SM4,
  71.   FEAT_SME,
  72.   FEAT_MEMTAG,
  73.   FEAT_MEMTAG2,
  74.   FEAT_MEMTAG3,
  75.   FEAT_SB,
  76.   FEAT_PREDRES,
  77.   FEAT_SSBS,
  78.   FEAT_SSBS2,
  79.   FEAT_BTI,
  80.   FEAT_LS64,
  81.   FEAT_LS64_V,
  82.   FEAT_LS64_ACCDATA,
  83.   FEAT_WFXT,
  84.   FEAT_SME_F64,
  85.   FEAT_SME_I64,
  86.   FEAT_SME2,
  87.   FEAT_MAX
  88. };
  89.  
  90. // Arch extension modifiers for CPUs. These are labelled with their Arm ARM
  91. // feature name (though the canonical reference for those is AArch64.td)
  92. // clang-format off
  93. enum ArchExtKind : uint64_t {
  94.   AEK_INVALID =     0,
  95.   AEK_NONE =        1,
  96.   AEK_CRC =         1 << 1,  // FEAT_CRC32
  97.   AEK_CRYPTO =      1 << 2,
  98.   AEK_FP =          1 << 3,  // FEAT_FP
  99.   AEK_SIMD =        1 << 4,  // FEAT_AdvSIMD
  100.   AEK_FP16 =        1 << 5,  // FEAT_FP16
  101.   AEK_PROFILE =     1 << 6,  // FEAT_SPE
  102.   AEK_RAS =         1 << 7,  // FEAT_RAS, FEAT_RASv1p1
  103.   AEK_LSE =         1 << 8,  // FEAT_LSE
  104.   AEK_SVE =         1 << 9,  // FEAT_SVE
  105.   AEK_DOTPROD =     1 << 10, // FEAT_DotProd
  106.   AEK_RCPC =        1 << 11, // FEAT_LRCPC
  107.   AEK_RDM =         1 << 12, // FEAT_RDM
  108.   AEK_SM4 =         1 << 13, // FEAT_SM4, FEAT_SM3
  109.   AEK_SHA3 =        1 << 14, // FEAT_SHA3, FEAT_SHA512
  110.   AEK_SHA2 =        1 << 15, // FEAT_SHA1, FEAT_SHA256
  111.   AEK_AES =         1 << 16, // FEAT_AES, FEAT_PMULL
  112.   AEK_FP16FML =     1 << 17, // FEAT_FHM
  113.   AEK_RAND =        1 << 18, // FEAT_RNG
  114.   AEK_MTE =         1 << 19, // FEAT_MTE, FEAT_MTE2
  115.   AEK_SSBS =        1 << 20, // FEAT_SSBS, FEAT_SSBS2
  116.   AEK_SB =          1 << 21, // FEAT_SB
  117.   AEK_PREDRES =     1 << 22, // FEAT_SPECRES
  118.   AEK_SVE2 =        1 << 23, // FEAT_SVE2
  119.   AEK_SVE2AES =     1 << 24, // FEAT_SVE_AES, FEAT_SVE_PMULL128
  120.   AEK_SVE2SM4 =     1 << 25, // FEAT_SVE_SM4
  121.   AEK_SVE2SHA3 =    1 << 26, // FEAT_SVE_SHA3
  122.   AEK_SVE2BITPERM = 1 << 27, // FEAT_SVE_BitPerm
  123.   AEK_TME =         1 << 28, // FEAT_TME
  124.   AEK_BF16 =        1 << 29, // FEAT_BF16
  125.   AEK_I8MM =        1 << 30, // FEAT_I8MM
  126.   AEK_F32MM =       1ULL << 31, // FEAT_F32MM
  127.   AEK_F64MM =       1ULL << 32, // FEAT_F64MM
  128.   AEK_LS64 =        1ULL << 33, // FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA
  129.   AEK_BRBE =        1ULL << 34, // FEAT_BRBE
  130.   AEK_PAUTH =       1ULL << 35, // FEAT_PAuth
  131.   AEK_FLAGM =       1ULL << 36, // FEAT_FlagM
  132.   AEK_SME =         1ULL << 37, // FEAT_SME
  133.   AEK_SMEF64F64 =   1ULL << 38, // FEAT_SME_F64F64
  134.   AEK_SMEI16I64 =   1ULL << 39, // FEAT_SME_I16I64
  135.   AEK_HBC =         1ULL << 40, // FEAT_HBC
  136.   AEK_MOPS =        1ULL << 41, // FEAT_MOPS
  137.   AEK_PERFMON =     1ULL << 42, // FEAT_PMUv3
  138.   AEK_SME2 =        1ULL << 43, // FEAT_SME2
  139.   AEK_SVE2p1 =      1ULL << 44, // FEAT_SVE2p1
  140.   AEK_SME2p1 =      1ULL << 45, // FEAT_SME2p1
  141.   AEK_B16B16 =      1ULL << 46, // FEAT_B16B16
  142.   AEK_SMEF16F16 =   1ULL << 47, // FEAT_SMEF16F16
  143.   AEK_CSSC =        1ULL << 48, // FEAT_CSSC
  144.   AEK_RCPC3 =       1ULL << 49, // FEAT_LRCPC3
  145.   AEK_THE =         1ULL << 50, // FEAT_THE
  146.   AEK_D128 =        1ULL << 51, // FEAT_D128
  147.   AEK_LSE128 =      1ULL << 52, // FEAT_LSE128
  148.   AEK_SPECRES2 =    1ULL << 53, // FEAT_SPECRES2
  149.   AEK_RASv2 =       1ULL << 54, // FEAT_RASv2
  150.   AEK_ITE =         1ULL << 55, // FEAT_ITE
  151. };
  152. // clang-format on
  153.  
  154. // Represents an extension that can be enabled with -march=<arch>+<extension>.
  155. // Typically these correspond to Arm Architecture extensions, unlike
  156. // SubtargetFeature which may represent either an actual extension or some
  157. // internal LLVM property.
  158. struct ExtensionInfo {
  159.   StringRef Name;       // Human readable name, e.g. "profile".
  160.   ArchExtKind ID;       // Corresponding to the ArchExtKind, this extensions
  161.                         // representation in the bitfield.
  162.   StringRef Feature;    // -mattr enable string, e.g. "+spe"
  163.   StringRef NegFeature; // -mattr disable string, e.g. "-spe"
  164.  
  165.   // FIXME These were added by D127812 FMV support and need documenting:
  166.   CPUFeatures CPUFeature; // Bitfield value set in __aarch64_cpu_features
  167.   StringRef DependentFeatures;
  168.   unsigned FmvPriority;
  169.   static constexpr unsigned MaxFMVPriority = 1000;
  170. };
  171.  
  172. // clang-format off
  173. inline constexpr ExtensionInfo Extensions[] = {
  174.     {"aes", AArch64::AEK_AES, "+aes", "-aes", FEAT_AES, "+fp-armv8,+neon", 150},
  175.     {"b16b16", AArch64::AEK_B16B16, "+b16b16", "-b16b16", FEAT_MAX, "", 0},
  176.     {"bf16", AArch64::AEK_BF16, "+bf16", "-bf16", FEAT_BF16, "+bf16", 280},
  177.     {"brbe", AArch64::AEK_BRBE, "+brbe", "-brbe", FEAT_MAX, "", 0},
  178.     {"bti", AArch64::AEK_NONE, {}, {}, FEAT_BTI, "+bti", 510},
  179.     {"crc", AArch64::AEK_CRC, "+crc", "-crc", FEAT_CRC, "+crc", 110},
  180.     {"crypto", AArch64::AEK_CRYPTO, "+crypto", "-crypto", FEAT_MAX, "+aes,+sha2", 0},
  181.     {"cssc", AArch64::AEK_CSSC, "+cssc", "-cssc", FEAT_MAX, "", 0},
  182.     {"d128", AArch64::AEK_D128, "+d128", "-d128", FEAT_MAX, "", 0},
  183.     {"dgh", AArch64::AEK_NONE, {}, {}, FEAT_DGH, "", 260},
  184.     {"dit", AArch64::AEK_NONE, {}, {}, FEAT_DIT, "+dit", 180},
  185.     {"dotprod", AArch64::AEK_DOTPROD, "+dotprod", "-dotprod", FEAT_DOTPROD, "+dotprod,+fp-armv8,+neon", 50},
  186.     {"dpb", AArch64::AEK_NONE, {}, {}, FEAT_DPB, "+ccpp", 190},
  187.     {"dpb2", AArch64::AEK_NONE, {}, {}, FEAT_DPB2, "+ccpp,+ccdp", 200},
  188.     {"ebf16", AArch64::AEK_NONE, {}, {}, FEAT_EBF16, "+bf16", 290},
  189.     {"f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm", FEAT_SVE_F32MM, "+sve,+f32mm,+fullfp16,+fp-armv8,+neon", 350},
  190.     {"f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm", FEAT_SVE_F64MM, "+sve,+f64mm,+fullfp16,+fp-armv8,+neon", 360},
  191.     {"fcma", AArch64::AEK_NONE, {}, {}, FEAT_FCMA, "+fp-armv8,+neon,+complxnum", 220},
  192.     {"flagm", AArch64::AEK_FLAGM, "+flagm", "-flagm", FEAT_FLAGM, "+flagm", 20},
  193.     {"flagm2", AArch64::AEK_NONE, {}, {}, FEAT_FLAGM2, "+flagm,+altnzcv", 30},
  194.     {"fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8", FEAT_FP, "+fp-armv8,+neon", 90},
  195.     {"fp16", AArch64::AEK_FP16, "+fullfp16", "-fullfp16", FEAT_FP16, "+fullfp16,+fp-armv8,+neon", 170},
  196.     {"fp16fml", AArch64::AEK_FP16FML, "+fp16fml", "-fp16fml", FEAT_FP16FML, "+fp16fml,+fullfp16,+fp-armv8,+neon", 40},
  197.     {"frintts", AArch64::AEK_NONE, {}, {}, FEAT_FRINTTS, "+fptoint", 250},
  198.     {"hbc", AArch64::AEK_HBC, "+hbc", "-hbc", FEAT_MAX, "", 0},
  199.     {"i8mm", AArch64::AEK_I8MM, "+i8mm", "-i8mm", FEAT_I8MM, "+i8mm", 270},
  200.     {"ite", AArch64::AEK_ITE, "+ite", "-ite", FEAT_MAX, "", 0},
  201.     {"jscvt", AArch64::AEK_NONE, {}, {}, FEAT_JSCVT, "+fp-armv8,+neon,+jsconv", 210},
  202.     {"ls64_accdata", AArch64::AEK_NONE, {}, {}, FEAT_LS64_ACCDATA, "+ls64", 540},
  203.     {"ls64_v", AArch64::AEK_NONE, {}, {}, FEAT_LS64_V, "", 530},
  204.     {"ls64", AArch64::AEK_LS64, "+ls64", "-ls64", FEAT_LS64, "", 520},
  205.     {"lse", AArch64::AEK_LSE, "+lse", "-lse", FEAT_LSE, "+lse", 80},
  206.     {"lse128", AArch64::AEK_LSE128, "+lse128", "-lse128", FEAT_MAX, "", 0},
  207.     {"memtag", AArch64::AEK_MTE, "+mte", "-mte", FEAT_MEMTAG, "", 440},
  208.     {"memtag2", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG2, "+mte", 450},
  209.     {"memtag3", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG3, "+mte", 460},
  210.     {"mops", AArch64::AEK_MOPS, "+mops", "-mops", FEAT_MAX, "", 0},
  211.     {"pauth", AArch64::AEK_PAUTH, "+pauth", "-pauth", FEAT_MAX, "", 0},
  212.     {"pmull", AArch64::AEK_NONE, {}, {}, FEAT_PMULL, "+aes,+fp-armv8,+neon", 160},
  213.     {"pmuv3", AArch64::AEK_PERFMON, "+perfmon", "-perfmon", FEAT_MAX, "", 0},
  214.     {"predres", AArch64::AEK_PREDRES, "+predres", "-predres", FEAT_PREDRES, "+predres", 480},
  215.     {"predres2", AArch64::AEK_SPECRES2, "+specres2", "-specres2", FEAT_MAX, "", 0},
  216.     {"profile", AArch64::AEK_PROFILE, "+spe", "-spe", FEAT_MAX, "", 0},
  217.     {"ras", AArch64::AEK_RAS, "+ras", "-ras", FEAT_MAX, "", 0},
  218.     {"rasv2", AArch64::AEK_RASv2, "+rasv2", "-rasv2", FEAT_MAX, "", 0},
  219.     {"rcpc", AArch64::AEK_RCPC, "+rcpc", "-rcpc", FEAT_RCPC, "+rcpc", 230},
  220.     {"rcpc2", AArch64::AEK_NONE, {}, {}, FEAT_RCPC2, "+rcpc", 240},
  221.     {"rcpc3", AArch64::AEK_RCPC3, "+rcpc3", "-rcpc3", FEAT_MAX, "", 0},
  222.     {"rdm", AArch64::AEK_RDM, "+rdm", "-rdm", FEAT_RDM, "+rdm,+fp-armv8,+neon", 70},
  223.     {"rng", AArch64::AEK_RAND, "+rand", "-rand", FEAT_RNG, "+rand", 10},
  224.     {"rpres", AArch64::AEK_NONE, {}, {}, FEAT_RPRES, "", 300},
  225.     {"sb", AArch64::AEK_SB, "+sb", "-sb", FEAT_SB, "+sb", 470},
  226.     {"sha1", AArch64::AEK_NONE, {}, {}, FEAT_SHA1, "+fp-armv8,+neon", 120},
  227.     {"sha2", AArch64::AEK_SHA2, "+sha2", "-sha2", FEAT_SHA2, "+sha2,+fp-armv8,+neon", 130},
  228.     {"sha3", AArch64::AEK_SHA3, "+sha3", "-sha3", FEAT_SHA3, "+sha3,+sha2,+fp-armv8,+neon", 140},
  229.     {"simd", AArch64::AEK_SIMD, "+neon", "-neon", FEAT_SIMD, "+fp-armv8,+neon", 100},
  230.     {"sm4", AArch64::AEK_SM4, "+sm4", "-sm4", FEAT_SM4, "+sm4,+fp-armv8,+neon", 60},
  231.     {"sme-f16f16", AArch64::AEK_SMEF16F16, "+sme-f16f16", "-sme-f16f16", FEAT_MAX, "", 0},
  232.     {"sme-f64f64", AArch64::AEK_SMEF64F64, "+sme-f64f64", "-sme-f64f64", FEAT_SME_F64, "+sme,+sme-f64f64,+bf16", 560},
  233.     {"sme-i16i64", AArch64::AEK_SMEI16I64, "+sme-i16i64", "-sme-i16i64", FEAT_SME_I64, "+sme,+sme-i16i64,+bf16", 570},
  234.     {"sme", AArch64::AEK_SME, "+sme", "-sme", FEAT_SME, "+sme,+bf16", 430},
  235.     {"sme2", AArch64::AEK_SME2, "+sme2", "-sme2", FEAT_SME2, "+sme2,+sme,+bf16", 580},
  236.     {"sme2p1", AArch64::AEK_SME2p1, "+sme2p1", "-sme2p1", FEAT_MAX, "", 0},
  237.     {"ssbs", AArch64::AEK_SSBS, "+ssbs", "-ssbs", FEAT_SSBS, "", 490},
  238.     {"ssbs2", AArch64::AEK_NONE, {}, {}, FEAT_SSBS2, "+ssbs", 500},
  239.     {"sve-bf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_BF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320},
  240.     {"sve-ebf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_EBF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330},
  241.     {"sve-i8mm", AArch64::AEK_NONE, {}, {}, FEAT_SVE_I8MM, "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340},
  242.     {"sve", AArch64::AEK_SVE, "+sve", "-sve", FEAT_SVE, "+sve,+fullfp16,+fp-armv8,+neon", 310},
  243.     {"sve2-aes", AArch64::AEK_SVE2AES, "+sve2-aes", "-sve2-aes", FEAT_SVE_AES, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 380},
  244.     {"sve2-bitperm", AArch64::AEK_SVE2BITPERM, "+sve2-bitperm", "-sve2-bitperm", FEAT_SVE_BITPERM, "+sve2,+sve,+sve2-bitperm,+fullfp16,+fp-armv8,+neon", 400},
  245.     {"sve2-pmull128", AArch64::AEK_NONE, {}, {}, FEAT_SVE_PMULL128, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390},
  246.     {"sve2-sha3", AArch64::AEK_SVE2SHA3, "+sve2-sha3", "-sve2-sha3", FEAT_SVE_SHA3, "+sve2,+sve,+sve2-sha3,+fullfp16,+fp-armv8,+neon", 410},
  247.     {"sve2-sm4", AArch64::AEK_SVE2SM4, "+sve2-sm4", "-sve2-sm4", FEAT_SVE_SM4, "+sve2,+sve,+sve2-sm4,+fullfp16,+fp-armv8,+neon", 420},
  248.     {"sve2", AArch64::AEK_SVE2, "+sve2", "-sve2", FEAT_SVE2, "+sve2,+sve,+fullfp16,+fp-armv8,+neon", 370},
  249.     {"sve2p1", AArch64::AEK_SVE2p1, "+sve2p1", "-sve2p1", FEAT_MAX, "", 0},
  250.     {"the", AArch64::AEK_THE, "+the", "-the", FEAT_MAX, "", 0},
  251.     {"tme", AArch64::AEK_TME, "+tme", "-tme", FEAT_MAX, "", 0},
  252.     {"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550},
  253.     // Special cases
  254.     {"none", AArch64::AEK_NONE, {}, {}, FEAT_MAX, "", ExtensionInfo::MaxFMVPriority},
  255.     {"invalid", AArch64::AEK_INVALID, {}, {}, FEAT_MAX, "", 0},
  256. };
  257. // clang-format on
  258.  
  259. enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' };
  260.  
  261. // Information about a specific architecture, e.g. V8.1-A
  262. struct ArchInfo {
  263.   VersionTuple Version;  // Architecture version, major + minor.
  264.   ArchProfile Profile;   // Architecuture profile
  265.   StringRef Name;        // Human readable name, e.g. "armv8.1-a"
  266.   StringRef ArchFeature; // Command line feature flag, e.g. +v8a
  267.   uint64_t DefaultExts;  // bitfield of default extensions ArchExtKind
  268.  
  269.   bool operator==(const ArchInfo &Other) const {
  270.     return this->Name == Other.Name;
  271.   }
  272.   bool operator!=(const ArchInfo &Other) const {
  273.     return this->Name != Other.Name;
  274.   }
  275.  
  276.   // Defines the following partial order, indicating when an architecture is
  277.   // a superset of another:
  278.   //
  279.   //     v9.4a > v9.3a > v9.3a > v9.3a > v9a;
  280.   //       v       v       v       v       v
  281.   //     v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a;
  282.   //
  283.   // v8r and INVALID have no relation to anything. This is used to
  284.   // determine which features to enable for a given architecture. See
  285.   // AArch64TargetInfo::setFeatureEnabled.
  286.   bool implies(const ArchInfo &Other) const {
  287.     if (this->Profile != Other.Profile)
  288.       return false; // ARMV8R and INVALID
  289.     if (this->Version.getMajor() == Other.Version.getMajor()) {
  290.       return this->Version > Other.Version;
  291.     }
  292.     if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) {
  293.       return this->Version.getMinor().value() + 5 >=
  294.              Other.Version.getMinor().value();
  295.     }
  296.     return false;
  297.   }
  298.  
  299.   // Return ArchFeature without the leading "+".
  300.   StringRef getSubArch() const { return ArchFeature.substr(1); }
  301.  
  302.   // Search for ArchInfo by SubArch name
  303.   static const ArchInfo &findBySubArch(StringRef SubArch);
  304. };
  305.  
  306. // clang-format off
  307. inline constexpr ArchInfo INVALID   = { VersionTuple{0, 0}, AProfile, "invalid", "+", (AArch64::AEK_NONE)};
  308. inline constexpr ArchInfo ARMV8A    = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", (AArch64::AEK_FP | AArch64::AEK_SIMD), };
  309. inline constexpr ArchInfo ARMV8_1A  = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts | AArch64::AEK_CRC | AArch64::AEK_LSE | AArch64::AEK_RDM)};
  310. inline constexpr ArchInfo ARMV8_2A  = { VersionTuple{8, 2}, AProfile, "armv8.2-a", "+v8.2a", (ARMV8_1A.DefaultExts | AArch64::AEK_RAS)};
  311. inline constexpr ArchInfo ARMV8_3A  = { VersionTuple{8, 3}, AProfile, "armv8.3-a", "+v8.3a", (ARMV8_2A.DefaultExts | AArch64::AEK_RCPC)};
  312. inline constexpr ArchInfo ARMV8_4A  = { VersionTuple{8, 4}, AProfile, "armv8.4-a", "+v8.4a", (ARMV8_3A.DefaultExts | AArch64::AEK_DOTPROD)};
  313. inline constexpr ArchInfo ARMV8_5A  = { VersionTuple{8, 5}, AProfile, "armv8.5-a", "+v8.5a", (ARMV8_4A.DefaultExts)};
  314. inline constexpr ArchInfo ARMV8_6A  = { VersionTuple{8, 6}, AProfile, "armv8.6-a", "+v8.6a", (ARMV8_5A.DefaultExts | AArch64::AEK_BF16 | AArch64::AEK_I8MM)};
  315. inline constexpr ArchInfo ARMV8_7A  = { VersionTuple{8, 7}, AProfile, "armv8.7-a", "+v8.7a", (ARMV8_6A.DefaultExts)};
  316. inline constexpr ArchInfo ARMV8_8A  = { VersionTuple{8, 8}, AProfile, "armv8.8-a", "+v8.8a", (ARMV8_7A.DefaultExts | AArch64::AEK_MOPS | AArch64::AEK_HBC)};
  317. inline constexpr ArchInfo ARMV8_9A  = { VersionTuple{8, 9}, AProfile, "armv8.9-a", "+v8.9a", (ARMV8_8A.DefaultExts | AArch64::AEK_SPECRES2 | AArch64::AEK_CSSC | AArch64::AEK_RASv2)};
  318. inline constexpr ArchInfo ARMV9A    = { VersionTuple{9, 0}, AProfile, "armv9-a", "+v9a", (ARMV8_5A.DefaultExts | AArch64::AEK_FP16 | AArch64::AEK_SVE | AArch64::AEK_SVE2)};
  319. inline constexpr ArchInfo ARMV9_1A  = { VersionTuple{9, 1}, AProfile, "armv9.1-a", "+v9.1a", (ARMV9A.DefaultExts | AArch64::AEK_BF16 | AArch64::AEK_I8MM)};
  320. inline constexpr ArchInfo ARMV9_2A  = { VersionTuple{9, 2}, AProfile, "armv9.2-a", "+v9.2a", (ARMV9_1A.DefaultExts)};
  321. inline constexpr ArchInfo ARMV9_3A  = { VersionTuple{9, 3}, AProfile, "armv9.3-a", "+v9.3a", (ARMV9_2A.DefaultExts | AArch64::AEK_MOPS | AArch64::AEK_HBC)};
  322. inline constexpr ArchInfo ARMV9_4A  = { VersionTuple{9, 4}, AProfile, "armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts | AArch64::AEK_SPECRES2 | AArch64::AEK_CSSC | AArch64::AEK_RASv2)};
  323. // For v8-R, we do not enable crypto and align with GCC that enables a more minimal set of optional architecture extensions.
  324. inline constexpr ArchInfo ARMV8R    = { VersionTuple{8, 0}, RProfile, "armv8-r", "+v8r", ((ARMV8_5A.DefaultExts ^ AArch64::AEK_LSE) | AArch64::AEK_SSBS | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SB), };
  325. // clang-format on
  326.  
  327. // The set of all architectures
  328. static constexpr std::array<const ArchInfo *, 17> ArchInfos = {
  329.     &INVALID,  &ARMV8A,   &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A,
  330.     &ARMV8_5A, &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A,
  331.     &ARMV9_1A, &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV8R,
  332. };
  333.  
  334. // Details of a specific CPU.
  335. struct CpuInfo {
  336.   StringRef Name; // Name, as written for -mcpu.
  337.   const ArchInfo &Arch;
  338.   uint64_t DefaultExtensions; // Default extensions for this CPU. These will be
  339.                               // ORd with the architecture defaults.
  340. };
  341.  
  342. inline constexpr CpuInfo CpuInfos[] = {
  343.     {"cortex-a34", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  344.     {"cortex-a35", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  345.     {"cortex-a53", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  346.     {"cortex-a55", ARMV8_2A,
  347.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  348.       AArch64::AEK_RCPC)},
  349.     {"cortex-a510", ARMV9A,
  350.      (AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SB |
  351.       AArch64::AEK_PAUTH | AArch64::AEK_MTE | AArch64::AEK_SSBS |
  352.       AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
  353.       AArch64::AEK_FP16FML)},
  354.     {"cortex-a57", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  355.     {"cortex-a65", ARMV8_2A,
  356.      (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  357.       AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  358.     {"cortex-a65ae", ARMV8_2A,
  359.      (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  360.       AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  361.     {"cortex-a72", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  362.     {"cortex-a73", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  363.     {"cortex-a75", ARMV8_2A,
  364.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  365.       AArch64::AEK_RCPC)},
  366.     {"cortex-a76", ARMV8_2A,
  367.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  368.       AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  369.     {"cortex-a76ae", ARMV8_2A,
  370.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  371.       AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  372.     {"cortex-a77", ARMV8_2A,
  373.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_RCPC |
  374.       AArch64::AEK_DOTPROD | AArch64::AEK_SSBS)},
  375.     {"cortex-a78", ARMV8_2A,
  376.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  377.       AArch64::AEK_RCPC | AArch64::AEK_SSBS | AArch64::AEK_PROFILE)},
  378.     {"cortex-a78c", ARMV8_2A,
  379.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  380.       AArch64::AEK_RCPC | AArch64::AEK_SSBS | AArch64::AEK_PROFILE |
  381.       AArch64::AEK_FLAGM | AArch64::AEK_PAUTH | AArch64::AEK_FP16FML)},
  382.     {"cortex-a710", ARMV9A,
  383.      (AArch64::AEK_MTE | AArch64::AEK_PAUTH | AArch64::AEK_FLAGM |
  384.       AArch64::AEK_SB | AArch64::AEK_I8MM | AArch64::AEK_FP16FML |
  385.       AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
  386.       AArch64::AEK_BF16)},
  387.     {"cortex-a715", ARMV9A,
  388.      (AArch64::AEK_SB | AArch64::AEK_SSBS | AArch64::AEK_MTE |
  389.       AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PAUTH |
  390.       AArch64::AEK_I8MM | AArch64::AEK_PREDRES | AArch64::AEK_PERFMON |
  391.       AArch64::AEK_PROFILE | AArch64::AEK_SVE | AArch64::AEK_SVE2BITPERM |
  392.       AArch64::AEK_BF16 | AArch64::AEK_FLAGM)},
  393.     {"cortex-r82", ARMV8R, (AArch64::AEK_LSE)},
  394.     {"cortex-x1", ARMV8_2A,
  395.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  396.       AArch64::AEK_RCPC | AArch64::AEK_SSBS | AArch64::AEK_PROFILE)},
  397.     {"cortex-x1c", ARMV8_2A,
  398.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
  399.       AArch64::AEK_RCPC | AArch64::AEK_SSBS | AArch64::AEK_PAUTH |
  400.       AArch64::AEK_PROFILE)},
  401.     {"cortex-x2", ARMV9A,
  402.      (AArch64::AEK_MTE | AArch64::AEK_BF16 | AArch64::AEK_I8MM |
  403.       AArch64::AEK_PAUTH | AArch64::AEK_SSBS | AArch64::AEK_SB |
  404.       AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
  405.       AArch64::AEK_FP16FML)},
  406.     {"cortex-x3", ARMV9A,
  407.      (AArch64::AEK_SVE | AArch64::AEK_PERFMON | AArch64::AEK_PROFILE |
  408.       AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_MTE |
  409.       AArch64::AEK_SVE2BITPERM | AArch64::AEK_SB | AArch64::AEK_PAUTH |
  410.       AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PREDRES |
  411.       AArch64::AEK_FLAGM | AArch64::AEK_SSBS)},
  412.     {"neoverse-e1", ARMV8_2A,
  413.      (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  414.       AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  415.     {"neoverse-n1", ARMV8_2A,
  416.      (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  417.       AArch64::AEK_PROFILE | AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
  418.     {"neoverse-n2", ARMV8_5A,
  419.      (AArch64::AEK_CRYPTO | AArch64::AEK_BF16 | AArch64::AEK_DOTPROD |
  420.       AArch64::AEK_FP16 | AArch64::AEK_I8MM | AArch64::AEK_MTE |
  421.       AArch64::AEK_SB | AArch64::AEK_SSBS | AArch64::AEK_SVE |
  422.       AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM)},
  423.     {"neoverse-512tvb", ARMV8_4A,
  424.      (AArch64::AEK_CRYPTO | AArch64::AEK_SVE | AArch64::AEK_SSBS |
  425.       AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_DOTPROD |
  426.       AArch64::AEK_PROFILE | AArch64::AEK_RAND | AArch64::AEK_FP16FML |
  427.       AArch64::AEK_I8MM)},
  428.     {"neoverse-v1", ARMV8_4A,
  429.      (AArch64::AEK_CRYPTO | AArch64::AEK_SVE | AArch64::AEK_SSBS |
  430.       AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_DOTPROD |
  431.       AArch64::AEK_PROFILE | AArch64::AEK_RAND | AArch64::AEK_FP16FML |
  432.       AArch64::AEK_I8MM)},
  433.     {"neoverse-v2", ARMV9A,
  434.      (AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SSBS |
  435.       AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_RAND |
  436.       AArch64::AEK_DOTPROD | AArch64::AEK_PROFILE | AArch64::AEK_SVE2BITPERM |
  437.       AArch64::AEK_FP16FML | AArch64::AEK_I8MM | AArch64::AEK_MTE)},
  438.     {"cyclone", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_NONE)},
  439.     {"apple-a7", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_NONE)},
  440.     {"apple-a8", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_NONE)},
  441.     {"apple-a9", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_NONE)},
  442.     {"apple-a10", ARMV8A,
  443.      (AArch64::AEK_CRYPTO | AArch64::AEK_CRC | AArch64::AEK_RDM)},
  444.     {"apple-a11", ARMV8_2A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  445.     {"apple-a12", ARMV8_3A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  446.     {"apple-a13", ARMV8_4A,
  447.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  448.       AArch64::AEK_SHA3)},
  449.     {"apple-a14", ARMV8_5A,
  450.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  451.       AArch64::AEK_SHA3)},
  452.     {"apple-a15", ARMV8_5A,
  453.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  454.       AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_I8MM)},
  455.     {"apple-a16", ARMV8_5A,
  456.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  457.       AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_I8MM)},
  458.     {"apple-m1", ARMV8_5A,
  459.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  460.       AArch64::AEK_SHA3)},
  461.     {"apple-m2", ARMV8_5A,
  462.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
  463.       AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_I8MM)},
  464.     {"apple-s4", ARMV8_3A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  465.     {"apple-s5", ARMV8_3A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  466.     {"exynos-m3", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  467.     {"exynos-m4", ARMV8_2A,
  468.      (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16)},
  469.     {"exynos-m5", ARMV8_2A,
  470.      (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16)},
  471.     {"falkor", ARMV8A,
  472.      (AArch64::AEK_CRYPTO | AArch64::AEK_CRC | AArch64::AEK_RDM)},
  473.     {"saphira", ARMV8_3A, (AArch64::AEK_CRYPTO | AArch64::AEK_PROFILE)},
  474.     {"kryo", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  475.     {"thunderx2t99", ARMV8_1A, (AArch64::AEK_CRYPTO)},
  476.     {"thunderx3t110", ARMV8_3A, (AArch64::AEK_CRYPTO)},
  477.     {"thunderx", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  478.     {"thunderxt88", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  479.     {"thunderxt81", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  480.     {"thunderxt83", ARMV8A, (AArch64::AEK_CRYPTO | AArch64::AEK_CRC)},
  481.     {"tsv110", ARMV8_2A,
  482.      (AArch64::AEK_CRYPTO | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
  483.       AArch64::AEK_FP16FML | AArch64::AEK_PROFILE)},
  484.     {"a64fx", ARMV8_2A,
  485.      (AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_SVE)},
  486.     {"carmel", ARMV8_2A, (AArch64::AEK_CRYPTO | AArch64::AEK_FP16)},
  487.     {"ampere1", ARMV8_6A,
  488.      (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
  489.       AArch64::AEK_FP16 | AArch64::AEK_SB | AArch64::AEK_SSBS |
  490.       AArch64::AEK_RAND)},
  491.     {"ampere1a", ARMV8_6A,
  492.      (AArch64::AEK_FP16 | AArch64::AEK_RAND | AArch64::AEK_SM4 |
  493.       AArch64::AEK_SHA3 | AArch64::AEK_SHA2 | AArch64::AEK_AES |
  494.       AArch64::AEK_MTE | AArch64::AEK_SB | AArch64::AEK_SSBS)},
  495.     // Invalid CPU
  496.     {"invalid", INVALID, (AArch64::AEK_INVALID)},
  497. };
  498.  
  499. // An alias for a CPU.
  500. struct CpuAlias {
  501.   StringRef Alias;
  502.   StringRef Name;
  503. };
  504.  
  505. inline constexpr CpuAlias CpuAliases[] = {{"grace", "neoverse-v2"}};
  506.  
  507. bool getExtensionFeatures(uint64_t Extensions,
  508.                           std::vector<StringRef> &Features);
  509.  
  510. StringRef getArchExtFeature(StringRef ArchExt);
  511. StringRef resolveCPUAlias(StringRef CPU);
  512.  
  513. // Information by Name
  514. uint64_t getDefaultExtensions(StringRef CPU, const ArchInfo &AI);
  515. void getFeatureOption(StringRef Name, std::string &Feature);
  516. const ArchInfo &getArchForCpu(StringRef CPU);
  517.  
  518. // Parser
  519. const ArchInfo &parseArch(StringRef Arch);
  520. ArchExtKind parseArchExt(StringRef ArchExt);
  521. // Given the name of a CPU or alias, return the correponding CpuInfo.
  522. const CpuInfo &parseCpu(StringRef Name);
  523. // Used by target parser tests
  524. void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values);
  525.  
  526. bool isX18ReservedByDefault(const Triple &TT);
  527. uint64_t getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs);
  528.  
  529. } // namespace AArch64
  530. } // namespace llvm
  531.  
  532. #endif
  533.