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::ARMV9A
:
219 case llvm::ARM::ArchKind::ARMV9_1A
:
221 case llvm::ARM::ArchKind::ARMV9_2A
:
223 case llvm::ARM::ArchKind::ARMV9_3A
:
225 case llvm::ARM::ArchKind::ARMV8MBaseline
:
227 case llvm::ARM::ArchKind::ARMV8MMainline
:
229 case llvm::ARM::ArchKind::ARMV8R
:
231 case llvm::ARM::ArchKind::ARMV8_1MMainline
:
236 StringRef
ARMTargetInfo::getCPUProfile() const {
237 switch (ArchProfile
) {
238 case llvm::ARM::ProfileKind::A
:
240 case llvm::ARM::ProfileKind::R
:
242 case llvm::ARM::ProfileKind::M
:
249 ARMTargetInfo::ARMTargetInfo(const llvm::Triple
&Triple
,
250 const TargetOptions
&Opts
)
251 : TargetInfo(Triple
), FPMath(FP_Default
), IsAAPCS(true), LDREX(0),
253 bool IsOpenBSD
= Triple
.isOSOpenBSD();
254 bool IsNetBSD
= Triple
.isOSNetBSD();
256 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
257 // environment where size_t is `unsigned long` rather than `unsigned int`
259 PtrDiffType
= IntPtrType
=
260 (Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO() || IsOpenBSD
||
265 SizeType
= (Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO() || IsOpenBSD
||
270 // ptrdiff_t is inconsistent on Darwin
271 if ((Triple
.isOSDarwin() || Triple
.isOSBinFormatMachO()) &&
272 !Triple
.isWatchABI())
273 PtrDiffType
= SignedInt
;
275 // Cache arch related info.
278 // {} in inline assembly are neon specifiers, not assembly variant
280 NoAsmVariants
= true;
282 // FIXME: This duplicates code from the driver that sets the -target-abi
283 // option - this code is used if -target-abi isn't passed and should
284 // be unified in some way.
285 if (Triple
.isOSBinFormatMachO()) {
286 // The backend is hardwired to assume AAPCS for M-class processors, ensure
287 // the frontend matches that.
288 if (Triple
.getEnvironment() == llvm::Triple::EABI
||
289 Triple
.getOS() == llvm::Triple::UnknownOS
||
290 ArchProfile
== llvm::ARM::ProfileKind::M
) {
292 } else if (Triple
.isWatchABI()) {
297 } else if (Triple
.isOSWindows()) {
298 // FIXME: this is invalid for WindowsCE
301 // Select the default based on the platform.
302 switch (Triple
.getEnvironment()) {
303 case llvm::Triple::Android
:
304 case llvm::Triple::GNUEABI
:
305 case llvm::Triple::GNUEABIHF
:
306 case llvm::Triple::MuslEABI
:
307 case llvm::Triple::MuslEABIHF
:
308 setABI("aapcs-linux");
310 case llvm::Triple::EABIHF
:
311 case llvm::Triple::EABI
:
314 case llvm::Triple::GNU
:
321 setABI("aapcs-linux");
328 // ARM targets default to using the ARM C++ ABI.
329 TheCXXABI
.set(TargetCXXABI::GenericARM
);
331 // ARM has atomics up to 8 bytes
334 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
335 // as well the default alignment
336 if (IsAAPCS
&& !Triple
.isAndroid())
337 DefaultAlignForAttributeAligned
= MaxVectorAlign
= 64;
339 // Do force alignment of members that follow zero length bitfields. If
340 // the alignment of the zero-length bitfield is greater than the member
341 // that follows it, `bar', `bar' will be aligned as the type of the
342 // zero length bitfield.
343 UseZeroLengthBitfieldAlignment
= true;
345 if (Triple
.getOS() == llvm::Triple::Linux
||
346 Triple
.getOS() == llvm::Triple::UnknownOS
)
347 this->MCountName
= Opts
.EABIVersion
== llvm::EABI::GNU
348 ? "llvm.arm.gnu.eabi.mcount"
351 SoftFloatABI
= llvm::is_contained(Opts
.FeaturesAsWritten
, "+soft-float-abi");
354 StringRef
ARMTargetInfo::getABI() const { return ABI
; }
356 bool ARMTargetInfo::setABI(const std::string
&Name
) {
359 // The defaults (above) are for AAPCS, check if we need to change them.
361 // FIXME: We need support for -meabi... we could just mangle it into the
363 if (Name
== "apcs-gnu" || Name
== "aapcs16") {
364 setABIAPCS(Name
== "aapcs16");
367 if (Name
== "aapcs" || Name
== "aapcs-vfp" || Name
== "aapcs-linux") {
374 bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch
) const {
375 llvm::ARM::ArchKind CPUArch
= llvm::ARM::parseCPUArch(Arch
);
376 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
377 CPUArch
= llvm::ARM::parseArch(getTriple().getArchName());
379 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
382 StringRef ArchFeature
= llvm::ARM::getArchName(CPUArch
);
384 llvm::Triple(ArchFeature
, getTriple().getVendorName(),
385 getTriple().getOSName(), getTriple().getEnvironmentName());
387 StringRef SubArch
= llvm::ARM::getSubArch(CPUArch
);
388 llvm::ARM::ProfileKind Profile
= llvm::ARM::parseArchProfile(SubArch
);
389 return a
.isArmT32() && (Profile
== llvm::ARM::ProfileKind::M
);
392 bool ARMTargetInfo::validateBranchProtection(StringRef Spec
, StringRef Arch
,
393 BranchProtectionInfo
&BPI
,
394 StringRef
&Err
) const {
395 llvm::ARM::ParsedBranchProtection PBP
;
396 if (!llvm::ARM::parseBranchProtection(Spec
, PBP
, Err
))
399 if (!isBranchProtectionSupportedArch(Arch
))
403 llvm::StringSwitch
<LangOptions::SignReturnAddressScopeKind
>(PBP
.Scope
)
404 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf
)
405 .Case("all", LangOptions::SignReturnAddressScopeKind::All
)
406 .Default(LangOptions::SignReturnAddressScopeKind::None
);
408 // Don't care for the sign key, beyond issuing a warning.
409 if (PBP
.Key
== "b_key")
411 BPI
.SignKey
= LangOptions::SignReturnAddressKeyKind::AKey
;
413 BPI
.BranchTargetEnforcement
= PBP
.BranchTargetEnforcement
;
417 // FIXME: This should be based on Arch attributes, not CPU names.
418 bool ARMTargetInfo::initFeatureMap(
419 llvm::StringMap
<bool> &Features
, DiagnosticsEngine
&Diags
, StringRef CPU
,
420 const std::vector
<std::string
> &FeaturesVec
) const {
422 std::string ArchFeature
;
423 std::vector
<StringRef
> TargetFeatures
;
424 llvm::ARM::ArchKind Arch
= llvm::ARM::parseArch(getTriple().getArchName());
426 // Map the base architecture to an appropriate target feature, so we don't
427 // rely on the target triple.
428 llvm::ARM::ArchKind CPUArch
= llvm::ARM::parseCPUArch(CPU
);
429 if (CPUArch
== llvm::ARM::ArchKind::INVALID
)
431 if (CPUArch
!= llvm::ARM::ArchKind::INVALID
) {
432 ArchFeature
= ("+" + llvm::ARM::getArchName(CPUArch
)).str();
433 TargetFeatures
.push_back(ArchFeature
);
436 // get default FPU features
437 unsigned FPUKind
= llvm::ARM::getDefaultFPU(CPU
, Arch
);
438 llvm::ARM::getFPUFeatures(FPUKind
, TargetFeatures
);
440 // get default Extension features
441 uint64_t Extensions
= llvm::ARM::getDefaultExtensions(CPU
, Arch
);
442 llvm::ARM::getExtensionFeatures(Extensions
, TargetFeatures
);
444 for (auto Feature
: TargetFeatures
)
445 if (Feature
[0] == '+')
446 Features
[Feature
.drop_front(1)] = true;
448 // Enable or disable thumb-mode explicitly per function to enable mixed
449 // ARM and Thumb code generation.
451 Features
["thumb-mode"] = true;
453 Features
["thumb-mode"] = false;
455 // Convert user-provided arm and thumb GNU target attributes to
456 // [-|+]thumb-mode target features respectively.
457 std::vector
<std::string
> UpdatedFeaturesVec
;
458 for (const auto &Feature
: FeaturesVec
) {
459 // Skip soft-float-abi; it's something we only use to initialize a bit of
460 // class state, and is otherwise unrecognized.
461 if (Feature
== "+soft-float-abi")
464 StringRef FixedFeature
;
465 if (Feature
== "+arm")
466 FixedFeature
= "-thumb-mode";
467 else if (Feature
== "+thumb")
468 FixedFeature
= "+thumb-mode";
470 FixedFeature
= Feature
;
471 UpdatedFeaturesVec
.push_back(FixedFeature
.str());
474 return TargetInfo::initFeatureMap(Features
, Diags
, CPU
, UpdatedFeaturesVec
);
478 bool ARMTargetInfo::handleTargetFeatures(std::vector
<std::string
> &Features
,
479 DiagnosticsEngine
&Diags
) {
489 // Note that SoftFloatABI is initialized in our constructor.
496 ARMCDECoprocMask
= 0;
498 FPRegsDisabled
= false;
500 // This does not diagnose illegal cases like having both
501 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
502 for (const auto &Feature
: Features
) {
503 if (Feature
== "+soft-float") {
505 } else if (Feature
== "+vfp2sp" || Feature
== "+vfp2") {
508 if (Feature
== "+vfp2")
510 } else if (Feature
== "+vfp3sp" || Feature
== "+vfp3d16sp" ||
511 Feature
== "+vfp3" || Feature
== "+vfp3d16") {
514 if (Feature
== "+vfp3" || Feature
== "+vfp3d16")
516 } else if (Feature
== "+vfp4sp" || Feature
== "+vfp4d16sp" ||
517 Feature
== "+vfp4" || Feature
== "+vfp4d16") {
519 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
520 if (Feature
== "+vfp4" || Feature
== "+vfp4d16")
522 } else if (Feature
== "+fp-armv8sp" || Feature
== "+fp-armv8d16sp" ||
523 Feature
== "+fp-armv8" || Feature
== "+fp-armv8d16") {
525 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
526 if (Feature
== "+fp-armv8" || Feature
== "+fp-armv8d16")
528 } else if (Feature
== "+neon") {
531 } else if (Feature
== "+hwdiv") {
533 } else if (Feature
== "+hwdiv-arm") {
535 } else if (Feature
== "+crc") {
537 } else if (Feature
== "+crypto") {
539 } else if (Feature
== "+sha2") {
541 } else if (Feature
== "+aes") {
543 } else if (Feature
== "+dsp") {
545 } else if (Feature
== "+fp64") {
547 } else if (Feature
== "+8msecext") {
548 if (CPUProfile
!= "M" || ArchVersion
!= 8) {
549 Diags
.Report(diag::err_target_unsupported_mcmse
) << CPU
;
552 } else if (Feature
== "+strict-align") {
554 } else if (Feature
== "+fp16") {
556 } else if (Feature
== "+fullfp16") {
557 HasLegalHalfType
= true;
558 } else if (Feature
== "+dotprod") {
560 } else if (Feature
== "+mve") {
562 } else if (Feature
== "+mve.fp") {
563 HasLegalHalfType
= true;
565 MVE
|= MVE_INT
| MVE_FP
;
566 HW_FP
|= HW_FP_SP
| HW_FP_HP
;
567 } else if (Feature
== "+i8mm") {
569 } else if (Feature
.size() == strlen("+cdecp0") && Feature
>= "+cdecp0" &&
570 Feature
<= "+cdecp7") {
571 unsigned Coproc
= Feature
.back() - '0';
572 ARMCDECoprocMask
|= (1U << Coproc
);
573 } else if (Feature
== "+bf16") {
575 } else if (Feature
== "-fpregs") {
576 FPRegsDisabled
= true;
577 } else if (Feature
== "+pacbti") {
583 switch (ArchVersion
) {
585 if (ArchProfile
== llvm::ARM::ProfileKind::M
)
587 else if (ArchKind
== llvm::ARM::ArchKind::ARMV6K
)
588 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
593 if (ArchProfile
== llvm::ARM::ProfileKind::M
)
594 LDREX
= LDREX_W
| LDREX_H
| LDREX_B
;
596 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
600 LDREX
= LDREX_D
| LDREX_W
| LDREX_H
| LDREX_B
;
603 if (!(FPU
& NeonFPU
) && FPMath
== FP_Neon
) {
604 Diags
.Report(diag::err_target_unsupported_fpmath
) << "neon";
608 if (FPMath
== FP_Neon
)
609 Features
.push_back("+neonfp");
610 else if (FPMath
== FP_VFP
)
611 Features
.push_back("-neonfp");
616 bool ARMTargetInfo::hasFeature(StringRef Feature
) const {
617 return llvm::StringSwitch
<bool>(Feature
)
619 .Case("aarch32", true)
620 .Case("softfloat", SoftFloat
)
621 .Case("thumb", isThumb())
622 .Case("neon", (FPU
& NeonFPU
) && !SoftFloat
)
623 .Case("vfp", FPU
&& !SoftFloat
)
624 .Case("hwdiv", HWDiv
& HWDivThumb
)
625 .Case("hwdiv-arm", HWDiv
& HWDivARM
)
626 .Case("mve", hasMVE())
630 bool ARMTargetInfo::hasBFloat16Type() const {
631 return HasBFloat16
&& !SoftFloat
;
634 bool ARMTargetInfo::isValidCPUName(StringRef Name
) const {
635 return Name
== "generic" ||
636 llvm::ARM::parseCPUArch(Name
) != llvm::ARM::ArchKind::INVALID
;
639 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl
<StringRef
> &Values
) const {
640 llvm::ARM::fillValidCPUArchList(Values
);
643 bool ARMTargetInfo::setCPU(const std::string
&Name
) {
644 if (Name
!= "generic")
645 setArchInfo(llvm::ARM::parseCPUArch(Name
));
647 if (ArchKind
== llvm::ARM::ArchKind::INVALID
)
654 bool ARMTargetInfo::setFPMath(StringRef Name
) {
655 if (Name
== "neon") {
658 } else if (Name
== "vfp" || Name
== "vfp2" || Name
== "vfp3" ||
666 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions
&Opts
,
667 MacroBuilder
&Builder
) const {
668 Builder
.defineMacro("__ARM_FEATURE_QRDMX", "1");
671 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions
&Opts
,
672 MacroBuilder
&Builder
) const {
673 // Also include the ARMv8.1-A defines
674 getTargetDefinesARMV81A(Opts
, Builder
);
677 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions
&Opts
,
678 MacroBuilder
&Builder
) const {
679 // Also include the ARMv8.2-A defines
680 Builder
.defineMacro("__ARM_FEATURE_COMPLEX", "1");
681 getTargetDefinesARMV82A(Opts
, Builder
);
684 void ARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
685 MacroBuilder
&Builder
) const {
686 // Target identification.
687 Builder
.defineMacro("__arm");
688 Builder
.defineMacro("__arm__");
689 // For bare-metal none-eabi.
690 if (getTriple().getOS() == llvm::Triple::UnknownOS
&&
691 (getTriple().getEnvironment() == llvm::Triple::EABI
||
692 getTriple().getEnvironment() == llvm::Triple::EABIHF
))
693 Builder
.defineMacro("__ELF__");
695 // Target properties.
696 Builder
.defineMacro("__REGISTER_PREFIX__", "");
698 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
699 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
700 if (getTriple().isWatchABI())
701 Builder
.defineMacro("__ARM_ARCH_7K__", "2");
703 if (!CPUAttr
.empty())
704 Builder
.defineMacro("__ARM_ARCH_" + CPUAttr
+ "__");
706 // ACLE 6.4.1 ARM/Thumb instruction set architecture
707 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
708 Builder
.defineMacro("__ARM_ARCH", Twine(ArchVersion
));
710 if (ArchVersion
>= 8) {
711 // ACLE 6.5.7 Crypto Extension
712 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
713 // feature macros for AES and SHA2
715 Builder
.defineMacro("__ARM_FEATURE_CRYPTO", "1");
717 Builder
.defineMacro("__ARM_FEATURE_SHA2", "1");
719 Builder
.defineMacro("__ARM_FEATURE_AES", "1");
720 // ACLE 6.5.8 CRC32 Extension
722 Builder
.defineMacro("__ARM_FEATURE_CRC32", "1");
723 // ACLE 6.5.10 Numeric Maximum and Minimum
724 Builder
.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
725 // ACLE 6.5.9 Directed Rounding
726 Builder
.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
729 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
730 // is not defined for the M-profile.
731 // NOTE that the default profile is assumed to be 'A'
732 if (CPUProfile
.empty() || ArchProfile
!= llvm::ARM::ProfileKind::M
)
733 Builder
.defineMacro("__ARM_ARCH_ISA_ARM", "1");
735 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
736 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
737 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
738 // v7 and v8 architectures excluding v8-M Baseline.
739 if (supportsThumb2())
740 Builder
.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
741 else if (supportsThumb())
742 Builder
.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
744 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
745 // instruction set such as ARM or Thumb.
746 Builder
.defineMacro("__ARM_32BIT_STATE", "1");
748 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
750 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
751 if (!CPUProfile
.empty())
752 Builder
.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile
+ "'");
754 // ACLE 6.4.3 Unaligned access supported in hardware
756 Builder
.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
758 // ACLE 6.4.4 LDREX/STREX
760 Builder
.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX
));
763 if (ArchVersion
== 5 || (ArchVersion
== 6 && CPUProfile
!= "M") ||
765 Builder
.defineMacro("__ARM_FEATURE_CLZ", "1");
767 // ACLE 6.5.1 Hardware Floating Point
769 Builder
.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP
));
772 Builder
.defineMacro("__ARM_ACLE", "200");
774 // FP16 support (we currently only support IEEE format).
775 Builder
.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
776 Builder
.defineMacro("__ARM_FP16_ARGS", "1");
778 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
779 if (ArchVersion
>= 7 && (FPU
& VFP4FPU
))
780 Builder
.defineMacro("__ARM_FEATURE_FMA", "1");
782 // Subtarget options.
784 // FIXME: It's more complicated than this and we don't really support
786 // Windows on ARM does not "support" interworking
787 if (5 <= ArchVersion
&& ArchVersion
<= 8 && !getTriple().isOSWindows())
788 Builder
.defineMacro("__THUMB_INTERWORK__");
790 if (ABI
== "aapcs" || ABI
== "aapcs-linux" || ABI
== "aapcs-vfp") {
791 // Embedded targets on Darwin follow AAPCS, but not EABI.
792 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
793 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
794 Builder
.defineMacro("__ARM_EABI__");
795 Builder
.defineMacro("__ARM_PCS", "1");
798 if ((!SoftFloat
&& !SoftFloatABI
) || ABI
== "aapcs-vfp" || ABI
== "aapcs16")
799 Builder
.defineMacro("__ARM_PCS_VFP", "1");
802 Builder
.defineMacro("__SOFTFP__");
804 // ACLE position independent code macros.
806 Builder
.defineMacro("__ARM_ROPI", "1");
808 Builder
.defineMacro("__ARM_RWPI", "1");
810 if (ArchKind
== llvm::ARM::ArchKind::XSCALE
)
811 Builder
.defineMacro("__XSCALE__");
814 Builder
.defineMacro("__THUMBEL__");
815 Builder
.defineMacro("__thumb__");
816 if (supportsThumb2())
817 Builder
.defineMacro("__thumb2__");
820 // ACLE 6.4.9 32-bit SIMD instructions
821 if ((CPUProfile
!= "M" && ArchVersion
>= 6) || (CPUProfile
== "M" && DSP
))
822 Builder
.defineMacro("__ARM_FEATURE_SIMD32", "1");
824 // ACLE 6.4.10 Hardware Integer Divide
825 if (((HWDiv
& HWDivThumb
) && isThumb()) ||
826 ((HWDiv
& HWDivARM
) && !isThumb())) {
827 Builder
.defineMacro("__ARM_FEATURE_IDIV", "1");
828 Builder
.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
831 // Note, this is always on in gcc, even though it doesn't make sense.
832 Builder
.defineMacro("__APCS_32__");
834 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware
835 // FPU is present. Moreover, the VFP format is the only one supported by
836 // clang. For these reasons, this macro is always defined.
837 Builder
.defineMacro("__VFP_FP__");
839 if (FPUModeIsVFP((FPUMode
)FPU
)) {
841 Builder
.defineMacro("__ARM_VFPV2__");
843 Builder
.defineMacro("__ARM_VFPV3__");
845 Builder
.defineMacro("__ARM_VFPV4__");
847 Builder
.defineMacro("__ARM_FPV5__");
850 // This only gets set when Neon instructions are actually available, unlike
851 // the VFP define, hence the soft float and arch check. This is subtly
852 // different from gcc, we follow the intent which was that it should be set
853 // when Neon instructions are actually available.
854 if ((FPU
& NeonFPU
) && !SoftFloat
&& ArchVersion
>= 7) {
855 Builder
.defineMacro("__ARM_NEON", "1");
856 Builder
.defineMacro("__ARM_NEON__");
857 // current AArch32 NEON implementations do not support double-precision
858 // floating-point even when it is present in VFP.
859 Builder
.defineMacro("__ARM_NEON_FP",
860 "0x" + Twine::utohexstr(HW_FP
& ~HW_FP_DP
));
864 Builder
.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
868 Builder
.defineMacro("__ARM_FEATURE_CDE", "1");
869 Builder
.defineMacro("__ARM_FEATURE_CDE_COPROC",
870 "0x" + Twine::utohexstr(getARMCDECoprocMask()));
873 Builder
.defineMacro("__ARM_SIZEOF_WCHAR_T",
874 Twine(Opts
.WCharSize
? Opts
.WCharSize
: 4));
876 Builder
.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts
.ShortEnums
? "1" : "4");
879 if (ArchVersion
== 8 && ArchProfile
== llvm::ARM::ProfileKind::M
)
880 Builder
.defineMacro("__ARM_FEATURE_CMSE", Opts
.Cmse
? "3" : "1");
882 if (ArchVersion
>= 6 && CPUAttr
!= "6M" && CPUAttr
!= "8M_BASE") {
883 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
884 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
885 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
886 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
889 // ACLE 6.4.7 DSP instructions
891 Builder
.defineMacro("__ARM_FEATURE_DSP", "1");
894 // ACLE 6.4.8 Saturation instructions
896 if ((ArchVersion
== 6 && CPUProfile
!= "M") || ArchVersion
> 6) {
897 Builder
.defineMacro("__ARM_FEATURE_SAT", "1");
901 // ACLE 6.4.6 Q (saturation) flag
903 Builder
.defineMacro("__ARM_FEATURE_QBIT", "1");
905 if (Opts
.UnsafeFPMath
)
906 Builder
.defineMacro("__ARM_FP_FAST", "1");
908 // Armv8.2-A FP16 vector intrinsic
909 if ((FPU
& NeonFPU
) && HasLegalHalfType
)
910 Builder
.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
912 // Armv8.2-A FP16 scalar intrinsics
913 if (HasLegalHalfType
)
914 Builder
.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
916 // Armv8.2-A dot product intrinsics
918 Builder
.defineMacro("__ARM_FEATURE_DOTPROD", "1");
921 Builder
.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
924 Builder
.defineMacro("__ARM_FEATURE_PAUTH", "1");
927 Builder
.defineMacro("__ARM_FEATURE_BTI", "1");
930 Builder
.defineMacro("__ARM_FEATURE_BF16", "1");
931 Builder
.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
932 Builder
.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
935 if (Opts
.BranchTargetEnforcement
)
936 Builder
.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
938 if (Opts
.hasSignReturnAddress()) {
940 if (Opts
.isSignReturnAddressScopeAll())
942 Builder
.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value
));
948 case llvm::ARM::ArchKind::ARMV8_1A
:
949 getTargetDefinesARMV81A(Opts
, Builder
);
951 case llvm::ARM::ArchKind::ARMV8_2A
:
952 getTargetDefinesARMV82A(Opts
, Builder
);
954 case llvm::ARM::ArchKind::ARMV8_3A
:
955 case llvm::ARM::ArchKind::ARMV8_4A
:
956 case llvm::ARM::ArchKind::ARMV8_5A
:
957 case llvm::ARM::ArchKind::ARMV8_6A
:
958 case llvm::ARM::ArchKind::ARMV8_7A
:
959 case llvm::ARM::ArchKind::ARMV8_8A
:
960 case llvm::ARM::ArchKind::ARMV9A
:
961 case llvm::ARM::ArchKind::ARMV9_1A
:
962 case llvm::ARM::ArchKind::ARMV9_2A
:
963 case llvm::ARM::ArchKind::ARMV9_3A
:
964 getTargetDefinesARMV83A(Opts
, Builder
);
969 const Builtin::Info
ARMTargetInfo::BuiltinInfo
[] = {
970 #define BUILTIN(ID, TYPE, ATTRS) \
971 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
972 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
973 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
974 #include "clang/Basic/BuiltinsNEON.def"
976 #define BUILTIN(ID, TYPE, ATTRS) \
977 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
978 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
979 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
980 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
981 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
982 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
983 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
984 #include "clang/Basic/BuiltinsARM.def"
987 ArrayRef
<Builtin::Info
> ARMTargetInfo::getTargetBuiltins() const {
988 return llvm::makeArrayRef(BuiltinInfo
, clang::ARM::LastTSBuiltin
-
989 Builtin::FirstTSBuiltin
);
992 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
993 TargetInfo::BuiltinVaListKind
ARMTargetInfo::getBuiltinVaListKind() const {
995 ? AAPCSABIBuiltinVaList
996 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
997 : TargetInfo::VoidPtrBuiltinVaList
);
1000 const char *const ARMTargetInfo::GCCRegNames
[] = {
1001 // Integer registers
1002 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1003 "r12", "sp", "lr", "pc",
1006 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1007 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1008 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1011 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1012 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1013 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1016 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1017 "q12", "q13", "q14", "q15"};
1019 ArrayRef
<const char *> ARMTargetInfo::getGCCRegNames() const {
1020 return llvm::makeArrayRef(GCCRegNames
);
1023 const TargetInfo::GCCRegAlias
ARMTargetInfo::GCCRegAliases
[] = {
1024 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
1025 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
1026 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1027 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
1028 // The S, D and Q registers overlap, but aren't really aliases; we
1029 // don't want to substitute one of these for a different-sized one.
1032 ArrayRef
<TargetInfo::GCCRegAlias
> ARMTargetInfo::getGCCRegAliases() const {
1033 return llvm::makeArrayRef(GCCRegAliases
);
1036 bool ARMTargetInfo::validateAsmConstraint(
1037 const char *&Name
, TargetInfo::ConstraintInfo
&Info
) const {
1041 case 'l': // r0-r7 if thumb, r0-r15 if ARM
1042 Info
.setAllowsRegister();
1044 case 'h': // r8-r15, thumb only
1046 Info
.setAllowsRegister();
1050 case 's': // An integer constant, but allowing only relocatable values.
1052 case 't': // s0-s31, d0-d31, or q0-q15
1053 case 'w': // s0-s15, d0-d7, or q0-q3
1054 case 'x': // s0-s31, d0-d15, or q0-q7
1057 Info
.setAllowsRegister();
1059 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1060 // only available in ARMv6T2 and above
1061 if (CPUAttr
.equals("6T2") || ArchVersion
>= 7) {
1062 Info
.setRequiresImmediate(0, 65535);
1068 if (!supportsThumb2())
1069 Info
.setRequiresImmediate(0, 255);
1071 // FIXME: should check if immediate value would be valid for a Thumb2
1072 // data-processing instruction
1073 Info
.setRequiresImmediate();
1075 // FIXME: should check if immediate value would be valid for an ARM
1076 // data-processing instruction
1077 Info
.setRequiresImmediate();
1080 if (isThumb() && !supportsThumb2())
1081 Info
.setRequiresImmediate(-255, -1);
1083 Info
.setRequiresImmediate(-4095, 4095);
1087 if (!supportsThumb2())
1088 // FIXME: should check if immediate value can be obtained from shifting
1089 // a value between 0 and 255 left by any amount
1090 Info
.setRequiresImmediate();
1092 // FIXME: should check if immediate value would be valid for a Thumb2
1093 // data-processing instruction when inverted
1094 Info
.setRequiresImmediate();
1096 // FIXME: should check if immediate value would be valid for an ARM
1097 // data-processing instruction when inverted
1098 Info
.setRequiresImmediate();
1102 if (!supportsThumb2())
1103 Info
.setRequiresImmediate(-7, 7);
1105 // FIXME: should check if immediate value would be valid for a Thumb2
1106 // data-processing instruction when negated
1107 Info
.setRequiresImmediate();
1109 // FIXME: should check if immediate value would be valid for an ARM
1110 // data-processing instruction when negated
1111 Info
.setRequiresImmediate();
1114 if (isThumb() && !supportsThumb2())
1115 // FIXME: should check if immediate value is a multiple of 4 between 0 and
1117 Info
.setRequiresImmediate();
1119 // FIXME: should check if immediate value is a power of two or a integer
1121 Info
.setRequiresImmediate();
1125 if (isThumb() && !supportsThumb2()) {
1126 Info
.setRequiresImmediate(0, 31);
1132 if (isThumb() && !supportsThumb2()) {
1133 // FIXME: should check if immediate value is a multiple of 4 between -508
1135 Info
.setRequiresImmediate();
1139 case 'Q': // A memory address that is a single base register.
1140 Info
.setAllowsMemory();
1146 case 'e': // Even general-purpose register
1147 case 'o': // Odd general-purpose register
1148 Info
.setAllowsRegister();
1153 case 'U': // a memory reference...
1155 case 'q': // ...ARMV4 ldrsb
1156 case 'v': // ...VFP load/store (reg+constant offset)
1157 case 'y': // ...iWMMXt load/store
1158 case 't': // address valid for load/store opaque types wider
1160 case 'n': // valid address for Neon doubleword vector load/store
1161 case 'm': // valid address for Neon element and structure load/store
1162 case 's': // valid address for non-offset loads/stores of quad-word
1163 // values in four ARM registers
1164 Info
.setAllowsMemory();
1173 std::string
ARMTargetInfo::convertConstraint(const char *&Constraint
) const {
1175 switch (*Constraint
) {
1176 case 'U': // Two-character constraint; add "^" hint for later parsing.
1178 R
= std::string("^") + std::string(Constraint
, 2);
1181 case 'p': // 'p' should be translated to 'r' by default.
1182 R
= std::string("r");
1185 return std::string(1, *Constraint
);
1190 bool ARMTargetInfo::validateConstraintModifier(
1191 StringRef Constraint
, char Modifier
, unsigned Size
,
1192 std::string
&SuggestedModifier
) const {
1193 bool isOutput
= (Constraint
[0] == '=');
1194 bool isInOut
= (Constraint
[0] == '+');
1196 // Strip off constraint modifiers.
1197 while (Constraint
[0] == '=' || Constraint
[0] == '+' || Constraint
[0] == '&')
1198 Constraint
= Constraint
.substr(1);
1200 switch (Constraint
[0]) {
1206 return (isInOut
|| isOutput
|| Size
<= 64);
1208 // A register of size 32 cannot fit a vector type.
1216 const char *ARMTargetInfo::getClobbers() const {
1217 // FIXME: Is this really right?
1221 TargetInfo::CallingConvCheckResult
1222 ARMTargetInfo::checkCallingConvention(CallingConv CC
) const {
1228 case CC_OpenCLKernel
:
1231 return CCCR_Warning
;
1235 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo
) const {
1243 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1245 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple
&Triple
,
1246 const TargetOptions
&Opts
)
1247 : ARMTargetInfo(Triple
, Opts
) {}
1249 void ARMleTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1250 MacroBuilder
&Builder
) const {
1251 Builder
.defineMacro("__ARMEL__");
1252 ARMTargetInfo::getTargetDefines(Opts
, Builder
);
1255 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple
&Triple
,
1256 const TargetOptions
&Opts
)
1257 : ARMTargetInfo(Triple
, Opts
) {}
1259 void ARMbeTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1260 MacroBuilder
&Builder
) const {
1261 Builder
.defineMacro("__ARMEB__");
1262 Builder
.defineMacro("__ARM_BIG_ENDIAN");
1263 ARMTargetInfo::getTargetDefines(Opts
, Builder
);
1266 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple
&Triple
,
1267 const TargetOptions
&Opts
)
1268 : WindowsTargetInfo
<ARMleTargetInfo
>(Triple
, Opts
), Triple(Triple
) {
1271 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions
&Opts
,
1272 MacroBuilder
&Builder
) const {
1273 // FIXME: this is invalid for WindowsCE
1274 Builder
.defineMacro("_M_ARM_NT", "1");
1275 Builder
.defineMacro("_M_ARMT", "_M_ARM");
1276 Builder
.defineMacro("_M_THUMB", "_M_ARM");
1278 assert((Triple
.getArch() == llvm::Triple::arm
||
1279 Triple
.getArch() == llvm::Triple::thumb
) &&
1280 "invalid architecture for Windows ARM target info");
1281 unsigned Offset
= Triple
.getArch() == llvm::Triple::arm
? 4 : 6;
1282 Builder
.defineMacro("_M_ARM", Triple
.getArchName().substr(Offset
));
1284 // TODO map the complete set of values
1285 // 31: VFPv3 40: VFPv4
1286 Builder
.defineMacro("_M_ARM_FP", "31");
1289 TargetInfo::BuiltinVaListKind
1290 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1291 return TargetInfo::CharPtrBuiltinVaList
;
1294 TargetInfo::CallingConvCheckResult
1295 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC
) const {
1298 case CC_X86ThisCall
:
1299 case CC_X86FastCall
:
1300 case CC_X86VectorCall
:
1303 case CC_OpenCLKernel
:
1304 case CC_PreserveMost
:
1305 case CC_PreserveAll
:
1310 return CCCR_Warning
;
1314 // Windows ARM + Itanium C++ ABI Target
1315 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1316 const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
1317 : WindowsARMTargetInfo(Triple
, Opts
) {
1318 TheCXXABI
.set(TargetCXXABI::GenericARM
);
1321 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1322 const LangOptions
&Opts
, MacroBuilder
&Builder
) const {
1323 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1325 if (Opts
.MSVCCompat
)
1326 WindowsARMTargetInfo::getVisualStudioDefines(Opts
, Builder
);
1329 // Windows ARM, MS (C++) ABI
1330 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple
&Triple
,
1331 const TargetOptions
&Opts
)
1332 : WindowsARMTargetInfo(Triple
, Opts
) {
1333 TheCXXABI
.set(TargetCXXABI::Microsoft
);
1336 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1337 MacroBuilder
&Builder
) const {
1338 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1339 WindowsARMTargetInfo::getVisualStudioDefines(Opts
, Builder
);
1342 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple
&Triple
,
1343 const TargetOptions
&Opts
)
1344 : WindowsARMTargetInfo(Triple
, Opts
) {
1345 TheCXXABI
.set(TargetCXXABI::GenericARM
);
1348 void MinGWARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1349 MacroBuilder
&Builder
) const {
1350 WindowsARMTargetInfo::getTargetDefines(Opts
, Builder
);
1351 Builder
.defineMacro("_ARM_");
1354 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple
&Triple
,
1355 const TargetOptions
&Opts
)
1356 : ARMleTargetInfo(Triple
, Opts
) {
1357 this->WCharType
= TargetInfo::UnsignedShort
;
1358 TLSSupported
= false;
1359 DoubleAlign
= LongLongAlign
= 64;
1360 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1363 void CygwinARMTargetInfo::getTargetDefines(const LangOptions
&Opts
,
1364 MacroBuilder
&Builder
) const {
1365 ARMleTargetInfo::getTargetDefines(Opts
, Builder
);
1366 Builder
.defineMacro("_ARM_");
1367 Builder
.defineMacro("__CYGWIN__");
1368 Builder
.defineMacro("__CYGWIN32__");
1369 DefineStd(Builder
, "unix", Opts
);
1371 Builder
.defineMacro("_GNU_SOURCE");
1374 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple
&Triple
,
1375 const TargetOptions
&Opts
)
1376 : DarwinTargetInfo
<ARMleTargetInfo
>(Triple
, Opts
) {
1377 HasAlignMac68kSupport
= true;
1378 // iOS always has 64-bit atomic instructions.
1379 // FIXME: This should be based off of the target features in
1381 MaxAtomicInlineWidth
= 64;
1383 if (Triple
.isWatchABI()) {
1384 // Darwin on iOS uses a variant of the ARM C++ ABI.
1385 TheCXXABI
.set(TargetCXXABI::WatchOS
);
1387 // BOOL should be a real boolean on the new ABI
1388 UseSignedCharForObjCBool
= false;
1390 TheCXXABI
.set(TargetCXXABI::iOS
);
1393 void DarwinARMTargetInfo::getOSDefines(const LangOptions
&Opts
,
1394 const llvm::Triple
&Triple
,
1395 MacroBuilder
&Builder
) const {
1396 getDarwinDefines(Builder
, Opts
, Triple
, PlatformName
, PlatformMinVersion
);
1399 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple
&Triple
,
1400 const TargetOptions
&Opts
)
1401 : ARMleTargetInfo(llvm::Triple("armv7", Triple
.getVendorName(),
1403 Triple
.getEnvironmentName()),
1405 IsRenderScriptTarget
= true;
1406 LongWidth
= LongAlign
= 64;
1409 void RenderScript32TargetInfo::getTargetDefines(const LangOptions
&Opts
,
1410 MacroBuilder
&Builder
) const {
1411 Builder
.defineMacro("__RENDERSCRIPT__");
1412 ARMleTargetInfo::getTargetDefines(Opts
, Builder
);