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