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;
401 // This does not diagnose illegal cases like having both
402 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
403 uint32_t HW_FP_remove = 0;
404 for (const auto &Feature : Features) {
405 if (Feature == "+soft-float") {
407 } else if (Feature == "+soft-float-abi") {
409 } else if (Feature == "+vfp2") {
411 HW_FP |= HW_FP_SP | HW_FP_DP;
412 } else if (Feature == "+vfp3") {
414 HW_FP |= HW_FP_SP | HW_FP_DP;
415 } else if (Feature == "+vfp4") {
417 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
418 } else if (Feature == "+fp-armv8") {
420 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
421 } else if (Feature == "+neon") {
423 HW_FP |= HW_FP_SP | HW_FP_DP;
424 } else if (Feature == "+hwdiv") {
426 } else if (Feature == "+hwdiv-arm") {
428 } else if (Feature == "+crc") {
430 } else if (Feature == "+crypto") {
432 } else if (Feature == "+dsp") {
434 } else if (Feature == "+fp-only-sp") {
435 HW_FP_remove |= HW_FP_DP;
436 } else if (Feature == "+strict-align") {
438 } else if (Feature == "+fp16") {
440 } else if (Feature == "+fullfp16") {
441 HasLegalHalfType = true;
442 } else if (Feature == "+dotprod") {
446 HW_FP &= ~HW_FP_remove;
448 switch (ArchVersion) {
450 if (ArchProfile == llvm::ARM::ProfileKind::M)
452 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
453 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
458 if (ArchProfile == llvm::ARM::ProfileKind::M)
459 LDREX = LDREX_W | LDREX_H | LDREX_B;
461 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
464 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
467 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
468 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
472 if (FPMath == FP_Neon)
473 Features.push_back("+neonfp");
474 else if (FPMath == FP_VFP)
475 Features.push_back("-neonfp");
477 // Remove front-end specific options which the backend handles differently.
478 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
479 if (Feature != Features.end())
480 Features.erase(Feature);
485 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
486 return llvm::StringSwitch<bool>(Feature)
488 .Case("aarch32", true)
489 .Case("softfloat", SoftFloat)
490 .Case("thumb", isThumb())
491 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
492 .Case("vfp", FPU && !SoftFloat)
493 .Case("hwdiv", HWDiv & HWDivThumb)
494 .Case("hwdiv-arm", HWDiv & HWDivARM)
498 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
499 return Name == "generic" ||
500 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
503 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
504 llvm::ARM::fillValidCPUArchList(Values);
507 bool ARMTargetInfo::setCPU(const std::string &Name) {
508 if (Name != "generic")
509 setArchInfo(llvm::ARM::parseCPUArch(Name));
511 if (ArchKind == llvm::ARM::ArchKind::INVALID)
518 bool ARMTargetInfo::setFPMath(StringRef Name) {
519 if (Name == "neon") {
522 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
530 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
531 MacroBuilder &Builder) const {
532 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
535 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
536 MacroBuilder &Builder) const {
537 // Also include the ARMv8.1-A defines
538 getTargetDefinesARMV81A(Opts, Builder);
541 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
542 MacroBuilder &Builder) const {
543 // Target identification.
544 Builder.defineMacro("__arm");
545 Builder.defineMacro("__arm__");
546 // For bare-metal none-eabi.
547 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
548 (getTriple().getEnvironment() == llvm::Triple::EABI ||
549 getTriple().getEnvironment() == llvm::Triple::EABIHF))
550 Builder.defineMacro("__ELF__");
552 // Target properties.
553 Builder.defineMacro("__REGISTER_PREFIX__", "");
555 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
556 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
557 if (getTriple().isWatchABI())
558 Builder.defineMacro("__ARM_ARCH_7K__", "2");
560 if (!CPUAttr.empty())
561 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
563 // ACLE 6.4.1 ARM/Thumb instruction set architecture
564 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
565 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
567 if (ArchVersion >= 8) {
568 // ACLE 6.5.7 Crypto Extension
570 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
571 // ACLE 6.5.8 CRC32 Extension
573 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
574 // ACLE 6.5.10 Numeric Maximum and Minimum
575 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
576 // ACLE 6.5.9 Directed Rounding
577 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
580 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
581 // is not defined for the M-profile.
582 // NOTE that the default profile is assumed to be 'A'
583 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
584 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
586 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
587 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
588 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
589 // v7 and v8 architectures excluding v8-M Baseline.
590 if (supportsThumb2())
591 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
592 else if (supportsThumb())
593 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
595 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
596 // instruction set such as ARM or Thumb.
597 Builder.defineMacro("__ARM_32BIT_STATE", "1");
599 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
601 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
602 if (!CPUProfile.empty())
603 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
605 // ACLE 6.4.3 Unaligned access supported in hardware
607 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
609 // ACLE 6.4.4 LDREX/STREX
611 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
614 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
616 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
618 // ACLE 6.5.1 Hardware Floating Point
620 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
623 Builder.defineMacro("__ARM_ACLE", "200");
625 // FP16 support (we currently only support IEEE format).
626 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
627 Builder.defineMacro("__ARM_FP16_ARGS", "1");
629 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
630 if (ArchVersion >= 7 && (FPU & VFP4FPU))
631 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
633 // Subtarget options.
635 // FIXME: It's more complicated than this and we don't really support
637 // Windows on ARM does not "support" interworking
638 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
639 Builder.defineMacro("__THUMB_INTERWORK__");
641 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
642 // Embedded targets on Darwin follow AAPCS, but not EABI.
643 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
644 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
645 Builder.defineMacro("__ARM_EABI__");
646 Builder.defineMacro("__ARM_PCS", "1");
649 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
650 Builder.defineMacro("__ARM_PCS_VFP", "1");
653 Builder.defineMacro("__SOFTFP__");
655 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
656 Builder.defineMacro("__XSCALE__");
659 Builder.defineMacro("__THUMBEL__");
660 Builder.defineMacro("__thumb__");
661 if (supportsThumb2())
662 Builder.defineMacro("__thumb2__");
665 // ACLE 6.4.9 32-bit SIMD instructions
666 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
667 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
669 // ACLE 6.4.10 Hardware Integer Divide
670 if (((HWDiv & HWDivThumb) && isThumb()) ||
671 ((HWDiv & HWDivARM) && !isThumb())) {
672 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
673 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
676 // Note, this is always on in gcc, even though it doesn't make sense.
677 Builder.defineMacro("__APCS_32__");
679 if (FPUModeIsVFP((FPUMode)FPU)) {
680 Builder.defineMacro("__VFP_FP__");
682 Builder.defineMacro("__ARM_VFPV2__");
684 Builder.defineMacro("__ARM_VFPV3__");
686 Builder.defineMacro("__ARM_VFPV4__");
688 Builder.defineMacro("__ARM_FPV5__");
691 // This only gets set when Neon instructions are actually available, unlike
692 // the VFP define, hence the soft float and arch check. This is subtly
693 // different from gcc, we follow the intent which was that it should be set
694 // when Neon instructions are actually available.
695 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
696 Builder.defineMacro("__ARM_NEON", "1");
697 Builder.defineMacro("__ARM_NEON__");
698 // current AArch32 NEON implementations do not support double-precision
699 // floating-point even when it is present in VFP.
700 Builder.defineMacro("__ARM_NEON_FP",
701 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
704 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
705 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
707 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
709 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
710 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
711 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
712 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
713 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
716 // ACLE 6.4.7 DSP instructions
718 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
721 // ACLE 6.4.8 Saturation instructions
723 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
724 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
728 // ACLE 6.4.6 Q (saturation) flag
730 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
732 if (Opts.UnsafeFPMath)
733 Builder.defineMacro("__ARM_FP_FAST", "1");
735 // Armv8.2-A FP16 vector intrinsic
736 if ((FPU & NeonFPU) && HasLegalHalfType)
737 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
739 // Armv8.2-A FP16 scalar intrinsics
740 if (HasLegalHalfType)
741 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
743 // Armv8.2-A dot product intrinsics
745 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
750 case llvm::ARM::ArchKind::ARMV8_1A:
751 getTargetDefinesARMV81A(Opts, Builder);
753 case llvm::ARM::ArchKind::ARMV8_2A:
754 getTargetDefinesARMV82A(Opts, Builder);
759 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
760 #define BUILTIN(ID, TYPE, ATTRS) \
761 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
762 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
763 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
764 #include "clang/Basic/BuiltinsNEON.def"
766 #define BUILTIN(ID, TYPE, ATTRS) \
767 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
768 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
769 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
770 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
771 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
772 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
773 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
774 #include "clang/Basic/BuiltinsARM.def"
777 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
778 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
779 Builtin::FirstTSBuiltin);
782 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
783 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
785 ? AAPCSABIBuiltinVaList
786 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
787 : TargetInfo::VoidPtrBuiltinVaList);
790 const char *const ARMTargetInfo::GCCRegNames[] = {
792 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
793 "r12", "sp", "lr", "pc",
796 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
797 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
798 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
801 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
802 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
803 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
806 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
807 "q12", "q13", "q14", "q15"};
809 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
810 return llvm::makeArrayRef(GCCRegNames);
813 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
814 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
815 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
816 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
817 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
818 // The S, D and Q registers overlap, but aren't really aliases; we
819 // don't want to substitute one of these for a different-sized one.
822 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
823 return llvm::makeArrayRef(GCCRegAliases);
826 bool ARMTargetInfo::validateAsmConstraint(
827 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
833 case 't': // VFP Floating point register single precision
834 case 'w': // VFP Floating point register double precision
835 Info.setAllowsRegister();
844 case 'Q': // A memory address that is a single base register.
845 Info.setAllowsMemory();
847 case 'U': // a memory reference...
849 case 'q': // ...ARMV4 ldrsb
850 case 'v': // ...VFP load/store (reg+constant offset)
851 case 'y': // ...iWMMXt load/store
852 case 't': // address valid for load/store opaque types wider
854 case 'n': // valid address for Neon doubleword vector load/store
855 case 'm': // valid address for Neon element and structure load/store
856 case 's': // valid address for non-offset loads/stores of quad-word
857 // values in four ARM registers
858 Info.setAllowsMemory();
866 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
868 switch (*Constraint) {
869 case 'U': // Two-character constraint; add "^" hint for later parsing.
870 R = std::string("^") + std::string(Constraint, 2);
873 case 'p': // 'p' should be translated to 'r' by default.
874 R = std::string("r");
877 return std::string(1, *Constraint);
882 bool ARMTargetInfo::validateConstraintModifier(
883 StringRef Constraint, char Modifier, unsigned Size,
884 std::string &SuggestedModifier) const {
885 bool isOutput = (Constraint[0] == '=');
886 bool isInOut = (Constraint[0] == '+');
888 // Strip off constraint modifiers.
889 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
890 Constraint = Constraint.substr(1);
892 switch (Constraint[0]) {
898 return (isInOut || isOutput || Size <= 64);
900 // A register of size 32 cannot fit a vector type.
908 const char *ARMTargetInfo::getClobbers() const {
909 // FIXME: Is this really right?
913 TargetInfo::CallingConvCheckResult
914 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
919 case CC_OpenCLKernel:
926 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
934 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
936 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
937 const TargetOptions &Opts)
938 : ARMTargetInfo(Triple, Opts) {}
940 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
941 MacroBuilder &Builder) const {
942 Builder.defineMacro("__ARMEL__");
943 ARMTargetInfo::getTargetDefines(Opts, Builder);
946 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
947 const TargetOptions &Opts)
948 : ARMTargetInfo(Triple, Opts) {}
950 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
951 MacroBuilder &Builder) const {
952 Builder.defineMacro("__ARMEB__");
953 Builder.defineMacro("__ARM_BIG_ENDIAN");
954 ARMTargetInfo::getTargetDefines(Opts, Builder);
957 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
958 const TargetOptions &Opts)
959 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
962 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
963 MacroBuilder &Builder) const {
964 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
966 // FIXME: this is invalid for WindowsCE
967 Builder.defineMacro("_M_ARM_NT", "1");
968 Builder.defineMacro("_M_ARMT", "_M_ARM");
969 Builder.defineMacro("_M_THUMB", "_M_ARM");
971 assert((Triple.getArch() == llvm::Triple::arm ||
972 Triple.getArch() == llvm::Triple::thumb) &&
973 "invalid architecture for Windows ARM target info");
974 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
975 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
977 // TODO map the complete set of values
978 // 31: VFPv3 40: VFPv4
979 Builder.defineMacro("_M_ARM_FP", "31");
982 TargetInfo::BuiltinVaListKind
983 WindowsARMTargetInfo::getBuiltinVaListKind() const {
984 return TargetInfo::CharPtrBuiltinVaList;
987 TargetInfo::CallingConvCheckResult
988 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
993 case CC_X86VectorCall:
996 case CC_OpenCLKernel:
997 case CC_PreserveMost:
1002 return CCCR_Warning;
1006 // Windows ARM + Itanium C++ ABI Target
1007 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1008 const llvm::Triple &Triple, const TargetOptions &Opts)
1009 : WindowsARMTargetInfo(Triple, Opts) {
1010 TheCXXABI.set(TargetCXXABI::GenericARM);
1013 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1014 const LangOptions &Opts, MacroBuilder &Builder) const {
1015 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1017 if (Opts.MSVCCompat)
1018 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1021 // Windows ARM, MS (C++) ABI
1022 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1023 const TargetOptions &Opts)
1024 : WindowsARMTargetInfo(Triple, Opts) {
1025 TheCXXABI.set(TargetCXXABI::Microsoft);
1028 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1029 MacroBuilder &Builder) const {
1030 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1031 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1034 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1035 const TargetOptions &Opts)
1036 : WindowsARMTargetInfo(Triple, Opts) {
1037 TheCXXABI.set(TargetCXXABI::GenericARM);
1040 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1041 MacroBuilder &Builder) const {
1042 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1043 Builder.defineMacro("_ARM_");
1046 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1047 const TargetOptions &Opts)
1048 : ARMleTargetInfo(Triple, Opts) {
1049 this->WCharType = TargetInfo::UnsignedShort;
1050 TLSSupported = false;
1051 DoubleAlign = LongLongAlign = 64;
1052 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1055 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1056 MacroBuilder &Builder) const {
1057 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1058 Builder.defineMacro("_ARM_");
1059 Builder.defineMacro("__CYGWIN__");
1060 Builder.defineMacro("__CYGWIN32__");
1061 DefineStd(Builder, "unix", Opts);
1063 Builder.defineMacro("_GNU_SOURCE");
1066 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1067 const TargetOptions &Opts)
1068 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1069 HasAlignMac68kSupport = true;
1070 // iOS always has 64-bit atomic instructions.
1071 // FIXME: This should be based off of the target features in
1073 MaxAtomicInlineWidth = 64;
1075 if (Triple.isWatchABI()) {
1076 // Darwin on iOS uses a variant of the ARM C++ ABI.
1077 TheCXXABI.set(TargetCXXABI::WatchOS);
1079 // BOOL should be a real boolean on the new ABI
1080 UseSignedCharForObjCBool = false;
1082 TheCXXABI.set(TargetCXXABI::iOS);
1085 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1086 const llvm::Triple &Triple,
1087 MacroBuilder &Builder) const {
1088 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1091 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1092 const TargetOptions &Opts)
1093 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1095 Triple.getEnvironmentName()),
1097 IsRenderScriptTarget = true;
1098 LongWidth = LongAlign = 64;
1101 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1102 MacroBuilder &Builder) const {
1103 Builder.defineMacro("__RENDERSCRIPT__");
1104 ARMleTargetInfo::getTargetDefines(Opts, Builder);