1 //===--- ARM.cpp - Implement ARM target feature support -------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements ARM TargetInfo objects.
11 //===----------------------------------------------------------------------===//
14 #include "clang/Basic/Builtins.h"
15 #include "clang/Basic/Diagnostic.h"
16 #include "clang/Basic/TargetBuiltins.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/TargetParser/ARMTargetParser.h"
22 using namespace clang
;
23 using namespace clang::targets
;
25 void ARMTargetInfo::setABIAAPCS() {
28 DoubleAlign
= LongLongAlign
= LongDoubleAlign
= SuitableAlign
= 64;
29 BFloat16Width
= BFloat16Align
= 16;
30 BFloat16Format
= &llvm::APFloat::BFloat();
32 const llvm::Triple
&T
= getTriple();
34 bool IsNetBSD
= T
.isOSNetBSD();
35 bool IsOpenBSD
= T
.isOSOpenBSD();
36 if (!T
.isOSWindows() && !IsNetBSD
&& !IsOpenBSD
)
37 WCharType
= UnsignedInt
;
39 UseBitFieldTypeAlignment
= true;
41 ZeroLengthBitfieldBoundary
= 0;
43 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
44 // so set preferred for small types to 32.
45 if (T
.isOSBinFormatMachO()) {
46 resetDataLayout(BigEndian
47 ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
48 : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
50 } else if (T
.isOSWindows()) {
51 assert(!BigEndian
&& "Windows on ARM does not support big endian");
61 } else if (T
.isOSNaCl()) {
62 assert(!BigEndian
&& "NaCl on ARM does not support big endian");
63 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
65 resetDataLayout(BigEndian
66 ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
67 : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
70 // FIXME: Enumerated types are variable width in straight AAPCS.
73 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16
) {
74 const llvm::Triple
&T
= getTriple();
79 DoubleAlign
= LongLongAlign
= LongDoubleAlign
= SuitableAlign
= 64;
81 DoubleAlign
= LongLongAlign
= LongDoubleAlign
= SuitableAlign
= 32;
82 BFloat16Width
= BFloat16Align
= 16;
83 BFloat16Format
= &llvm::APFloat::BFloat();
85 WCharType
= SignedInt
;
87 // Do not respect the alignment of bit-field types when laying out
88 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
89 UseBitFieldTypeAlignment
= false;
91 /// gcc forces the alignment to 4 bytes, regardless of the type of the
92 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
94 ZeroLengthBitfieldBoundary
= 32;
96 if (T
.isOSBinFormatMachO() && IsAAPCS16
) {
97 assert(!BigEndian
&& "AAPCS16 does not support big-endian");
98 resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_");
99 } else if (T
.isOSBinFormatMachO())
102 ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
103 : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32",
108 ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
109 : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
111 // FIXME: Override "preferred align" for double and long long.
114 void ARMTargetInfo::setArchInfo() {
115 StringRef ArchName
= getTriple().getArchName();
117 ArchISA
= llvm::ARM::parseArchISA(ArchName
);
118 CPU
= std::string(llvm::ARM::getDefaultCPU(ArchName
));
119 llvm::ARM::ArchKind AK
= llvm::ARM::parseArch(ArchName
);
120 if (AK
!= llvm::ARM::ArchKind::INVALID
)
122 setArchInfo(ArchKind
);
125 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind
) {
128 // cache TargetParser info
130 SubArch
= llvm::ARM::getSubArch(ArchKind
);
131 ArchProfile
= llvm::ARM::parseArchProfile(SubArch
);
132 ArchVersion
= llvm::ARM::parseArchVersion(SubArch
);
134 // cache CPU related strings
135 CPUAttr
= getCPUAttr();
136 CPUProfile
= getCPUProfile();
139 void ARMTargetInfo::setAtomic() {
140 // when triple does not specify a sub arch,
141 // then we are not using inline atomics
142 bool ShouldUseInlineAtomic
=
143 (ArchISA
== llvm::ARM::ISAKind::ARM
&& ArchVersion
>= 6) ||
144 (ArchISA
== llvm::ARM::ISAKind::THUMB
&& ArchVersion
>= 7);
145 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
146 if (ArchProfile
== llvm::ARM::ProfileKind::M
) {
147 MaxAtomicPromoteWidth
= 32;
148 if (ShouldUseInlineAtomic
)
149 MaxAtomicInlineWidth
= 32;
151 MaxAtomicPromoteWidth
= 64;
152 if (ShouldUseInlineAtomic
)
153 MaxAtomicInlineWidth
= 64;
157 bool ARMTargetInfo::hasMVE() const {
158 return ArchKind
== llvm::ARM::ArchKind::ARMV8_1MMainline
&& MVE
!= 0;
161 bool ARMTargetInfo::hasMVEFloat() const {
162 return hasMVE() && (MVE
& MVE_FP
);
165 bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; }
167 bool ARMTargetInfo::isThumb() const {
168 return ArchISA
== llvm::ARM::ISAKind::THUMB
;
171 bool ARMTargetInfo::supportsThumb() const {
172 return CPUAttr
.count('T') || ArchVersion
>= 6;
175 bool ARMTargetInfo::supportsThumb2() const {
176 return CPUAttr
== "6T2" || (ArchVersion
>= 7 && CPUAttr
!= "8M_BASE");
179 StringRef
ARMTargetInfo::getCPUAttr() const {
180 // For most sub-arches, the build attribute CPU name is enough.
181 // For Cortex variants, it's slightly different.
184 return llvm::ARM::getCPUAttr(ArchKind
);
185 case llvm::ARM::ArchKind::ARMV6M
:
187 case llvm::ARM::ArchKind::ARMV7S
:
189 case llvm::ARM::ArchKind::ARMV7A
:
191 case llvm::ARM::ArchKind::ARMV7R
:
193 case llvm::ARM::ArchKind::ARMV7M
:
195 case llvm::ARM::ArchKind::ARMV7EM
:
197 case llvm::ARM::ArchKind::ARMV7VE
:
199 case llvm::ARM::ArchKind::ARMV8A
:
201 case llvm::ARM::ArchKind::ARMV8_1A
:
203 case llvm::ARM::ArchKind::ARMV8_2A
:
205 case llvm::ARM::ArchKind::ARMV8_3A
:
207 case llvm::ARM::ArchKind::ARMV8_4A
:
209 case llvm::ARM::ArchKind::ARMV8_5A
:
211 case llvm::ARM::ArchKind::ARMV8_6A
:
213 case llvm::ARM::ArchKind::ARMV8_7A
:
215 case llvm::ARM::ArchKind::ARMV8_8A
:
217 case llvm::ARM::ArchKind::ARMV8_9A
:
219 case llvm::ARM::ArchKind::ARMV9A
:
221 case llvm::ARM::ArchKind::ARMV9_1A
:
223 case llvm::ARM::ArchKind::ARMV9_2A
:
225 case llvm::ARM::ArchKind::ARMV9_3A
:
227 case llvm::ARM::ArchKind::ARMV9_4A
:
229 case llvm::ARM::ArchKind::ARMV9_5A
:
231 case llvm::ARM::ArchKind::ARMV9_6A
:
233 case llvm::ARM::ArchKind::ARMV8MBaseline
:
235 case llvm::ARM::ArchKind::ARMV8MMainline
:
237 case llvm::ARM::ArchKind::ARMV8R
:
239 case llvm::ARM::ArchKind::ARMV8_1MMainline
:
244 StringRef
ARMTargetInfo::getCPUProfile() const {
245 switch (ArchProfile
) {
246 case llvm::ARM::ProfileKind::A
:
248 case llvm::ARM::ProfileKind::R
:
250 case llvm::ARM::ProfileKind::M
:
257 ARMTargetInfo::ARMTargetInfo(const llvm::Triple
&Triple
,
258 const TargetOptions
&Opts
)
259 : TargetInfo(Triple
), FPMath(FP_Default
), IsAAPCS(true), LDREX(0),
261 bool IsFreeBSD
= Triple
.isOSFreeBSD();
262 bool IsOpenBSD
= Triple
.isOSOpenBSD();
263 bool IsNetBSD
= Triple
.isOSNetBSD();
264 bool IsHaiku
= Triple
.isOSHaiku();
265 bool IsOHOS
= Triple
.isOHOSFamily();
267 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
268 // environment where size_t is `unsigned long` rather than `unsigned int`
270 PtrDiffType
= IntPtrType
=
271 (Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO() || IsOpenBSD
||
276 SizeType
= (Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO() || IsOpenBSD
||
281 // ptrdiff_t is inconsistent on Darwin
282 if ((Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO()) &&
283 !Triple
.isWatchABI())
284 PtrDiffType
= SignedInt
;
286 // Cache arch related info.
289 // {} in inline assembly are neon specifiers, not assembly variant
291 NoAsmVariants
= true;
293 // FIXME: This duplicates code from the driver that sets the -target-abi
294 // option - this code is used if -target-abi isn't passed and should
295 // be unified in some way.
296 if (Triple
.isOSBinFormatMachO()) {
297 // The backend is hardwired to assume AAPCS for M-class processors, ensure
298 // the frontend matches that.
299 if (Triple
.getEnvironment() == llvm::Triple::EABI
||
300 Triple
.getOS() == llvm::Triple::UnknownOS
||
301 ArchProfile
== llvm::ARM::ProfileKind::M
) {
303 } else if (Triple
.isWatchABI()) {
308 } else if (Triple
.isOSWindows()) {
309 // FIXME: this is invalid for WindowsCE
312 // Select the default based on the platform.
313 switch (Triple
.getEnvironment()) {
314 case llvm::Triple::Android
:
315 case llvm::Triple::GNUEABI
:
316 case llvm::Triple::GNUEABIT64
:
317 case llvm::Triple::GNUEABIHF
:
318 case llvm::Triple::GNUEABIHFT64
:
319 case llvm::Triple::MuslEABI
:
320 case llvm::Triple::MuslEABIHF
:
321 case llvm::Triple::OpenHOS
:
322 setABI("aapcs-linux");
324 case llvm::Triple::EABIHF
:
325 case llvm::Triple::EABI
:
328 case llvm::Triple::GNU
:
334 else if (IsFreeBSD
|| IsOpenBSD
|| IsHaiku
|| IsOHOS
)
335 setABI("aapcs-linux");
342 // ARM targets default to using the ARM C++ ABI.
343 TheCXXABI
.set(TargetCXXABI::GenericARM
);
345 // ARM has atomics up to 8 bytes
348 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
349 // as well the default alignment
350 if (IsAAPCS
&& !Triple
.isAndroid())
351 DefaultAlignForAttributeAligned
= MaxVectorAlign
= 64;
353 // Do force alignment of members that follow zero length bitfields. If
354 // the alignment of the zero-length bitfield is greater than the member
355 // that follows it, `bar', `bar' will be aligned as the type of the
356 // zero length bitfield.
357 UseZeroLengthBitfieldAlignment
= true;
359 if (Triple
.getOS() == llvm::Triple::Linux
||
360 Triple
.getOS() == llvm::Triple::UnknownOS
)
361 this->MCountName
= Opts
.EABIVersion
== llvm::EABI::GNU
362 ? "llvm.arm.gnu.eabi.mcount"
365 SoftFloatABI
= llvm::is_contained(Opts
.FeaturesAsWritten
, "+soft-float-abi");
368 StringRef
ARMTargetInfo::getABI() const { return ABI
; }
370 bool ARMTargetInfo::setABI(const std::string
&Name
) {
373 // The defaults (above) are for AAPCS, check if we need to change them.
375 // FIXME: We need support for -meabi... we could just mangle it into the
377 if (Name
== "apcs-gnu" || Name
== "aapcs16") {
378 setABIAPCS(Name
== "aapcs16");
381 if (Name
== "aapcs" || Name
== "aapcs-vfp" || Name
== "aapcs-linux") {
388 bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch
) const {
389 llvm::ARM::ArchKind CPUArch
= llvm::ARM::parseCPUArch(Arch
);
390 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
391 CPUArch
= llvm::ARM::parseArch(getTriple().getArchName());
393 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
396 StringRef ArchFeature
= llvm::ARM::getArchName(CPUArch
);
398 llvm::Triple(ArchFeature
, getTriple().getVendorName(),
399 getTriple().getOSName(), getTriple().getEnvironmentName());
401 StringRef SubArch
= llvm::ARM::getSubArch(CPUArch
);
402 llvm::ARM::ProfileKind Profile
= llvm::ARM::parseArchProfile(SubArch
);
403 return a
.isArmT32() && (Profile
== llvm::ARM::ProfileKind::M
);
406 bool ARMTargetInfo::validateBranchProtection(StringRef Spec
, StringRef Arch
,
407 BranchProtectionInfo
&BPI
,
408 StringRef
&Err
) const {
409 llvm::ARM::ParsedBranchProtection PBP
;
410 if (!llvm::ARM::parseBranchProtection(Spec
, PBP
, Err
))
413 if (!isBranchProtectionSupportedArch(Arch
))
417 llvm::StringSwitch
<LangOptions::SignReturnAddressScopeKind
>(PBP
.Scope
)
418 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf
)
419 .Case("all", LangOptions::SignReturnAddressScopeKind::All
)
420 .Default(LangOptions::SignReturnAddressScopeKind::None
);
422 // Don't care for the sign key, beyond issuing a warning.
423 if (PBP
.Key
== "b_key")
425 BPI
.SignKey
= LangOptions::SignReturnAddressKeyKind::AKey
;
427 BPI
.BranchTargetEnforcement
= PBP
.BranchTargetEnforcement
;
428 BPI
.BranchProtectionPAuthLR
= PBP
.BranchProtectionPAuthLR
;
432 // FIXME: This should be based on Arch attributes, not CPU names.
433 bool ARMTargetInfo::initFeatureMap(
434 llvm::StringMap
<bool> &Features
, DiagnosticsEngine
&Diags
, StringRef CPU
,
435 const std::vector
<std::string
> &FeaturesVec
) const {
437 std::string ArchFeature
;
438 std::vector
<StringRef
> TargetFeatures
;
439 llvm::ARM::ArchKind Arch
= llvm::ARM::parseArch(getTriple().getArchName());
441 // Map the base architecture to an appropriate target feature, so we don't
442 // rely on the target triple.
443 llvm::ARM::ArchKind CPUArch
= llvm::ARM::parseCPUArch(CPU
);
444 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
446 if (CPUArch
!= llvm::ARM::ArchKind::INVALID
) {
447 ArchFeature
= ("+" + llvm::ARM::getArchName(CPUArch
)).str();
448 TargetFeatures
.push_back(ArchFeature
);
450 // These features are added to allow arm_neon.h target(..) attributes to
451 // match with both arm and aarch64. We need to add all previous architecture
452 // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
453 // v8.x counterparts are added too. We only need these for anything > 8.0-A.
454 for (llvm::ARM::ArchKind I
= llvm::ARM::convertV9toV8(CPUArch
);
455 I
!= llvm::ARM::ArchKind::INVALID
; --I
)
456 Features
[llvm::ARM::getSubArch(I
)] = true;
457 if (CPUArch
> llvm::ARM::ArchKind::ARMV8A
&&
458 CPUArch
<= llvm::ARM::ArchKind::ARMV9_3A
)
459 for (llvm::ARM::ArchKind I
= CPUArch
; I
!= llvm::ARM::ArchKind::INVALID
;
461 Features
[llvm::ARM::getSubArch(I
)] = true;
464 // get default FPU features
465 llvm::ARM::FPUKind FPUKind
= llvm::ARM::getDefaultFPU(CPU
, Arch
);
466 llvm::ARM::getFPUFeatures(FPUKind
, TargetFeatures
);
468 // get default Extension features
469 uint64_t Extensions
= llvm::ARM::getDefaultExtensions(CPU
, Arch
);
470 llvm::ARM::getExtensionFeatures(Extensions
, TargetFeatures
);
472 for (auto Feature
: TargetFeatures
)
473 if (Feature
[0] == '+')
474 Features
[Feature
.drop_front(1)] = true;
476 // Enable or disable thumb-mode explicitly per function to enable mixed
477 // ARM and Thumb code generation.
479 Features
["thumb-mode"] = true;
481 Features
["thumb-mode"] = false;
483 // Convert user-provided arm and thumb GNU target attributes to
484 // [-|+]thumb-mode target features respectively.
485 std::vector
<std::string
> UpdatedFeaturesVec
;
486 for (const auto &Feature
: FeaturesVec
) {
487 // Skip soft-float-abi; it's something we only use to initialize a bit of
488 // class state, and is otherwise unrecognized.
489 if (Feature
== "+soft-float-abi")
492 StringRef FixedFeature
;
493 if (Feature
== "+arm")
494 FixedFeature
= "-thumb-mode";
495 else if (Feature
== "+thumb")
496 FixedFeature
= "+thumb-mode";
498 FixedFeature
= Feature
;
499 UpdatedFeaturesVec
.push_back(FixedFeature
.str());
502 return TargetInfo::initFeatureMap(Features
, Diags
, CPU
, UpdatedFeaturesVec
);
506 bool ARMTargetInfo::handleTargetFeatures(std::vector
<std::string
> &Features
,
507 DiagnosticsEngine
&Diags
) {
515 HasUnalignedAccess
= true;
517 // Note that SoftFloatABI is initialized in our constructor.
524 ARMCDECoprocMask
= 0;
526 HasFullBFloat16
= false;
527 FPRegsDisabled
= false;
529 // This does not diagnose illegal cases like having both
530 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
531 for (const auto &Feature
: Features
) {
532 if (Feature
== "+soft-float") {
534 } else if (Feature
== "+vfp2sp" || Feature
== "+vfp2") {
537 if (Feature
== "+vfp2")
539 } else if (Feature
== "+vfp3sp" || Feature
== "+vfp3d16sp" ||
540 Feature
== "+vfp3" || Feature
== "+vfp3d16") {
543 if (Feature
== "+vfp3" || Feature
== "+vfp3d16")
545 } else if (Feature
== "+vfp4sp" || Feature
== "+vfp4d16sp" ||
546 Feature
== "+vfp4" || Feature
== "+vfp4d16") {
548 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
549 if (Feature
== "+vfp4" || Feature
== "+vfp4d16")
551 } else if (Feature
== "+fp-armv8sp" || Feature
== "+fp-armv8d16sp" ||
552 Feature
== "+fp-armv8" || Feature
== "+fp-armv8d16") {
554 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
555 if (Feature
== "+fp-armv8" || Feature
== "+fp-armv8d16")
557 } else if (Feature
== "+neon") {
560 } else if (Feature
== "+hwdiv") {
562 } else if (Feature
== "+hwdiv-arm") {
564 } else if (Feature
== "+crc") {
566 } else if (Feature
== "+crypto") {
568 } else if (Feature
== "+sha2") {
570 } else if (Feature
== "+aes") {
572 } else if (Feature
== "+dsp") {
574 } else if (Feature
== "+fp64") {
576 } else if (Feature
== "+8msecext") {
577 if (CPUProfile
!= "M" || ArchVersion
!= 8) {
578 Diags
.Report(diag::err_target_unsupported_mcmse
) << CPU
;
581 } else if (Feature
== "+strict-align") {
582 HasUnalignedAccess
= false;
583 } else if (Feature
== "+fp16") {
585 } else if (Feature
== "+fullfp16") {
586 HasLegalHalfType
= true;
587 } else if (Feature
== "+dotprod") {
589 } else if (Feature
== "+mve") {
591 } else if (Feature
== "+mve.fp") {
592 HasLegalHalfType
= true;
594 MVE
|= MVE_INT
| MVE_FP
;
595 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
596 } else if (Feature
== "+i8mm") {
598 } else if (Feature
.size() == strlen("+cdecp0") && Feature
>= "+cdecp0" &&
599 Feature
<= "+cdecp7") {
600 unsigned Coproc
= Feature
.back() - '0';
601 ARMCDECoprocMask
|= (1U << Coproc
);
602 } else if (Feature
== "+bf16") {
604 } else if (Feature
== "-fpregs") {
605 FPRegsDisabled
= true;
606 } else if (Feature
== "+pacbti") {
609 } else if (Feature
== "+fullbf16") {
610 HasFullBFloat16
= true;
614 HalfArgsAndReturns
= true;
616 switch (ArchVersion
) {
618 if (ArchProfile
== llvm::ARM::ProfileKind::M
)
620 else if (ArchKind
== llvm::ARM::ArchKind::ARMV6K
)
621 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
626 if (ArchProfile
== llvm::ARM::ProfileKind::M
)
627 LDREX
= LDREX_W
| LDREX_H
| LDREX_B
;
629 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
633 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
636 if (!(FPU
& NeonFPU
) && FPMath
== FP_Neon
) {
637 Diags
.Report(diag::err_target_unsupported_fpmath
) << "neon";
641 if (FPMath
== FP_Neon
)
642 Features
.push_back("+neonfp");
643 else if (FPMath
== FP_VFP
)
644 Features
.push_back("-neonfp");
649 bool ARMTargetInfo::hasFeature(StringRef Feature
) const {
650 return llvm::StringSwitch
<bool>(Feature
)
652 .Case("aarch32", true)
653 .Case("softfloat", SoftFloat
)
654 .Case("thumb", isThumb())
655 .Case("neon", (FPU
& NeonFPU
) && !SoftFloat
)
656 .Case("vfp", FPU
&& !SoftFloat
)
657 .Case("hwdiv", HWDiv
& HWDivThumb
)
658 .Case("hwdiv-arm", HWDiv
& HWDivARM
)
659 .Case("mve", hasMVE())
663 bool ARMTargetInfo::hasBFloat16Type() const {
664 // The __bf16 type is generally available so long as we have any fp registers.
665 return HasBFloat16
|| (FPU
&& !SoftFloat
);
668 bool ARMTargetInfo::isValidCPUName(StringRef Name
) const {
669 return Name
== "generic" ||
670 llvm::ARM::parseCPUArch(Name
) != llvm::ARM::ArchKind::INVALID
;
673 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl
<StringRef
> &Values
) const {
674 llvm::ARM::fillValidCPUArchList(Values
);
677 bool ARMTargetInfo::setCPU(const std::string
&Name
) {
678 if (Name
!= "generic")
679 setArchInfo(llvm::ARM::parseCPUArch(Name
));
681 if (ArchKind
== llvm::ARM::ArchKind::INVALID
)
688 bool ARMTargetInfo::setFPMath(StringRef Name
) {
689 if (Name
== "neon") {
692 } else if (Name
== "vfp" || Name
== "vfp2" || Name
== "vfp3" ||
700 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions
&Opts
,
701 MacroBuilder
&Builder
) const {
702 Builder
.defineMacro("__ARM_FEATURE_QRDMX", "1");
705 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions
&Opts
,
706 MacroBuilder
&Builder
) const {
707 // Also include the ARMv8.1-A defines
708 getTargetDefinesARMV81A(Opts
, Builder
);
711 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions
&Opts
,
712 MacroBuilder
&Builder
) const {
713 // Also include the ARMv8.2-A defines
714 Builder
.defineMacro("__ARM_FEATURE_COMPLEX", "1");
715 getTargetDefinesARMV82A(Opts
, Builder
);
718 void ARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
719 MacroBuilder
&Builder
) const {
720 // Target identification.
721 Builder
.defineMacro("__arm");
722 Builder
.defineMacro("__arm__");
723 // For bare-metal none-eabi.
724 if (getTriple().getOS() == llvm::Triple::UnknownOS
&&
725 (getTriple().getEnvironment() == llvm::Triple::EABI
||
726 getTriple().getEnvironment() == llvm::Triple::EABIHF
) &&
728 Builder
.defineMacro("_GNU_SOURCE");
731 // Target properties.
732 Builder
.defineMacro("__REGISTER_PREFIX__", "");
734 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
735 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
736 if (getTriple().isWatchABI())
737 Builder
.defineMacro("__ARM_ARCH_7K__", "2");
739 if (!CPUAttr
.empty())
740 Builder
.defineMacro("__ARM_ARCH_" + CPUAttr
+ "__");
742 // ACLE 6.4.1 ARM/Thumb instruction set architecture
743 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
744 Builder
.defineMacro("__ARM_ARCH", Twine(ArchVersion
));
746 if (ArchVersion
>= 8) {
747 // ACLE 6.5.7 Crypto Extension
748 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
749 // feature macros for AES and SHA2
751 Builder
.defineMacro("__ARM_FEATURE_CRYPTO", "1");
753 Builder
.defineMacro("__ARM_FEATURE_SHA2", "1");
755 Builder
.defineMacro("__ARM_FEATURE_AES", "1");
756 // ACLE 6.5.8 CRC32 Extension
758 Builder
.defineMacro("__ARM_FEATURE_CRC32", "1");
759 // ACLE 6.5.10 Numeric Maximum and Minimum
760 Builder
.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
761 // ACLE 6.5.9 Directed Rounding
762 Builder
.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
765 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
766 // is not defined for the M-profile.
767 // NOTE that the default profile is assumed to be 'A'
768 if (CPUProfile
.empty() || ArchProfile
!= llvm::ARM::ProfileKind::M
)
769 Builder
.defineMacro("__ARM_ARCH_ISA_ARM", "1");
771 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
772 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
773 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
774 // v7 and v8 architectures excluding v8-M Baseline.
775 if (supportsThumb2())
776 Builder
.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
777 else if (supportsThumb())
778 Builder
.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
780 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
781 // instruction set such as ARM or Thumb.
782 Builder
.defineMacro("__ARM_32BIT_STATE", "1");
784 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
786 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
787 if (!CPUProfile
.empty())
788 Builder
.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile
+ "'");
790 // ACLE 6.4.3 Unaligned access supported in hardware
791 if (HasUnalignedAccess
)
792 Builder
.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
794 // ACLE 6.4.4 LDREX/STREX
796 Builder
.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX
));
799 if (ArchVersion
== 5 || (ArchVersion
== 6 && CPUProfile
!= "M") ||
801 Builder
.defineMacro("__ARM_FEATURE_CLZ", "1");
803 // ACLE 6.5.1 Hardware Floating Point
805 Builder
.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP
));
808 Builder
.defineMacro("__ARM_ACLE", "200");
810 // FP16 support (we currently only support IEEE format).
811 Builder
.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
812 Builder
.defineMacro("__ARM_FP16_ARGS", "1");
814 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
815 if (ArchVersion
>= 7 && (FPU
& VFP4FPU
))
816 Builder
.defineMacro("__ARM_FEATURE_FMA", "1");
818 // Subtarget options.
820 // FIXME: It's more complicated than this and we don't really support
822 // Windows on ARM does not "support" interworking
823 if (5 <= ArchVersion
&& ArchVersion
<= 8 && !getTriple().isOSWindows())
824 Builder
.defineMacro("__THUMB_INTERWORK__");
826 if (ABI
== "aapcs" || ABI
== "aapcs-linux" || ABI
== "aapcs-vfp") {
827 // Embedded targets on Darwin follow AAPCS, but not EABI.
828 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
829 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
830 Builder
.defineMacro("__ARM_EABI__");
831 Builder
.defineMacro("__ARM_PCS", "1");
834 if ((!SoftFloat
&& !SoftFloatABI
) || ABI
== "aapcs-vfp" || ABI
== "aapcs16")
835 Builder
.defineMacro("__ARM_PCS_VFP", "1");
837 if (SoftFloat
|| (SoftFloatABI
&& !FPU
))
838 Builder
.defineMacro("__SOFTFP__");
840 // ACLE position independent code macros.
842 Builder
.defineMacro("__ARM_ROPI", "1");
844 Builder
.defineMacro("__ARM_RWPI", "1");
846 // Macros for enabling co-proc intrinsics
847 uint64_t FeatureCoprocBF
= 0;
851 case llvm::ARM::ArchKind::ARMV4
:
852 case llvm::ARM::ArchKind::ARMV4T
:
853 // Filter __arm_ldcl and __arm_stcl in acle.h
854 FeatureCoprocBF
= isThumb() ? 0 : FEATURE_COPROC_B1
;
856 case llvm::ARM::ArchKind::ARMV5T
:
857 FeatureCoprocBF
= isThumb() ? 0 : FEATURE_COPROC_B1
| FEATURE_COPROC_B2
;
859 case llvm::ARM::ArchKind::ARMV5TE
:
860 case llvm::ARM::ArchKind::ARMV5TEJ
:
863 FEATURE_COPROC_B1
| FEATURE_COPROC_B2
| FEATURE_COPROC_B3
;
865 case llvm::ARM::ArchKind::ARMV6
:
866 case llvm::ARM::ArchKind::ARMV6K
:
867 case llvm::ARM::ArchKind::ARMV6KZ
:
868 case llvm::ARM::ArchKind::ARMV6T2
:
869 if (!isThumb() || ArchKind
== llvm::ARM::ArchKind::ARMV6T2
)
870 FeatureCoprocBF
= FEATURE_COPROC_B1
| FEATURE_COPROC_B2
|
871 FEATURE_COPROC_B3
| FEATURE_COPROC_B4
;
873 case llvm::ARM::ArchKind::ARMV7A
:
874 case llvm::ARM::ArchKind::ARMV7R
:
875 case llvm::ARM::ArchKind::ARMV7M
:
876 case llvm::ARM::ArchKind::ARMV7S
:
877 case llvm::ARM::ArchKind::ARMV7EM
:
878 FeatureCoprocBF
= FEATURE_COPROC_B1
| FEATURE_COPROC_B2
|
879 FEATURE_COPROC_B3
| FEATURE_COPROC_B4
;
881 case llvm::ARM::ArchKind::ARMV8A
:
882 case llvm::ARM::ArchKind::ARMV8R
:
883 case llvm::ARM::ArchKind::ARMV8_1A
:
884 case llvm::ARM::ArchKind::ARMV8_2A
:
885 case llvm::ARM::ArchKind::ARMV8_3A
:
886 case llvm::ARM::ArchKind::ARMV8_4A
:
887 case llvm::ARM::ArchKind::ARMV8_5A
:
888 case llvm::ARM::ArchKind::ARMV8_6A
:
889 case llvm::ARM::ArchKind::ARMV8_7A
:
890 case llvm::ARM::ArchKind::ARMV8_8A
:
891 case llvm::ARM::ArchKind::ARMV8_9A
:
892 case llvm::ARM::ArchKind::ARMV9A
:
893 case llvm::ARM::ArchKind::ARMV9_1A
:
894 case llvm::ARM::ArchKind::ARMV9_2A
:
895 case llvm::ARM::ArchKind::ARMV9_3A
:
896 case llvm::ARM::ArchKind::ARMV9_4A
:
897 case llvm::ARM::ArchKind::ARMV9_5A
:
898 case llvm::ARM::ArchKind::ARMV9_6A
:
899 // Filter __arm_cdp, __arm_ldcl, __arm_stcl in arm_acle.h
900 FeatureCoprocBF
= FEATURE_COPROC_B1
| FEATURE_COPROC_B3
;
902 case llvm::ARM::ArchKind::ARMV8MMainline
:
903 case llvm::ARM::ArchKind::ARMV8_1MMainline
:
904 FeatureCoprocBF
= FEATURE_COPROC_B1
| FEATURE_COPROC_B2
|
905 FEATURE_COPROC_B3
| FEATURE_COPROC_B4
;
908 Builder
.defineMacro("__ARM_FEATURE_COPROC",
909 "0x" + Twine::utohexstr(FeatureCoprocBF
));
911 if (ArchKind
== llvm::ARM::ArchKind::XSCALE
)
912 Builder
.defineMacro("__XSCALE__");
915 Builder
.defineMacro("__THUMBEL__");
916 Builder
.defineMacro("__thumb__");
917 if (supportsThumb2())
918 Builder
.defineMacro("__thumb2__");
921 // ACLE 6.4.9 32-bit SIMD instructions
922 if ((CPUProfile
!= "M" && ArchVersion
>= 6) || (CPUProfile
== "M" && DSP
))
923 Builder
.defineMacro("__ARM_FEATURE_SIMD32", "1");
925 // ACLE 6.4.10 Hardware Integer Divide
926 if (((HWDiv
& HWDivThumb
) && isThumb()) ||
927 ((HWDiv
& HWDivARM
) && !isThumb())) {
928 Builder
.defineMacro("__ARM_FEATURE_IDIV", "1");
929 Builder
.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
932 // Note, this is always on in gcc, even though it doesn't make sense.
933 Builder
.defineMacro("__APCS_32__");
935 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware
936 // FPU is present. Moreover, the VFP format is the only one supported by
937 // clang. For these reasons, this macro is always defined.
938 Builder
.defineMacro("__VFP_FP__");
940 if (FPUModeIsVFP((FPUMode
)FPU
)) {
942 Builder
.defineMacro("__ARM_VFPV2__");
944 Builder
.defineMacro("__ARM_VFPV3__");
946 Builder
.defineMacro("__ARM_VFPV4__");
948 Builder
.defineMacro("__ARM_FPV5__");
951 // This only gets set when Neon instructions are actually available, unlike
952 // the VFP define, hence the soft float and arch check. This is subtly
953 // different from gcc, we follow the intent which was that it should be set
954 // when Neon instructions are actually available.
955 if ((FPU
& NeonFPU
) && !SoftFloat
&& ArchVersion
>= 7) {
956 Builder
.defineMacro("__ARM_NEON", "1");
957 Builder
.defineMacro("__ARM_NEON__");
958 // current AArch32 NEON implementations do not support double-precision
959 // floating-point even when it is present in VFP.
960 Builder
.defineMacro("__ARM_NEON_FP",
961 "0x" + Twine::utohexstr(HW_FP
& ~HW_FP_DP
));
965 Builder
.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
969 Builder
.defineMacro("__ARM_FEATURE_CDE", "1");
970 Builder
.defineMacro("__ARM_FEATURE_CDE_COPROC",
971 "0x" + Twine::utohexstr(getARMCDECoprocMask()));
974 Builder
.defineMacro("__ARM_SIZEOF_WCHAR_T",
975 Twine(Opts
.WCharSize
? Opts
.WCharSize
: 4));
977 Builder
.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts
.ShortEnums
? "1" : "4");
980 if (ArchVersion
== 8 && ArchProfile
== llvm::ARM::ProfileKind::M
)
981 Builder
.defineMacro("__ARM_FEATURE_CMSE", Opts
.Cmse
? "3" : "1");
983 if (ArchVersion
>= 6 && CPUAttr
!= "6M" && CPUAttr
!= "8M_BASE") {
984 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
985 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
986 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
987 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
990 // ACLE 6.4.7 DSP instructions
992 Builder
.defineMacro("__ARM_FEATURE_DSP", "1");
995 // ACLE 6.4.8 Saturation instructions
997 if ((ArchVersion
== 6 && CPUProfile
!= "M") || ArchVersion
> 6) {
998 Builder
.defineMacro("__ARM_FEATURE_SAT", "1");
1002 // ACLE 6.4.6 Q (saturation) flag
1004 Builder
.defineMacro("__ARM_FEATURE_QBIT", "1");
1006 if (Opts
.UnsafeFPMath
)
1007 Builder
.defineMacro("__ARM_FP_FAST", "1");
1009 // Armv8.2-A FP16 vector intrinsic
1010 if ((FPU
& NeonFPU
) && HasLegalHalfType
)
1011 Builder
.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
1013 // Armv8.2-A FP16 scalar intrinsics
1014 if (HasLegalHalfType
)
1015 Builder
.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
1017 // Armv8.2-A dot product intrinsics
1019 Builder
.defineMacro("__ARM_FEATURE_DOTPROD", "1");
1022 Builder
.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
1025 Builder
.defineMacro("__ARM_FEATURE_PAUTH", "1");
1028 Builder
.defineMacro("__ARM_FEATURE_BTI", "1");
1031 Builder
.defineMacro("__ARM_FEATURE_BF16", "1");
1032 Builder
.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
1033 Builder
.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
1036 if (Opts
.BranchTargetEnforcement
)
1037 Builder
.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
1039 if (Opts
.hasSignReturnAddress()) {
1041 if (Opts
.isSignReturnAddressScopeAll())
1043 Builder
.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value
));
1049 case llvm::ARM::ArchKind::ARMV8_1A
:
1050 getTargetDefinesARMV81A(Opts
, Builder
);
1052 case llvm::ARM::ArchKind::ARMV8_2A
:
1053 getTargetDefinesARMV82A(Opts
, Builder
);
1055 case llvm::ARM::ArchKind::ARMV8_3A
:
1056 case llvm::ARM::ArchKind::ARMV8_4A
:
1057 case llvm::ARM::ArchKind::ARMV8_5A
:
1058 case llvm::ARM::ArchKind::ARMV8_6A
:
1059 case llvm::ARM::ArchKind::ARMV8_7A
:
1060 case llvm::ARM::ArchKind::ARMV8_8A
:
1061 case llvm::ARM::ArchKind::ARMV8_9A
:
1062 case llvm::ARM::ArchKind::ARMV9A
:
1063 case llvm::ARM::ArchKind::ARMV9_1A
:
1064 case llvm::ARM::ArchKind::ARMV9_2A
:
1065 case llvm::ARM::ArchKind::ARMV9_3A
:
1066 case llvm::ARM::ArchKind::ARMV9_4A
:
1067 case llvm::ARM::ArchKind::ARMV9_5A
:
1068 case llvm::ARM::ArchKind::ARMV9_6A
:
1069 getTargetDefinesARMV83A(Opts
, Builder
);
1074 static constexpr Builtin::Info BuiltinInfo
[] = {
1075 #define BUILTIN(ID, TYPE, ATTRS) \
1076 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1077 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1078 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1079 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1080 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1081 #include "clang/Basic/BuiltinsNEON.def"
1083 #define BUILTIN(ID, TYPE, ATTRS) \
1084 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1085 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
1086 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
1087 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1088 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1089 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1090 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1091 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
1092 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
1093 #include "clang/Basic/BuiltinsARM.def"
1096 ArrayRef
<Builtin::Info
> ARMTargetInfo::getTargetBuiltins() const {
1097 return llvm::ArrayRef(BuiltinInfo
,
1098 clang::ARM::LastTSBuiltin
- Builtin::FirstTSBuiltin
);
1101 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
1102 TargetInfo::BuiltinVaListKind
ARMTargetInfo::getBuiltinVaListKind() const {
1104 ? AAPCSABIBuiltinVaList
1105 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
1106 : TargetInfo::VoidPtrBuiltinVaList
);
1109 const char *const ARMTargetInfo::GCCRegNames
[] = {
1110 // Integer registers
1111 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1112 "r12", "sp", "lr", "pc",
1115 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1116 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1117 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1120 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1121 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1122 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1125 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1126 "q12", "q13", "q14", "q15"};
1128 ArrayRef
<const char *> ARMTargetInfo::getGCCRegNames() const {
1129 return llvm::ArrayRef(GCCRegNames
);
1132 const TargetInfo::GCCRegAlias
ARMTargetInfo::GCCRegAliases
[] = {
1133 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
1134 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
1135 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1136 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
1137 // The S, D and Q registers overlap, but aren't really aliases; we
1138 // don't want to substitute one of these for a different-sized one.
1141 ArrayRef
<TargetInfo::GCCRegAlias
> ARMTargetInfo::getGCCRegAliases() const {
1142 return llvm::ArrayRef(GCCRegAliases
);
1145 bool ARMTargetInfo::validateAsmConstraint(
1146 const char *&Name
, TargetInfo::ConstraintInfo
&Info
) const {
1150 case 'l': // r0-r7 if thumb, r0-r15 if ARM
1151 Info
.setAllowsRegister();
1153 case 'h': // r8-r15, thumb only
1155 Info
.setAllowsRegister();
1159 case 's': // An integer constant, but allowing only relocatable values.
1161 case 't': // s0-s31, d0-d31, or q0-q15
1162 case 'w': // s0-s15, d0-d7, or q0-q3
1163 case 'x': // s0-s31, d0-d15, or q0-q7
1166 Info
.setAllowsRegister();
1168 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1169 // only available in ARMv6T2 and above
1170 if (CPUAttr
== "6T2" || ArchVersion
>= 7) {
1171 Info
.setRequiresImmediate(0, 65535);
1177 if (!supportsThumb2())
1178 Info
.setRequiresImmediate(0, 255);
1180 // FIXME: should check if immediate value would be valid for a Thumb2
1181 // data-processing instruction
1182 Info
.setRequiresImmediate();
1184 // FIXME: should check if immediate value would be valid for an ARM
1185 // data-processing instruction
1186 Info
.setRequiresImmediate();
1189 if (isThumb() && !supportsThumb2())
1190 Info
.setRequiresImmediate(-255, -1);
1192 Info
.setRequiresImmediate(-4095, 4095);
1196 if (!supportsThumb2())
1197 // FIXME: should check if immediate value can be obtained from shifting
1198 // a value between 0 and 255 left by any amount
1199 Info
.setRequiresImmediate();
1201 // FIXME: should check if immediate value would be valid for a Thumb2
1202 // data-processing instruction when inverted
1203 Info
.setRequiresImmediate();
1205 // FIXME: should check if immediate value would be valid for an ARM
1206 // data-processing instruction when inverted
1207 Info
.setRequiresImmediate();
1211 if (!supportsThumb2())
1212 Info
.setRequiresImmediate(-7, 7);
1214 // FIXME: should check if immediate value would be valid for a Thumb2
1215 // data-processing instruction when negated
1216 Info
.setRequiresImmediate();
1218 // FIXME: should check if immediate value would be valid for an ARM
1219 // data-processing instruction when negated
1220 Info
.setRequiresImmediate();
1223 if (isThumb() && !supportsThumb2())
1224 // FIXME: should check if immediate value is a multiple of 4 between 0 and
1226 Info
.setRequiresImmediate();
1228 // FIXME: should check if immediate value is a power of two or a integer
1230 Info
.setRequiresImmediate();
1234 if (isThumb() && !supportsThumb2()) {
1235 Info
.setRequiresImmediate(0, 31);
1241 if (isThumb() && !supportsThumb2()) {
1242 // FIXME: should check if immediate value is a multiple of 4 between -508
1244 Info
.setRequiresImmediate();
1248 case 'Q': // A memory address that is a single base register.
1249 Info
.setAllowsMemory();
1255 case 'e': // Even general-purpose register
1256 case 'o': // Odd general-purpose register
1257 Info
.setAllowsRegister();
1262 case 'U': // a memory reference...
1264 case 'q': // ...ARMV4 ldrsb
1265 case 'v': // ...VFP load/store (reg+constant offset)
1266 case 'y': // ...iWMMXt load/store
1267 case 't': // address valid for load/store opaque types wider
1269 case 'n': // valid address for Neon doubleword vector load/store
1270 case 'm': // valid address for Neon element and structure load/store
1271 case 's': // valid address for non-offset loads/stores of quad-word
1272 // values in four ARM registers
1273 Info
.setAllowsMemory();
1282 std::string
ARMTargetInfo::convertConstraint(const char *&Constraint
) const {
1284 switch (*Constraint
) {
1285 case 'U': // Two-character constraint; add "^" hint for later parsing.
1287 R
= std::string("^") + std::string(Constraint
, 2);
1290 case 'p': // 'p' should be translated to 'r' by default.
1291 R
= std::string("r");
1294 return std::string(1, *Constraint
);
1299 bool ARMTargetInfo::validateConstraintModifier(
1300 StringRef Constraint
, char Modifier
, unsigned Size
,
1301 std::string
&SuggestedModifier
) const {
1302 bool isOutput
= (Constraint
[0] == '=');
1303 bool isInOut
= (Constraint
[0] == '+');
1305 // Strip off constraint modifiers.
1306 Constraint
= Constraint
.ltrim("=+&");
1308 switch (Constraint
[0]) {
1314 return (isInOut
|| isOutput
|| Size
<= 64);
1316 // A register of size 32 cannot fit a vector type.
1324 std::string_view
ARMTargetInfo::getClobbers() const {
1325 // FIXME: Is this really right?
1329 TargetInfo::CallingConvCheckResult
1330 ARMTargetInfo::checkCallingConvention(CallingConv CC
) const {
1336 case CC_OpenCLKernel
:
1339 return CCCR_Warning
;
1343 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo
) const {
1351 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1353 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple
&Triple
,
1354 const TargetOptions
&Opts
)
1355 : ARMTargetInfo(Triple
, Opts
) {}
1357 void ARMleTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1358 MacroBuilder
&Builder
) const {
1359 Builder
.defineMacro("__ARMEL__");
1360 ARMTargetInfo::getTargetDefines(Opts
, Builder
);
1363 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple
&Triple
,
1364 const TargetOptions
&Opts
)
1365 : ARMTargetInfo(Triple
, Opts
) {}
1367 void ARMbeTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1368 MacroBuilder
&Builder
) const {
1369 Builder
.defineMacro("__ARMEB__");
1370 Builder
.defineMacro("__ARM_BIG_ENDIAN");
1371 ARMTargetInfo::getTargetDefines(Opts
, Builder
);
1374 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple
&Triple
,
1375 const TargetOptions
&Opts
)
1376 : WindowsTargetInfo
<ARMleTargetInfo
>(Triple
, Opts
), Triple(Triple
) {
1379 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions
&Opts
,
1380 MacroBuilder
&Builder
) const {
1381 // FIXME: this is invalid for WindowsCE
1382 Builder
.defineMacro("_M_ARM_NT", "1");
1383 Builder
.defineMacro("_M_ARMT", "_M_ARM");
1384 Builder
.defineMacro("_M_THUMB", "_M_ARM");
1386 assert((Triple
.getArch() == llvm::Triple::arm
||
1387 Triple
.getArch() == llvm::Triple::thumb
) &&
1388 "invalid architecture for Windows ARM target info");
1389 unsigned Offset
= Triple
.getArch() == llvm::Triple::arm
? 4 : 6;
1390 Builder
.defineMacro("_M_ARM", Triple
.getArchName().substr(Offset
));
1392 // TODO map the complete set of values
1393 // 31: VFPv3 40: VFPv4
1394 Builder
.defineMacro("_M_ARM_FP", "31");
1397 TargetInfo::BuiltinVaListKind
1398 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1399 return TargetInfo::CharPtrBuiltinVaList
;
1402 TargetInfo::CallingConvCheckResult
1403 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC
) const {
1406 case CC_X86ThisCall
:
1407 case CC_X86FastCall
:
1408 case CC_X86VectorCall
:
1411 case CC_OpenCLKernel
:
1412 case CC_PreserveMost
:
1413 case CC_PreserveAll
:
1418 return CCCR_Warning
;
1422 // Windows ARM + Itanium C++ ABI Target
1423 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1424 const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
1425 : WindowsARMTargetInfo(Triple
, Opts
) {
1426 TheCXXABI
.set(TargetCXXABI::GenericARM
);
1429 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1430 const LangOptions
&Opts
, MacroBuilder
&Builder
) const {
1431 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1433 if (Opts
.MSVCCompat
)
1434 WindowsARMTargetInfo::getVisualStudioDefines(Opts
, Builder
);
1437 // Windows ARM, MS (C++) ABI
1438 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple
&Triple
,
1439 const TargetOptions
&Opts
)
1440 : WindowsARMTargetInfo(Triple
, Opts
) {
1441 TheCXXABI
.set(TargetCXXABI::Microsoft
);
1444 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1445 MacroBuilder
&Builder
) const {
1446 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1447 WindowsARMTargetInfo::getVisualStudioDefines(Opts
, Builder
);
1450 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple
&Triple
,
1451 const TargetOptions
&Opts
)
1452 : WindowsARMTargetInfo(Triple
, Opts
) {
1453 TheCXXABI
.set(TargetCXXABI::GenericARM
);
1456 void MinGWARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1457 MacroBuilder
&Builder
) const {
1458 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1459 Builder
.defineMacro("_ARM_");
1462 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple
&Triple
,
1463 const TargetOptions
&Opts
)
1464 : ARMleTargetInfo(Triple
, Opts
) {
1465 this->WCharType
= TargetInfo::UnsignedShort
;
1466 TLSSupported
= false;
1467 DoubleAlign
= LongLongAlign
= 64;
1468 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1471 void CygwinARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1472 MacroBuilder
&Builder
) const {
1473 ARMleTargetInfo::getTargetDefines(Opts
, Builder
);
1474 Builder
.defineMacro("_ARM_");
1475 Builder
.defineMacro("__CYGWIN__");
1476 Builder
.defineMacro("__CYGWIN32__");
1477 DefineStd(Builder
, "unix", Opts
);
1479 Builder
.defineMacro("_GNU_SOURCE");
1482 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple
&Triple
,
1483 const TargetOptions
&Opts
)
1484 : DarwinTargetInfo
<ARMleTargetInfo
>(Triple
, Opts
) {
1485 HasAlignMac68kSupport
= true;
1486 if (Triple
.isWatchABI()) {
1487 // Darwin on iOS uses a variant of the ARM C++ ABI.
1488 TheCXXABI
.set(TargetCXXABI::WatchOS
);
1490 // BOOL should be a real boolean on the new ABI
1491 UseSignedCharForObjCBool
= false;
1493 TheCXXABI
.set(TargetCXXABI::iOS
);
1496 void DarwinARMTargetInfo::getOSDefines(const LangOptions
&Opts
,
1497 const llvm::Triple
&Triple
,
1498 MacroBuilder
&Builder
) const {
1499 getDarwinDefines(Builder
, Opts
, Triple
, PlatformName
, PlatformMinVersion
);