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.isOSNetBSD();
32 bool IsOpenBSD = T.isOSOpenBSD();
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::ARMV8_5A:
194 case llvm::ARM::ArchKind::ARMV8MBaseline:
196 case llvm::ARM::ArchKind::ARMV8MMainline:
198 case llvm::ARM::ArchKind::ARMV8R:
203 StringRef ARMTargetInfo::getCPUProfile() const {
204 switch (ArchProfile) {
205 case llvm::ARM::ProfileKind::A:
207 case llvm::ARM::ProfileKind::R:
209 case llvm::ARM::ProfileKind::M:
216 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
217 const TargetOptions &Opts)
218 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
220 bool IsOpenBSD = Triple.isOSOpenBSD();
221 bool IsNetBSD = Triple.isOSNetBSD();
223 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
224 // environment where size_t is `unsigned long` rather than `unsigned int`
226 PtrDiffType = IntPtrType =
227 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
232 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
237 // ptrdiff_t is inconsistent on Darwin
238 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
239 !Triple.isWatchABI())
240 PtrDiffType = SignedInt;
242 // Cache arch related info.
245 // {} in inline assembly are neon specifiers, not assembly variant
247 NoAsmVariants = true;
249 // FIXME: This duplicates code from the driver that sets the -target-abi
250 // option - this code is used if -target-abi isn't passed and should
251 // be unified in some way.
252 if (Triple.isOSBinFormatMachO()) {
253 // The backend is hardwired to assume AAPCS for M-class processors, ensure
254 // the frontend matches that.
255 if (Triple.getEnvironment() == llvm::Triple::EABI ||
256 Triple.getOS() == llvm::Triple::UnknownOS ||
257 ArchProfile == llvm::ARM::ProfileKind::M) {
259 } else if (Triple.isWatchABI()) {
264 } else if (Triple.isOSWindows()) {
265 // FIXME: this is invalid for WindowsCE
268 // Select the default based on the platform.
269 switch (Triple.getEnvironment()) {
270 case llvm::Triple::Android:
271 case llvm::Triple::GNUEABI:
272 case llvm::Triple::GNUEABIHF:
273 case llvm::Triple::MuslEABI:
274 case llvm::Triple::MuslEABIHF:
275 setABI("aapcs-linux");
277 case llvm::Triple::EABIHF:
278 case llvm::Triple::EABI:
281 case llvm::Triple::GNU:
288 setABI("aapcs-linux");
295 // ARM targets default to using the ARM C++ ABI.
296 TheCXXABI.set(TargetCXXABI::GenericARM);
298 // ARM has atomics up to 8 bytes
301 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
302 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
305 // Do force alignment of members that follow zero length bitfields. If
306 // the alignment of the zero-length bitfield is greater than the member
307 // that follows it, `bar', `bar' will be aligned as the type of the
308 // zero length bitfield.
309 UseZeroLengthBitfieldAlignment = true;
311 if (Triple.getOS() == llvm::Triple::Linux ||
312 Triple.getOS() == llvm::Triple::UnknownOS)
313 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
314 ? "\01__gnu_mcount_nc"
318 StringRef ARMTargetInfo::getABI() const { return ABI; }
320 bool ARMTargetInfo::setABI(const std::string &Name) {
323 // The defaults (above) are for AAPCS, check if we need to change them.
325 // FIXME: We need support for -meabi... we could just mangle it into the
327 if (Name == "apcs-gnu" || Name == "aapcs16") {
328 setABIAPCS(Name == "aapcs16");
331 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
338 // FIXME: This should be based on Arch attributes, not CPU names.
339 bool ARMTargetInfo::initFeatureMap(
340 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
341 const std::vector<std::string> &FeaturesVec) const {
343 std::string ArchFeature;
344 std::vector<StringRef> TargetFeatures;
345 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
347 // Map the base architecture to an appropriate target feature, so we don't
348 // rely on the target triple.
349 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
350 if (CPUArch == llvm::ARM::ArchKind::INVALID)
352 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
353 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
354 TargetFeatures.push_back(ArchFeature);
357 // get default FPU features
358 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
359 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
361 // get default Extension features
362 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
363 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
365 for (auto Feature : TargetFeatures)
366 if (Feature[0] == '+')
367 Features[Feature.drop_front(1)] = true;
369 // Enable or disable thumb-mode explicitly per function to enable mixed
370 // ARM and Thumb code generation.
372 Features["thumb-mode"] = true;
374 Features["thumb-mode"] = false;
376 // Convert user-provided arm and thumb GNU target attributes to
377 // [-|+]thumb-mode target features respectively.
378 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
379 for (auto &Feature : UpdatedFeaturesVec) {
380 if (Feature.compare("+arm") == 0)
381 Feature = "-thumb-mode";
382 else if (Feature.compare("+thumb") == 0)
383 Feature = "+thumb-mode";
386 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
390 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
391 DiagnosticsEngine &Diags) {
397 SoftFloat = SoftFloatABI = false;
402 // This does not diagnose illegal cases like having both
403 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
404 uint32_t HW_FP_remove = 0;
405 for (const auto &Feature : Features) {
406 if (Feature == "+soft-float") {
408 } else if (Feature == "+soft-float-abi") {
410 } else if (Feature == "+vfp2") {
412 HW_FP |= HW_FP_SP | HW_FP_DP;
413 } else if (Feature == "+vfp3") {
415 HW_FP |= HW_FP_SP | HW_FP_DP;
416 } else if (Feature == "+vfp4") {
418 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
419 } else if (Feature == "+fp-armv8") {
421 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
422 } else if (Feature == "+neon") {
424 HW_FP |= HW_FP_SP | HW_FP_DP;
425 } else if (Feature == "+hwdiv") {
427 } else if (Feature == "+hwdiv-arm") {
429 } else if (Feature == "+crc") {
431 } else if (Feature == "+crypto") {
433 } else if (Feature == "+dsp") {
435 } else if (Feature == "+fp-only-sp") {
436 HW_FP_remove |= HW_FP_DP;
437 } else if (Feature == "+strict-align") {
439 } else if (Feature == "+fp16") {
441 } else if (Feature == "+fullfp16") {
442 HasLegalHalfType = true;
443 } else if (Feature == "+dotprod") {
447 HW_FP &= ~HW_FP_remove;
449 switch (ArchVersion) {
451 if (ArchProfile == llvm::ARM::ProfileKind::M)
453 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
454 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
459 if (ArchProfile == llvm::ARM::ProfileKind::M)
460 LDREX = LDREX_W | LDREX_H | LDREX_B;
462 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
465 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
468 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
469 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
473 if (FPMath == FP_Neon)
474 Features.push_back("+neonfp");
475 else if (FPMath == FP_VFP)
476 Features.push_back("-neonfp");
478 // Remove front-end specific options which the backend handles differently.
479 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
480 if (Feature != Features.end())
481 Features.erase(Feature);
486 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
487 return llvm::StringSwitch<bool>(Feature)
489 .Case("aarch32", true)
490 .Case("softfloat", SoftFloat)
491 .Case("thumb", isThumb())
492 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
493 .Case("vfp", FPU && !SoftFloat)
494 .Case("hwdiv", HWDiv & HWDivThumb)
495 .Case("hwdiv-arm", HWDiv & HWDivARM)
499 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
500 return Name == "generic" ||
501 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
504 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
505 llvm::ARM::fillValidCPUArchList(Values);
508 bool ARMTargetInfo::setCPU(const std::string &Name) {
509 if (Name != "generic")
510 setArchInfo(llvm::ARM::parseCPUArch(Name));
512 if (ArchKind == llvm::ARM::ArchKind::INVALID)
519 bool ARMTargetInfo::setFPMath(StringRef Name) {
520 if (Name == "neon") {
523 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
531 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
532 MacroBuilder &Builder) const {
533 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
536 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
537 MacroBuilder &Builder) const {
538 // Also include the ARMv8.1-A defines
539 getTargetDefinesARMV81A(Opts, Builder);
542 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
543 MacroBuilder &Builder) const {
544 // Target identification.
545 Builder.defineMacro("__arm");
546 Builder.defineMacro("__arm__");
547 // For bare-metal none-eabi.
548 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
549 (getTriple().getEnvironment() == llvm::Triple::EABI ||
550 getTriple().getEnvironment() == llvm::Triple::EABIHF))
551 Builder.defineMacro("__ELF__");
553 // Target properties.
554 Builder.defineMacro("__REGISTER_PREFIX__", "");
556 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
557 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
558 if (getTriple().isWatchABI())
559 Builder.defineMacro("__ARM_ARCH_7K__", "2");
561 if (!CPUAttr.empty())
562 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
564 // ACLE 6.4.1 ARM/Thumb instruction set architecture
565 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
566 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
568 if (ArchVersion >= 8) {
569 // ACLE 6.5.7 Crypto Extension
571 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
572 // ACLE 6.5.8 CRC32 Extension
574 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
575 // ACLE 6.5.10 Numeric Maximum and Minimum
576 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
577 // ACLE 6.5.9 Directed Rounding
578 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
581 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
582 // is not defined for the M-profile.
583 // NOTE that the default profile is assumed to be 'A'
584 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
585 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
587 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
588 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
589 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
590 // v7 and v8 architectures excluding v8-M Baseline.
591 if (supportsThumb2())
592 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
593 else if (supportsThumb())
594 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
596 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
597 // instruction set such as ARM or Thumb.
598 Builder.defineMacro("__ARM_32BIT_STATE", "1");
600 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
602 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
603 if (!CPUProfile.empty())
604 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
606 // ACLE 6.4.3 Unaligned access supported in hardware
608 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
610 // ACLE 6.4.4 LDREX/STREX
612 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
615 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
617 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
619 // ACLE 6.5.1 Hardware Floating Point
621 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
624 Builder.defineMacro("__ARM_ACLE", "200");
626 // FP16 support (we currently only support IEEE format).
627 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
628 Builder.defineMacro("__ARM_FP16_ARGS", "1");
630 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
631 if (ArchVersion >= 7 && (FPU & VFP4FPU))
632 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
634 // Subtarget options.
636 // FIXME: It's more complicated than this and we don't really support
638 // Windows on ARM does not "support" interworking
639 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
640 Builder.defineMacro("__THUMB_INTERWORK__");
642 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
643 // Embedded targets on Darwin follow AAPCS, but not EABI.
644 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
645 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
646 Builder.defineMacro("__ARM_EABI__");
647 Builder.defineMacro("__ARM_PCS", "1");
650 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
651 Builder.defineMacro("__ARM_PCS_VFP", "1");
654 Builder.defineMacro("__SOFTFP__");
656 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
657 Builder.defineMacro("__XSCALE__");
660 Builder.defineMacro("__THUMBEL__");
661 Builder.defineMacro("__thumb__");
662 if (supportsThumb2())
663 Builder.defineMacro("__thumb2__");
666 // ACLE 6.4.9 32-bit SIMD instructions
667 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
668 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
670 // ACLE 6.4.10 Hardware Integer Divide
671 if (((HWDiv & HWDivThumb) && isThumb()) ||
672 ((HWDiv & HWDivARM) && !isThumb())) {
673 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
674 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
677 // Note, this is always on in gcc, even though it doesn't make sense.
678 Builder.defineMacro("__APCS_32__");
680 if (FPUModeIsVFP((FPUMode)FPU)) {
681 Builder.defineMacro("__VFP_FP__");
683 Builder.defineMacro("__ARM_VFPV2__");
685 Builder.defineMacro("__ARM_VFPV3__");
687 Builder.defineMacro("__ARM_VFPV4__");
689 Builder.defineMacro("__ARM_FPV5__");
692 // This only gets set when Neon instructions are actually available, unlike
693 // the VFP define, hence the soft float and arch check. This is subtly
694 // different from gcc, we follow the intent which was that it should be set
695 // when Neon instructions are actually available.
696 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
697 Builder.defineMacro("__ARM_NEON", "1");
698 Builder.defineMacro("__ARM_NEON__");
699 // current AArch32 NEON implementations do not support double-precision
700 // floating-point even when it is present in VFP.
701 Builder.defineMacro("__ARM_NEON_FP",
702 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
705 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
706 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
708 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
710 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
711 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
712 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
713 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
714 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
717 // ACLE 6.4.7 DSP instructions
719 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
722 // ACLE 6.4.8 Saturation instructions
724 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
725 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
729 // ACLE 6.4.6 Q (saturation) flag
731 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
733 if (Opts.UnsafeFPMath)
734 Builder.defineMacro("__ARM_FP_FAST", "1");
736 // Armv8.2-A FP16 vector intrinsic
737 if ((FPU & NeonFPU) && HasLegalHalfType)
738 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
740 // Armv8.2-A FP16 scalar intrinsics
741 if (HasLegalHalfType)
742 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
744 // Armv8.2-A dot product intrinsics
746 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
751 case llvm::ARM::ArchKind::ARMV8_1A:
752 getTargetDefinesARMV81A(Opts, Builder);
754 case llvm::ARM::ArchKind::ARMV8_2A:
755 getTargetDefinesARMV82A(Opts, Builder);
760 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
761 #define BUILTIN(ID, TYPE, ATTRS) \
762 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
763 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
764 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
765 #include "clang/Basic/BuiltinsNEON.def"
767 #define BUILTIN(ID, TYPE, ATTRS) \
768 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
769 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
770 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
771 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
772 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
773 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
774 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
775 #include "clang/Basic/BuiltinsARM.def"
778 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
779 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
780 Builtin::FirstTSBuiltin);
783 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
784 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
786 ? AAPCSABIBuiltinVaList
787 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
788 : TargetInfo::VoidPtrBuiltinVaList);
791 const char *const ARMTargetInfo::GCCRegNames[] = {
793 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
794 "r12", "sp", "lr", "pc",
797 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
798 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
799 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
802 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
803 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
804 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
807 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
808 "q12", "q13", "q14", "q15"};
810 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
811 return llvm::makeArrayRef(GCCRegNames);
814 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
815 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
816 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
817 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
818 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
819 // The S, D and Q registers overlap, but aren't really aliases; we
820 // don't want to substitute one of these for a different-sized one.
823 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
824 return llvm::makeArrayRef(GCCRegAliases);
827 bool ARMTargetInfo::validateAsmConstraint(
828 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
834 case 't': // VFP Floating point register single precision
835 case 'w': // VFP Floating point register double precision
836 Info.setAllowsRegister();
845 case 'Q': // A memory address that is a single base register.
846 Info.setAllowsMemory();
848 case 'U': // a memory reference...
850 case 'q': // ...ARMV4 ldrsb
851 case 'v': // ...VFP load/store (reg+constant offset)
852 case 'y': // ...iWMMXt load/store
853 case 't': // address valid for load/store opaque types wider
855 case 'n': // valid address for Neon doubleword vector load/store
856 case 'm': // valid address for Neon element and structure load/store
857 case 's': // valid address for non-offset loads/stores of quad-word
858 // values in four ARM registers
859 Info.setAllowsMemory();
867 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
869 switch (*Constraint) {
870 case 'U': // Two-character constraint; add "^" hint for later parsing.
871 R = std::string("^") + std::string(Constraint, 2);
874 case 'p': // 'p' should be translated to 'r' by default.
875 R = std::string("r");
878 return std::string(1, *Constraint);
883 bool ARMTargetInfo::validateConstraintModifier(
884 StringRef Constraint, char Modifier, unsigned Size,
885 std::string &SuggestedModifier) const {
886 bool isOutput = (Constraint[0] == '=');
887 bool isInOut = (Constraint[0] == '+');
889 // Strip off constraint modifiers.
890 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
891 Constraint = Constraint.substr(1);
893 switch (Constraint[0]) {
899 return (isInOut || isOutput || Size <= 64);
901 // A register of size 32 cannot fit a vector type.
909 const char *ARMTargetInfo::getClobbers() const {
910 // FIXME: Is this really right?
914 TargetInfo::CallingConvCheckResult
915 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
920 case CC_OpenCLKernel:
927 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
935 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
937 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
938 const TargetOptions &Opts)
939 : ARMTargetInfo(Triple, Opts) {}
941 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
942 MacroBuilder &Builder) const {
943 Builder.defineMacro("__ARMEL__");
944 ARMTargetInfo::getTargetDefines(Opts, Builder);
947 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
948 const TargetOptions &Opts)
949 : ARMTargetInfo(Triple, Opts) {}
951 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
952 MacroBuilder &Builder) const {
953 Builder.defineMacro("__ARMEB__");
954 Builder.defineMacro("__ARM_BIG_ENDIAN");
955 ARMTargetInfo::getTargetDefines(Opts, Builder);
958 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
959 const TargetOptions &Opts)
960 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
963 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
964 MacroBuilder &Builder) const {
965 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
967 // FIXME: this is invalid for WindowsCE
968 Builder.defineMacro("_M_ARM_NT", "1");
969 Builder.defineMacro("_M_ARMT", "_M_ARM");
970 Builder.defineMacro("_M_THUMB", "_M_ARM");
972 assert((Triple.getArch() == llvm::Triple::arm ||
973 Triple.getArch() == llvm::Triple::thumb) &&
974 "invalid architecture for Windows ARM target info");
975 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
976 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
978 // TODO map the complete set of values
979 // 31: VFPv3 40: VFPv4
980 Builder.defineMacro("_M_ARM_FP", "31");
983 TargetInfo::BuiltinVaListKind
984 WindowsARMTargetInfo::getBuiltinVaListKind() const {
985 return TargetInfo::CharPtrBuiltinVaList;
988 TargetInfo::CallingConvCheckResult
989 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
994 case CC_X86VectorCall:
997 case CC_OpenCLKernel:
998 case CC_PreserveMost:
1003 return CCCR_Warning;
1007 // Windows ARM + Itanium C++ ABI Target
1008 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1009 const llvm::Triple &Triple, const TargetOptions &Opts)
1010 : WindowsARMTargetInfo(Triple, Opts) {
1011 TheCXXABI.set(TargetCXXABI::GenericARM);
1014 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1015 const LangOptions &Opts, MacroBuilder &Builder) const {
1016 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1018 if (Opts.MSVCCompat)
1019 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1022 // Windows ARM, MS (C++) ABI
1023 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1024 const TargetOptions &Opts)
1025 : WindowsARMTargetInfo(Triple, Opts) {
1026 TheCXXABI.set(TargetCXXABI::Microsoft);
1029 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1030 MacroBuilder &Builder) const {
1031 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1032 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1035 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1036 const TargetOptions &Opts)
1037 : WindowsARMTargetInfo(Triple, Opts) {
1038 TheCXXABI.set(TargetCXXABI::GenericARM);
1041 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1042 MacroBuilder &Builder) const {
1043 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1044 Builder.defineMacro("_ARM_");
1047 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1048 const TargetOptions &Opts)
1049 : ARMleTargetInfo(Triple, Opts) {
1050 this->WCharType = TargetInfo::UnsignedShort;
1051 TLSSupported = false;
1052 DoubleAlign = LongLongAlign = 64;
1053 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1056 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1057 MacroBuilder &Builder) const {
1058 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1059 Builder.defineMacro("_ARM_");
1060 Builder.defineMacro("__CYGWIN__");
1061 Builder.defineMacro("__CYGWIN32__");
1062 DefineStd(Builder, "unix", Opts);
1064 Builder.defineMacro("_GNU_SOURCE");
1067 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1068 const TargetOptions &Opts)
1069 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1070 HasAlignMac68kSupport = true;
1071 // iOS always has 64-bit atomic instructions.
1072 // FIXME: This should be based off of the target features in
1074 MaxAtomicInlineWidth = 64;
1076 if (Triple.isWatchABI()) {
1077 // Darwin on iOS uses a variant of the ARM C++ ABI.
1078 TheCXXABI.set(TargetCXXABI::WatchOS);
1080 // BOOL should be a real boolean on the new ABI
1081 UseSignedCharForObjCBool = false;
1083 TheCXXABI.set(TargetCXXABI::iOS);
1086 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1087 const llvm::Triple &Triple,
1088 MacroBuilder &Builder) const {
1089 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1092 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1093 const TargetOptions &Opts)
1094 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1096 Triple.getEnvironmentName()),
1098 IsRenderScriptTarget = true;
1099 LongWidth = LongAlign = 64;
1102 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1103 MacroBuilder &Builder) const {
1104 Builder.defineMacro("__RENDERSCRIPT__");
1105 ARMleTargetInfo::getTargetDefines(Opts, Builder);