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"
21 using namespace clang
;
22 using namespace clang::targets
;
24 void ARMTargetInfo::setABIAAPCS() {
27 DoubleAlign
= LongLongAlign
= LongDoubleAlign
= SuitableAlign
= 64;
28 BFloat16Width
= BFloat16Align
= 16;
29 BFloat16Format
= &llvm::APFloat::BFloat();
31 const llvm::Triple
&T
= getTriple();
33 bool IsNetBSD
= T
.isOSNetBSD();
34 bool IsOpenBSD
= T
.isOSOpenBSD();
35 if (!T
.isOSWindows() && !IsNetBSD
&& !IsOpenBSD
)
36 WCharType
= UnsignedInt
;
38 UseBitFieldTypeAlignment
= true;
40 ZeroLengthBitfieldBoundary
= 0;
42 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
43 // so set preferred for small types to 32.
44 if (T
.isOSBinFormatMachO()) {
45 resetDataLayout(BigEndian
46 ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
47 : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
49 } else if (T
.isOSWindows()) {
50 assert(!BigEndian
&& "Windows on ARM does not support big endian");
60 } else if (T
.isOSNaCl()) {
61 assert(!BigEndian
&& "NaCl on ARM does not support big endian");
62 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
64 resetDataLayout(BigEndian
65 ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
66 : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
69 // FIXME: Enumerated types are variable width in straight AAPCS.
72 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16
) {
73 const llvm::Triple
&T
= getTriple();
78 DoubleAlign
= LongLongAlign
= LongDoubleAlign
= SuitableAlign
= 64;
80 DoubleAlign
= LongLongAlign
= LongDoubleAlign
= SuitableAlign
= 32;
81 BFloat16Width
= BFloat16Align
= 16;
82 BFloat16Format
= &llvm::APFloat::BFloat();
84 WCharType
= SignedInt
;
86 // Do not respect the alignment of bit-field types when laying out
87 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
88 UseBitFieldTypeAlignment
= false;
90 /// gcc forces the alignment to 4 bytes, regardless of the type of the
91 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
93 ZeroLengthBitfieldBoundary
= 32;
95 if (T
.isOSBinFormatMachO() && IsAAPCS16
) {
96 assert(!BigEndian
&& "AAPCS16 does not support big-endian");
97 resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_");
98 } else if (T
.isOSBinFormatMachO())
101 ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
102 : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32",
107 ? "E-m:e-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");
110 // FIXME: Override "preferred align" for double and long long.
113 void ARMTargetInfo::setArchInfo() {
114 StringRef ArchName
= getTriple().getArchName();
116 ArchISA
= llvm::ARM::parseArchISA(ArchName
);
117 CPU
= std::string(llvm::ARM::getDefaultCPU(ArchName
));
118 llvm::ARM::ArchKind AK
= llvm::ARM::parseArch(ArchName
);
119 if (AK
!= llvm::ARM::ArchKind::INVALID
)
121 setArchInfo(ArchKind
);
124 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind
) {
127 // cache TargetParser info
129 SubArch
= llvm::ARM::getSubArch(ArchKind
);
130 ArchProfile
= llvm::ARM::parseArchProfile(SubArch
);
131 ArchVersion
= llvm::ARM::parseArchVersion(SubArch
);
133 // cache CPU related strings
134 CPUAttr
= getCPUAttr();
135 CPUProfile
= getCPUProfile();
138 void ARMTargetInfo::setAtomic() {
139 // when triple does not specify a sub arch,
140 // then we are not using inline atomics
141 bool ShouldUseInlineAtomic
=
142 (ArchISA
== llvm::ARM::ISAKind::ARM
&& ArchVersion
>= 6) ||
143 (ArchISA
== llvm::ARM::ISAKind::THUMB
&& ArchVersion
>= 7);
144 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
145 if (ArchProfile
== llvm::ARM::ProfileKind::M
) {
146 MaxAtomicPromoteWidth
= 32;
147 if (ShouldUseInlineAtomic
)
148 MaxAtomicInlineWidth
= 32;
150 MaxAtomicPromoteWidth
= 64;
151 if (ShouldUseInlineAtomic
)
152 MaxAtomicInlineWidth
= 64;
156 bool ARMTargetInfo::hasMVE() const {
157 return ArchKind
== llvm::ARM::ArchKind::ARMV8_1MMainline
&& MVE
!= 0;
160 bool ARMTargetInfo::hasMVEFloat() const {
161 return hasMVE() && (MVE
& MVE_FP
);
164 bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; }
166 bool ARMTargetInfo::isThumb() const {
167 return ArchISA
== llvm::ARM::ISAKind::THUMB
;
170 bool ARMTargetInfo::supportsThumb() const {
171 return CPUAttr
.count('T') || ArchVersion
>= 6;
174 bool ARMTargetInfo::supportsThumb2() const {
175 return CPUAttr
.equals("6T2") ||
176 (ArchVersion
>= 7 && !CPUAttr
.equals("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::ARMV8MBaseline
:
231 case llvm::ARM::ArchKind::ARMV8MMainline
:
233 case llvm::ARM::ArchKind::ARMV8R
:
235 case llvm::ARM::ArchKind::ARMV8_1MMainline
:
240 StringRef
ARMTargetInfo::getCPUProfile() const {
241 switch (ArchProfile
) {
242 case llvm::ARM::ProfileKind::A
:
244 case llvm::ARM::ProfileKind::R
:
246 case llvm::ARM::ProfileKind::M
:
253 ARMTargetInfo::ARMTargetInfo(const llvm::Triple
&Triple
,
254 const TargetOptions
&Opts
)
255 : TargetInfo(Triple
), FPMath(FP_Default
), IsAAPCS(true), LDREX(0),
257 bool IsOpenBSD
= Triple
.isOSOpenBSD();
258 bool IsNetBSD
= Triple
.isOSNetBSD();
260 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
261 // environment where size_t is `unsigned long` rather than `unsigned int`
263 PtrDiffType
= IntPtrType
=
264 (Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO() || IsOpenBSD
||
269 SizeType
= (Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO() || IsOpenBSD
||
274 // ptrdiff_t is inconsistent on Darwin
275 if ((Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO()) &&
276 !Triple
.isWatchABI())
277 PtrDiffType
= SignedInt
;
279 // Cache arch related info.
282 // {} in inline assembly are neon specifiers, not assembly variant
284 NoAsmVariants
= true;
286 // FIXME: This duplicates code from the driver that sets the -target-abi
287 // option - this code is used if -target-abi isn't passed and should
288 // be unified in some way.
289 if (Triple
.isOSBinFormatMachO()) {
290 // The backend is hardwired to assume AAPCS for M-class processors, ensure
291 // the frontend matches that.
292 if (Triple
.getEnvironment() == llvm::Triple::EABI
||
293 Triple
.getOS() == llvm::Triple::UnknownOS
||
294 ArchProfile
== llvm::ARM::ProfileKind::M
) {
296 } else if (Triple
.isWatchABI()) {
301 } else if (Triple
.isOSWindows()) {
302 // FIXME: this is invalid for WindowsCE
305 // Select the default based on the platform.
306 switch (Triple
.getEnvironment()) {
307 case llvm::Triple::Android
:
308 case llvm::Triple::GNUEABI
:
309 case llvm::Triple::GNUEABIHF
:
310 case llvm::Triple::MuslEABI
:
311 case llvm::Triple::MuslEABIHF
:
312 setABI("aapcs-linux");
314 case llvm::Triple::EABIHF
:
315 case llvm::Triple::EABI
:
318 case llvm::Triple::GNU
:
325 setABI("aapcs-linux");
332 // ARM targets default to using the ARM C++ ABI.
333 TheCXXABI
.set(TargetCXXABI::GenericARM
);
335 // ARM has atomics up to 8 bytes
338 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
339 // as well the default alignment
340 if (IsAAPCS
&& !Triple
.isAndroid())
341 DefaultAlignForAttributeAligned
= MaxVectorAlign
= 64;
343 // Do force alignment of members that follow zero length bitfields. If
344 // the alignment of the zero-length bitfield is greater than the member
345 // that follows it, `bar', `bar' will be aligned as the type of the
346 // zero length bitfield.
347 UseZeroLengthBitfieldAlignment
= true;
349 if (Triple
.getOS() == llvm::Triple::Linux
||
350 Triple
.getOS() == llvm::Triple::UnknownOS
)
351 this->MCountName
= Opts
.EABIVersion
== llvm::EABI::GNU
352 ? "llvm.arm.gnu.eabi.mcount"
355 SoftFloatABI
= llvm::is_contained(Opts
.FeaturesAsWritten
, "+soft-float-abi");
358 StringRef
ARMTargetInfo::getABI() const { return ABI
; }
360 bool ARMTargetInfo::setABI(const std::string
&Name
) {
363 // The defaults (above) are for AAPCS, check if we need to change them.
365 // FIXME: We need support for -meabi... we could just mangle it into the
367 if (Name
== "apcs-gnu" || Name
== "aapcs16") {
368 setABIAPCS(Name
== "aapcs16");
371 if (Name
== "aapcs" || Name
== "aapcs-vfp" || Name
== "aapcs-linux") {
378 bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch
) const {
379 llvm::ARM::ArchKind CPUArch
= llvm::ARM::parseCPUArch(Arch
);
380 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
381 CPUArch
= llvm::ARM::parseArch(getTriple().getArchName());
383 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
386 StringRef ArchFeature
= llvm::ARM::getArchName(CPUArch
);
388 llvm::Triple(ArchFeature
, getTriple().getVendorName(),
389 getTriple().getOSName(), getTriple().getEnvironmentName());
391 StringRef SubArch
= llvm::ARM::getSubArch(CPUArch
);
392 llvm::ARM::ProfileKind Profile
= llvm::ARM::parseArchProfile(SubArch
);
393 return a
.isArmT32() && (Profile
== llvm::ARM::ProfileKind::M
);
396 bool ARMTargetInfo::validateBranchProtection(StringRef Spec
, StringRef Arch
,
397 BranchProtectionInfo
&BPI
,
398 StringRef
&Err
) const {
399 llvm::ARM::ParsedBranchProtection PBP
;
400 if (!llvm::ARM::parseBranchProtection(Spec
, PBP
, Err
))
403 if (!isBranchProtectionSupportedArch(Arch
))
407 llvm::StringSwitch
<LangOptions::SignReturnAddressScopeKind
>(PBP
.Scope
)
408 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf
)
409 .Case("all", LangOptions::SignReturnAddressScopeKind::All
)
410 .Default(LangOptions::SignReturnAddressScopeKind::None
);
412 // Don't care for the sign key, beyond issuing a warning.
413 if (PBP
.Key
== "b_key")
415 BPI
.SignKey
= LangOptions::SignReturnAddressKeyKind::AKey
;
417 BPI
.BranchTargetEnforcement
= PBP
.BranchTargetEnforcement
;
421 // FIXME: This should be based on Arch attributes, not CPU names.
422 bool ARMTargetInfo::initFeatureMap(
423 llvm::StringMap
<bool> &Features
, DiagnosticsEngine
&Diags
, StringRef CPU
,
424 const std::vector
<std::string
> &FeaturesVec
) const {
426 std::string ArchFeature
;
427 std::vector
<StringRef
> TargetFeatures
;
428 llvm::ARM::ArchKind Arch
= llvm::ARM::parseArch(getTriple().getArchName());
430 // Map the base architecture to an appropriate target feature, so we don't
431 // rely on the target triple.
432 llvm::ARM::ArchKind CPUArch
= llvm::ARM::parseCPUArch(CPU
);
433 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
435 if (CPUArch
!= llvm::ARM::ArchKind::INVALID
) {
436 ArchFeature
= ("+" + llvm::ARM::getArchName(CPUArch
)).str();
437 TargetFeatures
.push_back(ArchFeature
);
439 // These features are added to allow arm_neon.h target(..) attributes to
440 // match with both arm and aarch64. We need to add all previous architecture
441 // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
442 // v8.x counterparts are added too. We only need these for anything > 8.0-A.
443 for (llvm::ARM::ArchKind I
= llvm::ARM::convertV9toV8(CPUArch
);
444 I
!= llvm::ARM::ArchKind::INVALID
; --I
)
445 Features
[llvm::ARM::getSubArch(I
)] = true;
446 if (CPUArch
> llvm::ARM::ArchKind::ARMV8A
&&
447 CPUArch
<= llvm::ARM::ArchKind::ARMV9_3A
)
448 for (llvm::ARM::ArchKind I
= CPUArch
; I
!= llvm::ARM::ArchKind::INVALID
;
450 Features
[llvm::ARM::getSubArch(I
)] = true;
453 // get default FPU features
454 unsigned FPUKind
= llvm::ARM::getDefaultFPU(CPU
, Arch
);
455 llvm::ARM::getFPUFeatures(FPUKind
, TargetFeatures
);
457 // get default Extension features
458 uint64_t Extensions
= llvm::ARM::getDefaultExtensions(CPU
, Arch
);
459 llvm::ARM::getExtensionFeatures(Extensions
, TargetFeatures
);
461 for (auto Feature
: TargetFeatures
)
462 if (Feature
[0] == '+')
463 Features
[Feature
.drop_front(1)] = true;
465 // Enable or disable thumb-mode explicitly per function to enable mixed
466 // ARM and Thumb code generation.
468 Features
["thumb-mode"] = true;
470 Features
["thumb-mode"] = false;
472 // Convert user-provided arm and thumb GNU target attributes to
473 // [-|+]thumb-mode target features respectively.
474 std::vector
<std::string
> UpdatedFeaturesVec
;
475 for (const auto &Feature
: FeaturesVec
) {
476 // Skip soft-float-abi; it's something we only use to initialize a bit of
477 // class state, and is otherwise unrecognized.
478 if (Feature
== "+soft-float-abi")
481 StringRef FixedFeature
;
482 if (Feature
== "+arm")
483 FixedFeature
= "-thumb-mode";
484 else if (Feature
== "+thumb")
485 FixedFeature
= "+thumb-mode";
487 FixedFeature
= Feature
;
488 UpdatedFeaturesVec
.push_back(FixedFeature
.str());
491 return TargetInfo::initFeatureMap(Features
, Diags
, CPU
, UpdatedFeaturesVec
);
495 bool ARMTargetInfo::handleTargetFeatures(std::vector
<std::string
> &Features
,
496 DiagnosticsEngine
&Diags
) {
506 // Note that SoftFloatABI is initialized in our constructor.
513 ARMCDECoprocMask
= 0;
515 FPRegsDisabled
= false;
517 // This does not diagnose illegal cases like having both
518 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
519 for (const auto &Feature
: Features
) {
520 if (Feature
== "+soft-float") {
522 } else if (Feature
== "+vfp2sp" || Feature
== "+vfp2") {
525 if (Feature
== "+vfp2")
527 } else if (Feature
== "+vfp3sp" || Feature
== "+vfp3d16sp" ||
528 Feature
== "+vfp3" || Feature
== "+vfp3d16") {
531 if (Feature
== "+vfp3" || Feature
== "+vfp3d16")
533 } else if (Feature
== "+vfp4sp" || Feature
== "+vfp4d16sp" ||
534 Feature
== "+vfp4" || Feature
== "+vfp4d16") {
536 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
537 if (Feature
== "+vfp4" || Feature
== "+vfp4d16")
539 } else if (Feature
== "+fp-armv8sp" || Feature
== "+fp-armv8d16sp" ||
540 Feature
== "+fp-armv8" || Feature
== "+fp-armv8d16") {
542 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
543 if (Feature
== "+fp-armv8" || Feature
== "+fp-armv8d16")
545 } else if (Feature
== "+neon") {
548 } else if (Feature
== "+hwdiv") {
550 } else if (Feature
== "+hwdiv-arm") {
552 } else if (Feature
== "+crc") {
554 } else if (Feature
== "+crypto") {
556 } else if (Feature
== "+sha2") {
558 } else if (Feature
== "+aes") {
560 } else if (Feature
== "+dsp") {
562 } else if (Feature
== "+fp64") {
564 } else if (Feature
== "+8msecext") {
565 if (CPUProfile
!= "M" || ArchVersion
!= 8) {
566 Diags
.Report(diag::err_target_unsupported_mcmse
) << CPU
;
569 } else if (Feature
== "+strict-align") {
571 } else if (Feature
== "+fp16") {
573 } else if (Feature
== "+fullfp16") {
574 HasLegalHalfType
= true;
575 } else if (Feature
== "+dotprod") {
577 } else if (Feature
== "+mve") {
579 } else if (Feature
== "+mve.fp") {
580 HasLegalHalfType
= true;
582 MVE
|= MVE_INT
| MVE_FP
;
583 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
584 } else if (Feature
== "+i8mm") {
586 } else if (Feature
.size() == strlen("+cdecp0") && Feature
>= "+cdecp0" &&
587 Feature
<= "+cdecp7") {
588 unsigned Coproc
= Feature
.back() - '0';
589 ARMCDECoprocMask
|= (1U << Coproc
);
590 } else if (Feature
== "+bf16") {
592 } else if (Feature
== "-fpregs") {
593 FPRegsDisabled
= true;
594 } else if (Feature
== "+pacbti") {
600 HalfArgsAndReturns
= true;
602 switch (ArchVersion
) {
604 if (ArchProfile
== llvm::ARM::ProfileKind::M
)
606 else if (ArchKind
== llvm::ARM::ArchKind::ARMV6K
)
607 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
612 if (ArchProfile
== llvm::ARM::ProfileKind::M
)
613 LDREX
= LDREX_W
| LDREX_H
| LDREX_B
;
615 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
619 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
622 if (!(FPU
& NeonFPU
) && FPMath
== FP_Neon
) {
623 Diags
.Report(diag::err_target_unsupported_fpmath
) << "neon";
627 if (FPMath
== FP_Neon
)
628 Features
.push_back("+neonfp");
629 else if (FPMath
== FP_VFP
)
630 Features
.push_back("-neonfp");
635 bool ARMTargetInfo::hasFeature(StringRef Feature
) const {
636 return llvm::StringSwitch
<bool>(Feature
)
638 .Case("aarch32", true)
639 .Case("softfloat", SoftFloat
)
640 .Case("thumb", isThumb())
641 .Case("neon", (FPU
& NeonFPU
) && !SoftFloat
)
642 .Case("vfp", FPU
&& !SoftFloat
)
643 .Case("hwdiv", HWDiv
& HWDivThumb
)
644 .Case("hwdiv-arm", HWDiv
& HWDivARM
)
645 .Case("mve", hasMVE())
649 bool ARMTargetInfo::hasBFloat16Type() const {
650 // The __bf16 type is generally available so long as we have any fp registers.
651 return HasBFloat16
|| (FPU
&& !SoftFloat
);
654 bool ARMTargetInfo::isValidCPUName(StringRef Name
) const {
655 return Name
== "generic" ||
656 llvm::ARM::parseCPUArch(Name
) != llvm::ARM::ArchKind::INVALID
;
659 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl
<StringRef
> &Values
) const {
660 llvm::ARM::fillValidCPUArchList(Values
);
663 bool ARMTargetInfo::setCPU(const std::string
&Name
) {
664 if (Name
!= "generic")
665 setArchInfo(llvm::ARM::parseCPUArch(Name
));
667 if (ArchKind
== llvm::ARM::ArchKind::INVALID
)
674 bool ARMTargetInfo::setFPMath(StringRef Name
) {
675 if (Name
== "neon") {
678 } else if (Name
== "vfp" || Name
== "vfp2" || Name
== "vfp3" ||
686 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions
&Opts
,
687 MacroBuilder
&Builder
) const {
688 Builder
.defineMacro("__ARM_FEATURE_QRDMX", "1");
691 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions
&Opts
,
692 MacroBuilder
&Builder
) const {
693 // Also include the ARMv8.1-A defines
694 getTargetDefinesARMV81A(Opts
, Builder
);
697 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions
&Opts
,
698 MacroBuilder
&Builder
) const {
699 // Also include the ARMv8.2-A defines
700 Builder
.defineMacro("__ARM_FEATURE_COMPLEX", "1");
701 getTargetDefinesARMV82A(Opts
, Builder
);
704 void ARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
705 MacroBuilder
&Builder
) const {
706 // Target identification.
707 Builder
.defineMacro("__arm");
708 Builder
.defineMacro("__arm__");
709 // For bare-metal none-eabi.
710 if (getTriple().getOS() == llvm::Triple::UnknownOS
&&
711 (getTriple().getEnvironment() == llvm::Triple::EABI
||
712 getTriple().getEnvironment() == llvm::Triple::EABIHF
)) {
713 Builder
.defineMacro("__ELF__");
715 Builder
.defineMacro("_GNU_SOURCE");
718 // Target properties.
719 Builder
.defineMacro("__REGISTER_PREFIX__", "");
721 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
722 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
723 if (getTriple().isWatchABI())
724 Builder
.defineMacro("__ARM_ARCH_7K__", "2");
726 if (!CPUAttr
.empty())
727 Builder
.defineMacro("__ARM_ARCH_" + CPUAttr
+ "__");
729 // ACLE 6.4.1 ARM/Thumb instruction set architecture
730 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
731 Builder
.defineMacro("__ARM_ARCH", Twine(ArchVersion
));
733 if (ArchVersion
>= 8) {
734 // ACLE 6.5.7 Crypto Extension
735 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
736 // feature macros for AES and SHA2
738 Builder
.defineMacro("__ARM_FEATURE_CRYPTO", "1");
740 Builder
.defineMacro("__ARM_FEATURE_SHA2", "1");
742 Builder
.defineMacro("__ARM_FEATURE_AES", "1");
743 // ACLE 6.5.8 CRC32 Extension
745 Builder
.defineMacro("__ARM_FEATURE_CRC32", "1");
746 // ACLE 6.5.10 Numeric Maximum and Minimum
747 Builder
.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
748 // ACLE 6.5.9 Directed Rounding
749 Builder
.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
752 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
753 // is not defined for the M-profile.
754 // NOTE that the default profile is assumed to be 'A'
755 if (CPUProfile
.empty() || ArchProfile
!= llvm::ARM::ProfileKind::M
)
756 Builder
.defineMacro("__ARM_ARCH_ISA_ARM", "1");
758 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
759 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
760 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
761 // v7 and v8 architectures excluding v8-M Baseline.
762 if (supportsThumb2())
763 Builder
.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
764 else if (supportsThumb())
765 Builder
.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
767 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
768 // instruction set such as ARM or Thumb.
769 Builder
.defineMacro("__ARM_32BIT_STATE", "1");
771 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
773 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
774 if (!CPUProfile
.empty())
775 Builder
.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile
+ "'");
777 // ACLE 6.4.3 Unaligned access supported in hardware
779 Builder
.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
781 // ACLE 6.4.4 LDREX/STREX
783 Builder
.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX
));
786 if (ArchVersion
== 5 || (ArchVersion
== 6 && CPUProfile
!= "M") ||
788 Builder
.defineMacro("__ARM_FEATURE_CLZ", "1");
790 // ACLE 6.5.1 Hardware Floating Point
792 Builder
.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP
));
795 Builder
.defineMacro("__ARM_ACLE", "200");
797 // FP16 support (we currently only support IEEE format).
798 Builder
.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
799 Builder
.defineMacro("__ARM_FP16_ARGS", "1");
801 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
802 if (ArchVersion
>= 7 && (FPU
& VFP4FPU
))
803 Builder
.defineMacro("__ARM_FEATURE_FMA", "1");
805 // Subtarget options.
807 // FIXME: It's more complicated than this and we don't really support
809 // Windows on ARM does not "support" interworking
810 if (5 <= ArchVersion
&& ArchVersion
<= 8 && !getTriple().isOSWindows())
811 Builder
.defineMacro("__THUMB_INTERWORK__");
813 if (ABI
== "aapcs" || ABI
== "aapcs-linux" || ABI
== "aapcs-vfp") {
814 // Embedded targets on Darwin follow AAPCS, but not EABI.
815 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
816 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
817 Builder
.defineMacro("__ARM_EABI__");
818 Builder
.defineMacro("__ARM_PCS", "1");
821 if ((!SoftFloat
&& !SoftFloatABI
) || ABI
== "aapcs-vfp" || ABI
== "aapcs16")
822 Builder
.defineMacro("__ARM_PCS_VFP", "1");
824 if (SoftFloat
|| (SoftFloatABI
&& !FPU
))
825 Builder
.defineMacro("__SOFTFP__");
827 // ACLE position independent code macros.
829 Builder
.defineMacro("__ARM_ROPI", "1");
831 Builder
.defineMacro("__ARM_RWPI", "1");
833 if (ArchKind
== llvm::ARM::ArchKind::XSCALE
)
834 Builder
.defineMacro("__XSCALE__");
837 Builder
.defineMacro("__THUMBEL__");
838 Builder
.defineMacro("__thumb__");
839 if (supportsThumb2())
840 Builder
.defineMacro("__thumb2__");
843 // ACLE 6.4.9 32-bit SIMD instructions
844 if ((CPUProfile
!= "M" && ArchVersion
>= 6) || (CPUProfile
== "M" && DSP
))
845 Builder
.defineMacro("__ARM_FEATURE_SIMD32", "1");
847 // ACLE 6.4.10 Hardware Integer Divide
848 if (((HWDiv
& HWDivThumb
) && isThumb()) ||
849 ((HWDiv
& HWDivARM
) && !isThumb())) {
850 Builder
.defineMacro("__ARM_FEATURE_IDIV", "1");
851 Builder
.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
854 // Note, this is always on in gcc, even though it doesn't make sense.
855 Builder
.defineMacro("__APCS_32__");
857 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware
858 // FPU is present. Moreover, the VFP format is the only one supported by
859 // clang. For these reasons, this macro is always defined.
860 Builder
.defineMacro("__VFP_FP__");
862 if (FPUModeIsVFP((FPUMode
)FPU
)) {
864 Builder
.defineMacro("__ARM_VFPV2__");
866 Builder
.defineMacro("__ARM_VFPV3__");
868 Builder
.defineMacro("__ARM_VFPV4__");
870 Builder
.defineMacro("__ARM_FPV5__");
873 // This only gets set when Neon instructions are actually available, unlike
874 // the VFP define, hence the soft float and arch check. This is subtly
875 // different from gcc, we follow the intent which was that it should be set
876 // when Neon instructions are actually available.
877 if ((FPU
& NeonFPU
) && !SoftFloat
&& ArchVersion
>= 7) {
878 Builder
.defineMacro("__ARM_NEON", "1");
879 Builder
.defineMacro("__ARM_NEON__");
880 // current AArch32 NEON implementations do not support double-precision
881 // floating-point even when it is present in VFP.
882 Builder
.defineMacro("__ARM_NEON_FP",
883 "0x" + Twine::utohexstr(HW_FP
& ~HW_FP_DP
));
887 Builder
.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
891 Builder
.defineMacro("__ARM_FEATURE_CDE", "1");
892 Builder
.defineMacro("__ARM_FEATURE_CDE_COPROC",
893 "0x" + Twine::utohexstr(getARMCDECoprocMask()));
896 Builder
.defineMacro("__ARM_SIZEOF_WCHAR_T",
897 Twine(Opts
.WCharSize
? Opts
.WCharSize
: 4));
899 Builder
.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts
.ShortEnums
? "1" : "4");
902 if (ArchVersion
== 8 && ArchProfile
== llvm::ARM::ProfileKind::M
)
903 Builder
.defineMacro("__ARM_FEATURE_CMSE", Opts
.Cmse
? "3" : "1");
905 if (ArchVersion
>= 6 && CPUAttr
!= "6M" && CPUAttr
!= "8M_BASE") {
906 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
907 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
908 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
909 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
912 // ACLE 6.4.7 DSP instructions
914 Builder
.defineMacro("__ARM_FEATURE_DSP", "1");
917 // ACLE 6.4.8 Saturation instructions
919 if ((ArchVersion
== 6 && CPUProfile
!= "M") || ArchVersion
> 6) {
920 Builder
.defineMacro("__ARM_FEATURE_SAT", "1");
924 // ACLE 6.4.6 Q (saturation) flag
926 Builder
.defineMacro("__ARM_FEATURE_QBIT", "1");
928 if (Opts
.UnsafeFPMath
)
929 Builder
.defineMacro("__ARM_FP_FAST", "1");
931 // Armv8.2-A FP16 vector intrinsic
932 if ((FPU
& NeonFPU
) && HasLegalHalfType
)
933 Builder
.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
935 // Armv8.2-A FP16 scalar intrinsics
936 if (HasLegalHalfType
)
937 Builder
.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
939 // Armv8.2-A dot product intrinsics
941 Builder
.defineMacro("__ARM_FEATURE_DOTPROD", "1");
944 Builder
.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
947 Builder
.defineMacro("__ARM_FEATURE_PAUTH", "1");
950 Builder
.defineMacro("__ARM_FEATURE_BTI", "1");
953 Builder
.defineMacro("__ARM_FEATURE_BF16", "1");
954 Builder
.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
955 Builder
.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
958 if (Opts
.BranchTargetEnforcement
)
959 Builder
.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
961 if (Opts
.hasSignReturnAddress()) {
963 if (Opts
.isSignReturnAddressScopeAll())
965 Builder
.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value
));
971 case llvm::ARM::ArchKind::ARMV8_1A
:
972 getTargetDefinesARMV81A(Opts
, Builder
);
974 case llvm::ARM::ArchKind::ARMV8_2A
:
975 getTargetDefinesARMV82A(Opts
, Builder
);
977 case llvm::ARM::ArchKind::ARMV8_3A
:
978 case llvm::ARM::ArchKind::ARMV8_4A
:
979 case llvm::ARM::ArchKind::ARMV8_5A
:
980 case llvm::ARM::ArchKind::ARMV8_6A
:
981 case llvm::ARM::ArchKind::ARMV8_7A
:
982 case llvm::ARM::ArchKind::ARMV8_8A
:
983 case llvm::ARM::ArchKind::ARMV8_9A
:
984 case llvm::ARM::ArchKind::ARMV9A
:
985 case llvm::ARM::ArchKind::ARMV9_1A
:
986 case llvm::ARM::ArchKind::ARMV9_2A
:
987 case llvm::ARM::ArchKind::ARMV9_3A
:
988 case llvm::ARM::ArchKind::ARMV9_4A
:
989 getTargetDefinesARMV83A(Opts
, Builder
);
994 static constexpr Builtin::Info BuiltinInfo
[] = {
995 #define BUILTIN(ID, TYPE, ATTRS) \
996 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
997 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
998 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
999 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1000 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1001 #include "clang/Basic/BuiltinsNEON.def"
1003 #define BUILTIN(ID, TYPE, ATTRS) \
1004 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1005 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
1006 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
1007 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1008 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1009 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1010 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1011 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
1012 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
1013 #include "clang/Basic/BuiltinsARM.def"
1016 ArrayRef
<Builtin::Info
> ARMTargetInfo::getTargetBuiltins() const {
1017 return llvm::ArrayRef(BuiltinInfo
,
1018 clang::ARM::LastTSBuiltin
- Builtin::FirstTSBuiltin
);
1021 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
1022 TargetInfo::BuiltinVaListKind
ARMTargetInfo::getBuiltinVaListKind() const {
1024 ? AAPCSABIBuiltinVaList
1025 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
1026 : TargetInfo::VoidPtrBuiltinVaList
);
1029 const char *const ARMTargetInfo::GCCRegNames
[] = {
1030 // Integer registers
1031 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1032 "r12", "sp", "lr", "pc",
1035 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1036 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1037 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1040 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1041 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1042 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1045 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1046 "q12", "q13", "q14", "q15"};
1048 ArrayRef
<const char *> ARMTargetInfo::getGCCRegNames() const {
1049 return llvm::ArrayRef(GCCRegNames
);
1052 const TargetInfo::GCCRegAlias
ARMTargetInfo::GCCRegAliases
[] = {
1053 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
1054 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
1055 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1056 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
1057 // The S, D and Q registers overlap, but aren't really aliases; we
1058 // don't want to substitute one of these for a different-sized one.
1061 ArrayRef
<TargetInfo::GCCRegAlias
> ARMTargetInfo::getGCCRegAliases() const {
1062 return llvm::ArrayRef(GCCRegAliases
);
1065 bool ARMTargetInfo::validateAsmConstraint(
1066 const char *&Name
, TargetInfo::ConstraintInfo
&Info
) const {
1070 case 'l': // r0-r7 if thumb, r0-r15 if ARM
1071 Info
.setAllowsRegister();
1073 case 'h': // r8-r15, thumb only
1075 Info
.setAllowsRegister();
1079 case 's': // An integer constant, but allowing only relocatable values.
1081 case 't': // s0-s31, d0-d31, or q0-q15
1082 case 'w': // s0-s15, d0-d7, or q0-q3
1083 case 'x': // s0-s31, d0-d15, or q0-q7
1086 Info
.setAllowsRegister();
1088 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1089 // only available in ARMv6T2 and above
1090 if (CPUAttr
.equals("6T2") || ArchVersion
>= 7) {
1091 Info
.setRequiresImmediate(0, 65535);
1097 if (!supportsThumb2())
1098 Info
.setRequiresImmediate(0, 255);
1100 // FIXME: should check if immediate value would be valid for a Thumb2
1101 // data-processing instruction
1102 Info
.setRequiresImmediate();
1104 // FIXME: should check if immediate value would be valid for an ARM
1105 // data-processing instruction
1106 Info
.setRequiresImmediate();
1109 if (isThumb() && !supportsThumb2())
1110 Info
.setRequiresImmediate(-255, -1);
1112 Info
.setRequiresImmediate(-4095, 4095);
1116 if (!supportsThumb2())
1117 // FIXME: should check if immediate value can be obtained from shifting
1118 // a value between 0 and 255 left by any amount
1119 Info
.setRequiresImmediate();
1121 // FIXME: should check if immediate value would be valid for a Thumb2
1122 // data-processing instruction when inverted
1123 Info
.setRequiresImmediate();
1125 // FIXME: should check if immediate value would be valid for an ARM
1126 // data-processing instruction when inverted
1127 Info
.setRequiresImmediate();
1131 if (!supportsThumb2())
1132 Info
.setRequiresImmediate(-7, 7);
1134 // FIXME: should check if immediate value would be valid for a Thumb2
1135 // data-processing instruction when negated
1136 Info
.setRequiresImmediate();
1138 // FIXME: should check if immediate value would be valid for an ARM
1139 // data-processing instruction when negated
1140 Info
.setRequiresImmediate();
1143 if (isThumb() && !supportsThumb2())
1144 // FIXME: should check if immediate value is a multiple of 4 between 0 and
1146 Info
.setRequiresImmediate();
1148 // FIXME: should check if immediate value is a power of two or a integer
1150 Info
.setRequiresImmediate();
1154 if (isThumb() && !supportsThumb2()) {
1155 Info
.setRequiresImmediate(0, 31);
1161 if (isThumb() && !supportsThumb2()) {
1162 // FIXME: should check if immediate value is a multiple of 4 between -508
1164 Info
.setRequiresImmediate();
1168 case 'Q': // A memory address that is a single base register.
1169 Info
.setAllowsMemory();
1175 case 'e': // Even general-purpose register
1176 case 'o': // Odd general-purpose register
1177 Info
.setAllowsRegister();
1182 case 'U': // a memory reference...
1184 case 'q': // ...ARMV4 ldrsb
1185 case 'v': // ...VFP load/store (reg+constant offset)
1186 case 'y': // ...iWMMXt load/store
1187 case 't': // address valid for load/store opaque types wider
1189 case 'n': // valid address for Neon doubleword vector load/store
1190 case 'm': // valid address for Neon element and structure load/store
1191 case 's': // valid address for non-offset loads/stores of quad-word
1192 // values in four ARM registers
1193 Info
.setAllowsMemory();
1202 std::string
ARMTargetInfo::convertConstraint(const char *&Constraint
) const {
1204 switch (*Constraint
) {
1205 case 'U': // Two-character constraint; add "^" hint for later parsing.
1207 R
= std::string("^") + std::string(Constraint
, 2);
1210 case 'p': // 'p' should be translated to 'r' by default.
1211 R
= std::string("r");
1214 return std::string(1, *Constraint
);
1219 bool ARMTargetInfo::validateConstraintModifier(
1220 StringRef Constraint
, char Modifier
, unsigned Size
,
1221 std::string
&SuggestedModifier
) const {
1222 bool isOutput
= (Constraint
[0] == '=');
1223 bool isInOut
= (Constraint
[0] == '+');
1225 // Strip off constraint modifiers.
1226 while (Constraint
[0] == '=' || Constraint
[0] == '+' || Constraint
[0] == '&')
1227 Constraint
= Constraint
.substr(1);
1229 switch (Constraint
[0]) {
1235 return (isInOut
|| isOutput
|| Size
<= 64);
1237 // A register of size 32 cannot fit a vector type.
1245 const char *ARMTargetInfo::getClobbers() const {
1246 // FIXME: Is this really right?
1250 TargetInfo::CallingConvCheckResult
1251 ARMTargetInfo::checkCallingConvention(CallingConv CC
) const {
1257 case CC_OpenCLKernel
:
1260 return CCCR_Warning
;
1264 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo
) const {
1272 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1274 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple
&Triple
,
1275 const TargetOptions
&Opts
)
1276 : ARMTargetInfo(Triple
, Opts
) {}
1278 void ARMleTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1279 MacroBuilder
&Builder
) const {
1280 Builder
.defineMacro("__ARMEL__");
1281 ARMTargetInfo::getTargetDefines(Opts
, Builder
);
1284 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple
&Triple
,
1285 const TargetOptions
&Opts
)
1286 : ARMTargetInfo(Triple
, Opts
) {}
1288 void ARMbeTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1289 MacroBuilder
&Builder
) const {
1290 Builder
.defineMacro("__ARMEB__");
1291 Builder
.defineMacro("__ARM_BIG_ENDIAN");
1292 ARMTargetInfo::getTargetDefines(Opts
, Builder
);
1295 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple
&Triple
,
1296 const TargetOptions
&Opts
)
1297 : WindowsTargetInfo
<ARMleTargetInfo
>(Triple
, Opts
), Triple(Triple
) {
1300 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions
&Opts
,
1301 MacroBuilder
&Builder
) const {
1302 // FIXME: this is invalid for WindowsCE
1303 Builder
.defineMacro("_M_ARM_NT", "1");
1304 Builder
.defineMacro("_M_ARMT", "_M_ARM");
1305 Builder
.defineMacro("_M_THUMB", "_M_ARM");
1307 assert((Triple
.getArch() == llvm::Triple::arm
||
1308 Triple
.getArch() == llvm::Triple::thumb
) &&
1309 "invalid architecture for Windows ARM target info");
1310 unsigned Offset
= Triple
.getArch() == llvm::Triple::arm
? 4 : 6;
1311 Builder
.defineMacro("_M_ARM", Triple
.getArchName().substr(Offset
));
1313 // TODO map the complete set of values
1314 // 31: VFPv3 40: VFPv4
1315 Builder
.defineMacro("_M_ARM_FP", "31");
1318 TargetInfo::BuiltinVaListKind
1319 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1320 return TargetInfo::CharPtrBuiltinVaList
;
1323 TargetInfo::CallingConvCheckResult
1324 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC
) const {
1327 case CC_X86ThisCall
:
1328 case CC_X86FastCall
:
1329 case CC_X86VectorCall
:
1332 case CC_OpenCLKernel
:
1333 case CC_PreserveMost
:
1334 case CC_PreserveAll
:
1339 return CCCR_Warning
;
1343 // Windows ARM + Itanium C++ ABI Target
1344 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1345 const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
1346 : WindowsARMTargetInfo(Triple
, Opts
) {
1347 TheCXXABI
.set(TargetCXXABI::GenericARM
);
1350 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1351 const LangOptions
&Opts
, MacroBuilder
&Builder
) const {
1352 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1354 if (Opts
.MSVCCompat
)
1355 WindowsARMTargetInfo::getVisualStudioDefines(Opts
, Builder
);
1358 // Windows ARM, MS (C++) ABI
1359 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple
&Triple
,
1360 const TargetOptions
&Opts
)
1361 : WindowsARMTargetInfo(Triple
, Opts
) {
1362 TheCXXABI
.set(TargetCXXABI::Microsoft
);
1365 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1366 MacroBuilder
&Builder
) const {
1367 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1368 WindowsARMTargetInfo::getVisualStudioDefines(Opts
, Builder
);
1371 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple
&Triple
,
1372 const TargetOptions
&Opts
)
1373 : WindowsARMTargetInfo(Triple
, Opts
) {
1374 TheCXXABI
.set(TargetCXXABI::GenericARM
);
1377 void MinGWARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1378 MacroBuilder
&Builder
) const {
1379 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1380 Builder
.defineMacro("_ARM_");
1383 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple
&Triple
,
1384 const TargetOptions
&Opts
)
1385 : ARMleTargetInfo(Triple
, Opts
) {
1386 this->WCharType
= TargetInfo::UnsignedShort
;
1387 TLSSupported
= false;
1388 DoubleAlign
= LongLongAlign
= 64;
1389 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1392 void CygwinARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1393 MacroBuilder
&Builder
) const {
1394 ARMleTargetInfo::getTargetDefines(Opts
, Builder
);
1395 Builder
.defineMacro("_ARM_");
1396 Builder
.defineMacro("__CYGWIN__");
1397 Builder
.defineMacro("__CYGWIN32__");
1398 DefineStd(Builder
, "unix", Opts
);
1400 Builder
.defineMacro("_GNU_SOURCE");
1403 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple
&Triple
,
1404 const TargetOptions
&Opts
)
1405 : DarwinTargetInfo
<ARMleTargetInfo
>(Triple
, Opts
) {
1406 HasAlignMac68kSupport
= true;
1407 // iOS always has 64-bit atomic instructions.
1408 // FIXME: This should be based off of the target features in
1410 MaxAtomicInlineWidth
= 64;
1412 if (Triple
.isWatchABI()) {
1413 // Darwin on iOS uses a variant of the ARM C++ ABI.
1414 TheCXXABI
.set(TargetCXXABI::WatchOS
);
1416 // BOOL should be a real boolean on the new ABI
1417 UseSignedCharForObjCBool
= false;
1419 TheCXXABI
.set(TargetCXXABI::iOS
);
1422 void DarwinARMTargetInfo::getOSDefines(const LangOptions
&Opts
,
1423 const llvm::Triple
&Triple
,
1424 MacroBuilder
&Builder
) const {
1425 getDarwinDefines(Builder
, Opts
, Triple
, PlatformName
, PlatformMinVersion
);
1428 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple
&Triple
,
1429 const TargetOptions
&Opts
)
1430 : ARMleTargetInfo(llvm::Triple("armv7", Triple
.getVendorName(),
1432 Triple
.getEnvironmentName()),
1434 IsRenderScriptTarget
= true;
1435 LongWidth
= LongAlign
= 64;
1438 void RenderScript32TargetInfo::getTargetDefines(const LangOptions
&Opts
,
1439 MacroBuilder
&Builder
) const {
1440 Builder
.defineMacro("__RENDERSCRIPT__");
1441 ARMleTargetInfo::getTargetDefines(Opts
, Builder
);