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