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 IsFreeBSD
= Triple
.isOSFreeBSD();
258 bool IsOpenBSD
= Triple
.isOSOpenBSD();
259 bool IsNetBSD
= Triple
.isOSNetBSD();
261 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
262 // environment where size_t is `unsigned long` rather than `unsigned int`
264 PtrDiffType
= IntPtrType
=
265 (Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO() || IsOpenBSD
||
270 SizeType
= (Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO() || IsOpenBSD
||
275 // ptrdiff_t is inconsistent on Darwin
276 if ((Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO()) &&
277 !Triple
.isWatchABI())
278 PtrDiffType
= SignedInt
;
280 // Cache arch related info.
283 // {} in inline assembly are neon specifiers, not assembly variant
285 NoAsmVariants
= true;
287 // FIXME: This duplicates code from the driver that sets the -target-abi
288 // option - this code is used if -target-abi isn't passed and should
289 // be unified in some way.
290 if (Triple
.isOSBinFormatMachO()) {
291 // The backend is hardwired to assume AAPCS for M-class processors, ensure
292 // the frontend matches that.
293 if (Triple
.getEnvironment() == llvm::Triple::EABI
||
294 Triple
.getOS() == llvm::Triple::UnknownOS
||
295 ArchProfile
== llvm::ARM::ProfileKind::M
) {
297 } else if (Triple
.isWatchABI()) {
302 } else if (Triple
.isOSWindows()) {
303 // FIXME: this is invalid for WindowsCE
306 // Select the default based on the platform.
307 switch (Triple
.getEnvironment()) {
308 case llvm::Triple::Android
:
309 case llvm::Triple::GNUEABI
:
310 case llvm::Triple::GNUEABIHF
:
311 case llvm::Triple::MuslEABI
:
312 case llvm::Triple::MuslEABIHF
:
313 case llvm::Triple::OpenHOS
:
314 setABI("aapcs-linux");
316 case llvm::Triple::EABIHF
:
317 case llvm::Triple::EABI
:
320 case llvm::Triple::GNU
:
326 else if (IsFreeBSD
|| IsOpenBSD
)
327 setABI("aapcs-linux");
334 // ARM targets default to using the ARM C++ ABI.
335 TheCXXABI
.set(TargetCXXABI::GenericARM
);
337 // ARM has atomics up to 8 bytes
340 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
341 // as well the default alignment
342 if (IsAAPCS
&& !Triple
.isAndroid())
343 DefaultAlignForAttributeAligned
= MaxVectorAlign
= 64;
345 // Do force alignment of members that follow zero length bitfields. If
346 // the alignment of the zero-length bitfield is greater than the member
347 // that follows it, `bar', `bar' will be aligned as the type of the
348 // zero length bitfield.
349 UseZeroLengthBitfieldAlignment
= true;
351 if (Triple
.getOS() == llvm::Triple::Linux
||
352 Triple
.getOS() == llvm::Triple::UnknownOS
)
353 this->MCountName
= Opts
.EABIVersion
== llvm::EABI::GNU
354 ? "llvm.arm.gnu.eabi.mcount"
357 SoftFloatABI
= llvm::is_contained(Opts
.FeaturesAsWritten
, "+soft-float-abi");
360 StringRef
ARMTargetInfo::getABI() const { return ABI
; }
362 bool ARMTargetInfo::setABI(const std::string
&Name
) {
365 // The defaults (above) are for AAPCS, check if we need to change them.
367 // FIXME: We need support for -meabi... we could just mangle it into the
369 if (Name
== "apcs-gnu" || Name
== "aapcs16") {
370 setABIAPCS(Name
== "aapcs16");
373 if (Name
== "aapcs" || Name
== "aapcs-vfp" || Name
== "aapcs-linux") {
380 bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch
) const {
381 llvm::ARM::ArchKind CPUArch
= llvm::ARM::parseCPUArch(Arch
);
382 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
383 CPUArch
= llvm::ARM::parseArch(getTriple().getArchName());
385 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
388 StringRef ArchFeature
= llvm::ARM::getArchName(CPUArch
);
390 llvm::Triple(ArchFeature
, getTriple().getVendorName(),
391 getTriple().getOSName(), getTriple().getEnvironmentName());
393 StringRef SubArch
= llvm::ARM::getSubArch(CPUArch
);
394 llvm::ARM::ProfileKind Profile
= llvm::ARM::parseArchProfile(SubArch
);
395 return a
.isArmT32() && (Profile
== llvm::ARM::ProfileKind::M
);
398 bool ARMTargetInfo::validateBranchProtection(StringRef Spec
, StringRef Arch
,
399 BranchProtectionInfo
&BPI
,
400 StringRef
&Err
) const {
401 llvm::ARM::ParsedBranchProtection PBP
;
402 if (!llvm::ARM::parseBranchProtection(Spec
, PBP
, Err
))
405 if (!isBranchProtectionSupportedArch(Arch
))
409 llvm::StringSwitch
<LangOptions::SignReturnAddressScopeKind
>(PBP
.Scope
)
410 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf
)
411 .Case("all", LangOptions::SignReturnAddressScopeKind::All
)
412 .Default(LangOptions::SignReturnAddressScopeKind::None
);
414 // Don't care for the sign key, beyond issuing a warning.
415 if (PBP
.Key
== "b_key")
417 BPI
.SignKey
= LangOptions::SignReturnAddressKeyKind::AKey
;
419 BPI
.BranchTargetEnforcement
= PBP
.BranchTargetEnforcement
;
423 // FIXME: This should be based on Arch attributes, not CPU names.
424 bool ARMTargetInfo::initFeatureMap(
425 llvm::StringMap
<bool> &Features
, DiagnosticsEngine
&Diags
, StringRef CPU
,
426 const std::vector
<std::string
> &FeaturesVec
) const {
428 std::string ArchFeature
;
429 std::vector
<StringRef
> TargetFeatures
;
430 llvm::ARM::ArchKind Arch
= llvm::ARM::parseArch(getTriple().getArchName());
432 // Map the base architecture to an appropriate target feature, so we don't
433 // rely on the target triple.
434 llvm::ARM::ArchKind CPUArch
= llvm::ARM::parseCPUArch(CPU
);
435 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
437 if (CPUArch
!= llvm::ARM::ArchKind::INVALID
) {
438 ArchFeature
= ("+" + llvm::ARM::getArchName(CPUArch
)).str();
439 TargetFeatures
.push_back(ArchFeature
);
441 // These features are added to allow arm_neon.h target(..) attributes to
442 // match with both arm and aarch64. We need to add all previous architecture
443 // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
444 // v8.x counterparts are added too. We only need these for anything > 8.0-A.
445 for (llvm::ARM::ArchKind I
= llvm::ARM::convertV9toV8(CPUArch
);
446 I
!= llvm::ARM::ArchKind::INVALID
; --I
)
447 Features
[llvm::ARM::getSubArch(I
)] = true;
448 if (CPUArch
> llvm::ARM::ArchKind::ARMV8A
&&
449 CPUArch
<= llvm::ARM::ArchKind::ARMV9_3A
)
450 for (llvm::ARM::ArchKind I
= CPUArch
; I
!= llvm::ARM::ArchKind::INVALID
;
452 Features
[llvm::ARM::getSubArch(I
)] = true;
455 // get default FPU features
456 llvm::ARM::FPUKind FPUKind
= llvm::ARM::getDefaultFPU(CPU
, Arch
);
457 llvm::ARM::getFPUFeatures(FPUKind
, TargetFeatures
);
459 // get default Extension features
460 uint64_t Extensions
= llvm::ARM::getDefaultExtensions(CPU
, Arch
);
461 llvm::ARM::getExtensionFeatures(Extensions
, TargetFeatures
);
463 for (auto Feature
: TargetFeatures
)
464 if (Feature
[0] == '+')
465 Features
[Feature
.drop_front(1)] = true;
467 // Enable or disable thumb-mode explicitly per function to enable mixed
468 // ARM and Thumb code generation.
470 Features
["thumb-mode"] = true;
472 Features
["thumb-mode"] = false;
474 // Convert user-provided arm and thumb GNU target attributes to
475 // [-|+]thumb-mode target features respectively.
476 std::vector
<std::string
> UpdatedFeaturesVec
;
477 for (const auto &Feature
: FeaturesVec
) {
478 // Skip soft-float-abi; it's something we only use to initialize a bit of
479 // class state, and is otherwise unrecognized.
480 if (Feature
== "+soft-float-abi")
483 StringRef FixedFeature
;
484 if (Feature
== "+arm")
485 FixedFeature
= "-thumb-mode";
486 else if (Feature
== "+thumb")
487 FixedFeature
= "+thumb-mode";
489 FixedFeature
= Feature
;
490 UpdatedFeaturesVec
.push_back(FixedFeature
.str());
493 return TargetInfo::initFeatureMap(Features
, Diags
, CPU
, UpdatedFeaturesVec
);
497 bool ARMTargetInfo::handleTargetFeatures(std::vector
<std::string
> &Features
,
498 DiagnosticsEngine
&Diags
) {
508 // Note that SoftFloatABI is initialized in our constructor.
515 ARMCDECoprocMask
= 0;
517 HasFullBFloat16
= false;
518 FPRegsDisabled
= false;
520 // This does not diagnose illegal cases like having both
521 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
522 for (const auto &Feature
: Features
) {
523 if (Feature
== "+soft-float") {
525 } else if (Feature
== "+vfp2sp" || Feature
== "+vfp2") {
528 if (Feature
== "+vfp2")
530 } else if (Feature
== "+vfp3sp" || Feature
== "+vfp3d16sp" ||
531 Feature
== "+vfp3" || Feature
== "+vfp3d16") {
534 if (Feature
== "+vfp3" || Feature
== "+vfp3d16")
536 } else if (Feature
== "+vfp4sp" || Feature
== "+vfp4d16sp" ||
537 Feature
== "+vfp4" || Feature
== "+vfp4d16") {
539 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
540 if (Feature
== "+vfp4" || Feature
== "+vfp4d16")
542 } else if (Feature
== "+fp-armv8sp" || Feature
== "+fp-armv8d16sp" ||
543 Feature
== "+fp-armv8" || Feature
== "+fp-armv8d16") {
545 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
546 if (Feature
== "+fp-armv8" || Feature
== "+fp-armv8d16")
548 } else if (Feature
== "+neon") {
551 } else if (Feature
== "+hwdiv") {
553 } else if (Feature
== "+hwdiv-arm") {
555 } else if (Feature
== "+crc") {
557 } else if (Feature
== "+crypto") {
559 } else if (Feature
== "+sha2") {
561 } else if (Feature
== "+aes") {
563 } else if (Feature
== "+dsp") {
565 } else if (Feature
== "+fp64") {
567 } else if (Feature
== "+8msecext") {
568 if (CPUProfile
!= "M" || ArchVersion
!= 8) {
569 Diags
.Report(diag::err_target_unsupported_mcmse
) << CPU
;
572 } else if (Feature
== "+strict-align") {
574 } else if (Feature
== "+fp16") {
576 } else if (Feature
== "+fullfp16") {
577 HasLegalHalfType
= true;
578 } else if (Feature
== "+dotprod") {
580 } else if (Feature
== "+mve") {
582 } else if (Feature
== "+mve.fp") {
583 HasLegalHalfType
= true;
585 MVE
|= MVE_INT
| MVE_FP
;
586 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
587 } else if (Feature
== "+i8mm") {
589 } else if (Feature
.size() == strlen("+cdecp0") && Feature
>= "+cdecp0" &&
590 Feature
<= "+cdecp7") {
591 unsigned Coproc
= Feature
.back() - '0';
592 ARMCDECoprocMask
|= (1U << Coproc
);
593 } else if (Feature
== "+bf16") {
595 } else if (Feature
== "-fpregs") {
596 FPRegsDisabled
= true;
597 } else if (Feature
== "+pacbti") {
600 } else if (Feature
== "+fullbf16") {
601 HasFullBFloat16
= true;
605 HalfArgsAndReturns
= true;
607 switch (ArchVersion
) {
609 if (ArchProfile
== llvm::ARM::ProfileKind::M
)
611 else if (ArchKind
== llvm::ARM::ArchKind::ARMV6K
)
612 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
617 if (ArchProfile
== llvm::ARM::ProfileKind::M
)
618 LDREX
= LDREX_W
| LDREX_H
| LDREX_B
;
620 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
624 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
627 if (!(FPU
& NeonFPU
) && FPMath
== FP_Neon
) {
628 Diags
.Report(diag::err_target_unsupported_fpmath
) << "neon";
632 if (FPMath
== FP_Neon
)
633 Features
.push_back("+neonfp");
634 else if (FPMath
== FP_VFP
)
635 Features
.push_back("-neonfp");
640 bool ARMTargetInfo::hasFeature(StringRef Feature
) const {
641 return llvm::StringSwitch
<bool>(Feature
)
643 .Case("aarch32", true)
644 .Case("softfloat", SoftFloat
)
645 .Case("thumb", isThumb())
646 .Case("neon", (FPU
& NeonFPU
) && !SoftFloat
)
647 .Case("vfp", FPU
&& !SoftFloat
)
648 .Case("hwdiv", HWDiv
& HWDivThumb
)
649 .Case("hwdiv-arm", HWDiv
& HWDivARM
)
650 .Case("mve", hasMVE())
654 bool ARMTargetInfo::hasBFloat16Type() const {
655 // The __bf16 type is generally available so long as we have any fp registers.
656 return HasBFloat16
|| (FPU
&& !SoftFloat
);
659 bool ARMTargetInfo::isValidCPUName(StringRef Name
) const {
660 return Name
== "generic" ||
661 llvm::ARM::parseCPUArch(Name
) != llvm::ARM::ArchKind::INVALID
;
664 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl
<StringRef
> &Values
) const {
665 llvm::ARM::fillValidCPUArchList(Values
);
668 bool ARMTargetInfo::setCPU(const std::string
&Name
) {
669 if (Name
!= "generic")
670 setArchInfo(llvm::ARM::parseCPUArch(Name
));
672 if (ArchKind
== llvm::ARM::ArchKind::INVALID
)
679 bool ARMTargetInfo::setFPMath(StringRef Name
) {
680 if (Name
== "neon") {
683 } else if (Name
== "vfp" || Name
== "vfp2" || Name
== "vfp3" ||
691 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions
&Opts
,
692 MacroBuilder
&Builder
) const {
693 Builder
.defineMacro("__ARM_FEATURE_QRDMX", "1");
696 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions
&Opts
,
697 MacroBuilder
&Builder
) const {
698 // Also include the ARMv8.1-A defines
699 getTargetDefinesARMV81A(Opts
, Builder
);
702 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions
&Opts
,
703 MacroBuilder
&Builder
) const {
704 // Also include the ARMv8.2-A defines
705 Builder
.defineMacro("__ARM_FEATURE_COMPLEX", "1");
706 getTargetDefinesARMV82A(Opts
, Builder
);
709 void ARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
710 MacroBuilder
&Builder
) const {
711 // Target identification.
712 Builder
.defineMacro("__arm");
713 Builder
.defineMacro("__arm__");
714 // For bare-metal none-eabi.
715 if (getTriple().getOS() == llvm::Triple::UnknownOS
&&
716 (getTriple().getEnvironment() == llvm::Triple::EABI
||
717 getTriple().getEnvironment() == llvm::Triple::EABIHF
) &&
719 Builder
.defineMacro("_GNU_SOURCE");
722 // Target properties.
723 Builder
.defineMacro("__REGISTER_PREFIX__", "");
725 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
726 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
727 if (getTriple().isWatchABI())
728 Builder
.defineMacro("__ARM_ARCH_7K__", "2");
730 if (!CPUAttr
.empty())
731 Builder
.defineMacro("__ARM_ARCH_" + CPUAttr
+ "__");
733 // ACLE 6.4.1 ARM/Thumb instruction set architecture
734 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
735 Builder
.defineMacro("__ARM_ARCH", Twine(ArchVersion
));
737 if (ArchVersion
>= 8) {
738 // ACLE 6.5.7 Crypto Extension
739 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
740 // feature macros for AES and SHA2
742 Builder
.defineMacro("__ARM_FEATURE_CRYPTO", "1");
744 Builder
.defineMacro("__ARM_FEATURE_SHA2", "1");
746 Builder
.defineMacro("__ARM_FEATURE_AES", "1");
747 // ACLE 6.5.8 CRC32 Extension
749 Builder
.defineMacro("__ARM_FEATURE_CRC32", "1");
750 // ACLE 6.5.10 Numeric Maximum and Minimum
751 Builder
.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
752 // ACLE 6.5.9 Directed Rounding
753 Builder
.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
756 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
757 // is not defined for the M-profile.
758 // NOTE that the default profile is assumed to be 'A'
759 if (CPUProfile
.empty() || ArchProfile
!= llvm::ARM::ProfileKind::M
)
760 Builder
.defineMacro("__ARM_ARCH_ISA_ARM", "1");
762 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
763 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
764 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
765 // v7 and v8 architectures excluding v8-M Baseline.
766 if (supportsThumb2())
767 Builder
.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
768 else if (supportsThumb())
769 Builder
.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
771 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
772 // instruction set such as ARM or Thumb.
773 Builder
.defineMacro("__ARM_32BIT_STATE", "1");
775 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
777 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
778 if (!CPUProfile
.empty())
779 Builder
.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile
+ "'");
781 // ACLE 6.4.3 Unaligned access supported in hardware
783 Builder
.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
785 // ACLE 6.4.4 LDREX/STREX
787 Builder
.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX
));
790 if (ArchVersion
== 5 || (ArchVersion
== 6 && CPUProfile
!= "M") ||
792 Builder
.defineMacro("__ARM_FEATURE_CLZ", "1");
794 // ACLE 6.5.1 Hardware Floating Point
796 Builder
.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP
));
799 Builder
.defineMacro("__ARM_ACLE", "200");
801 // FP16 support (we currently only support IEEE format).
802 Builder
.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
803 Builder
.defineMacro("__ARM_FP16_ARGS", "1");
805 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
806 if (ArchVersion
>= 7 && (FPU
& VFP4FPU
))
807 Builder
.defineMacro("__ARM_FEATURE_FMA", "1");
809 // Subtarget options.
811 // FIXME: It's more complicated than this and we don't really support
813 // Windows on ARM does not "support" interworking
814 if (5 <= ArchVersion
&& ArchVersion
<= 8 && !getTriple().isOSWindows())
815 Builder
.defineMacro("__THUMB_INTERWORK__");
817 if (ABI
== "aapcs" || ABI
== "aapcs-linux" || ABI
== "aapcs-vfp") {
818 // Embedded targets on Darwin follow AAPCS, but not EABI.
819 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
820 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
821 Builder
.defineMacro("__ARM_EABI__");
822 Builder
.defineMacro("__ARM_PCS", "1");
825 if ((!SoftFloat
&& !SoftFloatABI
) || ABI
== "aapcs-vfp" || ABI
== "aapcs16")
826 Builder
.defineMacro("__ARM_PCS_VFP", "1");
828 if (SoftFloat
|| (SoftFloatABI
&& !FPU
))
829 Builder
.defineMacro("__SOFTFP__");
831 // ACLE position independent code macros.
833 Builder
.defineMacro("__ARM_ROPI", "1");
835 Builder
.defineMacro("__ARM_RWPI", "1");
837 if (ArchKind
== llvm::ARM::ArchKind::XSCALE
)
838 Builder
.defineMacro("__XSCALE__");
841 Builder
.defineMacro("__THUMBEL__");
842 Builder
.defineMacro("__thumb__");
843 if (supportsThumb2())
844 Builder
.defineMacro("__thumb2__");
847 // ACLE 6.4.9 32-bit SIMD instructions
848 if ((CPUProfile
!= "M" && ArchVersion
>= 6) || (CPUProfile
== "M" && DSP
))
849 Builder
.defineMacro("__ARM_FEATURE_SIMD32", "1");
851 // ACLE 6.4.10 Hardware Integer Divide
852 if (((HWDiv
& HWDivThumb
) && isThumb()) ||
853 ((HWDiv
& HWDivARM
) && !isThumb())) {
854 Builder
.defineMacro("__ARM_FEATURE_IDIV", "1");
855 Builder
.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
858 // Note, this is always on in gcc, even though it doesn't make sense.
859 Builder
.defineMacro("__APCS_32__");
861 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware
862 // FPU is present. Moreover, the VFP format is the only one supported by
863 // clang. For these reasons, this macro is always defined.
864 Builder
.defineMacro("__VFP_FP__");
866 if (FPUModeIsVFP((FPUMode
)FPU
)) {
868 Builder
.defineMacro("__ARM_VFPV2__");
870 Builder
.defineMacro("__ARM_VFPV3__");
872 Builder
.defineMacro("__ARM_VFPV4__");
874 Builder
.defineMacro("__ARM_FPV5__");
877 // This only gets set when Neon instructions are actually available, unlike
878 // the VFP define, hence the soft float and arch check. This is subtly
879 // different from gcc, we follow the intent which was that it should be set
880 // when Neon instructions are actually available.
881 if ((FPU
& NeonFPU
) && !SoftFloat
&& ArchVersion
>= 7) {
882 Builder
.defineMacro("__ARM_NEON", "1");
883 Builder
.defineMacro("__ARM_NEON__");
884 // current AArch32 NEON implementations do not support double-precision
885 // floating-point even when it is present in VFP.
886 Builder
.defineMacro("__ARM_NEON_FP",
887 "0x" + Twine::utohexstr(HW_FP
& ~HW_FP_DP
));
891 Builder
.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
895 Builder
.defineMacro("__ARM_FEATURE_CDE", "1");
896 Builder
.defineMacro("__ARM_FEATURE_CDE_COPROC",
897 "0x" + Twine::utohexstr(getARMCDECoprocMask()));
900 Builder
.defineMacro("__ARM_SIZEOF_WCHAR_T",
901 Twine(Opts
.WCharSize
? Opts
.WCharSize
: 4));
903 Builder
.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts
.ShortEnums
? "1" : "4");
906 if (ArchVersion
== 8 && ArchProfile
== llvm::ARM::ProfileKind::M
)
907 Builder
.defineMacro("__ARM_FEATURE_CMSE", Opts
.Cmse
? "3" : "1");
909 if (ArchVersion
>= 6 && CPUAttr
!= "6M" && CPUAttr
!= "8M_BASE") {
910 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
911 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
912 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
913 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
916 // ACLE 6.4.7 DSP instructions
918 Builder
.defineMacro("__ARM_FEATURE_DSP", "1");
921 // ACLE 6.4.8 Saturation instructions
923 if ((ArchVersion
== 6 && CPUProfile
!= "M") || ArchVersion
> 6) {
924 Builder
.defineMacro("__ARM_FEATURE_SAT", "1");
928 // ACLE 6.4.6 Q (saturation) flag
930 Builder
.defineMacro("__ARM_FEATURE_QBIT", "1");
932 if (Opts
.UnsafeFPMath
)
933 Builder
.defineMacro("__ARM_FP_FAST", "1");
935 // Armv8.2-A FP16 vector intrinsic
936 if ((FPU
& NeonFPU
) && HasLegalHalfType
)
937 Builder
.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
939 // Armv8.2-A FP16 scalar intrinsics
940 if (HasLegalHalfType
)
941 Builder
.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
943 // Armv8.2-A dot product intrinsics
945 Builder
.defineMacro("__ARM_FEATURE_DOTPROD", "1");
948 Builder
.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
951 Builder
.defineMacro("__ARM_FEATURE_PAUTH", "1");
954 Builder
.defineMacro("__ARM_FEATURE_BTI", "1");
957 Builder
.defineMacro("__ARM_FEATURE_BF16", "1");
958 Builder
.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
959 Builder
.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
962 if (Opts
.BranchTargetEnforcement
)
963 Builder
.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
965 if (Opts
.hasSignReturnAddress()) {
967 if (Opts
.isSignReturnAddressScopeAll())
969 Builder
.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value
));
975 case llvm::ARM::ArchKind::ARMV8_1A
:
976 getTargetDefinesARMV81A(Opts
, Builder
);
978 case llvm::ARM::ArchKind::ARMV8_2A
:
979 getTargetDefinesARMV82A(Opts
, Builder
);
981 case llvm::ARM::ArchKind::ARMV8_3A
:
982 case llvm::ARM::ArchKind::ARMV8_4A
:
983 case llvm::ARM::ArchKind::ARMV8_5A
:
984 case llvm::ARM::ArchKind::ARMV8_6A
:
985 case llvm::ARM::ArchKind::ARMV8_7A
:
986 case llvm::ARM::ArchKind::ARMV8_8A
:
987 case llvm::ARM::ArchKind::ARMV8_9A
:
988 case llvm::ARM::ArchKind::ARMV9A
:
989 case llvm::ARM::ArchKind::ARMV9_1A
:
990 case llvm::ARM::ArchKind::ARMV9_2A
:
991 case llvm::ARM::ArchKind::ARMV9_3A
:
992 case llvm::ARM::ArchKind::ARMV9_4A
:
993 getTargetDefinesARMV83A(Opts
, Builder
);
998 static constexpr Builtin::Info BuiltinInfo
[] = {
999 #define BUILTIN(ID, TYPE, ATTRS) \
1000 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1001 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1002 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1003 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1004 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1005 #include "clang/Basic/BuiltinsNEON.def"
1007 #define BUILTIN(ID, TYPE, ATTRS) \
1008 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1009 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
1010 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
1011 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1012 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1013 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1014 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1015 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
1016 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
1017 #include "clang/Basic/BuiltinsARM.def"
1020 ArrayRef
<Builtin::Info
> ARMTargetInfo::getTargetBuiltins() const {
1021 return llvm::ArrayRef(BuiltinInfo
,
1022 clang::ARM::LastTSBuiltin
- Builtin::FirstTSBuiltin
);
1025 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
1026 TargetInfo::BuiltinVaListKind
ARMTargetInfo::getBuiltinVaListKind() const {
1028 ? AAPCSABIBuiltinVaList
1029 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
1030 : TargetInfo::VoidPtrBuiltinVaList
);
1033 const char *const ARMTargetInfo::GCCRegNames
[] = {
1034 // Integer registers
1035 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1036 "r12", "sp", "lr", "pc",
1039 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1040 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1041 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1044 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1045 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1046 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1049 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1050 "q12", "q13", "q14", "q15"};
1052 ArrayRef
<const char *> ARMTargetInfo::getGCCRegNames() const {
1053 return llvm::ArrayRef(GCCRegNames
);
1056 const TargetInfo::GCCRegAlias
ARMTargetInfo::GCCRegAliases
[] = {
1057 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
1058 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
1059 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1060 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
1061 // The S, D and Q registers overlap, but aren't really aliases; we
1062 // don't want to substitute one of these for a different-sized one.
1065 ArrayRef
<TargetInfo::GCCRegAlias
> ARMTargetInfo::getGCCRegAliases() const {
1066 return llvm::ArrayRef(GCCRegAliases
);
1069 bool ARMTargetInfo::validateAsmConstraint(
1070 const char *&Name
, TargetInfo::ConstraintInfo
&Info
) const {
1074 case 'l': // r0-r7 if thumb, r0-r15 if ARM
1075 Info
.setAllowsRegister();
1077 case 'h': // r8-r15, thumb only
1079 Info
.setAllowsRegister();
1083 case 's': // An integer constant, but allowing only relocatable values.
1085 case 't': // s0-s31, d0-d31, or q0-q15
1086 case 'w': // s0-s15, d0-d7, or q0-q3
1087 case 'x': // s0-s31, d0-d15, or q0-q7
1090 Info
.setAllowsRegister();
1092 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1093 // only available in ARMv6T2 and above
1094 if (CPUAttr
.equals("6T2") || ArchVersion
>= 7) {
1095 Info
.setRequiresImmediate(0, 65535);
1101 if (!supportsThumb2())
1102 Info
.setRequiresImmediate(0, 255);
1104 // FIXME: should check if immediate value would be valid for a Thumb2
1105 // data-processing instruction
1106 Info
.setRequiresImmediate();
1108 // FIXME: should check if immediate value would be valid for an ARM
1109 // data-processing instruction
1110 Info
.setRequiresImmediate();
1113 if (isThumb() && !supportsThumb2())
1114 Info
.setRequiresImmediate(-255, -1);
1116 Info
.setRequiresImmediate(-4095, 4095);
1120 if (!supportsThumb2())
1121 // FIXME: should check if immediate value can be obtained from shifting
1122 // a value between 0 and 255 left by any amount
1123 Info
.setRequiresImmediate();
1125 // FIXME: should check if immediate value would be valid for a Thumb2
1126 // data-processing instruction when inverted
1127 Info
.setRequiresImmediate();
1129 // FIXME: should check if immediate value would be valid for an ARM
1130 // data-processing instruction when inverted
1131 Info
.setRequiresImmediate();
1135 if (!supportsThumb2())
1136 Info
.setRequiresImmediate(-7, 7);
1138 // FIXME: should check if immediate value would be valid for a Thumb2
1139 // data-processing instruction when negated
1140 Info
.setRequiresImmediate();
1142 // FIXME: should check if immediate value would be valid for an ARM
1143 // data-processing instruction when negated
1144 Info
.setRequiresImmediate();
1147 if (isThumb() && !supportsThumb2())
1148 // FIXME: should check if immediate value is a multiple of 4 between 0 and
1150 Info
.setRequiresImmediate();
1152 // FIXME: should check if immediate value is a power of two or a integer
1154 Info
.setRequiresImmediate();
1158 if (isThumb() && !supportsThumb2()) {
1159 Info
.setRequiresImmediate(0, 31);
1165 if (isThumb() && !supportsThumb2()) {
1166 // FIXME: should check if immediate value is a multiple of 4 between -508
1168 Info
.setRequiresImmediate();
1172 case 'Q': // A memory address that is a single base register.
1173 Info
.setAllowsMemory();
1179 case 'e': // Even general-purpose register
1180 case 'o': // Odd general-purpose register
1181 Info
.setAllowsRegister();
1186 case 'U': // a memory reference...
1188 case 'q': // ...ARMV4 ldrsb
1189 case 'v': // ...VFP load/store (reg+constant offset)
1190 case 'y': // ...iWMMXt load/store
1191 case 't': // address valid for load/store opaque types wider
1193 case 'n': // valid address for Neon doubleword vector load/store
1194 case 'm': // valid address for Neon element and structure load/store
1195 case 's': // valid address for non-offset loads/stores of quad-word
1196 // values in four ARM registers
1197 Info
.setAllowsMemory();
1206 std::string
ARMTargetInfo::convertConstraint(const char *&Constraint
) const {
1208 switch (*Constraint
) {
1209 case 'U': // Two-character constraint; add "^" hint for later parsing.
1211 R
= std::string("^") + std::string(Constraint
, 2);
1214 case 'p': // 'p' should be translated to 'r' by default.
1215 R
= std::string("r");
1218 return std::string(1, *Constraint
);
1223 bool ARMTargetInfo::validateConstraintModifier(
1224 StringRef Constraint
, char Modifier
, unsigned Size
,
1225 std::string
&SuggestedModifier
) const {
1226 bool isOutput
= (Constraint
[0] == '=');
1227 bool isInOut
= (Constraint
[0] == '+');
1229 // Strip off constraint modifiers.
1230 while (Constraint
[0] == '=' || Constraint
[0] == '+' || Constraint
[0] == '&')
1231 Constraint
= Constraint
.substr(1);
1233 switch (Constraint
[0]) {
1239 return (isInOut
|| isOutput
|| Size
<= 64);
1241 // A register of size 32 cannot fit a vector type.
1249 std::string_view
ARMTargetInfo::getClobbers() const {
1250 // FIXME: Is this really right?
1254 TargetInfo::CallingConvCheckResult
1255 ARMTargetInfo::checkCallingConvention(CallingConv CC
) const {
1261 case CC_OpenCLKernel
:
1264 return CCCR_Warning
;
1268 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo
) const {
1276 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1278 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple
&Triple
,
1279 const TargetOptions
&Opts
)
1280 : ARMTargetInfo(Triple
, Opts
) {}
1282 void ARMleTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1283 MacroBuilder
&Builder
) const {
1284 Builder
.defineMacro("__ARMEL__");
1285 ARMTargetInfo::getTargetDefines(Opts
, Builder
);
1288 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple
&Triple
,
1289 const TargetOptions
&Opts
)
1290 : ARMTargetInfo(Triple
, Opts
) {}
1292 void ARMbeTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1293 MacroBuilder
&Builder
) const {
1294 Builder
.defineMacro("__ARMEB__");
1295 Builder
.defineMacro("__ARM_BIG_ENDIAN");
1296 ARMTargetInfo::getTargetDefines(Opts
, Builder
);
1299 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple
&Triple
,
1300 const TargetOptions
&Opts
)
1301 : WindowsTargetInfo
<ARMleTargetInfo
>(Triple
, Opts
), Triple(Triple
) {
1304 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions
&Opts
,
1305 MacroBuilder
&Builder
) const {
1306 // FIXME: this is invalid for WindowsCE
1307 Builder
.defineMacro("_M_ARM_NT", "1");
1308 Builder
.defineMacro("_M_ARMT", "_M_ARM");
1309 Builder
.defineMacro("_M_THUMB", "_M_ARM");
1311 assert((Triple
.getArch() == llvm::Triple::arm
||
1312 Triple
.getArch() == llvm::Triple::thumb
) &&
1313 "invalid architecture for Windows ARM target info");
1314 unsigned Offset
= Triple
.getArch() == llvm::Triple::arm
? 4 : 6;
1315 Builder
.defineMacro("_M_ARM", Triple
.getArchName().substr(Offset
));
1317 // TODO map the complete set of values
1318 // 31: VFPv3 40: VFPv4
1319 Builder
.defineMacro("_M_ARM_FP", "31");
1322 TargetInfo::BuiltinVaListKind
1323 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1324 return TargetInfo::CharPtrBuiltinVaList
;
1327 TargetInfo::CallingConvCheckResult
1328 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC
) const {
1331 case CC_X86ThisCall
:
1332 case CC_X86FastCall
:
1333 case CC_X86VectorCall
:
1336 case CC_OpenCLKernel
:
1337 case CC_PreserveMost
:
1338 case CC_PreserveAll
:
1343 return CCCR_Warning
;
1347 // Windows ARM + Itanium C++ ABI Target
1348 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1349 const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
1350 : WindowsARMTargetInfo(Triple
, Opts
) {
1351 TheCXXABI
.set(TargetCXXABI::GenericARM
);
1354 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1355 const LangOptions
&Opts
, MacroBuilder
&Builder
) const {
1356 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1358 if (Opts
.MSVCCompat
)
1359 WindowsARMTargetInfo::getVisualStudioDefines(Opts
, Builder
);
1362 // Windows ARM, MS (C++) ABI
1363 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple
&Triple
,
1364 const TargetOptions
&Opts
)
1365 : WindowsARMTargetInfo(Triple
, Opts
) {
1366 TheCXXABI
.set(TargetCXXABI::Microsoft
);
1369 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1370 MacroBuilder
&Builder
) const {
1371 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1372 WindowsARMTargetInfo::getVisualStudioDefines(Opts
, Builder
);
1375 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple
&Triple
,
1376 const TargetOptions
&Opts
)
1377 : WindowsARMTargetInfo(Triple
, Opts
) {
1378 TheCXXABI
.set(TargetCXXABI::GenericARM
);
1381 void MinGWARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1382 MacroBuilder
&Builder
) const {
1383 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1384 Builder
.defineMacro("_ARM_");
1387 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple
&Triple
,
1388 const TargetOptions
&Opts
)
1389 : ARMleTargetInfo(Triple
, Opts
) {
1390 this->WCharType
= TargetInfo::UnsignedShort
;
1391 TLSSupported
= false;
1392 DoubleAlign
= LongLongAlign
= 64;
1393 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1396 void CygwinARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1397 MacroBuilder
&Builder
) const {
1398 ARMleTargetInfo::getTargetDefines(Opts
, Builder
);
1399 Builder
.defineMacro("_ARM_");
1400 Builder
.defineMacro("__CYGWIN__");
1401 Builder
.defineMacro("__CYGWIN32__");
1402 DefineStd(Builder
, "unix", Opts
);
1404 Builder
.defineMacro("_GNU_SOURCE");
1407 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple
&Triple
,
1408 const TargetOptions
&Opts
)
1409 : DarwinTargetInfo
<ARMleTargetInfo
>(Triple
, Opts
) {
1410 HasAlignMac68kSupport
= true;
1411 if (Triple
.isWatchABI()) {
1412 // Darwin on iOS uses a variant of the ARM C++ ABI.
1413 TheCXXABI
.set(TargetCXXABI::WatchOS
);
1415 // BOOL should be a real boolean on the new ABI
1416 UseSignedCharForObjCBool
= false;
1418 TheCXXABI
.set(TargetCXXABI::iOS
);
1421 void DarwinARMTargetInfo::getOSDefines(const LangOptions
&Opts
,
1422 const llvm::Triple
&Triple
,
1423 MacroBuilder
&Builder
) const {
1424 getDarwinDefines(Builder
, Opts
, Triple
, PlatformName
, PlatformMinVersion
);
1427 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple
&Triple
,
1428 const TargetOptions
&Opts
)
1429 : ARMleTargetInfo(llvm::Triple("armv7", Triple
.getVendorName(),
1431 Triple
.getEnvironmentName()),
1433 IsRenderScriptTarget
= true;
1434 LongWidth
= LongAlign
= 64;
1437 void RenderScript32TargetInfo::getTargetDefines(const LangOptions
&Opts
,
1438 MacroBuilder
&Builder
) const {
1439 Builder
.defineMacro("__RENDERSCRIPT__");
1440 ARMleTargetInfo::getTargetDefines(Opts
, Builder
);