Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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