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