1 //===--- ARM.cpp - Implement ARM target feature support -------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements ARM TargetInfo objects.
12 //===----------------------------------------------------------------------===//
15 #include "clang/Basic/Builtins.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/TargetBuiltins.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
22 using namespace clang;
23 using namespace clang::targets;
25 void ARMTargetInfo::setABIAAPCS() {
28 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
29 const llvm::Triple &T = getTriple();
31 bool IsNetBSD = T.getOS() == llvm::Triple::NetBSD;
32 bool IsOpenBSD = T.getOS() == llvm::Triple::OpenBSD;
33 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
34 WCharType = UnsignedInt;
36 UseBitFieldTypeAlignment = true;
38 ZeroLengthBitfieldBoundary = 0;
40 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
41 // so set preferred for small types to 32.
42 if (T.isOSBinFormatMachO()) {
43 resetDataLayout(BigEndian
44 ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
45 : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
46 } else if (T.isOSWindows()) {
47 assert(!BigEndian && "Windows on ARM does not support big endian");
56 } else if (T.isOSNaCl()) {
57 assert(!BigEndian && "NaCl on ARM does not support big endian");
58 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
60 resetDataLayout(BigEndian
61 ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
62 : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
65 // FIXME: Enumerated types are variable width in straight AAPCS.
68 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
69 const llvm::Triple &T = getTriple();
74 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
76 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
78 WCharType = SignedInt;
80 // Do not respect the alignment of bit-field types when laying out
81 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
82 UseBitFieldTypeAlignment = false;
84 /// gcc forces the alignment to 4 bytes, regardless of the type of the
85 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
87 ZeroLengthBitfieldBoundary = 32;
89 if (T.isOSBinFormatMachO() && IsAAPCS16) {
90 assert(!BigEndian && "AAPCS16 does not support big-endian");
91 resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
92 } else if (T.isOSBinFormatMachO())
95 ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
96 : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
100 ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
101 : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
103 // FIXME: Override "preferred align" for double and long long.
106 void ARMTargetInfo::setArchInfo() {
107 StringRef ArchName = getTriple().getArchName();
109 ArchISA = llvm::ARM::parseArchISA(ArchName);
110 CPU = llvm::ARM::getDefaultCPU(ArchName);
111 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
112 if (AK != llvm::ARM::ArchKind::INVALID)
114 setArchInfo(ArchKind);
117 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
120 // cache TargetParser info
122 SubArch = llvm::ARM::getSubArch(ArchKind);
123 ArchProfile = llvm::ARM::parseArchProfile(SubArch);
124 ArchVersion = llvm::ARM::parseArchVersion(SubArch);
126 // cache CPU related strings
127 CPUAttr = getCPUAttr();
128 CPUProfile = getCPUProfile();
131 void ARMTargetInfo::setAtomic() {
132 // when triple does not specify a sub arch,
133 // then we are not using inline atomics
134 bool ShouldUseInlineAtomic =
135 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
136 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
137 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
138 if (ArchProfile == llvm::ARM::ProfileKind::M) {
139 MaxAtomicPromoteWidth = 32;
140 if (ShouldUseInlineAtomic)
141 MaxAtomicInlineWidth = 32;
143 MaxAtomicPromoteWidth = 64;
144 if (ShouldUseInlineAtomic)
145 MaxAtomicInlineWidth = 64;
149 bool ARMTargetInfo::isThumb() const {
150 return ArchISA == llvm::ARM::ISAKind::THUMB;
153 bool ARMTargetInfo::supportsThumb() const {
154 return CPUAttr.count('T') || ArchVersion >= 6;
157 bool ARMTargetInfo::supportsThumb2() const {
158 return CPUAttr.equals("6T2") ||
159 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
162 StringRef ARMTargetInfo::getCPUAttr() const {
163 // For most sub-arches, the build attribute CPU name is enough.
164 // For Cortex variants, it's slightly different.
167 return llvm::ARM::getCPUAttr(ArchKind);
168 case llvm::ARM::ArchKind::ARMV6M:
170 case llvm::ARM::ArchKind::ARMV7S:
172 case llvm::ARM::ArchKind::ARMV7A:
174 case llvm::ARM::ArchKind::ARMV7R:
176 case llvm::ARM::ArchKind::ARMV7M:
178 case llvm::ARM::ArchKind::ARMV7EM:
180 case llvm::ARM::ArchKind::ARMV7VE:
182 case llvm::ARM::ArchKind::ARMV8A:
184 case llvm::ARM::ArchKind::ARMV8_1A:
186 case llvm::ARM::ArchKind::ARMV8_2A:
188 case llvm::ARM::ArchKind::ARMV8_3A:
190 case llvm::ARM::ArchKind::ARMV8_4A:
192 case llvm::ARM::ArchKind::ARMV8MBaseline:
194 case llvm::ARM::ArchKind::ARMV8MMainline:
196 case llvm::ARM::ArchKind::ARMV8R:
201 StringRef ARMTargetInfo::getCPUProfile() const {
202 switch (ArchProfile) {
203 case llvm::ARM::ProfileKind::A:
205 case llvm::ARM::ProfileKind::R:
207 case llvm::ARM::ProfileKind::M:
214 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
215 const TargetOptions &Opts)
216 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
218 bool IsOpenBSD = Triple.getOS() == llvm::Triple::OpenBSD;
219 bool IsNetBSD = Triple.getOS() == llvm::Triple::NetBSD;
221 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
222 // environment where size_t is `unsigned long` rather than `unsigned int`
224 PtrDiffType = IntPtrType =
225 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
230 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
235 // ptrdiff_t is inconsistent on Darwin
236 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
237 !Triple.isWatchABI())
238 PtrDiffType = SignedInt;
240 // Cache arch related info.
243 // {} in inline assembly are neon specifiers, not assembly variant
245 NoAsmVariants = true;
247 // FIXME: This duplicates code from the driver that sets the -target-abi
248 // option - this code is used if -target-abi isn't passed and should
249 // be unified in some way.
250 if (Triple.isOSBinFormatMachO()) {
251 // The backend is hardwired to assume AAPCS for M-class processors, ensure
252 // the frontend matches that.
253 if (Triple.getEnvironment() == llvm::Triple::EABI ||
254 Triple.getOS() == llvm::Triple::UnknownOS ||
255 ArchProfile == llvm::ARM::ProfileKind::M) {
257 } else if (Triple.isWatchABI()) {
262 } else if (Triple.isOSWindows()) {
263 // FIXME: this is invalid for WindowsCE
266 // Select the default based on the platform.
267 switch (Triple.getEnvironment()) {
268 case llvm::Triple::Android:
269 case llvm::Triple::GNUEABI:
270 case llvm::Triple::GNUEABIHF:
271 case llvm::Triple::MuslEABI:
272 case llvm::Triple::MuslEABIHF:
273 setABI("aapcs-linux");
275 case llvm::Triple::EABIHF:
276 case llvm::Triple::EABI:
279 case llvm::Triple::GNU:
283 if (Triple.getOS() == llvm::Triple::NetBSD)
285 else if (Triple.getOS() == llvm::Triple::OpenBSD)
286 setABI("aapcs-linux");
293 // ARM targets default to using the ARM C++ ABI.
294 TheCXXABI.set(TargetCXXABI::GenericARM);
296 // ARM has atomics up to 8 bytes
299 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
300 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
303 // Do force alignment of members that follow zero length bitfields. If
304 // the alignment of the zero-length bitfield is greater than the member
305 // that follows it, `bar', `bar' will be aligned as the type of the
306 // zero length bitfield.
307 UseZeroLengthBitfieldAlignment = true;
309 if (Triple.getOS() == llvm::Triple::Linux ||
310 Triple.getOS() == llvm::Triple::UnknownOS)
311 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
312 ? "\01__gnu_mcount_nc"
316 StringRef ARMTargetInfo::getABI() const { return ABI; }
318 bool ARMTargetInfo::setABI(const std::string &Name) {
321 // The defaults (above) are for AAPCS, check if we need to change them.
323 // FIXME: We need support for -meabi... we could just mangle it into the
325 if (Name == "apcs-gnu" || Name == "aapcs16") {
326 setABIAPCS(Name == "aapcs16");
329 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
336 // FIXME: This should be based on Arch attributes, not CPU names.
337 bool ARMTargetInfo::initFeatureMap(
338 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
339 const std::vector<std::string> &FeaturesVec) const {
341 std::string ArchFeature;
342 std::vector<StringRef> TargetFeatures;
343 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
345 // Map the base architecture to an appropriate target feature, so we don't
346 // rely on the target triple.
347 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
348 if (CPUArch == llvm::ARM::ArchKind::INVALID)
350 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
351 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
352 TargetFeatures.push_back(ArchFeature);
355 // get default FPU features
356 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
357 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
359 // get default Extension features
360 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
361 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
363 for (auto Feature : TargetFeatures)
364 if (Feature[0] == '+')
365 Features[Feature.drop_front(1)] = true;
367 // Enable or disable thumb-mode explicitly per function to enable mixed
368 // ARM and Thumb code generation.
370 Features["thumb-mode"] = true;
372 Features["thumb-mode"] = false;
374 // Convert user-provided arm and thumb GNU target attributes to
375 // [-|+]thumb-mode target features respectively.
376 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
377 for (auto &Feature : UpdatedFeaturesVec) {
378 if (Feature.compare("+arm") == 0)
379 Feature = "-thumb-mode";
380 else if (Feature.compare("+thumb") == 0)
381 Feature = "+thumb-mode";
384 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
388 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
389 DiagnosticsEngine &Diags) {
395 SoftFloat = SoftFloatABI = false;
399 // This does not diagnose illegal cases like having both
400 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
401 uint32_t HW_FP_remove = 0;
402 for (const auto &Feature : Features) {
403 if (Feature == "+soft-float") {
405 } else if (Feature == "+soft-float-abi") {
407 } else if (Feature == "+vfp2") {
409 HW_FP |= HW_FP_SP | HW_FP_DP;
410 } else if (Feature == "+vfp3") {
412 HW_FP |= HW_FP_SP | HW_FP_DP;
413 } else if (Feature == "+vfp4") {
415 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
416 } else if (Feature == "+fp-armv8") {
418 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
419 } else if (Feature == "+neon") {
421 HW_FP |= HW_FP_SP | HW_FP_DP;
422 } else if (Feature == "+hwdiv") {
424 } else if (Feature == "+hwdiv-arm") {
426 } else if (Feature == "+crc") {
428 } else if (Feature == "+crypto") {
430 } else if (Feature == "+dsp") {
432 } else if (Feature == "+fp-only-sp") {
433 HW_FP_remove |= HW_FP_DP;
434 } else if (Feature == "+strict-align") {
436 } else if (Feature == "+fp16") {
438 } else if (Feature == "+fullfp16") {
439 HasLegalHalfType = true;
440 } else if (Feature == "+dotprod") {
444 HW_FP &= ~HW_FP_remove;
446 switch (ArchVersion) {
448 if (ArchProfile == llvm::ARM::ProfileKind::M)
450 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
451 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
456 if (ArchProfile == llvm::ARM::ProfileKind::M)
457 LDREX = LDREX_W | LDREX_H | LDREX_B;
459 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
462 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
465 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
466 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
470 if (FPMath == FP_Neon)
471 Features.push_back("+neonfp");
472 else if (FPMath == FP_VFP)
473 Features.push_back("-neonfp");
475 // Remove front-end specific options which the backend handles differently.
476 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
477 if (Feature != Features.end())
478 Features.erase(Feature);
483 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
484 return llvm::StringSwitch<bool>(Feature)
486 .Case("aarch32", true)
487 .Case("softfloat", SoftFloat)
488 .Case("thumb", isThumb())
489 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
490 .Case("vfp", FPU && !SoftFloat)
491 .Case("hwdiv", HWDiv & HWDivThumb)
492 .Case("hwdiv-arm", HWDiv & HWDivARM)
496 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
497 return Name == "generic" ||
498 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
501 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
502 llvm::ARM::fillValidCPUArchList(Values);
505 bool ARMTargetInfo::setCPU(const std::string &Name) {
506 if (Name != "generic")
507 setArchInfo(llvm::ARM::parseCPUArch(Name));
509 if (ArchKind == llvm::ARM::ArchKind::INVALID)
516 bool ARMTargetInfo::setFPMath(StringRef Name) {
517 if (Name == "neon") {
520 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
528 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
529 MacroBuilder &Builder) const {
530 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
533 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
534 MacroBuilder &Builder) const {
535 // Also include the ARMv8.1-A defines
536 getTargetDefinesARMV81A(Opts, Builder);
539 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
540 MacroBuilder &Builder) const {
541 // Target identification.
542 Builder.defineMacro("__arm");
543 Builder.defineMacro("__arm__");
544 // For bare-metal none-eabi.
545 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
546 (getTriple().getEnvironment() == llvm::Triple::EABI ||
547 getTriple().getEnvironment() == llvm::Triple::EABIHF))
548 Builder.defineMacro("__ELF__");
550 // Target properties.
551 Builder.defineMacro("__REGISTER_PREFIX__", "");
553 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
554 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
555 if (getTriple().isWatchABI())
556 Builder.defineMacro("__ARM_ARCH_7K__", "2");
558 if (!CPUAttr.empty())
559 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
561 // ACLE 6.4.1 ARM/Thumb instruction set architecture
562 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
563 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
565 if (ArchVersion >= 8) {
566 // ACLE 6.5.7 Crypto Extension
568 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
569 // ACLE 6.5.8 CRC32 Extension
571 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
572 // ACLE 6.5.10 Numeric Maximum and Minimum
573 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
574 // ACLE 6.5.9 Directed Rounding
575 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
578 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
579 // is not defined for the M-profile.
580 // NOTE that the default profile is assumed to be 'A'
581 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
582 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
584 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
585 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
586 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
587 // v7 and v8 architectures excluding v8-M Baseline.
588 if (supportsThumb2())
589 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
590 else if (supportsThumb())
591 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
593 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
594 // instruction set such as ARM or Thumb.
595 Builder.defineMacro("__ARM_32BIT_STATE", "1");
597 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
599 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
600 if (!CPUProfile.empty())
601 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
603 // ACLE 6.4.3 Unaligned access supported in hardware
605 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
607 // ACLE 6.4.4 LDREX/STREX
609 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
612 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
614 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
616 // ACLE 6.5.1 Hardware Floating Point
618 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
621 Builder.defineMacro("__ARM_ACLE", "200");
623 // FP16 support (we currently only support IEEE format).
624 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
625 Builder.defineMacro("__ARM_FP16_ARGS", "1");
627 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
628 if (ArchVersion >= 7 && (FPU & VFP4FPU))
629 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
631 // Subtarget options.
633 // FIXME: It's more complicated than this and we don't really support
635 // Windows on ARM does not "support" interworking
636 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
637 Builder.defineMacro("__THUMB_INTERWORK__");
639 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
640 // Embedded targets on Darwin follow AAPCS, but not EABI.
641 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
642 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
643 Builder.defineMacro("__ARM_EABI__");
644 Builder.defineMacro("__ARM_PCS", "1");
647 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
648 Builder.defineMacro("__ARM_PCS_VFP", "1");
651 Builder.defineMacro("__SOFTFP__");
653 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
654 Builder.defineMacro("__XSCALE__");
657 Builder.defineMacro("__THUMBEL__");
658 Builder.defineMacro("__thumb__");
659 if (supportsThumb2())
660 Builder.defineMacro("__thumb2__");
663 // ACLE 6.4.9 32-bit SIMD instructions
664 if (ArchVersion >= 6 && (CPUProfile != "M" || CPUAttr == "7EM"))
665 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
667 // ACLE 6.4.10 Hardware Integer Divide
668 if (((HWDiv & HWDivThumb) && isThumb()) ||
669 ((HWDiv & HWDivARM) && !isThumb())) {
670 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
671 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
674 // Note, this is always on in gcc, even though it doesn't make sense.
675 Builder.defineMacro("__APCS_32__");
677 if (FPUModeIsVFP((FPUMode)FPU)) {
678 Builder.defineMacro("__VFP_FP__");
680 Builder.defineMacro("__ARM_VFPV2__");
682 Builder.defineMacro("__ARM_VFPV3__");
684 Builder.defineMacro("__ARM_VFPV4__");
686 Builder.defineMacro("__ARM_FPV5__");
689 // This only gets set when Neon instructions are actually available, unlike
690 // the VFP define, hence the soft float and arch check. This is subtly
691 // different from gcc, we follow the intent which was that it should be set
692 // when Neon instructions are actually available.
693 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
694 Builder.defineMacro("__ARM_NEON", "1");
695 Builder.defineMacro("__ARM_NEON__");
696 // current AArch32 NEON implementations do not support double-precision
697 // floating-point even when it is present in VFP.
698 Builder.defineMacro("__ARM_NEON_FP",
699 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
702 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
703 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
705 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
707 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
708 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
709 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
710 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
711 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
714 // ACLE 6.4.7 DSP instructions
716 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
719 // ACLE 6.4.8 Saturation instructions
721 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
722 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
726 // ACLE 6.4.6 Q (saturation) flag
728 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
730 if (Opts.UnsafeFPMath)
731 Builder.defineMacro("__ARM_FP_FAST", "1");
733 // Armv8.2-A FP16 vector intrinsic
734 if ((FPU & NeonFPU) && HasLegalHalfType)
735 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
737 // Armv8.2-A FP16 scalar intrinsics
738 if (HasLegalHalfType)
739 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
741 // Armv8.2-A dot product intrinsics
743 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
748 case llvm::ARM::ArchKind::ARMV8_1A:
749 getTargetDefinesARMV81A(Opts, Builder);
751 case llvm::ARM::ArchKind::ARMV8_2A:
752 getTargetDefinesARMV82A(Opts, Builder);
757 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
758 #define BUILTIN(ID, TYPE, ATTRS) \
759 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
760 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
761 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
762 #include "clang/Basic/BuiltinsNEON.def"
764 #define BUILTIN(ID, TYPE, ATTRS) \
765 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
766 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
767 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
768 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
769 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
770 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
771 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
772 #include "clang/Basic/BuiltinsARM.def"
775 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
776 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
777 Builtin::FirstTSBuiltin);
780 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
781 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
783 ? AAPCSABIBuiltinVaList
784 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
785 : TargetInfo::VoidPtrBuiltinVaList);
788 const char *const ARMTargetInfo::GCCRegNames[] = {
790 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
791 "r12", "sp", "lr", "pc",
794 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
795 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
796 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
799 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
800 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
801 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
804 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
805 "q12", "q13", "q14", "q15"};
807 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
808 return llvm::makeArrayRef(GCCRegNames);
811 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
812 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
813 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
814 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
815 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
816 // The S, D and Q registers overlap, but aren't really aliases; we
817 // don't want to substitute one of these for a different-sized one.
820 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
821 return llvm::makeArrayRef(GCCRegAliases);
824 bool ARMTargetInfo::validateAsmConstraint(
825 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
831 case 't': // VFP Floating point register single precision
832 case 'w': // VFP Floating point register double precision
833 Info.setAllowsRegister();
842 case 'Q': // A memory address that is a single base register.
843 Info.setAllowsMemory();
845 case 'U': // a memory reference...
847 case 'q': // ...ARMV4 ldrsb
848 case 'v': // ...VFP load/store (reg+constant offset)
849 case 'y': // ...iWMMXt load/store
850 case 't': // address valid for load/store opaque types wider
852 case 'n': // valid address for Neon doubleword vector load/store
853 case 'm': // valid address for Neon element and structure load/store
854 case 's': // valid address for non-offset loads/stores of quad-word
855 // values in four ARM registers
856 Info.setAllowsMemory();
864 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
866 switch (*Constraint) {
867 case 'U': // Two-character constraint; add "^" hint for later parsing.
868 R = std::string("^") + std::string(Constraint, 2);
871 case 'p': // 'p' should be translated to 'r' by default.
872 R = std::string("r");
875 return std::string(1, *Constraint);
880 bool ARMTargetInfo::validateConstraintModifier(
881 StringRef Constraint, char Modifier, unsigned Size,
882 std::string &SuggestedModifier) const {
883 bool isOutput = (Constraint[0] == '=');
884 bool isInOut = (Constraint[0] == '+');
886 // Strip off constraint modifiers.
887 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
888 Constraint = Constraint.substr(1);
890 switch (Constraint[0]) {
896 return (isInOut || isOutput || Size <= 64);
898 // A register of size 32 cannot fit a vector type.
906 const char *ARMTargetInfo::getClobbers() const {
907 // FIXME: Is this really right?
911 TargetInfo::CallingConvCheckResult
912 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
917 case CC_OpenCLKernel:
924 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
932 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
934 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
935 const TargetOptions &Opts)
936 : ARMTargetInfo(Triple, Opts) {}
938 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
939 MacroBuilder &Builder) const {
940 Builder.defineMacro("__ARMEL__");
941 ARMTargetInfo::getTargetDefines(Opts, Builder);
944 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
945 const TargetOptions &Opts)
946 : ARMTargetInfo(Triple, Opts) {}
948 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
949 MacroBuilder &Builder) const {
950 Builder.defineMacro("__ARMEB__");
951 Builder.defineMacro("__ARM_BIG_ENDIAN");
952 ARMTargetInfo::getTargetDefines(Opts, Builder);
955 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
956 const TargetOptions &Opts)
957 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
960 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
961 MacroBuilder &Builder) const {
962 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
964 // FIXME: this is invalid for WindowsCE
965 Builder.defineMacro("_M_ARM_NT", "1");
966 Builder.defineMacro("_M_ARMT", "_M_ARM");
967 Builder.defineMacro("_M_THUMB", "_M_ARM");
969 assert((Triple.getArch() == llvm::Triple::arm ||
970 Triple.getArch() == llvm::Triple::thumb) &&
971 "invalid architecture for Windows ARM target info");
972 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
973 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
975 // TODO map the complete set of values
976 // 31: VFPv3 40: VFPv4
977 Builder.defineMacro("_M_ARM_FP", "31");
980 TargetInfo::BuiltinVaListKind
981 WindowsARMTargetInfo::getBuiltinVaListKind() const {
982 return TargetInfo::CharPtrBuiltinVaList;
985 TargetInfo::CallingConvCheckResult
986 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
991 case CC_X86VectorCall:
994 case CC_OpenCLKernel:
995 case CC_PreserveMost:
1003 // Windows ARM + Itanium C++ ABI Target
1004 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1005 const llvm::Triple &Triple, const TargetOptions &Opts)
1006 : WindowsARMTargetInfo(Triple, Opts) {
1007 TheCXXABI.set(TargetCXXABI::GenericARM);
1010 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1011 const LangOptions &Opts, MacroBuilder &Builder) const {
1012 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1014 if (Opts.MSVCCompat)
1015 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1018 // Windows ARM, MS (C++) ABI
1019 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1020 const TargetOptions &Opts)
1021 : WindowsARMTargetInfo(Triple, Opts) {
1022 TheCXXABI.set(TargetCXXABI::Microsoft);
1025 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1026 MacroBuilder &Builder) const {
1027 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1028 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1031 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1032 const TargetOptions &Opts)
1033 : WindowsARMTargetInfo(Triple, Opts) {
1034 TheCXXABI.set(TargetCXXABI::GenericARM);
1037 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1038 MacroBuilder &Builder) const {
1039 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1040 Builder.defineMacro("_ARM_");
1043 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1044 const TargetOptions &Opts)
1045 : ARMleTargetInfo(Triple, Opts) {
1046 this->WCharType = TargetInfo::UnsignedShort;
1047 TLSSupported = false;
1048 DoubleAlign = LongLongAlign = 64;
1049 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1052 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1053 MacroBuilder &Builder) const {
1054 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1055 Builder.defineMacro("_ARM_");
1056 Builder.defineMacro("__CYGWIN__");
1057 Builder.defineMacro("__CYGWIN32__");
1058 DefineStd(Builder, "unix", Opts);
1060 Builder.defineMacro("_GNU_SOURCE");
1063 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1064 const TargetOptions &Opts)
1065 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1066 HasAlignMac68kSupport = true;
1067 // iOS always has 64-bit atomic instructions.
1068 // FIXME: This should be based off of the target features in
1070 MaxAtomicInlineWidth = 64;
1072 if (Triple.isWatchABI()) {
1073 // Darwin on iOS uses a variant of the ARM C++ ABI.
1074 TheCXXABI.set(TargetCXXABI::WatchOS);
1076 // BOOL should be a real boolean on the new ABI
1077 UseSignedCharForObjCBool = false;
1079 TheCXXABI.set(TargetCXXABI::iOS);
1082 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1083 const llvm::Triple &Triple,
1084 MacroBuilder &Builder) const {
1085 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1088 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1089 const TargetOptions &Opts)
1090 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1092 Triple.getEnvironmentName()),
1094 IsRenderScriptTarget = true;
1095 LongWidth = LongAlign = 64;
1098 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1099 MacroBuilder &Builder) const {
1100 Builder.defineMacro("__RENDERSCRIPT__");
1101 ARMleTargetInfo::getTargetDefines(Opts, Builder);