1//===--- AArch64.cpp - Implement AArch64 target feature support -----------===//
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 AArch64 TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#include "AArch64.h"
14#include "clang/Basic/Diagnostic.h"
15#include "clang/Basic/LangOptions.h"
16#include "clang/Basic/TargetBuiltins.h"
17#include "clang/Basic/TargetInfo.h"
18#include "llvm/ADT/APSInt.h"
19#include "llvm/ADT/ArrayRef.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/TargetParser/AArch64TargetParser.h"
22#include "llvm/TargetParser/ARMTargetParserCommon.h"
23#include <optional>
24
25using namespace clang;
26using namespace clang::targets;
27
28static constexpr int NumNeonBuiltins =
29 NEON::FirstFp16Builtin - Builtin::FirstTSBuiltin;
30static constexpr int NumFp16Builtins =
31 NEON::FirstTSBuiltin - NEON::FirstFp16Builtin;
32static constexpr int NumSVEBuiltins =
33 SVE::FirstNeonBridgeBuiltin - NEON::FirstTSBuiltin;
34static constexpr int NumSVENeonBridgeBuiltins =
35 SVE::FirstTSBuiltin - SVE::FirstNeonBridgeBuiltin;
36static constexpr int NumSMEBuiltins = SME::FirstTSBuiltin - SVE::FirstTSBuiltin;
37static constexpr int NumAArch64Builtins =
38 AArch64::LastTSBuiltin - SME::FirstTSBuiltin;
39static constexpr int NumBuiltins =
40 AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin;
41static_assert(NumBuiltins ==
42 (NumNeonBuiltins + NumFp16Builtins + NumSVEBuiltins +
43 NumSVENeonBridgeBuiltins + NumSMEBuiltins + NumAArch64Builtins));
44
45namespace clang {
46namespace AArch64 {
47#define GET_BUILTIN_STR_TABLE
48#include "clang/Basic/BuiltinsAArch64.inc"
49#undef GET_BUILTIN_STR_TABLE
50
51static constexpr Builtin::Info BuiltinInfos[] = {
52#define GET_BUILTIN_INFOS
53#include "clang/Basic/BuiltinsAArch64.inc"
54#undef GET_BUILTIN_INFOS
55};
56
57static constexpr Builtin::Info PrefixedBuiltinInfos[] = {
58#define GET_BUILTIN_PREFIXED_INFOS
59#include "clang/Basic/BuiltinsAArch64.inc"
60#undef GET_BUILTIN_PREFIXED_INFOS
61};
62static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) ==
63 NumAArch64Builtins);
64} // namespace AArch64
65
66namespace NEON {
67#define GET_NEON_BUILTIN_STR_TABLE
68#include "clang/Basic/arm_neon.inc"
69#undef GET_NEON_BUILTIN_STR_TABLE
70
71static constexpr std::array<Builtin::Info, NumNeonBuiltins> BuiltinInfos = {
72#define GET_NEON_BUILTIN_INFOS
73#include "clang/Basic/arm_neon.inc"
74#undef GET_NEON_BUILTIN_INFOS
75};
76
77namespace FP16 {
78#define GET_NEON_BUILTIN_STR_TABLE
79#include "clang/Basic/arm_fp16.inc"
80#undef GET_NEON_BUILTIN_STR_TABLE
81
82static constexpr std::array<Builtin::Info, NumFp16Builtins> BuiltinInfos = {
83#define GET_NEON_BUILTIN_INFOS
84#include "clang/Basic/arm_fp16.inc"
85#undef GET_NEON_BUILTIN_INFOS
86};
87} // namespace FP16
88} // namespace NEON
89
90namespace SVE {
91#define GET_SVE_BUILTIN_STR_TABLE
92#include "clang/Basic/arm_sve_builtins.inc"
93#undef GET_SVE_BUILTIN_STR_TABLE
94
95static constexpr std::array<Builtin::Info, NumSVEBuiltins> BuiltinInfos = {
96#define GET_SVE_BUILTIN_INFOS
97#include "clang/Basic/arm_sve_builtins.inc"
98#undef GET_SVE_BUILTIN_INFOS
99};
100} // namespace SVE
101
102namespace SME {
103#define GET_SME_BUILTIN_STR_TABLE
104#include "clang/Basic/arm_sme_builtins.inc"
105#undef GET_SME_BUILTIN_STR_TABLE
106
107static constexpr std::array<Builtin::Info, NumSMEBuiltins> BuiltinInfos = {
108#define GET_SME_BUILTIN_INFOS
109#include "clang/Basic/arm_sme_builtins.inc"
110#undef GET_SME_BUILTIN_INFOS
111};
112} // namespace SME
113} // namespace clang
114
115static constexpr llvm::StringTable BuiltinSVENeonBridgeStrings =
116 CLANG_BUILTIN_STR_TABLE_START
117#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
118#define GET_SVE_BUILTINS
119#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"
120#undef GET_SVE_BUILTINS
121#undef TARGET_BUILTIN
122 ;
123
124static constexpr auto BuiltinSVENeonBridgeInfos =
125 Builtin::MakeInfos<NumSVENeonBridgeBuiltins>(Infos: {
126#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
127#define GET_SVE_BUILTINS
128#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"
129#undef GET_SVE_BUILTINS
130#undef TARGET_BUILTIN
131 });
132
133AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
134 const TargetOptions &Opts)
135 : TargetInfo(Triple), ABI("aapcs") {
136 if (getTriple().isOSOpenBSD()) {
137 Int64Type = SignedLongLong;
138 IntMaxType = SignedLongLong;
139 } else {
140 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
141 WCharType = UnsignedInt;
142
143 Int64Type = SignedLong;
144 IntMaxType = SignedLong;
145 }
146
147 AddrSpaceMap = &ARM64AddrSpaceMap;
148
149 // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
150 HasFastHalfType = true;
151 HalfArgsAndReturns = true;
152 HasFloat16 = true;
153 HasStrictFP = true;
154
155 if (Triple.isArch64Bit())
156 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
157 else
158 LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
159
160 BitIntMaxAlign = 128;
161 MaxVectorAlign = 128;
162 MaxAtomicInlineWidth = 128;
163 MaxAtomicPromoteWidth = 128;
164
165 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
166 LongDoubleFormat = &llvm::APFloat::IEEEquad();
167
168 BFloat16Width = BFloat16Align = 16;
169 BFloat16Format = &llvm::APFloat::BFloat();
170
171 // Make __builtin_ms_va_list available.
172 HasBuiltinMSVaList = true;
173
174 // Make the Neon ACLE and SVE types available. Note that this deliberately
175 // doesn't depend on SveMode, since in principle it should be possible to turn
176 // SVE on and off within a translation unit. It should also be possible
177 // to compile the global declaration:
178 //
179 // __SVInt8_t *ptr;
180 //
181 // even without SVE.
182 HasAArch64ACLETypes = true;
183
184 // {} in inline assembly are neon specifiers, not assembly variant
185 // specifiers.
186 NoAsmVariants = true;
187
188 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
189 // contributes to the alignment of the containing aggregate in the same way
190 // a plain (non bit-field) member of that type would, without exception for
191 // zero-sized or anonymous bit-fields."
192 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
193 UseZeroLengthBitfieldAlignment = true;
194
195 // AAPCS64 allows any "fundamental integer data type" to be used for
196 // over-sized bitfields, which includes 128-bit integers.
197 LargestOverSizedBitfieldContainer = 128;
198
199 HasUnalignedAccess = true;
200
201 // AArch64 targets default to using the ARM C++ ABI.
202 TheCXXABI.set(TargetCXXABI::GenericAArch64);
203
204 if (Triple.getOS() == llvm::Triple::Linux)
205 this->MCountName = "\01_mcount";
206 else if (Triple.getOS() == llvm::Triple::UnknownOS)
207 this->MCountName =
208 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
209}
210
211StringRef AArch64TargetInfo::getABI() const { return ABI; }
212
213bool AArch64TargetInfo::setABI(const std::string &Name) {
214 if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs")
215 return false;
216
217 ABI = Name;
218 return true;
219}
220
221bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
222 if (hasFeature(Feature: "fp") && ABI == "aapcs-soft") {
223 // aapcs-soft is not allowed for targets with an FPU, to avoid there being
224 // two incomatible ABIs.
225 Diags.Report(DiagID: diag::err_target_unsupported_abi_with_fpu) << ABI;
226 return false;
227 }
228 return true;
229}
230
231bool AArch64TargetInfo::validateGlobalRegisterVariable(
232 StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {
233 if (RegName == "sp") {
234 HasSizeMismatch = RegSize != 64;
235 return true;
236 }
237 if (RegName.starts_with(Prefix: "w"))
238 HasSizeMismatch = RegSize != 32;
239 else if (RegName.starts_with(Prefix: "x"))
240 HasSizeMismatch = RegSize != 64;
241 else
242 return false;
243 StringRef RegNum = RegName.drop_front();
244 // Check if the register is reserved. See also
245 // AArch64TargetLowering::getRegisterByName().
246 return RegNum == "0" ||
247 (RegNum == "18" &&
248 llvm::AArch64::isX18ReservedByDefault(TT: getTriple())) ||
249 getTargetOpts().FeatureMap.lookup(Key: ("reserve-x" + RegNum).str());
250}
251
252bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
253 BranchProtectionInfo &BPI,
254 const LangOptions &LO,
255 StringRef &Err) const {
256 llvm::ARM::ParsedBranchProtection PBP;
257 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, Triple: getTriple(),
258 EnablePAuthLR: HasPAuthLR))
259 return false;
260
261 // GCS is currently untested with ptrauth-returns, but enabling this could be
262 // allowed in future after testing with a suitable system.
263 if (LO.PointerAuthReturns &&
264 (PBP.Scope != "none" || PBP.BranchProtectionPAuthLR ||
265 PBP.GuardedControlStack))
266 return false;
267
268 BPI.SignReturnAddr =
269 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
270 .Case(S: "non-leaf", Value: LangOptions::SignReturnAddressScopeKind::NonLeaf)
271 .Case(S: "all", Value: LangOptions::SignReturnAddressScopeKind::All)
272 .Default(Value: LangOptions::SignReturnAddressScopeKind::None);
273
274 if (PBP.Key == "a_key")
275 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
276 else
277 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;
278
279 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
280 BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
281 BPI.GuardedControlStack = PBP.GuardedControlStack;
282 return true;
283}
284
285bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
286 return llvm::AArch64::parseCpu(Name).has_value();
287}
288
289bool AArch64TargetInfo::setCPU(StringRef Name) { return isValidCPUName(Name); }
290
291void AArch64TargetInfo::fillValidCPUList(
292 SmallVectorImpl<StringRef> &Values) const {
293 llvm::AArch64::fillValidCPUArchList(Values);
294}
295
296void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
297 MacroBuilder &Builder) const {
298 Builder.defineMacro(Name: "__ARM_FEATURE_QRDMX", Value: "1");
299}
300
301void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
302 MacroBuilder &Builder) const {
303 // Also include the ARMv8.1 defines
304 getTargetDefinesARMV81A(Opts, Builder);
305}
306
307void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
308 MacroBuilder &Builder) const {
309 Builder.defineMacro(Name: "__ARM_FEATURE_COMPLEX", Value: "1");
310 Builder.defineMacro(Name: "__ARM_FEATURE_JCVT", Value: "1");
311 // Also include the Armv8.2 defines
312 getTargetDefinesARMV82A(Opts, Builder);
313}
314
315void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
316 MacroBuilder &Builder) const {
317 // Also include the Armv8.3 defines
318 getTargetDefinesARMV83A(Opts, Builder);
319}
320
321void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
322 MacroBuilder &Builder) const {
323 Builder.defineMacro(Name: "__ARM_FEATURE_FRINT", Value: "1");
324 // Also include the Armv8.4 defines
325 getTargetDefinesARMV84A(Opts, Builder);
326}
327
328void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts,
329 MacroBuilder &Builder) const {
330 // Also include the Armv8.5 defines
331 // FIXME: Armv8.6 makes the following extensions mandatory:
332 // - __ARM_FEATURE_BF16
333 // - __ARM_FEATURE_MATMUL_INT8
334 // Handle them here.
335 getTargetDefinesARMV85A(Opts, Builder);
336}
337
338void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,
339 MacroBuilder &Builder) const {
340 // Also include the Armv8.6 defines
341 getTargetDefinesARMV86A(Opts, Builder);
342}
343
344void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,
345 MacroBuilder &Builder) const {
346 // Also include the Armv8.7 defines
347 getTargetDefinesARMV87A(Opts, Builder);
348}
349
350void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,
351 MacroBuilder &Builder) const {
352 // Also include the Armv8.8 defines
353 getTargetDefinesARMV88A(Opts, Builder);
354}
355
356void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,
357 MacroBuilder &Builder) const {
358 // Armv9-A maps to Armv8.5-A
359 getTargetDefinesARMV85A(Opts, Builder);
360}
361
362void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,
363 MacroBuilder &Builder) const {
364 // Armv9.1-A maps to Armv8.6-A
365 getTargetDefinesARMV86A(Opts, Builder);
366}
367
368void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,
369 MacroBuilder &Builder) const {
370 // Armv9.2-A maps to Armv8.7-A
371 getTargetDefinesARMV87A(Opts, Builder);
372}
373
374void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,
375 MacroBuilder &Builder) const {
376 // Armv9.3-A maps to Armv8.8-A
377 getTargetDefinesARMV88A(Opts, Builder);
378}
379
380void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,
381 MacroBuilder &Builder) const {
382 // Armv9.4-A maps to Armv8.9-A
383 getTargetDefinesARMV89A(Opts, Builder);
384}
385
386void AArch64TargetInfo::getTargetDefinesARMV95A(const LangOptions &Opts,
387 MacroBuilder &Builder) const {
388 // Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A.
389 getTargetDefinesARMV94A(Opts, Builder);
390}
391
392void AArch64TargetInfo::getTargetDefinesARMV96A(const LangOptions &Opts,
393 MacroBuilder &Builder) const {
394 // Armv9.6-A does not have a v8.* equivalent, but is a superset of v9.5-A.
395 getTargetDefinesARMV95A(Opts, Builder);
396}
397
398void AArch64TargetInfo::getTargetDefinesARMV97A(const LangOptions &Opts,
399 MacroBuilder &Builder) const {
400 // Armv9.7-A does not have a v8.* equivalent, but is a superset of v9.6-A.
401 getTargetDefinesARMV96A(Opts, Builder);
402}
403
404void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
405 MacroBuilder &Builder) const {
406 // Target identification.
407 if (getTriple().isWindowsArm64EC()) {
408 // Define the same set of macros as would be defined on x86_64 to ensure that
409 // ARM64EC datatype layouts match those of x86_64 compiled code
410 Builder.defineMacro(Name: "__amd64__");
411 Builder.defineMacro(Name: "__amd64");
412 Builder.defineMacro(Name: "__x86_64");
413 Builder.defineMacro(Name: "__x86_64__");
414 Builder.defineMacro(Name: "__arm64ec__");
415 } else {
416 Builder.defineMacro(Name: "__aarch64__");
417 }
418
419 if (getTriple().isLFI())
420 Builder.defineMacro(Name: "__LFI__");
421
422 // Inline assembly supports AArch64 flag outputs.
423 Builder.defineMacro(Name: "__GCC_ASM_FLAG_OUTPUTS__");
424
425 std::string CodeModel = getTargetOpts().CodeModel;
426 if (CodeModel == "default")
427 CodeModel = "small";
428 for (char &c : CodeModel)
429 c = toupper(c: c);
430 Builder.defineMacro(Name: "__AARCH64_CMODEL_" + CodeModel + "__");
431
432 // ACLE predefines. Many can only have one possible value on v8 AArch64.
433 Builder.defineMacro(Name: "__ARM_ACLE_VERSION(year, quarter, patch)",
434 Value: "(100 * (year) + 10 * (quarter) + (patch))");
435#define ARM_ACLE_VERSION(Y, Q, P) (100 * (Y) + 10 * (Q) + (P))
436 Builder.defineMacro(Name: "__ARM_ACLE", Value: Twine(ARM_ACLE_VERSION(2024, 2, 0)));
437 Builder.defineMacro(Name: "__FUNCTION_MULTI_VERSIONING_SUPPORT_LEVEL",
438 Value: Twine(ARM_ACLE_VERSION(2024, 3, 0)));
439#undef ARM_ACLE_VERSION
440 Builder.defineMacro(Name: "__ARM_ARCH",
441 Value: std::to_string(val: ArchInfo->Version.getMajor()));
442 Builder.defineMacro(Name: "__ARM_ARCH_PROFILE",
443 Value: std::string("'") + (char)ArchInfo->Profile + "'");
444
445 Builder.defineMacro(Name: "__ARM_64BIT_STATE", Value: "1");
446 Builder.defineMacro(Name: "__ARM_PCS_AAPCS64", Value: "1");
447 Builder.defineMacro(Name: "__ARM_ARCH_ISA_A64", Value: "1");
448
449 Builder.defineMacro(Name: "__ARM_FEATURE_CLZ", Value: "1");
450 Builder.defineMacro(Name: "__ARM_FEATURE_FMA", Value: "1");
451 Builder.defineMacro(Name: "__ARM_FEATURE_LDREX", Value: "0xF");
452 Builder.defineMacro(Name: "__ARM_FEATURE_IDIV", Value: "1"); // As specified in ACLE
453 Builder.defineMacro(Name: "__ARM_FEATURE_DIV"); // For backwards compatibility
454 Builder.defineMacro(Name: "__ARM_FEATURE_NUMERIC_MAXMIN", Value: "1");
455 Builder.defineMacro(Name: "__ARM_FEATURE_DIRECTED_ROUNDING", Value: "1");
456
457 Builder.defineMacro(Name: "__ARM_ALIGN_MAX_STACK_PWR", Value: "4");
458
459 // These macros are set when Clang can parse declarations with these
460 // attributes.
461 Builder.defineMacro(Name: "__ARM_STATE_ZA", Value: "1");
462 Builder.defineMacro(Name: "__ARM_STATE_ZT0", Value: "1");
463
464 // 0xe implies support for half, single and double precision operations.
465 if (FPU & FPUMode)
466 Builder.defineMacro(Name: "__ARM_FP", Value: "0xE");
467
468 // PCS specifies this for SysV variants, which is all we support. Other ABIs
469 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
470 Builder.defineMacro(Name: "__ARM_FP16_FORMAT_IEEE", Value: "1");
471 Builder.defineMacro(Name: "__ARM_FP16_ARGS", Value: "1");
472
473 // Clang supports arm_neon_sve_bridge.h
474 Builder.defineMacro(Name: "__ARM_NEON_SVE_BRIDGE", Value: "1");
475
476 if (Opts.UnsafeFPMath)
477 Builder.defineMacro(Name: "__ARM_FP_FAST", Value: "1");
478
479 Builder.defineMacro(Name: "__ARM_SIZEOF_WCHAR_T",
480 Value: Twine(Opts.WCharSize ? Opts.WCharSize : 4));
481
482 Builder.defineMacro(Name: "__ARM_SIZEOF_MINIMAL_ENUM", Value: Opts.ShortEnums ? "1" : "4");
483
484 // Clang supports range prefetch intrinsics
485 Builder.defineMacro(Name: "__ARM_PREFETCH_RANGE", Value: "1");
486
487 if (FPU & NeonMode) {
488 Builder.defineMacro(Name: "__ARM_NEON", Value: "1");
489 // 64-bit NEON supports half, single and double precision operations.
490 Builder.defineMacro(Name: "__ARM_NEON_FP", Value: "0xE");
491 }
492
493 if (FPU & SveMode)
494 Builder.defineMacro(Name: "__ARM_FEATURE_SVE", Value: "1");
495
496 if (HasSVE2)
497 Builder.defineMacro(Name: "__ARM_FEATURE_SVE2", Value: "1");
498
499 if (HasSVE2p1)
500 Builder.defineMacro(Name: "__ARM_FEATURE_SVE2p1", Value: "1");
501
502 if (HasSVE2 && HasSVEAES)
503 Builder.defineMacro(Name: "__ARM_FEATURE_SVE2_AES", Value: "1");
504
505 if (HasSVE2 && HasSVEBitPerm)
506 Builder.defineMacro(Name: "__ARM_FEATURE_SVE2_BITPERM", Value: "1");
507
508 if (HasSVE2 && HasSVE2SHA3)
509 Builder.defineMacro(Name: "__ARM_FEATURE_SVE2_SHA3", Value: "1");
510
511 if (HasSVE2 && HasSVE2SM4)
512 Builder.defineMacro(Name: "__ARM_FEATURE_SVE2_SM4", Value: "1");
513
514 if (HasSVEB16B16)
515 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_B16B16", Value: "1");
516
517 if (HasSME) {
518 Builder.defineMacro(Name: "__ARM_FEATURE_SME");
519 Builder.defineMacro(Name: "__ARM_FEATURE_LOCALLY_STREAMING", Value: "1");
520 }
521
522 if (HasSME2)
523 Builder.defineMacro(Name: "__ARM_FEATURE_SME2", Value: "1");
524
525 if (HasSME2p1)
526 Builder.defineMacro(Name: "__ARM_FEATURE_SME2p1", Value: "1");
527
528 if (HasSMEF16F16)
529 Builder.defineMacro(Name: "__ARM_FEATURE_SME_F16F16", Value: "1");
530
531 if (HasSMEB16B16)
532 Builder.defineMacro(Name: "__ARM_FEATURE_SME_B16B16", Value: "1");
533
534 if (HasFP8)
535 Builder.defineMacro(Name: "__ARM_FEATURE_FP8", Value: "1");
536
537 if (HasFP8FMA)
538 Builder.defineMacro(Name: "__ARM_FEATURE_FP8FMA", Value: "1");
539
540 if (HasFP8DOT2)
541 Builder.defineMacro(Name: "__ARM_FEATURE_FP8DOT2", Value: "1");
542
543 if (HasFP8DOT4)
544 Builder.defineMacro(Name: "__ARM_FEATURE_FP8DOT4", Value: "1");
545
546 if (HasSSVE_FP8DOT2)
547 Builder.defineMacro(Name: "__ARM_FEATURE_SSVE_FP8DOT2", Value: "1");
548
549 if (HasSSVE_FP8DOT4)
550 Builder.defineMacro(Name: "__ARM_FEATURE_SSVE_FP8DOT4", Value: "1");
551
552 if (HasSSVE_FP8FMA)
553 Builder.defineMacro(Name: "__ARM_FEATURE_SSVE_FP8FMA", Value: "1");
554
555 if (HasSME_F8F32)
556 Builder.defineMacro(Name: "__ARM_FEATURE_SME_F8F32", Value: "1");
557
558 if (HasSME_F8F16)
559 Builder.defineMacro(Name: "__ARM_FEATURE_SME_F8F16", Value: "1");
560
561 if (HasCRC)
562 Builder.defineMacro(Name: "__ARM_FEATURE_CRC32", Value: "1");
563
564 if (HasCSSC)
565 Builder.defineMacro(Name: "__ARM_FEATURE_CSSC", Value: "1");
566
567 if (HasRCPC3)
568 Builder.defineMacro(Name: "__ARM_FEATURE_RCPC", Value: "3");
569 else if (HasRCPC)
570 Builder.defineMacro(Name: "__ARM_FEATURE_RCPC", Value: "1");
571
572 if (HasFPRCVT)
573 Builder.defineMacro(Name: "__ARM_FEATURE_FPRCVT", Value: "1");
574
575 if (HasF8F16MM)
576 Builder.defineMacro(Name: "__ARM_FEATURE_F8F16MM", Value: "1");
577
578 if (HasF8F32MM)
579 Builder.defineMacro(Name: "__ARM_FEATURE_F8F32MM", Value: "1");
580
581 if (HasSVE_F16F32MM)
582 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_F16F32MM", Value: "1");
583
584 if (HasSVE_BFSCALE)
585 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_BFSCALE", Value: "1");
586
587 if (HasSVE_B16MM)
588 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_B16MM", Value: "1");
589
590 if (HasF16MM)
591 Builder.defineMacro(Name: "__ARM_FEATURE_F16MM", Value: "1");
592
593 if (HasF16F32DOT)
594 Builder.defineMacro(Name: "__ARM_FEATURE_F16F32DOT", Value: "1");
595
596 if (HasF16F32MM)
597 Builder.defineMacro(Name: "__ARM_FEATURE_F16F32MM", Value: "1");
598
599 if (HasSVE_AES2)
600 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_AES2", Value: "1");
601
602 if (HasSSVE_AES)
603 Builder.defineMacro(Name: "__ARM_FEATURE_SSVE_AES", Value: "1");
604
605 if (HasSVE2p2)
606 Builder.defineMacro(Name: "__ARM_FEATURE_SVE2p2", Value: "1");
607
608 if (HasSVE2p3)
609 Builder.defineMacro(Name: "__ARM_FEATURE_SVE2p3", Value: "1");
610
611 if (HasSME2p2)
612 Builder.defineMacro(Name: "__ARM_FEATURE_SME2p2", Value: "1");
613
614 if (HasSME2p3)
615 Builder.defineMacro(Name: "__ARM_FEATURE_SME2p3", Value: "1");
616
617 if (HasFMV)
618 Builder.defineMacro(Name: "__HAVE_FUNCTION_MULTI_VERSIONING", Value: "1");
619
620 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
621 // macros for AES, SHA2, SHA3 and SM4
622 if (HasAES && HasSHA2)
623 Builder.defineMacro(Name: "__ARM_FEATURE_CRYPTO", Value: "1");
624
625 if (HasAES)
626 Builder.defineMacro(Name: "__ARM_FEATURE_AES", Value: "1");
627
628 if (HasSHA2)
629 Builder.defineMacro(Name: "__ARM_FEATURE_SHA2", Value: "1");
630
631 if (HasSHA3) {
632 Builder.defineMacro(Name: "__ARM_FEATURE_SHA3", Value: "1");
633 Builder.defineMacro(Name: "__ARM_FEATURE_SHA512", Value: "1");
634 }
635
636 if (HasSM4) {
637 Builder.defineMacro(Name: "__ARM_FEATURE_SM3", Value: "1");
638 Builder.defineMacro(Name: "__ARM_FEATURE_SM4", Value: "1");
639 }
640
641 if (HasPAuth)
642 Builder.defineMacro(Name: "__ARM_FEATURE_PAUTH", Value: "1");
643
644 if (HasPAuthLR)
645 Builder.defineMacro(Name: "__ARM_FEATURE_PAUTH_LR", Value: "1");
646
647 if (HasBTI)
648 Builder.defineMacro(Name: "__ARM_FEATURE_BTI", Value: "1");
649
650 if (HasUnalignedAccess)
651 Builder.defineMacro(Name: "__ARM_FEATURE_UNALIGNED", Value: "1");
652
653 if ((FPU & NeonMode) && HasFullFP16)
654 Builder.defineMacro(Name: "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", Value: "1");
655 if (HasFullFP16)
656 Builder.defineMacro(Name: "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", Value: "1");
657
658 if (HasDotProd)
659 Builder.defineMacro(Name: "__ARM_FEATURE_DOTPROD", Value: "1");
660
661 if (HasMTE)
662 Builder.defineMacro(Name: "__ARM_FEATURE_MEMORY_TAGGING", Value: "1");
663
664 if (HasMatMul)
665 Builder.defineMacro(Name: "__ARM_FEATURE_MATMUL_INT8", Value: "1");
666
667 if (HasLSE)
668 Builder.defineMacro(Name: "__ARM_FEATURE_ATOMICS", Value: "1");
669
670 if (HasBFloat16) {
671 Builder.defineMacro(Name: "__ARM_FEATURE_BF16", Value: "1");
672 Builder.defineMacro(Name: "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", Value: "1");
673 Builder.defineMacro(Name: "__ARM_BF16_FORMAT_ALTERNATIVE", Value: "1");
674 Builder.defineMacro(Name: "__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", Value: "1");
675 }
676
677 if ((FPU & SveMode) && HasBFloat16) {
678 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_BF16", Value: "1");
679 }
680
681 if ((FPU & SveMode) && HasMatmulFP64)
682 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_MATMUL_FP64", Value: "1");
683
684 if ((FPU & SveMode) && HasMatmulFP32)
685 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_MATMUL_FP32", Value: "1");
686
687 if ((FPU & SveMode) && HasMatMul)
688 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_MATMUL_INT8", Value: "1");
689
690 if ((FPU & NeonMode) && HasFP16FML)
691 Builder.defineMacro(Name: "__ARM_FEATURE_FP16_FML", Value: "1");
692
693 if (Opts.hasSignReturnAddress()) {
694 // Bitmask:
695 // 0: Protection using the A key
696 // 1: Protection using the B key
697 // 2: Protection including leaf functions
698 // 3: Protection using PC as a diversifier
699 unsigned Value = 0;
700
701 if (Opts.isSignReturnAddressWithAKey())
702 Value |= (1 << 0);
703 else
704 Value |= (1 << 1);
705
706 if (Opts.isSignReturnAddressScopeAll())
707 Value |= (1 << 2);
708
709 if (Opts.BranchProtectionPAuthLR)
710 Value |= (1 << 3);
711
712 Builder.defineMacro(Name: "__ARM_FEATURE_PAC_DEFAULT", Value: std::to_string(val: Value));
713 }
714
715 if (Opts.BranchTargetEnforcement)
716 Builder.defineMacro(Name: "__ARM_FEATURE_BTI_DEFAULT", Value: "1");
717
718 if (Opts.GuardedControlStack)
719 Builder.defineMacro(Name: "__ARM_FEATURE_GCS_DEFAULT", Value: "1");
720
721 if (HasLS64)
722 Builder.defineMacro(Name: "__ARM_FEATURE_LS64", Value: "1");
723
724 if (HasRandGen)
725 Builder.defineMacro(Name: "__ARM_FEATURE_RNG", Value: "1");
726
727 if (HasMOPS)
728 Builder.defineMacro(Name: "__ARM_FEATURE_MOPS", Value: "1");
729
730 if (HasD128)
731 Builder.defineMacro(Name: "__ARM_FEATURE_SYSREG128", Value: "1");
732
733 if (HasGCS)
734 Builder.defineMacro(Name: "__ARM_FEATURE_GCS", Value: "1");
735
736 if (*ArchInfo == llvm::AArch64::ARMV8_1A)
737 getTargetDefinesARMV81A(Opts, Builder);
738 else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
739 getTargetDefinesARMV82A(Opts, Builder);
740 else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
741 getTargetDefinesARMV83A(Opts, Builder);
742 else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
743 getTargetDefinesARMV84A(Opts, Builder);
744 else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
745 getTargetDefinesARMV85A(Opts, Builder);
746 else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
747 getTargetDefinesARMV86A(Opts, Builder);
748 else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
749 getTargetDefinesARMV87A(Opts, Builder);
750 else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
751 getTargetDefinesARMV88A(Opts, Builder);
752 else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
753 getTargetDefinesARMV89A(Opts, Builder);
754 else if (*ArchInfo == llvm::AArch64::ARMV9A)
755 getTargetDefinesARMV9A(Opts, Builder);
756 else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
757 getTargetDefinesARMV91A(Opts, Builder);
758 else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
759 getTargetDefinesARMV92A(Opts, Builder);
760 else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
761 getTargetDefinesARMV93A(Opts, Builder);
762 else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
763 getTargetDefinesARMV94A(Opts, Builder);
764 else if (*ArchInfo == llvm::AArch64::ARMV9_5A)
765 getTargetDefinesARMV95A(Opts, Builder);
766 else if (*ArchInfo == llvm::AArch64::ARMV9_6A)
767 getTargetDefinesARMV96A(Opts, Builder);
768 else if (*ArchInfo == llvm::AArch64::ARMV9_7A)
769 getTargetDefinesARMV97A(Opts, Builder);
770
771 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.
772 Builder.defineMacro(Name: "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
773 Builder.defineMacro(Name: "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
774 Builder.defineMacro(Name: "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
775 Builder.defineMacro(Name: "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
776 Builder.defineMacro(Name: "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
777
778 // Allow detection of fast FMA support.
779 Builder.defineMacro(Name: "__FP_FAST_FMA", Value: "1");
780 Builder.defineMacro(Name: "__FP_FAST_FMAF", Value: "1");
781
782 // C/C++ operators work on both VLS and VLA SVE types
783 if (FPU & SveMode)
784 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_VECTOR_OPERATORS", Value: "2");
785
786 if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {
787 Builder.defineMacro(Name: "__ARM_FEATURE_SVE_BITS", Value: Twine(Opts.VScaleMin * 128));
788 }
789}
790
791llvm::SmallVector<Builtin::InfosShard>
792AArch64TargetInfo::getTargetBuiltins() const {
793 return {
794 {.Strings: &NEON::BuiltinStrings, .Infos: NEON::BuiltinInfos, .NamePrefix: "__builtin_neon_"},
795 {.Strings: &NEON::FP16::BuiltinStrings, .Infos: NEON::FP16::BuiltinInfos,
796 .NamePrefix: "__builtin_neon_"},
797 {.Strings: &SVE::BuiltinStrings, .Infos: SVE::BuiltinInfos, .NamePrefix: "__builtin_sve_"},
798 {.Strings: &BuiltinSVENeonBridgeStrings, .Infos: BuiltinSVENeonBridgeInfos},
799 {.Strings: &SME::BuiltinStrings, .Infos: SME::BuiltinInfos, .NamePrefix: "__builtin_sme_"},
800 {.Strings: &AArch64::BuiltinStrings, .Infos: AArch64::BuiltinInfos},
801 {.Strings: &AArch64::BuiltinStrings, .Infos: AArch64::PrefixedBuiltinInfos,
802 .NamePrefix: "__builtin_arm_"},
803 };
804}
805
806std::optional<std::pair<unsigned, unsigned>>
807AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts,
808 ArmStreamingKind Mode,
809 llvm::StringMap<bool> *FeatureMap) const {
810 if (Mode == ArmStreamingKind::NotStreaming &&
811 (LangOpts.VScaleMin || LangOpts.VScaleMax))
812 return std::pair<unsigned, unsigned>(
813 LangOpts.VScaleMin ? LangOpts.VScaleMin : 1,
814 LangOpts.VScaleMax ? LangOpts.VScaleMax : 16);
815
816 if (Mode == ArmStreamingKind::Streaming &&
817 (LangOpts.VScaleStreamingMin || LangOpts.VScaleStreamingMax))
818 return std::pair<unsigned, unsigned>(
819 LangOpts.VScaleStreamingMin ? LangOpts.VScaleStreamingMin : 1,
820 LangOpts.VScaleStreamingMax ? LangOpts.VScaleStreamingMax : 16);
821
822 if (Mode == ArmStreamingKind::StreamingCompatible &&
823 ((LangOpts.VScaleMin && LangOpts.VScaleStreamingMin) ||
824 (LangOpts.VScaleMax && LangOpts.VScaleStreamingMax))) {
825 unsigned Min =
826 std::min(a: LangOpts.VScaleMin ? LangOpts.VScaleMin : 1,
827 b: LangOpts.VScaleStreamingMin ? LangOpts.VScaleStreamingMin : 1);
828 unsigned Max = std::max(
829 a: LangOpts.VScaleMax ? LangOpts.VScaleMax : 16,
830 b: LangOpts.VScaleStreamingMax ? LangOpts.VScaleStreamingMax : 16);
831 return std::pair(Min, Max);
832 }
833
834 if (hasFeature(Feature: "sve") || (FeatureMap && (FeatureMap->lookup(Key: "sve"))))
835 return std::pair<unsigned, unsigned>(1, 16);
836
837 if (Mode == ArmStreamingKind::Streaming &&
838 (hasFeature(Feature: "sme") || (FeatureMap && (FeatureMap->lookup(Key: "sme")))))
839 return std::pair<unsigned, unsigned>(1, 16);
840
841 return std::nullopt;
842}
843
844llvm::APInt
845AArch64TargetInfo::getFMVPriority(ArrayRef<StringRef> Features) const {
846 return llvm::AArch64::getFMVPriority(Features);
847}
848
849bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
850 // FMV extensions which imply no backend features do not affect codegen.
851 if (auto Ext = llvm::AArch64::parseFMVExtension(Extension: Name))
852 return Ext->ID.has_value();
853 return false;
854}
855
856bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
857 // CPU features might be separated by '+', extract them and check
858 llvm::SmallVector<StringRef, 8> Features;
859 FeatureStr.split(A&: Features, Separator: "+");
860 for (auto &Feature : Features)
861 if (!llvm::AArch64::parseFMVExtension(Extension: Feature.trim()).has_value())
862 return false;
863 return true;
864}
865
866/// A helper class for "hasFeature" lookups (mimicking a StringSwitch).
867struct FeatureLookupBuilder {
868 FeatureLookupBuilder(AArch64FeatureSet &Features) : Features(Features) {
869 Features.clear();
870 }
871
872 FeatureLookupBuilder &Case(StringRef Feat, bool HasFeature) {
873 if (HasFeature)
874 Features.insert(V: Feat);
875 return *this;
876 }
877
878 FeatureLookupBuilder &Cases(ArrayRef<StringRef> Feats, bool HasFeature) {
879 if (HasFeature)
880 Features.insert_range(R&: Feats);
881 return *this;
882 }
883
884private:
885 AArch64FeatureSet &Features;
886};
887
888void AArch64TargetInfo::computeFeatureLookup() {
889 FeatureLookupBuilder(HasFeatureLookup)
890 .Cases(Feats: {"aarch64", "arm64", "arm"}, HasFeature: true)
891 .Case(Feat: "fmv", HasFeature: HasFMV)
892 .Case(Feat: "fp", HasFeature: FPU & FPUMode)
893 .Cases(Feats: {"neon", "simd"}, HasFeature: FPU & NeonMode)
894 .Case(Feat: "jscvt", HasFeature: HasJSCVT)
895 .Case(Feat: "fcma", HasFeature: HasFCMA)
896 .Case(Feat: "rng", HasFeature: HasRandGen)
897 .Case(Feat: "flagm", HasFeature: HasFlagM)
898 .Case(Feat: "flagm2", HasFeature: HasAlternativeNZCV)
899 .Case(Feat: "fp16fml", HasFeature: HasFP16FML)
900 .Case(Feat: "dotprod", HasFeature: HasDotProd)
901 .Case(Feat: "sm4", HasFeature: HasSM4)
902 .Case(Feat: "rdm", HasFeature: HasRDM)
903 .Case(Feat: "lse", HasFeature: HasLSE)
904 .Case(Feat: "crc", HasFeature: HasCRC)
905 .Case(Feat: "cssc", HasFeature: HasCSSC)
906 .Case(Feat: "sha2", HasFeature: HasSHA2)
907 .Case(Feat: "sha3", HasFeature: HasSHA3)
908 .Cases(Feats: {"aes", "pmull"}, HasFeature: HasAES)
909 .Cases(Feats: {"fp16", "fullfp16"}, HasFeature: HasFullFP16)
910 .Case(Feat: "dit", HasFeature: HasDIT)
911 .Case(Feat: "dpb", HasFeature: HasCCPP)
912 .Case(Feat: "dpb2", HasFeature: HasCCDP)
913 .Case(Feat: "rcpc", HasFeature: HasRCPC)
914 .Case(Feat: "frintts", HasFeature: HasFRInt3264)
915 .Case(Feat: "i8mm", HasFeature: HasMatMul)
916 .Case(Feat: "bf16", HasFeature: HasBFloat16)
917 .Case(Feat: "sve", HasFeature: FPU & SveMode)
918 .Case(Feat: "sve-b16b16", HasFeature: HasSVEB16B16)
919 .Case(Feat: "f32mm", HasFeature: FPU & SveMode && HasMatmulFP32)
920 .Case(Feat: "f64mm", HasFeature: FPU & SveMode && HasMatmulFP64)
921 .Case(Feat: "sve2", HasFeature: FPU & SveMode && HasSVE2)
922 .Case(Feat: "sve-aes", HasFeature: HasSVEAES)
923 .Case(Feat: "sve-bitperm", HasFeature: FPU & HasSVEBitPerm)
924 .Case(Feat: "sve2-sha3", HasFeature: FPU & SveMode && HasSVE2SHA3)
925 .Case(Feat: "sve2-sm4", HasFeature: FPU & SveMode && HasSVE2SM4)
926 .Case(Feat: "sve2p1", HasFeature: FPU & SveMode && HasSVE2p1)
927 .Case(Feat: "sme", HasFeature: HasSME)
928 .Case(Feat: "sme2", HasFeature: HasSME2)
929 .Case(Feat: "sme2p1", HasFeature: HasSME2p1)
930 .Case(Feat: "sme-f64f64", HasFeature: HasSMEF64F64)
931 .Case(Feat: "sme-i16i64", HasFeature: HasSMEI16I64)
932 .Case(Feat: "sme-fa64", HasFeature: HasSMEFA64)
933 .Case(Feat: "sme-f16f16", HasFeature: HasSMEF16F16)
934 .Case(Feat: "sme-b16b16", HasFeature: HasSMEB16B16)
935 .Case(Feat: "memtag", HasFeature: HasMTE)
936 .Case(Feat: "sb", HasFeature: HasSB)
937 .Case(Feat: "predres", HasFeature: HasPredRes)
938 .Cases(Feats: {"ssbs", "ssbs2"}, HasFeature: HasSSBS)
939 .Case(Feat: "bti", HasFeature: HasBTI)
940 .Cases(Feats: {"ls64", "ls64_v", "ls64_accdata"}, HasFeature: HasLS64)
941 .Case(Feat: "wfxt", HasFeature: HasWFxT)
942 .Case(Feat: "rcpc3", HasFeature: HasRCPC3)
943 .Case(Feat: "fp8", HasFeature: HasFP8)
944 .Case(Feat: "fp8fma", HasFeature: HasFP8FMA)
945 .Case(Feat: "fp8dot2", HasFeature: HasFP8DOT2)
946 .Case(Feat: "fp8dot4", HasFeature: HasFP8DOT4)
947 .Case(Feat: "ssve-fp8dot2", HasFeature: HasSSVE_FP8DOT2)
948 .Case(Feat: "ssve-fp8dot4", HasFeature: HasSSVE_FP8DOT4)
949 .Case(Feat: "ssve-fp8fma", HasFeature: HasSSVE_FP8FMA)
950 .Case(Feat: "sme-f8f32", HasFeature: HasSME_F8F32)
951 .Case(Feat: "sme-f8f16", HasFeature: HasSME_F8F16)
952 .Case(Feat: "fprcvt", HasFeature: HasFPRCVT)
953 .Case(Feat: "f8f16mm", HasFeature: HasF8F16MM)
954 .Case(Feat: "f8f32mm", HasFeature: HasF8F32MM)
955 .Case(Feat: "sve-f16f32mm", HasFeature: HasSVE_F16F32MM)
956 .Case(Feat: "sve-bfscale", HasFeature: HasSVE_BFSCALE)
957 .Case(Feat: "sve-aes2", HasFeature: HasSVE_AES2)
958 .Case(Feat: "ssve-aes", HasFeature: HasSSVE_AES)
959 .Case(Feat: "sve2p2", HasFeature: FPU & SveMode && HasSVE2p2)
960 .Case(Feat: "sme2p2", HasFeature: HasSME2p2)
961 .Case(Feat: "sve2p3", HasFeature: FPU & SveMode && HasSVE2p3)
962 .Case(Feat: "sme2p3", HasFeature: HasSME2p3)
963 .Case(Feat: "sve-b16mm", HasFeature: HasSVE_B16MM)
964 .Case(Feat: "f16mm", HasFeature: HasF16MM)
965 .Case(Feat: "f16f32dot", HasFeature: HasF16F32DOT)
966 .Case(Feat: "f16f32mm", HasFeature: HasF16F32MM);
967}
968
969bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
970 return HasFeatureLookup.contains(V: Feature);
971}
972
973void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
974 StringRef Name, bool Enabled) const {
975 Features[Name] = Enabled;
976 // If the feature is an architecture feature (like v8.2a), add all previous
977 // architecture versions and any dependant target features.
978 const std::optional<llvm::AArch64::ArchInfo> ArchInfo =
979 llvm::AArch64::ArchInfo::findBySubArch(SubArch: Name);
980
981 if (!ArchInfo)
982 return; // Not an architecture, nothing more to do.
983
984 // Disabling an architecture feature does not affect dependent features
985 if (!Enabled)
986 return;
987
988 for (const auto &OtherArch : llvm::AArch64::ArchInfos)
989 if (ArchInfo->implies(Other: OtherArch))
990 Features[OtherArch.getSubArch()] = true;
991
992 // Set any features implied by the architecture
993 std::vector<StringRef> CPUFeats;
994 if (llvm::AArch64::getExtensionFeatures(Extensions: ArchInfo->DefaultExts, Features&: CPUFeats)) {
995 for (auto F : CPUFeats) {
996 assert(F[0] == '+' && "Expected + in target feature!");
997 Features[F.drop_front(N: 1)] = true;
998 }
999 }
1000}
1001
1002bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
1003 DiagnosticsEngine &Diags) {
1004 for (const auto &Feature : Features) {
1005 if (Feature == "-fp-armv8")
1006 HasNoFP = true;
1007 if (Feature == "-neon")
1008 HasNoNeon = true;
1009 if (Feature == "-sve")
1010 HasNoSVE = true;
1011
1012 if (Feature == "+neon" || Feature == "+fp-armv8")
1013 FPU |= NeonMode;
1014 if (Feature == "+jscvt") {
1015 HasJSCVT = true;
1016 FPU |= NeonMode;
1017 }
1018 if (Feature == "+fcma") {
1019 HasFCMA = true;
1020 FPU |= NeonMode;
1021 }
1022
1023 if (Feature == "+sve") {
1024 FPU |= NeonMode;
1025 FPU |= SveMode;
1026 HasFullFP16 = true;
1027 }
1028 if (Feature == "+sve2") {
1029 FPU |= NeonMode;
1030 FPU |= SveMode;
1031 HasFullFP16 = true;
1032 HasSVE2 = true;
1033 }
1034 if (Feature == "+sve2p1") {
1035 FPU |= NeonMode;
1036 FPU |= SveMode;
1037 HasFullFP16 = true;
1038 HasSVE2 = true;
1039 HasSVE2p1 = true;
1040 }
1041 if (Feature == "+sve-aes") {
1042 FPU |= NeonMode;
1043 HasFullFP16 = true;
1044 HasSVEAES = true;
1045 }
1046 if (Feature == "+sve2-sha3") {
1047 FPU |= NeonMode;
1048 FPU |= SveMode;
1049 HasFullFP16 = true;
1050 HasSVE2 = true;
1051 HasSVE2SHA3 = true;
1052 }
1053 if (Feature == "+sve2-sm4") {
1054 FPU |= NeonMode;
1055 FPU |= SveMode;
1056 HasFullFP16 = true;
1057 HasSVE2 = true;
1058 HasSVE2SM4 = true;
1059 }
1060 if (Feature == "+sve-b16b16")
1061 HasSVEB16B16 = true;
1062 if (Feature == "+sve-bitperm") {
1063 FPU |= NeonMode;
1064 HasFullFP16 = true;
1065 HasSVEBitPerm = true;
1066 }
1067 if (Feature == "+f32mm") {
1068 FPU |= NeonMode;
1069 FPU |= SveMode;
1070 HasFullFP16 = true;
1071 HasMatmulFP32 = true;
1072 }
1073 if (Feature == "+f64mm") {
1074 FPU |= NeonMode;
1075 FPU |= SveMode;
1076 HasFullFP16 = true;
1077 HasMatmulFP64 = true;
1078 }
1079 if (Feature == "+sme") {
1080 HasSME = true;
1081 HasBFloat16 = true;
1082 HasFullFP16 = true;
1083 }
1084 if (Feature == "+sme2") {
1085 HasSME = true;
1086 HasSME2 = true;
1087 HasBFloat16 = true;
1088 HasFullFP16 = true;
1089 }
1090 if (Feature == "+sme2p1") {
1091 HasSME = true;
1092 HasSME2 = true;
1093 HasSME2p1 = true;
1094 HasBFloat16 = true;
1095 HasFullFP16 = true;
1096 }
1097 if (Feature == "+sme-f64f64") {
1098 HasSME = true;
1099 HasSMEF64F64 = true;
1100 HasBFloat16 = true;
1101 HasFullFP16 = true;
1102 }
1103 if (Feature == "+sme-i16i64") {
1104 HasSME = true;
1105 HasSMEI16I64 = true;
1106 HasBFloat16 = true;
1107 HasFullFP16 = true;
1108 }
1109 if (Feature == "+sme-fa64") {
1110 FPU |= NeonMode;
1111 FPU |= SveMode;
1112 HasSME = true;
1113 HasSVE2 = true;
1114 HasSMEFA64 = true;
1115 }
1116 if (Feature == "+sme-f16f16") {
1117 HasSME = true;
1118 HasSME2 = true;
1119 HasBFloat16 = true;
1120 HasFullFP16 = true;
1121 HasSMEF16F16 = true;
1122 }
1123 if (Feature == "+sme-b16b16") {
1124 HasSME = true;
1125 HasSME2 = true;
1126 HasBFloat16 = true;
1127 HasFullFP16 = true;
1128 HasSVEB16B16 = true;
1129 HasSMEB16B16 = true;
1130 }
1131
1132 if (Feature == "+fp8")
1133 HasFP8 = true;
1134 if (Feature == "+fp8fma")
1135 HasFP8FMA = true;
1136 if (Feature == "+fp8dot2")
1137 HasFP8DOT2 = true;
1138 if (Feature == "+fp8dot4")
1139 HasFP8DOT4 = true;
1140 if (Feature == "+ssve-fp8dot2")
1141 HasSSVE_FP8DOT2 = true;
1142 if (Feature == "+ssve-fp8dot4")
1143 HasSSVE_FP8DOT4 = true;
1144 if (Feature == "+ssve-fp8fma")
1145 HasSSVE_FP8FMA = true;
1146 if (Feature == "+sme-f8f32")
1147 HasSME_F8F32 = true;
1148 if (Feature == "+sme-f8f16")
1149 HasSME_F8F16 = true;
1150 if (Feature == "+sb")
1151 HasSB = true;
1152 if (Feature == "+predres")
1153 HasPredRes = true;
1154 if (Feature == "+ssbs")
1155 HasSSBS = true;
1156 if (Feature == "+bti")
1157 HasBTI = true;
1158 if (Feature == "+wfxt")
1159 HasWFxT = true;
1160 if (Feature == "-fmv")
1161 HasFMV = false;
1162 if (Feature == "+crc")
1163 HasCRC = true;
1164 if (Feature == "+rcpc")
1165 HasRCPC = true;
1166 if (Feature == "+aes") {
1167 FPU |= NeonMode;
1168 HasAES = true;
1169 }
1170 if (Feature == "+sha2") {
1171 FPU |= NeonMode;
1172 HasSHA2 = true;
1173 }
1174 if (Feature == "+sha3") {
1175 FPU |= NeonMode;
1176 HasSHA2 = true;
1177 HasSHA3 = true;
1178 }
1179 if (Feature == "+rdm") {
1180 FPU |= NeonMode;
1181 HasRDM = true;
1182 }
1183 if (Feature == "+dit")
1184 HasDIT = true;
1185 if (Feature == "+cccp")
1186 HasCCPP = true;
1187 if (Feature == "+ccdp") {
1188 HasCCPP = true;
1189 HasCCDP = true;
1190 }
1191 if (Feature == "+fptoint")
1192 HasFRInt3264 = true;
1193 if (Feature == "+sm4") {
1194 FPU |= NeonMode;
1195 HasSM4 = true;
1196 }
1197 if (Feature == "+strict-align")
1198 HasUnalignedAccess = false;
1199 if (Feature == "+fprcvt")
1200 HasFPRCVT = true;
1201 if (Feature == "+f8f16mm")
1202 HasF8F16MM = true;
1203 if (Feature == "+f8f32mm")
1204 HasF8F32MM = true;
1205 if (Feature == "+sve-f16f32mm")
1206 HasSVE_F16F32MM = true;
1207 if (Feature == "+sve-b16mm")
1208 HasSVE_B16MM = true;
1209 if (Feature == "+f16mm")
1210 HasF16MM = true;
1211 if (Feature == "+f16f32dot")
1212 HasF16F32DOT = true;
1213 if (Feature == "+f16f32mm")
1214 HasF16F32MM = true;
1215 if (Feature == "+sve-bfscale")
1216 HasSVE_BFSCALE = true;
1217 if (Feature == "+sve-aes2")
1218 HasSVE_AES2 = true;
1219 if (Feature == "+ssve-aes")
1220 HasSSVE_AES = true;
1221 if (Feature == "+sve2p2")
1222 HasSVE2p2 = true;
1223 if (Feature == "+sve2p3")
1224 HasSVE2p3 = true;
1225 if (Feature == "+sme2p2")
1226 HasSME2p2 = true;
1227 if (Feature == "+sme2p3")
1228 HasSME2p3 = true;
1229
1230 // All predecessor archs are added but select the latest one for ArchKind.
1231 if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
1232 ArchInfo = &llvm::AArch64::ARMV8A;
1233 if (Feature == "+v8.1a" &&
1234 ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
1235 ArchInfo = &llvm::AArch64::ARMV8_1A;
1236 if (Feature == "+v8.2a" &&
1237 ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
1238 ArchInfo = &llvm::AArch64::ARMV8_2A;
1239 if (Feature == "+v8.3a" &&
1240 ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
1241 ArchInfo = &llvm::AArch64::ARMV8_3A;
1242 if (Feature == "+v8.4a" &&
1243 ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
1244 ArchInfo = &llvm::AArch64::ARMV8_4A;
1245 if (Feature == "+v8.5a" &&
1246 ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
1247 ArchInfo = &llvm::AArch64::ARMV8_5A;
1248 if (Feature == "+v8.6a" &&
1249 ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
1250 ArchInfo = &llvm::AArch64::ARMV8_6A;
1251 if (Feature == "+v8.7a" &&
1252 ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
1253 ArchInfo = &llvm::AArch64::ARMV8_7A;
1254 if (Feature == "+v8.8a" &&
1255 ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
1256 ArchInfo = &llvm::AArch64::ARMV8_8A;
1257 if (Feature == "+v8.9a" &&
1258 ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
1259 ArchInfo = &llvm::AArch64::ARMV8_9A;
1260 if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
1261 ArchInfo = &llvm::AArch64::ARMV9A;
1262 if (Feature == "+v9.1a" &&
1263 ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
1264 ArchInfo = &llvm::AArch64::ARMV9_1A;
1265 if (Feature == "+v9.2a" &&
1266 ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
1267 ArchInfo = &llvm::AArch64::ARMV9_2A;
1268 if (Feature == "+v9.3a" &&
1269 ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
1270 ArchInfo = &llvm::AArch64::ARMV9_3A;
1271 if (Feature == "+v9.4a" &&
1272 ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
1273 ArchInfo = &llvm::AArch64::ARMV9_4A;
1274 if (Feature == "+v9.5a" &&
1275 ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)
1276 ArchInfo = &llvm::AArch64::ARMV9_5A;
1277 if (Feature == "+v9.6a" &&
1278 ArchInfo->Version < llvm::AArch64::ARMV9_6A.Version)
1279 ArchInfo = &llvm::AArch64::ARMV9_6A;
1280 if (Feature == "+v9.7a" &&
1281 ArchInfo->Version < llvm::AArch64::ARMV9_7A.Version)
1282 ArchInfo = &llvm::AArch64::ARMV9_7A;
1283 if (Feature == "+v8r")
1284 ArchInfo = &llvm::AArch64::ARMV8R;
1285 if (Feature == "+fullfp16") {
1286 FPU |= NeonMode;
1287 HasFullFP16 = true;
1288 }
1289 if (Feature == "+dotprod") {
1290 FPU |= NeonMode;
1291 HasDotProd = true;
1292 }
1293 if (Feature == "+fp16fml") {
1294 FPU |= NeonMode;
1295 HasFullFP16 = true;
1296 HasFP16FML = true;
1297 }
1298 if (Feature == "+mte")
1299 HasMTE = true;
1300 if (Feature == "+pauth")
1301 HasPAuth = true;
1302 if (Feature == "+i8mm")
1303 HasMatMul = true;
1304 if (Feature == "+bf16")
1305 HasBFloat16 = true;
1306 if (Feature == "+lse")
1307 HasLSE = true;
1308 if (Feature == "+ls64")
1309 HasLS64 = true;
1310 if (Feature == "+rand")
1311 HasRandGen = true;
1312 if (Feature == "+flagm")
1313 HasFlagM = true;
1314 if (Feature == "+altnzcv") {
1315 HasFlagM = true;
1316 HasAlternativeNZCV = true;
1317 }
1318 if (Feature == "+mops")
1319 HasMOPS = true;
1320 if (Feature == "+d128")
1321 HasD128 = true;
1322 if (Feature == "+gcs")
1323 HasGCS = true;
1324 if (Feature == "+rcpc3")
1325 HasRCPC3 = true;
1326 if (Feature == "+pauth-lr") {
1327 HasPAuthLR = true;
1328 HasPAuth = true;
1329 }
1330 if (Feature == "+cssc")
1331 HasCSSC = true;
1332 }
1333
1334 // Check features that are manually disabled by command line options.
1335 // This needs to be checked after architecture-related features are handled,
1336 // making sure they are properly disabled when required.
1337 for (const auto &Feature : Features) {
1338 if (Feature == "-d128")
1339 HasD128 = false;
1340 }
1341
1342 resetDataLayout();
1343
1344 if (HasNoFP) {
1345 FPU &= ~FPUMode;
1346 FPU &= ~NeonMode;
1347 FPU &= ~SveMode;
1348 }
1349 if (HasNoNeon) {
1350 FPU &= ~NeonMode;
1351 FPU &= ~SveMode;
1352 }
1353 if (HasNoSVE)
1354 FPU &= ~SveMode;
1355
1356 computeFeatureLookup();
1357 return true;
1358}
1359
1360// Parse AArch64 Target attributes, which are a comma separated list of:
1361// "arch=<arch>" - parsed to features as per -march=..
1362// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
1363// "tune=<cpu>" - TuneCPU set to <cpu>
1364// "feature", "no-feature" - Add (or remove) feature.
1365// "+feature", "+nofeature" - Add (or remove) feature.
1366//
1367// A feature may correspond to an Extension (anything with a corresponding
1368// AEK_), in which case an ExtensionSet is used to parse it and expand its
1369// dependencies. If the feature does not yield a successful parse then it
1370// is passed through.
1371ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1372 ParsedTargetAttr Ret;
1373 if (Features == "default")
1374 return Ret;
1375 SmallVector<StringRef, 1> AttrFeatures;
1376 Features.split(A&: AttrFeatures, Separator: ",");
1377 bool FoundArch = false;
1378
1379 auto SplitAndAddFeatures = [](StringRef FeatString,
1380 std::vector<std::string> &Features,
1381 llvm::AArch64::ExtensionSet &FeatureBits) {
1382 SmallVector<StringRef, 8> SplitFeatures;
1383 FeatString.split(A&: SplitFeatures, Separator: StringRef("+"), MaxSplit: -1, KeepEmpty: false);
1384 for (StringRef Feature : SplitFeatures) {
1385 if (FeatureBits.parseModifier(Modifier: Feature))
1386 continue;
1387 // Pass through anything that failed to parse so that we can emit
1388 // diagnostics, as well as valid internal feature names.
1389 //
1390 // FIXME: We should consider rejecting internal feature names like
1391 // neon, v8a, etc.
1392 // FIXME: We should consider emitting diagnostics here.
1393 if (Feature.starts_with(Prefix: "no"))
1394 Features.push_back(x: "-" + Feature.drop_front(N: 2).str());
1395 else
1396 Features.push_back(x: "+" + Feature.str());
1397 }
1398 };
1399
1400 llvm::AArch64::ExtensionSet FeatureBits;
1401 // Reconstruct the bitset from the command line option features.
1402 FeatureBits.reconstructFromParsedFeatures(Features: getTargetOpts().FeaturesAsWritten,
1403 NonExtensions&: Ret.Features);
1404
1405 for (auto &Feature : AttrFeatures) {
1406 Feature = Feature.trim();
1407 if (Feature.starts_with(Prefix: "fpmath="))
1408 continue;
1409
1410 if (Feature.starts_with(Prefix: "branch-protection=")) {
1411 Ret.BranchProtection = Feature.split(Separator: '=').second.trim();
1412 continue;
1413 }
1414
1415 if (Feature.starts_with(Prefix: "arch=")) {
1416 if (FoundArch)
1417 Ret.Duplicate = "arch=";
1418 FoundArch = true;
1419 std::pair<StringRef, StringRef> Split =
1420 Feature.split(Separator: "=").second.trim().split(Separator: "+");
1421 const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Arch: Split.first);
1422
1423 // Parse the architecture version, adding the required features to
1424 // Ret.Features.
1425 if (!AI)
1426 continue;
1427 FeatureBits.addArchDefaults(Arch: *AI);
1428 // Add any extra features, after the +
1429 SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
1430 } else if (Feature.starts_with(Prefix: "cpu=")) {
1431 if (!Ret.CPU.empty())
1432 Ret.Duplicate = "cpu=";
1433 else {
1434 // Split the cpu string into "cpu=", "cortex-a710" and any remaining
1435 // "+feat" features.
1436 std::pair<StringRef, StringRef> Split =
1437 Feature.split(Separator: "=").second.trim().split(Separator: "+");
1438 Ret.CPU = Split.first;
1439 if (auto CpuInfo = llvm::AArch64::parseCpu(Name: Ret.CPU)) {
1440 FeatureBits.addCPUDefaults(CPU: *CpuInfo);
1441 SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
1442 }
1443 }
1444 } else if (Feature.starts_with(Prefix: "tune=")) {
1445 if (!Ret.Tune.empty())
1446 Ret.Duplicate = "tune=";
1447 else
1448 Ret.Tune = Feature.split(Separator: "=").second.trim();
1449 } else if (Feature.starts_with(Prefix: "+")) {
1450 SplitAndAddFeatures(Feature, Ret.Features, FeatureBits);
1451 } else {
1452 if (FeatureBits.parseModifier(Modifier: Feature, /* AllowNoDashForm = */ true))
1453 continue;
1454 // Pass through anything that failed to parse so that we can emit
1455 // diagnostics, as well as valid internal feature names.
1456 //
1457 // FIXME: We should consider rejecting internal feature names like
1458 // neon, v8a, etc.
1459 // FIXME: We should consider emitting diagnostics here.
1460 if (Feature.starts_with(Prefix: "no-"))
1461 Ret.Features.push_back(x: "-" + Feature.drop_front(N: 3).str());
1462 else
1463 Ret.Features.push_back(x: "+" + Feature.str());
1464 }
1465 }
1466 FeatureBits.toLLVMFeatureList(Features&: Ret.Features);
1467 return Ret;
1468}
1469
1470bool AArch64TargetInfo::hasBFloat16Type() const {
1471 return true;
1472}
1473
1474TargetInfo::CallingConvCheckResult
1475AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
1476 switch (CC) {
1477 case CC_C:
1478 case CC_Swift:
1479 case CC_SwiftAsync:
1480 case CC_PreserveMost:
1481 case CC_PreserveAll:
1482 case CC_PreserveNone:
1483 case CC_DeviceKernel:
1484 case CC_AArch64VectorCall:
1485 case CC_AArch64SVEPCS:
1486 case CC_Win64:
1487 return CCCR_OK;
1488 default:
1489 return CCCR_Warning;
1490 }
1491}
1492
1493bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
1494
1495TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
1496 return TargetInfo::AArch64ABIBuiltinVaList;
1497}
1498
1499const char *const AArch64TargetInfo::GCCRegNames[] = {
1500 // clang-format off
1501
1502 // 32-bit Integer registers
1503 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
1504 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
1505 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
1506
1507 // 64-bit Integer registers
1508 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
1509 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
1510 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
1511
1512 // 32-bit floating point regsisters
1513 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1514 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1515 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1516
1517 // 64-bit floating point regsisters
1518 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1519 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1520 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1521
1522 // Neon vector registers
1523 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
1524 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
1525 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1526
1527 // SVE vector registers
1528 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
1529 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
1530 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
1531
1532 // SVE predicate registers
1533 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
1534 "p11", "p12", "p13", "p14", "p15",
1535
1536 // SVE predicate-as-counter registers
1537 "pn0", "pn1", "pn2", "pn3", "pn4", "pn5", "pn6", "pn7", "pn8",
1538 "pn9", "pn10", "pn11", "pn12", "pn13", "pn14", "pn15",
1539
1540 // SME registers
1541 "za", "zt0",
1542
1543 // clang-format on
1544};
1545
1546ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
1547 return llvm::ArrayRef(GCCRegNames);
1548}
1549
1550const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
1551 {.Aliases: {"w31"}, .Register: "wsp"},
1552 {.Aliases: {"x31"}, .Register: "sp"},
1553 // GCC rN registers are aliases of xN registers.
1554 {.Aliases: {"r0"}, .Register: "x0"},
1555 {.Aliases: {"r1"}, .Register: "x1"},
1556 {.Aliases: {"r2"}, .Register: "x2"},
1557 {.Aliases: {"r3"}, .Register: "x3"},
1558 {.Aliases: {"r4"}, .Register: "x4"},
1559 {.Aliases: {"r5"}, .Register: "x5"},
1560 {.Aliases: {"r6"}, .Register: "x6"},
1561 {.Aliases: {"r7"}, .Register: "x7"},
1562 {.Aliases: {"r8"}, .Register: "x8"},
1563 {.Aliases: {"r9"}, .Register: "x9"},
1564 {.Aliases: {"r10"}, .Register: "x10"},
1565 {.Aliases: {"r11"}, .Register: "x11"},
1566 {.Aliases: {"r12"}, .Register: "x12"},
1567 {.Aliases: {"r13"}, .Register: "x13"},
1568 {.Aliases: {"r14"}, .Register: "x14"},
1569 {.Aliases: {"r15"}, .Register: "x15"},
1570 {.Aliases: {"r16"}, .Register: "x16"},
1571 {.Aliases: {"r17"}, .Register: "x17"},
1572 {.Aliases: {"r18"}, .Register: "x18"},
1573 {.Aliases: {"r19"}, .Register: "x19"},
1574 {.Aliases: {"r20"}, .Register: "x20"},
1575 {.Aliases: {"r21"}, .Register: "x21"},
1576 {.Aliases: {"r22"}, .Register: "x22"},
1577 {.Aliases: {"r23"}, .Register: "x23"},
1578 {.Aliases: {"r24"}, .Register: "x24"},
1579 {.Aliases: {"r25"}, .Register: "x25"},
1580 {.Aliases: {"r26"}, .Register: "x26"},
1581 {.Aliases: {"r27"}, .Register: "x27"},
1582 {.Aliases: {"r28"}, .Register: "x28"},
1583 {.Aliases: {"r29", "x29"}, .Register: "fp"},
1584 {.Aliases: {"r30", "x30"}, .Register: "lr"},
1585 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
1586 // don't want to substitute one of these for a different-sized one.
1587};
1588
1589ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
1590 return llvm::ArrayRef(GCCRegAliases);
1591}
1592
1593// Returns the length of cc constraint.
1594static unsigned matchAsmCCConstraint(const char *Name) {
1595 constexpr unsigned len = 5;
1596 auto RV = llvm::StringSwitch<unsigned>(Name)
1597 .Case(S: "@cceq", Value: len)
1598 .Case(S: "@ccne", Value: len)
1599 .Case(S: "@cchs", Value: len)
1600 .Case(S: "@cccs", Value: len)
1601 .Case(S: "@cccc", Value: len)
1602 .Case(S: "@cclo", Value: len)
1603 .Case(S: "@ccmi", Value: len)
1604 .Case(S: "@ccpl", Value: len)
1605 .Case(S: "@ccvs", Value: len)
1606 .Case(S: "@ccvc", Value: len)
1607 .Case(S: "@cchi", Value: len)
1608 .Case(S: "@ccls", Value: len)
1609 .Case(S: "@ccge", Value: len)
1610 .Case(S: "@cclt", Value: len)
1611 .Case(S: "@ccgt", Value: len)
1612 .Case(S: "@ccle", Value: len)
1613 .Default(Value: 0);
1614 return RV;
1615}
1616
1617std::string
1618AArch64TargetInfo::convertConstraint(const char *&Constraint) const {
1619 std::string R;
1620 switch (*Constraint) {
1621 case 'U': // Three-character constraint; add "@3" hint for later parsing.
1622 R = std::string("@3") + std::string(Constraint, 3);
1623 Constraint += 2;
1624 break;
1625 case '@':
1626 if (const unsigned Len = matchAsmCCConstraint(Name: Constraint)) {
1627 std::string Converted = "{" + std::string(Constraint, Len) + "}";
1628 Constraint += Len - 1;
1629 return Converted;
1630 }
1631 return std::string(1, *Constraint);
1632 default:
1633 R = TargetInfo::convertConstraint(Constraint);
1634 break;
1635 }
1636 return R;
1637}
1638
1639bool AArch64TargetInfo::validateAsmConstraint(
1640 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1641 switch (*Name) {
1642 default:
1643 return false;
1644 case 'w': // Floating point and SIMD registers (V0-V31)
1645 Info.setAllowsRegister();
1646 return true;
1647 case 'I': // Constant that can be used with an ADD instruction
1648 case 'J': // Constant that can be used with a SUB instruction
1649 case 'K': // Constant that can be used with a 32-bit logical instruction
1650 case 'L': // Constant that can be used with a 64-bit logical instruction
1651 case 'M': // Constant that can be used as a 32-bit MOV immediate
1652 case 'N': // Constant that can be used as a 64-bit MOV immediate
1653 case 'Y': // Floating point constant zero
1654 case 'Z': // Integer constant zero
1655 return true;
1656 case 'Q': // A memory reference with base register and no offset
1657 Info.setAllowsMemory();
1658 return true;
1659 case 'S': // A symbolic address
1660 Info.setAllowsRegister();
1661 return true;
1662 case 'U':
1663 if (Name[1] == 'p' &&
1664 (Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) {
1665 // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15)
1666 Info.setAllowsRegister();
1667 Name += 2;
1668 return true;
1669 }
1670 if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) {
1671 // Gpr registers ("Uci"=w8-11, "Ucj"=w12-15)
1672 Info.setAllowsRegister();
1673 Name += 2;
1674 return true;
1675 }
1676 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
1677 // Utf: A memory address suitable for ldp/stp in TF mode.
1678 // Usa: An absolute symbolic address.
1679 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
1680
1681 // Better to return an error saying that it's an unrecognised constraint
1682 // even if this is a valid constraint in gcc.
1683 return false;
1684 case 'z': // Zero register, wzr or xzr
1685 Info.setAllowsRegister();
1686 return true;
1687 case 'x': // Floating point and SIMD registers (V0-V15)
1688 Info.setAllowsRegister();
1689 return true;
1690 case 'y': // SVE registers (V0-V7)
1691 Info.setAllowsRegister();
1692 return true;
1693 case '@':
1694 // CC condition
1695 if (const unsigned Len = matchAsmCCConstraint(Name)) {
1696 Name += Len - 1;
1697 Info.setAllowsRegister();
1698 Info.setOutputOperandBounds(Min: 0, Max: 2);
1699 return true;
1700 }
1701 }
1702 return false;
1703}
1704
1705bool AArch64TargetInfo::validateConstraintModifier(
1706 StringRef Constraint, char Modifier, unsigned Size,
1707 std::string &SuggestedModifier) const {
1708 // Strip off constraint modifiers.
1709 Constraint = Constraint.ltrim(Chars: "=+&");
1710
1711 switch (Constraint[0]) {
1712 default:
1713 return true;
1714 case 'z':
1715 case 'r': {
1716 switch (Modifier) {
1717 case 'x':
1718 case 'w':
1719 // For now assume that the person knows what they're
1720 // doing with the modifier.
1721 return true;
1722 default:
1723 // By default an 'r' constraint will be in the 'x'
1724 // registers.
1725 if (Size == 64)
1726 return true;
1727
1728 if (Size == 512)
1729 return HasLS64;
1730
1731 SuggestedModifier = "w";
1732 return false;
1733 }
1734 }
1735 }
1736}
1737
1738std::string_view AArch64TargetInfo::getClobbers() const { return ""; }
1739
1740int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1741 if (RegNo == 0)
1742 return 0;
1743 if (RegNo == 1)
1744 return 1;
1745 return -1;
1746}
1747
1748bool AArch64TargetInfo::validatePointerAuthKey(
1749 const llvm::APSInt &value) const {
1750 return 0 <= value && value <= 3;
1751}
1752
1753bool AArch64TargetInfo::hasInt128Type() const { return true; }
1754
1755AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
1756 const TargetOptions &Opts)
1757 : AArch64TargetInfo(Triple, Opts) {}
1758
1759void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
1760 MacroBuilder &Builder) const {
1761 Builder.defineMacro(Name: "__AARCH64EL__");
1762 AArch64TargetInfo::getTargetDefines(Opts, Builder);
1763}
1764
1765AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
1766 const TargetOptions &Opts)
1767 : AArch64TargetInfo(Triple, Opts) {}
1768
1769void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
1770 MacroBuilder &Builder) const {
1771 Builder.defineMacro(Name: "__AARCH64EB__");
1772 Builder.defineMacro(Name: "__AARCH_BIG_ENDIAN");
1773 Builder.defineMacro(Name: "__ARM_BIG_ENDIAN");
1774 AArch64TargetInfo::getTargetDefines(Opts, Builder);
1775}
1776
1777WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
1778 const TargetOptions &Opts)
1779 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
1780
1781 // This is an LLP64 platform.
1782 // int:4, long:4, long long:8, long double:8.
1783 IntWidth = IntAlign = 32;
1784 LongWidth = LongAlign = 32;
1785 DoubleAlign = LongLongAlign = 64;
1786 LongDoubleWidth = LongDoubleAlign = 64;
1787 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1788 IntMaxType = SignedLongLong;
1789 Int64Type = SignedLongLong;
1790 SizeType = UnsignedLongLong;
1791 PtrDiffType = SignedLongLong;
1792 IntPtrType = SignedLongLong;
1793}
1794
1795TargetInfo::BuiltinVaListKind
1796WindowsARM64TargetInfo::getBuiltinVaListKind() const {
1797 return TargetInfo::CharPtrBuiltinVaList;
1798}
1799
1800TargetInfo::CallingConvCheckResult
1801WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
1802 switch (CC) {
1803 case CC_X86VectorCall:
1804 if (getTriple().isWindowsArm64EC())
1805 return CCCR_OK;
1806 return CCCR_Ignore;
1807 case CC_X86StdCall:
1808 case CC_X86ThisCall:
1809 case CC_X86FastCall:
1810 return CCCR_Ignore;
1811 case CC_C:
1812 case CC_DeviceKernel:
1813 case CC_PreserveMost:
1814 case CC_PreserveAll:
1815 case CC_PreserveNone:
1816 case CC_Swift:
1817 case CC_SwiftAsync:
1818 case CC_Win64:
1819 return CCCR_OK;
1820 default:
1821 return CCCR_Warning;
1822 }
1823}
1824
1825MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
1826 const TargetOptions &Opts)
1827 : WindowsARM64TargetInfo(Triple, Opts) {
1828 TheCXXABI.set(TargetCXXABI::Microsoft);
1829}
1830
1831void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
1832 MacroBuilder &Builder) const {
1833 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
1834 if (getTriple().isWindowsArm64EC()) {
1835 Builder.defineMacro(Name: "_M_X64", Value: "100");
1836 Builder.defineMacro(Name: "_M_AMD64", Value: "100");
1837 Builder.defineMacro(Name: "_M_ARM64EC", Value: "1");
1838 } else {
1839 Builder.defineMacro(Name: "_M_ARM64", Value: "1");
1840 }
1841}
1842
1843TargetInfo::CallingConvKind
1844MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
1845 return CCK_MicrosoftWin64;
1846}
1847
1848unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,
1849 bool HasNonWeakDef) const {
1850 unsigned Align =
1851 WindowsARM64TargetInfo::getMinGlobalAlign(Size: TypeSize, HasNonWeakDef);
1852
1853 return std::max(a: Align, b: Microsoft64BitMinGlobalAlign(TypeSize));
1854}
1855
1856MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
1857 const TargetOptions &Opts)
1858 : WindowsARM64TargetInfo(Triple, Opts) {
1859 TheCXXABI.set(TargetCXXABI::GenericAArch64);
1860}
1861
1862AppleMachOAArch64TargetInfo::AppleMachOAArch64TargetInfo(
1863 const llvm::Triple &Triple, const TargetOptions &Opts)
1864 : AppleMachOTargetInfo<AArch64leTargetInfo>(Triple, Opts) {}
1865
1866DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
1867 const TargetOptions &Opts)
1868 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
1869 Int64Type = SignedLongLong;
1870 if (getTriple().isArch32Bit())
1871 IntMaxType = SignedLongLong;
1872
1873 WCharType = SignedInt;
1874 UseSignedCharForObjCBool = false;
1875
1876 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
1877 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1878
1879 UseZeroLengthBitfieldAlignment = false;
1880
1881 if (getTriple().isArch32Bit()) {
1882 UseBitFieldTypeAlignment = false;
1883 ZeroLengthBitfieldBoundary = 32;
1884 UseZeroLengthBitfieldAlignment = true;
1885 TheCXXABI.set(TargetCXXABI::WatchOS);
1886 } else
1887 TheCXXABI.set(TargetCXXABI::AppleARM64);
1888}
1889
1890void clang::targets::getAppleMachOAArch64Defines(MacroBuilder &Builder,
1891 const LangOptions &Opts,
1892 const llvm::Triple &Triple) {
1893 Builder.defineMacro(Name: "__AARCH64_SIMD__");
1894 if (Triple.isArch32Bit())
1895 Builder.defineMacro(Name: "__ARM64_ARCH_8_32__");
1896 else
1897 Builder.defineMacro(Name: "__ARM64_ARCH_8__");
1898 Builder.defineMacro(Name: "__ARM_NEON__");
1899 Builder.defineMacro(Name: "__REGISTER_PREFIX__", Value: "");
1900 Builder.defineMacro(Name: "__arm64", Value: "1");
1901 Builder.defineMacro(Name: "__arm64__", Value: "1");
1902
1903 if (Triple.isArm64e()) {
1904 Builder.defineMacro(Name: "__arm64e__", Value: "1");
1905 Builder.defineMacro(Name: "__PTRAUTH_INTRINSICS__", Value: "1");
1906 }
1907}
1908
1909void AppleMachOAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
1910 const llvm::Triple &Triple,
1911 MacroBuilder &Builder) const {
1912 getAppleMachOAArch64Defines(Builder, Opts, Triple);
1913 AppleMachOTargetInfo<AArch64leTargetInfo>::getOSDefines(Opts, Triple,
1914 Builder);
1915}
1916
1917void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
1918 const llvm::Triple &Triple,
1919 MacroBuilder &Builder) const {
1920 getAppleMachOAArch64Defines(Builder, Opts, Triple);
1921 DarwinTargetInfo<AArch64leTargetInfo>::getOSDefines(Opts, Triple, Builder);
1922}
1923
1924TargetInfo::BuiltinVaListKind
1925DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
1926 return TargetInfo::CharPtrBuiltinVaList;
1927}
1928