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::ARMV8MBaseline:
190 case llvm::ARM::ArchKind::ARMV8MMainline:
192 case llvm::ARM::ArchKind::ARMV8R:
197 StringRef ARMTargetInfo::getCPUProfile() const {
198 switch (ArchProfile) {
199 case llvm::ARM::ProfileKind::A:
201 case llvm::ARM::ProfileKind::R:
203 case llvm::ARM::ProfileKind::M:
210 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
211 const TargetOptions &Opts)
212 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
214 bool IsOpenBSD = Triple.getOS() == llvm::Triple::OpenBSD;
215 bool IsNetBSD = Triple.getOS() == llvm::Triple::NetBSD;
217 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
218 // environment where size_t is `unsigned long` rather than `unsigned int`
220 PtrDiffType = IntPtrType =
221 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
226 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
231 // ptrdiff_t is inconsistent on Darwin
232 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
233 !Triple.isWatchABI())
234 PtrDiffType = SignedInt;
236 // Cache arch related info.
239 // {} in inline assembly are neon specifiers, not assembly variant
241 NoAsmVariants = true;
243 // FIXME: This duplicates code from the driver that sets the -target-abi
244 // option - this code is used if -target-abi isn't passed and should
245 // be unified in some way.
246 if (Triple.isOSBinFormatMachO()) {
247 // The backend is hardwired to assume AAPCS for M-class processors, ensure
248 // the frontend matches that.
249 if (Triple.getEnvironment() == llvm::Triple::EABI ||
250 Triple.getOS() == llvm::Triple::UnknownOS ||
251 ArchProfile == llvm::ARM::ProfileKind::M) {
253 } else if (Triple.isWatchABI()) {
258 } else if (Triple.isOSWindows()) {
259 // FIXME: this is invalid for WindowsCE
262 // Select the default based on the platform.
263 switch (Triple.getEnvironment()) {
264 case llvm::Triple::Android:
265 case llvm::Triple::GNUEABI:
266 case llvm::Triple::GNUEABIHF:
267 case llvm::Triple::MuslEABI:
268 case llvm::Triple::MuslEABIHF:
269 setABI("aapcs-linux");
271 case llvm::Triple::EABIHF:
272 case llvm::Triple::EABI:
275 case llvm::Triple::GNU:
279 if (Triple.getOS() == llvm::Triple::NetBSD)
281 else if (Triple.getOS() == llvm::Triple::OpenBSD)
282 setABI("aapcs-linux");
289 // ARM targets default to using the ARM C++ ABI.
290 TheCXXABI.set(TargetCXXABI::GenericARM);
292 // ARM has atomics up to 8 bytes
295 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
296 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
299 // Do force alignment of members that follow zero length bitfields. If
300 // the alignment of the zero-length bitfield is greater than the member
301 // that follows it, `bar', `bar' will be aligned as the type of the
302 // zero length bitfield.
303 UseZeroLengthBitfieldAlignment = true;
305 if (Triple.getOS() == llvm::Triple::Linux ||
306 Triple.getOS() == llvm::Triple::UnknownOS)
307 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
308 ? "\01__gnu_mcount_nc"
312 StringRef ARMTargetInfo::getABI() const { return ABI; }
314 bool ARMTargetInfo::setABI(const std::string &Name) {
317 // The defaults (above) are for AAPCS, check if we need to change them.
319 // FIXME: We need support for -meabi... we could just mangle it into the
321 if (Name == "apcs-gnu" || Name == "aapcs16") {
322 setABIAPCS(Name == "aapcs16");
325 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
332 // FIXME: This should be based on Arch attributes, not CPU names.
333 bool ARMTargetInfo::initFeatureMap(
334 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
335 const std::vector<std::string> &FeaturesVec) const {
337 std::vector<StringRef> TargetFeatures;
338 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
340 // get default FPU features
341 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
342 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
344 // get default Extension features
345 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
346 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
348 for (auto Feature : TargetFeatures)
349 if (Feature[0] == '+')
350 Features[Feature.drop_front(1)] = true;
352 // Enable or disable thumb-mode explicitly per function to enable mixed
353 // ARM and Thumb code generation.
355 Features["thumb-mode"] = true;
357 Features["thumb-mode"] = false;
359 // Convert user-provided arm and thumb GNU target attributes to
360 // [-|+]thumb-mode target features respectively.
361 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
362 for (auto &Feature : UpdatedFeaturesVec) {
363 if (Feature.compare("+arm") == 0)
364 Feature = "-thumb-mode";
365 else if (Feature.compare("+thumb") == 0)
366 Feature = "+thumb-mode";
369 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
373 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
374 DiagnosticsEngine &Diags) {
380 SoftFloat = SoftFloatABI = false;
383 // This does not diagnose illegal cases like having both
384 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
385 uint32_t HW_FP_remove = 0;
386 for (const auto &Feature : Features) {
387 if (Feature == "+soft-float") {
389 } else if (Feature == "+soft-float-abi") {
391 } else if (Feature == "+vfp2") {
393 HW_FP |= HW_FP_SP | HW_FP_DP;
394 } else if (Feature == "+vfp3") {
396 HW_FP |= HW_FP_SP | HW_FP_DP;
397 } else if (Feature == "+vfp4") {
399 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
400 } else if (Feature == "+fp-armv8") {
402 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
403 } else if (Feature == "+neon") {
405 HW_FP |= HW_FP_SP | HW_FP_DP;
406 } else if (Feature == "+hwdiv") {
408 } else if (Feature == "+hwdiv-arm") {
410 } else if (Feature == "+crc") {
412 } else if (Feature == "+crypto") {
414 } else if (Feature == "+dsp") {
416 } else if (Feature == "+fp-only-sp") {
417 HW_FP_remove |= HW_FP_DP;
418 } else if (Feature == "+strict-align") {
420 } else if (Feature == "+fp16") {
424 HW_FP &= ~HW_FP_remove;
426 switch (ArchVersion) {
428 if (ArchProfile == llvm::ARM::ProfileKind::M)
430 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
431 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
436 if (ArchProfile == llvm::ARM::ProfileKind::M)
437 LDREX = LDREX_W | LDREX_H | LDREX_B;
439 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
442 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
445 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
446 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
450 if (FPMath == FP_Neon)
451 Features.push_back("+neonfp");
452 else if (FPMath == FP_VFP)
453 Features.push_back("-neonfp");
455 // Remove front-end specific options which the backend handles differently.
456 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
457 if (Feature != Features.end())
458 Features.erase(Feature);
463 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
464 return llvm::StringSwitch<bool>(Feature)
466 .Case("aarch32", true)
467 .Case("softfloat", SoftFloat)
468 .Case("thumb", isThumb())
469 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
470 .Case("vfp", FPU && !SoftFloat)
471 .Case("hwdiv", HWDiv & HWDivThumb)
472 .Case("hwdiv-arm", HWDiv & HWDivARM)
476 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
477 return Name == "generic" ||
478 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
481 bool ARMTargetInfo::setCPU(const std::string &Name) {
482 if (Name != "generic")
483 setArchInfo(llvm::ARM::parseCPUArch(Name));
485 if (ArchKind == llvm::ARM::ArchKind::INVALID)
492 bool ARMTargetInfo::setFPMath(StringRef Name) {
493 if (Name == "neon") {
496 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
504 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
505 MacroBuilder &Builder) const {
506 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
509 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
510 MacroBuilder &Builder) const {
511 // Also include the ARMv8.1-A defines
512 getTargetDefinesARMV81A(Opts, Builder);
515 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
516 MacroBuilder &Builder) const {
517 // Target identification.
518 Builder.defineMacro("__arm");
519 Builder.defineMacro("__arm__");
520 // For bare-metal none-eabi.
521 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
522 (getTriple().getEnvironment() == llvm::Triple::EABI ||
523 getTriple().getEnvironment() == llvm::Triple::EABIHF))
524 Builder.defineMacro("__ELF__");
526 // Target properties.
527 Builder.defineMacro("__REGISTER_PREFIX__", "");
529 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
530 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
531 if (getTriple().isWatchABI())
532 Builder.defineMacro("__ARM_ARCH_7K__", "2");
534 if (!CPUAttr.empty())
535 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
537 // ACLE 6.4.1 ARM/Thumb instruction set architecture
538 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
539 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
541 if (ArchVersion >= 8) {
542 // ACLE 6.5.7 Crypto Extension
544 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
545 // ACLE 6.5.8 CRC32 Extension
547 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
548 // ACLE 6.5.10 Numeric Maximum and Minimum
549 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
550 // ACLE 6.5.9 Directed Rounding
551 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
554 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
555 // is not defined for the M-profile.
556 // NOTE that the default profile is assumed to be 'A'
557 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
558 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
560 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
561 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
562 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
563 // v7 and v8 architectures excluding v8-M Baseline.
564 if (supportsThumb2())
565 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
566 else if (supportsThumb())
567 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
569 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
570 // instruction set such as ARM or Thumb.
571 Builder.defineMacro("__ARM_32BIT_STATE", "1");
573 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
575 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
576 if (!CPUProfile.empty())
577 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
579 // ACLE 6.4.3 Unaligned access supported in hardware
581 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
583 // ACLE 6.4.4 LDREX/STREX
585 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
588 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
590 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
592 // ACLE 6.5.1 Hardware Floating Point
594 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
597 Builder.defineMacro("__ARM_ACLE", "200");
599 // FP16 support (we currently only support IEEE format).
600 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
601 Builder.defineMacro("__ARM_FP16_ARGS", "1");
603 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
604 if (ArchVersion >= 7 && (FPU & VFP4FPU))
605 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
607 // Subtarget options.
609 // FIXME: It's more complicated than this and we don't really support
611 // Windows on ARM does not "support" interworking
612 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
613 Builder.defineMacro("__THUMB_INTERWORK__");
615 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
616 // Embedded targets on Darwin follow AAPCS, but not EABI.
617 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
618 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
619 Builder.defineMacro("__ARM_EABI__");
620 Builder.defineMacro("__ARM_PCS", "1");
623 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
624 Builder.defineMacro("__ARM_PCS_VFP", "1");
627 Builder.defineMacro("__SOFTFP__");
629 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
630 Builder.defineMacro("__XSCALE__");
633 Builder.defineMacro("__THUMBEL__");
634 Builder.defineMacro("__thumb__");
635 if (supportsThumb2())
636 Builder.defineMacro("__thumb2__");
639 // ACLE 6.4.9 32-bit SIMD instructions
640 if (ArchVersion >= 6 && (CPUProfile != "M" || CPUAttr == "7EM"))
641 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
643 // ACLE 6.4.10 Hardware Integer Divide
644 if (((HWDiv & HWDivThumb) && isThumb()) ||
645 ((HWDiv & HWDivARM) && !isThumb())) {
646 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
647 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
650 // Note, this is always on in gcc, even though it doesn't make sense.
651 Builder.defineMacro("__APCS_32__");
653 if (FPUModeIsVFP((FPUMode)FPU)) {
654 Builder.defineMacro("__VFP_FP__");
656 Builder.defineMacro("__ARM_VFPV2__");
658 Builder.defineMacro("__ARM_VFPV3__");
660 Builder.defineMacro("__ARM_VFPV4__");
662 Builder.defineMacro("__ARM_FPV5__");
665 // This only gets set when Neon instructions are actually available, unlike
666 // the VFP define, hence the soft float and arch check. This is subtly
667 // different from gcc, we follow the intent which was that it should be set
668 // when Neon instructions are actually available.
669 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
670 Builder.defineMacro("__ARM_NEON", "1");
671 Builder.defineMacro("__ARM_NEON__");
672 // current AArch32 NEON implementations do not support double-precision
673 // floating-point even when it is present in VFP.
674 Builder.defineMacro("__ARM_NEON_FP",
675 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
678 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
679 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
681 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
683 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
684 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
685 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
686 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
687 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
690 // ACLE 6.4.7 DSP instructions
692 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
695 // ACLE 6.4.8 Saturation instructions
697 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
698 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
702 // ACLE 6.4.6 Q (saturation) flag
704 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
706 if (Opts.UnsafeFPMath)
707 Builder.defineMacro("__ARM_FP_FAST", "1");
712 case llvm::ARM::ArchKind::ARMV8_1A:
713 getTargetDefinesARMV81A(Opts, Builder);
715 case llvm::ARM::ArchKind::ARMV8_2A:
716 getTargetDefinesARMV82A(Opts, Builder);
721 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
722 #define BUILTIN(ID, TYPE, ATTRS) \
723 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
724 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
725 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
726 #include "clang/Basic/BuiltinsNEON.def"
728 #define BUILTIN(ID, TYPE, ATTRS) \
729 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
730 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
731 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
732 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
733 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
734 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
735 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
736 #include "clang/Basic/BuiltinsARM.def"
739 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
740 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
741 Builtin::FirstTSBuiltin);
744 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
745 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
747 ? AAPCSABIBuiltinVaList
748 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
749 : TargetInfo::VoidPtrBuiltinVaList);
752 const char *const ARMTargetInfo::GCCRegNames[] = {
754 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
755 "r12", "sp", "lr", "pc",
758 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
759 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
760 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
763 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
764 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
765 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
768 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
769 "q12", "q13", "q14", "q15"};
771 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
772 return llvm::makeArrayRef(GCCRegNames);
775 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
776 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
777 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
778 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
779 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
780 // The S, D and Q registers overlap, but aren't really aliases; we
781 // don't want to substitute one of these for a different-sized one.
784 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
785 return llvm::makeArrayRef(GCCRegAliases);
788 bool ARMTargetInfo::validateAsmConstraint(
789 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
795 case 't': // VFP Floating point register single precision
796 case 'w': // VFP Floating point register double precision
797 Info.setAllowsRegister();
806 case 'Q': // A memory address that is a single base register.
807 Info.setAllowsMemory();
809 case 'U': // a memory reference...
811 case 'q': // ...ARMV4 ldrsb
812 case 'v': // ...VFP load/store (reg+constant offset)
813 case 'y': // ...iWMMXt load/store
814 case 't': // address valid for load/store opaque types wider
816 case 'n': // valid address for Neon doubleword vector load/store
817 case 'm': // valid address for Neon element and structure load/store
818 case 's': // valid address for non-offset loads/stores of quad-word
819 // values in four ARM registers
820 Info.setAllowsMemory();
828 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
830 switch (*Constraint) {
831 case 'U': // Two-character constraint; add "^" hint for later parsing.
832 R = std::string("^") + std::string(Constraint, 2);
835 case 'p': // 'p' should be translated to 'r' by default.
836 R = std::string("r");
839 return std::string(1, *Constraint);
844 bool ARMTargetInfo::validateConstraintModifier(
845 StringRef Constraint, char Modifier, unsigned Size,
846 std::string &SuggestedModifier) const {
847 bool isOutput = (Constraint[0] == '=');
848 bool isInOut = (Constraint[0] == '+');
850 // Strip off constraint modifiers.
851 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
852 Constraint = Constraint.substr(1);
854 switch (Constraint[0]) {
860 return (isInOut || isOutput || Size <= 64);
862 // A register of size 32 cannot fit a vector type.
870 const char *ARMTargetInfo::getClobbers() const {
871 // FIXME: Is this really right?
875 TargetInfo::CallingConvCheckResult
876 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
881 case CC_OpenCLKernel:
888 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
896 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
898 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
899 const TargetOptions &Opts)
900 : ARMTargetInfo(Triple, Opts) {}
902 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
903 MacroBuilder &Builder) const {
904 Builder.defineMacro("__ARMEL__");
905 ARMTargetInfo::getTargetDefines(Opts, Builder);
908 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
909 const TargetOptions &Opts)
910 : ARMTargetInfo(Triple, Opts) {}
912 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
913 MacroBuilder &Builder) const {
914 Builder.defineMacro("__ARMEB__");
915 Builder.defineMacro("__ARM_BIG_ENDIAN");
916 ARMTargetInfo::getTargetDefines(Opts, Builder);
919 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
920 const TargetOptions &Opts)
921 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
924 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
925 MacroBuilder &Builder) const {
926 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
928 // FIXME: this is invalid for WindowsCE
929 Builder.defineMacro("_M_ARM_NT", "1");
930 Builder.defineMacro("_M_ARMT", "_M_ARM");
931 Builder.defineMacro("_M_THUMB", "_M_ARM");
933 assert((Triple.getArch() == llvm::Triple::arm ||
934 Triple.getArch() == llvm::Triple::thumb) &&
935 "invalid architecture for Windows ARM target info");
936 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
937 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
939 // TODO map the complete set of values
940 // 31: VFPv3 40: VFPv4
941 Builder.defineMacro("_M_ARM_FP", "31");
944 TargetInfo::BuiltinVaListKind
945 WindowsARMTargetInfo::getBuiltinVaListKind() const {
946 return TargetInfo::CharPtrBuiltinVaList;
949 TargetInfo::CallingConvCheckResult
950 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
955 case CC_X86VectorCall:
958 case CC_OpenCLKernel:
965 // Windows ARM + Itanium C++ ABI Target
966 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
967 const llvm::Triple &Triple, const TargetOptions &Opts)
968 : WindowsARMTargetInfo(Triple, Opts) {
969 TheCXXABI.set(TargetCXXABI::GenericARM);
972 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
973 const LangOptions &Opts, MacroBuilder &Builder) const {
974 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
977 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
980 // Windows ARM, MS (C++) ABI
981 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
982 const TargetOptions &Opts)
983 : WindowsARMTargetInfo(Triple, Opts) {
984 TheCXXABI.set(TargetCXXABI::Microsoft);
987 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
988 MacroBuilder &Builder) const {
989 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
990 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
993 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
994 const TargetOptions &Opts)
995 : WindowsARMTargetInfo(Triple, Opts) {
996 TheCXXABI.set(TargetCXXABI::GenericARM);
999 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1000 MacroBuilder &Builder) const {
1001 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1002 Builder.defineMacro("_ARM_");
1005 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1006 const TargetOptions &Opts)
1007 : ARMleTargetInfo(Triple, Opts) {
1008 this->WCharType = TargetInfo::UnsignedShort;
1009 TLSSupported = false;
1010 DoubleAlign = LongLongAlign = 64;
1011 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1014 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1015 MacroBuilder &Builder) const {
1016 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1017 Builder.defineMacro("_ARM_");
1018 Builder.defineMacro("__CYGWIN__");
1019 Builder.defineMacro("__CYGWIN32__");
1020 DefineStd(Builder, "unix", Opts);
1022 Builder.defineMacro("_GNU_SOURCE");
1025 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1026 const TargetOptions &Opts)
1027 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1028 HasAlignMac68kSupport = true;
1029 // iOS always has 64-bit atomic instructions.
1030 // FIXME: This should be based off of the target features in
1032 MaxAtomicInlineWidth = 64;
1034 if (Triple.isWatchABI()) {
1035 // Darwin on iOS uses a variant of the ARM C++ ABI.
1036 TheCXXABI.set(TargetCXXABI::WatchOS);
1038 // BOOL should be a real boolean on the new ABI
1039 UseSignedCharForObjCBool = false;
1041 TheCXXABI.set(TargetCXXABI::iOS);
1044 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1045 const llvm::Triple &Triple,
1046 MacroBuilder &Builder) const {
1047 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1050 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1051 const TargetOptions &Opts)
1052 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1054 Triple.getEnvironmentName()),
1056 IsRenderScriptTarget = true;
1057 LongWidth = LongAlign = 64;
1060 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1061 MacroBuilder &Builder) const {
1062 Builder.defineMacro("__RENDERSCRIPT__");
1063 ARMleTargetInfo::getTargetDefines(Opts, Builder);