[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / lib / Basic / Targets / ARM.cpp
blobf11751a7607311c478d387b056df17796ad59002
1 //===--- ARM.cpp - Implement ARM target feature support -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements ARM TargetInfo objects.
11 //===----------------------------------------------------------------------===//
13 #include "ARM.h"
14 #include "clang/Basic/Builtins.h"
15 #include "clang/Basic/Diagnostic.h"
16 #include "clang/Basic/TargetBuiltins.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/StringSwitch.h"
21 using namespace clang;
22 using namespace clang::targets;
24 void ARMTargetInfo::setABIAAPCS() {
25 IsAAPCS = true;
27 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
28 BFloat16Width = BFloat16Align = 16;
29 BFloat16Format = &llvm::APFloat::BFloat();
31 const llvm::Triple &T = getTriple();
33 bool IsNetBSD = T.isOSNetBSD();
34 bool IsOpenBSD = T.isOSOpenBSD();
35 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
36 WCharType = UnsignedInt;
38 UseBitFieldTypeAlignment = true;
40 ZeroLengthBitfieldBoundary = 0;
42 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
43 // so set preferred for small types to 32.
44 if (T.isOSBinFormatMachO()) {
45 resetDataLayout(BigEndian
46 ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
47 : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
48 "_");
49 } else if (T.isOSWindows()) {
50 assert(!BigEndian && "Windows on ARM does not support big endian");
51 resetDataLayout("e"
52 "-m:w"
53 "-p:32:32"
54 "-Fi8"
55 "-i64:64"
56 "-v128:64:128"
57 "-a:0:32"
58 "-n32"
59 "-S64");
60 } else if (T.isOSNaCl()) {
61 assert(!BigEndian && "NaCl on ARM does not support big endian");
62 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
63 } else {
64 resetDataLayout(BigEndian
65 ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
66 : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
69 // FIXME: Enumerated types are variable width in straight AAPCS.
72 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
73 const llvm::Triple &T = getTriple();
75 IsAAPCS = false;
77 if (IsAAPCS16)
78 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
79 else
80 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
81 BFloat16Width = BFloat16Align = 16;
82 BFloat16Format = &llvm::APFloat::BFloat();
84 WCharType = SignedInt;
86 // Do not respect the alignment of bit-field types when laying out
87 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
88 UseBitFieldTypeAlignment = false;
90 /// gcc forces the alignment to 4 bytes, regardless of the type of the
91 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
92 /// gcc.
93 ZeroLengthBitfieldBoundary = 32;
95 if (T.isOSBinFormatMachO() && IsAAPCS16) {
96 assert(!BigEndian && "AAPCS16 does not support big-endian");
97 resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_");
98 } else if (T.isOSBinFormatMachO())
99 resetDataLayout(
100 BigEndian
101 ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
102 : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32",
103 "_");
104 else
105 resetDataLayout(
106 BigEndian
107 ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
108 : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
110 // FIXME: Override "preferred align" for double and long long.
113 void ARMTargetInfo::setArchInfo() {
114 StringRef ArchName = getTriple().getArchName();
116 ArchISA = llvm::ARM::parseArchISA(ArchName);
117 CPU = std::string(llvm::ARM::getDefaultCPU(ArchName));
118 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
119 if (AK != llvm::ARM::ArchKind::INVALID)
120 ArchKind = AK;
121 setArchInfo(ArchKind);
124 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
125 StringRef SubArch;
127 // cache TargetParser info
128 ArchKind = Kind;
129 SubArch = llvm::ARM::getSubArch(ArchKind);
130 ArchProfile = llvm::ARM::parseArchProfile(SubArch);
131 ArchVersion = llvm::ARM::parseArchVersion(SubArch);
133 // cache CPU related strings
134 CPUAttr = getCPUAttr();
135 CPUProfile = getCPUProfile();
138 void ARMTargetInfo::setAtomic() {
139 // when triple does not specify a sub arch,
140 // then we are not using inline atomics
141 bool ShouldUseInlineAtomic =
142 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
143 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
144 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
145 if (ArchProfile == llvm::ARM::ProfileKind::M) {
146 MaxAtomicPromoteWidth = 32;
147 if (ShouldUseInlineAtomic)
148 MaxAtomicInlineWidth = 32;
149 } else {
150 MaxAtomicPromoteWidth = 64;
151 if (ShouldUseInlineAtomic)
152 MaxAtomicInlineWidth = 64;
156 bool ARMTargetInfo::hasMVE() const {
157 return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;
160 bool ARMTargetInfo::hasMVEFloat() const {
161 return hasMVE() && (MVE & MVE_FP);
164 bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; }
166 bool ARMTargetInfo::isThumb() const {
167 return ArchISA == llvm::ARM::ISAKind::THUMB;
170 bool ARMTargetInfo::supportsThumb() const {
171 return CPUAttr.count('T') || ArchVersion >= 6;
174 bool ARMTargetInfo::supportsThumb2() const {
175 return CPUAttr.equals("6T2") ||
176 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
179 StringRef ARMTargetInfo::getCPUAttr() const {
180 // For most sub-arches, the build attribute CPU name is enough.
181 // For Cortex variants, it's slightly different.
182 switch (ArchKind) {
183 default:
184 return llvm::ARM::getCPUAttr(ArchKind);
185 case llvm::ARM::ArchKind::ARMV6M:
186 return "6M";
187 case llvm::ARM::ArchKind::ARMV7S:
188 return "7S";
189 case llvm::ARM::ArchKind::ARMV7A:
190 return "7A";
191 case llvm::ARM::ArchKind::ARMV7R:
192 return "7R";
193 case llvm::ARM::ArchKind::ARMV7M:
194 return "7M";
195 case llvm::ARM::ArchKind::ARMV7EM:
196 return "7EM";
197 case llvm::ARM::ArchKind::ARMV7VE:
198 return "7VE";
199 case llvm::ARM::ArchKind::ARMV8A:
200 return "8A";
201 case llvm::ARM::ArchKind::ARMV8_1A:
202 return "8_1A";
203 case llvm::ARM::ArchKind::ARMV8_2A:
204 return "8_2A";
205 case llvm::ARM::ArchKind::ARMV8_3A:
206 return "8_3A";
207 case llvm::ARM::ArchKind::ARMV8_4A:
208 return "8_4A";
209 case llvm::ARM::ArchKind::ARMV8_5A:
210 return "8_5A";
211 case llvm::ARM::ArchKind::ARMV8_6A:
212 return "8_6A";
213 case llvm::ARM::ArchKind::ARMV8_7A:
214 return "8_7A";
215 case llvm::ARM::ArchKind::ARMV8_8A:
216 return "8_8A";
217 case llvm::ARM::ArchKind::ARMV8_9A:
218 return "8_9A";
219 case llvm::ARM::ArchKind::ARMV9A:
220 return "9A";
221 case llvm::ARM::ArchKind::ARMV9_1A:
222 return "9_1A";
223 case llvm::ARM::ArchKind::ARMV9_2A:
224 return "9_2A";
225 case llvm::ARM::ArchKind::ARMV9_3A:
226 return "9_3A";
227 case llvm::ARM::ArchKind::ARMV9_4A:
228 return "9_4A";
229 case llvm::ARM::ArchKind::ARMV8MBaseline:
230 return "8M_BASE";
231 case llvm::ARM::ArchKind::ARMV8MMainline:
232 return "8M_MAIN";
233 case llvm::ARM::ArchKind::ARMV8R:
234 return "8R";
235 case llvm::ARM::ArchKind::ARMV8_1MMainline:
236 return "8_1M_MAIN";
240 StringRef ARMTargetInfo::getCPUProfile() const {
241 switch (ArchProfile) {
242 case llvm::ARM::ProfileKind::A:
243 return "A";
244 case llvm::ARM::ProfileKind::R:
245 return "R";
246 case llvm::ARM::ProfileKind::M:
247 return "M";
248 default:
249 return "";
253 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
254 const TargetOptions &Opts)
255 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
256 HW_FP(0) {
257 bool IsOpenBSD = Triple.isOSOpenBSD();
258 bool IsNetBSD = Triple.isOSNetBSD();
260 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
261 // environment where size_t is `unsigned long` rather than `unsigned int`
263 PtrDiffType = IntPtrType =
264 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
265 IsNetBSD)
266 ? SignedLong
267 : SignedInt;
269 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
270 IsNetBSD)
271 ? UnsignedLong
272 : UnsignedInt;
274 // ptrdiff_t is inconsistent on Darwin
275 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
276 !Triple.isWatchABI())
277 PtrDiffType = SignedInt;
279 // Cache arch related info.
280 setArchInfo();
282 // {} in inline assembly are neon specifiers, not assembly variant
283 // specifiers.
284 NoAsmVariants = true;
286 // FIXME: This duplicates code from the driver that sets the -target-abi
287 // option - this code is used if -target-abi isn't passed and should
288 // be unified in some way.
289 if (Triple.isOSBinFormatMachO()) {
290 // The backend is hardwired to assume AAPCS for M-class processors, ensure
291 // the frontend matches that.
292 if (Triple.getEnvironment() == llvm::Triple::EABI ||
293 Triple.getOS() == llvm::Triple::UnknownOS ||
294 ArchProfile == llvm::ARM::ProfileKind::M) {
295 setABI("aapcs");
296 } else if (Triple.isWatchABI()) {
297 setABI("aapcs16");
298 } else {
299 setABI("apcs-gnu");
301 } else if (Triple.isOSWindows()) {
302 // FIXME: this is invalid for WindowsCE
303 setABI("aapcs");
304 } else {
305 // Select the default based on the platform.
306 switch (Triple.getEnvironment()) {
307 case llvm::Triple::Android:
308 case llvm::Triple::GNUEABI:
309 case llvm::Triple::GNUEABIHF:
310 case llvm::Triple::MuslEABI:
311 case llvm::Triple::MuslEABIHF:
312 setABI("aapcs-linux");
313 break;
314 case llvm::Triple::EABIHF:
315 case llvm::Triple::EABI:
316 setABI("aapcs");
317 break;
318 case llvm::Triple::GNU:
319 setABI("apcs-gnu");
320 break;
321 default:
322 if (IsNetBSD)
323 setABI("apcs-gnu");
324 else if (IsOpenBSD)
325 setABI("aapcs-linux");
326 else
327 setABI("aapcs");
328 break;
332 // ARM targets default to using the ARM C++ ABI.
333 TheCXXABI.set(TargetCXXABI::GenericARM);
335 // ARM has atomics up to 8 bytes
336 setAtomic();
338 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
339 // as well the default alignment
340 if (IsAAPCS && !Triple.isAndroid())
341 DefaultAlignForAttributeAligned = MaxVectorAlign = 64;
343 // Do force alignment of members that follow zero length bitfields. If
344 // the alignment of the zero-length bitfield is greater than the member
345 // that follows it, `bar', `bar' will be aligned as the type of the
346 // zero length bitfield.
347 UseZeroLengthBitfieldAlignment = true;
349 if (Triple.getOS() == llvm::Triple::Linux ||
350 Triple.getOS() == llvm::Triple::UnknownOS)
351 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
352 ? "llvm.arm.gnu.eabi.mcount"
353 : "\01mcount";
355 SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
358 StringRef ARMTargetInfo::getABI() const { return ABI; }
360 bool ARMTargetInfo::setABI(const std::string &Name) {
361 ABI = Name;
363 // The defaults (above) are for AAPCS, check if we need to change them.
365 // FIXME: We need support for -meabi... we could just mangle it into the
366 // name.
367 if (Name == "apcs-gnu" || Name == "aapcs16") {
368 setABIAPCS(Name == "aapcs16");
369 return true;
371 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
372 setABIAAPCS();
373 return true;
375 return false;
378 bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {
379 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);
380 if (CPUArch == llvm::ARM::ArchKind::INVALID)
381 CPUArch = llvm::ARM::parseArch(getTriple().getArchName());
383 if (CPUArch == llvm::ARM::ArchKind::INVALID)
384 return false;
386 StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
387 auto a =
388 llvm::Triple(ArchFeature, getTriple().getVendorName(),
389 getTriple().getOSName(), getTriple().getEnvironmentName());
391 StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
392 llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
393 return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
396 bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
397 BranchProtectionInfo &BPI,
398 StringRef &Err) const {
399 llvm::ARM::ParsedBranchProtection PBP;
400 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
401 return false;
403 if (!isBranchProtectionSupportedArch(Arch))
404 return false;
406 BPI.SignReturnAddr =
407 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
408 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
409 .Case("all", LangOptions::SignReturnAddressScopeKind::All)
410 .Default(LangOptions::SignReturnAddressScopeKind::None);
412 // Don't care for the sign key, beyond issuing a warning.
413 if (PBP.Key == "b_key")
414 Err = "b-key";
415 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
417 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
418 return true;
421 // FIXME: This should be based on Arch attributes, not CPU names.
422 bool ARMTargetInfo::initFeatureMap(
423 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
424 const std::vector<std::string> &FeaturesVec) const {
426 std::string ArchFeature;
427 std::vector<StringRef> TargetFeatures;
428 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
430 // Map the base architecture to an appropriate target feature, so we don't
431 // rely on the target triple.
432 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
433 if (CPUArch == llvm::ARM::ArchKind::INVALID)
434 CPUArch = Arch;
435 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
436 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
437 TargetFeatures.push_back(ArchFeature);
439 // These features are added to allow arm_neon.h target(..) attributes to
440 // match with both arm and aarch64. We need to add all previous architecture
441 // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
442 // v8.x counterparts are added too. We only need these for anything > 8.0-A.
443 for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch);
444 I != llvm::ARM::ArchKind::INVALID; --I)
445 Features[llvm::ARM::getSubArch(I)] = true;
446 if (CPUArch > llvm::ARM::ArchKind::ARMV8A &&
447 CPUArch <= llvm::ARM::ArchKind::ARMV9_3A)
448 for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID;
449 --I)
450 Features[llvm::ARM::getSubArch(I)] = true;
453 // get default FPU features
454 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
455 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
457 // get default Extension features
458 uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
459 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
461 for (auto Feature : TargetFeatures)
462 if (Feature[0] == '+')
463 Features[Feature.drop_front(1)] = true;
465 // Enable or disable thumb-mode explicitly per function to enable mixed
466 // ARM and Thumb code generation.
467 if (isThumb())
468 Features["thumb-mode"] = true;
469 else
470 Features["thumb-mode"] = false;
472 // Convert user-provided arm and thumb GNU target attributes to
473 // [-|+]thumb-mode target features respectively.
474 std::vector<std::string> UpdatedFeaturesVec;
475 for (const auto &Feature : FeaturesVec) {
476 // Skip soft-float-abi; it's something we only use to initialize a bit of
477 // class state, and is otherwise unrecognized.
478 if (Feature == "+soft-float-abi")
479 continue;
481 StringRef FixedFeature;
482 if (Feature == "+arm")
483 FixedFeature = "-thumb-mode";
484 else if (Feature == "+thumb")
485 FixedFeature = "+thumb-mode";
486 else
487 FixedFeature = Feature;
488 UpdatedFeaturesVec.push_back(FixedFeature.str());
491 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
495 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
496 DiagnosticsEngine &Diags) {
497 FPU = 0;
498 MVE = 0;
499 CRC = 0;
500 Crypto = 0;
501 SHA2 = 0;
502 AES = 0;
503 DSP = 0;
504 Unaligned = 1;
505 SoftFloat = false;
506 // Note that SoftFloatABI is initialized in our constructor.
507 HWDiv = 0;
508 DotProd = 0;
509 HasMatMul = 0;
510 HasPAC = 0;
511 HasBTI = 0;
512 HasFloat16 = true;
513 ARMCDECoprocMask = 0;
514 HasBFloat16 = false;
515 FPRegsDisabled = false;
517 // This does not diagnose illegal cases like having both
518 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
519 for (const auto &Feature : Features) {
520 if (Feature == "+soft-float") {
521 SoftFloat = true;
522 } else if (Feature == "+vfp2sp" || Feature == "+vfp2") {
523 FPU |= VFP2FPU;
524 HW_FP |= HW_FP_SP;
525 if (Feature == "+vfp2")
526 HW_FP |= HW_FP_DP;
527 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
528 Feature == "+vfp3" || Feature == "+vfp3d16") {
529 FPU |= VFP3FPU;
530 HW_FP |= HW_FP_SP;
531 if (Feature == "+vfp3" || Feature == "+vfp3d16")
532 HW_FP |= HW_FP_DP;
533 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
534 Feature == "+vfp4" || Feature == "+vfp4d16") {
535 FPU |= VFP4FPU;
536 HW_FP |= HW_FP_SP | HW_FP_HP;
537 if (Feature == "+vfp4" || Feature == "+vfp4d16")
538 HW_FP |= HW_FP_DP;
539 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
540 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
541 FPU |= FPARMV8;
542 HW_FP |= HW_FP_SP | HW_FP_HP;
543 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
544 HW_FP |= HW_FP_DP;
545 } else if (Feature == "+neon") {
546 FPU |= NeonFPU;
547 HW_FP |= HW_FP_SP;
548 } else if (Feature == "+hwdiv") {
549 HWDiv |= HWDivThumb;
550 } else if (Feature == "+hwdiv-arm") {
551 HWDiv |= HWDivARM;
552 } else if (Feature == "+crc") {
553 CRC = 1;
554 } else if (Feature == "+crypto") {
555 Crypto = 1;
556 } else if (Feature == "+sha2") {
557 SHA2 = 1;
558 } else if (Feature == "+aes") {
559 AES = 1;
560 } else if (Feature == "+dsp") {
561 DSP = 1;
562 } else if (Feature == "+fp64") {
563 HW_FP |= HW_FP_DP;
564 } else if (Feature == "+8msecext") {
565 if (CPUProfile != "M" || ArchVersion != 8) {
566 Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
567 return false;
569 } else if (Feature == "+strict-align") {
570 Unaligned = 0;
571 } else if (Feature == "+fp16") {
572 HW_FP |= HW_FP_HP;
573 } else if (Feature == "+fullfp16") {
574 HasLegalHalfType = true;
575 } else if (Feature == "+dotprod") {
576 DotProd = true;
577 } else if (Feature == "+mve") {
578 MVE |= MVE_INT;
579 } else if (Feature == "+mve.fp") {
580 HasLegalHalfType = true;
581 FPU |= FPARMV8;
582 MVE |= MVE_INT | MVE_FP;
583 HW_FP |= HW_FP_SP | HW_FP_HP;
584 } else if (Feature == "+i8mm") {
585 HasMatMul = 1;
586 } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" &&
587 Feature <= "+cdecp7") {
588 unsigned Coproc = Feature.back() - '0';
589 ARMCDECoprocMask |= (1U << Coproc);
590 } else if (Feature == "+bf16") {
591 HasBFloat16 = true;
592 } else if (Feature == "-fpregs") {
593 FPRegsDisabled = true;
594 } else if (Feature == "+pacbti") {
595 HasPAC = 1;
596 HasBTI = 1;
600 HalfArgsAndReturns = true;
602 switch (ArchVersion) {
603 case 6:
604 if (ArchProfile == llvm::ARM::ProfileKind::M)
605 LDREX = 0;
606 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
607 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
608 else
609 LDREX = LDREX_W;
610 break;
611 case 7:
612 if (ArchProfile == llvm::ARM::ProfileKind::M)
613 LDREX = LDREX_W | LDREX_H | LDREX_B;
614 else
615 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
616 break;
617 case 8:
618 case 9:
619 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
622 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
623 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
624 return false;
627 if (FPMath == FP_Neon)
628 Features.push_back("+neonfp");
629 else if (FPMath == FP_VFP)
630 Features.push_back("-neonfp");
632 return true;
635 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
636 return llvm::StringSwitch<bool>(Feature)
637 .Case("arm", true)
638 .Case("aarch32", true)
639 .Case("softfloat", SoftFloat)
640 .Case("thumb", isThumb())
641 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
642 .Case("vfp", FPU && !SoftFloat)
643 .Case("hwdiv", HWDiv & HWDivThumb)
644 .Case("hwdiv-arm", HWDiv & HWDivARM)
645 .Case("mve", hasMVE())
646 .Default(false);
649 bool ARMTargetInfo::hasBFloat16Type() const {
650 // The __bf16 type is generally available so long as we have any fp registers.
651 return HasBFloat16 || (FPU && !SoftFloat);
654 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
655 return Name == "generic" ||
656 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
659 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
660 llvm::ARM::fillValidCPUArchList(Values);
663 bool ARMTargetInfo::setCPU(const std::string &Name) {
664 if (Name != "generic")
665 setArchInfo(llvm::ARM::parseCPUArch(Name));
667 if (ArchKind == llvm::ARM::ArchKind::INVALID)
668 return false;
669 setAtomic();
670 CPU = Name;
671 return true;
674 bool ARMTargetInfo::setFPMath(StringRef Name) {
675 if (Name == "neon") {
676 FPMath = FP_Neon;
677 return true;
678 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
679 Name == "vfp4") {
680 FPMath = FP_VFP;
681 return true;
683 return false;
686 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
687 MacroBuilder &Builder) const {
688 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
691 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
692 MacroBuilder &Builder) const {
693 // Also include the ARMv8.1-A defines
694 getTargetDefinesARMV81A(Opts, Builder);
697 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
698 MacroBuilder &Builder) const {
699 // Also include the ARMv8.2-A defines
700 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
701 getTargetDefinesARMV82A(Opts, Builder);
704 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
705 MacroBuilder &Builder) const {
706 // Target identification.
707 Builder.defineMacro("__arm");
708 Builder.defineMacro("__arm__");
709 // For bare-metal none-eabi.
710 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
711 (getTriple().getEnvironment() == llvm::Triple::EABI ||
712 getTriple().getEnvironment() == llvm::Triple::EABIHF)) {
713 Builder.defineMacro("__ELF__");
714 if (Opts.CPlusPlus)
715 Builder.defineMacro("_GNU_SOURCE");
718 // Target properties.
719 Builder.defineMacro("__REGISTER_PREFIX__", "");
721 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
722 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
723 if (getTriple().isWatchABI())
724 Builder.defineMacro("__ARM_ARCH_7K__", "2");
726 if (!CPUAttr.empty())
727 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
729 // ACLE 6.4.1 ARM/Thumb instruction set architecture
730 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
731 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
733 if (ArchVersion >= 8) {
734 // ACLE 6.5.7 Crypto Extension
735 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
736 // feature macros for AES and SHA2
737 if (SHA2 && AES)
738 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
739 if (SHA2)
740 Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
741 if (AES)
742 Builder.defineMacro("__ARM_FEATURE_AES", "1");
743 // ACLE 6.5.8 CRC32 Extension
744 if (CRC)
745 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
746 // ACLE 6.5.10 Numeric Maximum and Minimum
747 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
748 // ACLE 6.5.9 Directed Rounding
749 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
752 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
753 // is not defined for the M-profile.
754 // NOTE that the default profile is assumed to be 'A'
755 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
756 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
758 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
759 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
760 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
761 // v7 and v8 architectures excluding v8-M Baseline.
762 if (supportsThumb2())
763 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
764 else if (supportsThumb())
765 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
767 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
768 // instruction set such as ARM or Thumb.
769 Builder.defineMacro("__ARM_32BIT_STATE", "1");
771 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
773 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
774 if (!CPUProfile.empty())
775 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
777 // ACLE 6.4.3 Unaligned access supported in hardware
778 if (Unaligned)
779 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
781 // ACLE 6.4.4 LDREX/STREX
782 if (LDREX)
783 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
785 // ACLE 6.4.5 CLZ
786 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
787 ArchVersion > 6)
788 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
790 // ACLE 6.5.1 Hardware Floating Point
791 if (HW_FP)
792 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
794 // ACLE predefines.
795 Builder.defineMacro("__ARM_ACLE", "200");
797 // FP16 support (we currently only support IEEE format).
798 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
799 Builder.defineMacro("__ARM_FP16_ARGS", "1");
801 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
802 if (ArchVersion >= 7 && (FPU & VFP4FPU))
803 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
805 // Subtarget options.
807 // FIXME: It's more complicated than this and we don't really support
808 // interworking.
809 // Windows on ARM does not "support" interworking
810 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
811 Builder.defineMacro("__THUMB_INTERWORK__");
813 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
814 // Embedded targets on Darwin follow AAPCS, but not EABI.
815 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
816 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
817 Builder.defineMacro("__ARM_EABI__");
818 Builder.defineMacro("__ARM_PCS", "1");
821 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
822 Builder.defineMacro("__ARM_PCS_VFP", "1");
824 if (SoftFloat || (SoftFloatABI && !FPU))
825 Builder.defineMacro("__SOFTFP__");
827 // ACLE position independent code macros.
828 if (Opts.ROPI)
829 Builder.defineMacro("__ARM_ROPI", "1");
830 if (Opts.RWPI)
831 Builder.defineMacro("__ARM_RWPI", "1");
833 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
834 Builder.defineMacro("__XSCALE__");
836 if (isThumb()) {
837 Builder.defineMacro("__THUMBEL__");
838 Builder.defineMacro("__thumb__");
839 if (supportsThumb2())
840 Builder.defineMacro("__thumb2__");
843 // ACLE 6.4.9 32-bit SIMD instructions
844 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
845 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
847 // ACLE 6.4.10 Hardware Integer Divide
848 if (((HWDiv & HWDivThumb) && isThumb()) ||
849 ((HWDiv & HWDivARM) && !isThumb())) {
850 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
851 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
854 // Note, this is always on in gcc, even though it doesn't make sense.
855 Builder.defineMacro("__APCS_32__");
857 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware
858 // FPU is present. Moreover, the VFP format is the only one supported by
859 // clang. For these reasons, this macro is always defined.
860 Builder.defineMacro("__VFP_FP__");
862 if (FPUModeIsVFP((FPUMode)FPU)) {
863 if (FPU & VFP2FPU)
864 Builder.defineMacro("__ARM_VFPV2__");
865 if (FPU & VFP3FPU)
866 Builder.defineMacro("__ARM_VFPV3__");
867 if (FPU & VFP4FPU)
868 Builder.defineMacro("__ARM_VFPV4__");
869 if (FPU & FPARMV8)
870 Builder.defineMacro("__ARM_FPV5__");
873 // This only gets set when Neon instructions are actually available, unlike
874 // the VFP define, hence the soft float and arch check. This is subtly
875 // different from gcc, we follow the intent which was that it should be set
876 // when Neon instructions are actually available.
877 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
878 Builder.defineMacro("__ARM_NEON", "1");
879 Builder.defineMacro("__ARM_NEON__");
880 // current AArch32 NEON implementations do not support double-precision
881 // floating-point even when it is present in VFP.
882 Builder.defineMacro("__ARM_NEON_FP",
883 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
886 if (hasMVE()) {
887 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
890 if (hasCDE()) {
891 Builder.defineMacro("__ARM_FEATURE_CDE", "1");
892 Builder.defineMacro("__ARM_FEATURE_CDE_COPROC",
893 "0x" + Twine::utohexstr(getARMCDECoprocMask()));
896 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
897 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
899 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
901 // CMSE
902 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
903 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
905 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
906 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
907 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
908 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
909 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
912 // ACLE 6.4.7 DSP instructions
913 if (DSP) {
914 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
917 // ACLE 6.4.8 Saturation instructions
918 bool SAT = false;
919 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
920 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
921 SAT = true;
924 // ACLE 6.4.6 Q (saturation) flag
925 if (DSP || SAT)
926 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
928 if (Opts.UnsafeFPMath)
929 Builder.defineMacro("__ARM_FP_FAST", "1");
931 // Armv8.2-A FP16 vector intrinsic
932 if ((FPU & NeonFPU) && HasLegalHalfType)
933 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
935 // Armv8.2-A FP16 scalar intrinsics
936 if (HasLegalHalfType)
937 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
939 // Armv8.2-A dot product intrinsics
940 if (DotProd)
941 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
943 if (HasMatMul)
944 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
946 if (HasPAC)
947 Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
949 if (HasBTI)
950 Builder.defineMacro("__ARM_FEATURE_BTI", "1");
952 if (HasBFloat16) {
953 Builder.defineMacro("__ARM_FEATURE_BF16", "1");
954 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
955 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
958 if (Opts.BranchTargetEnforcement)
959 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
961 if (Opts.hasSignReturnAddress()) {
962 unsigned Value = 1;
963 if (Opts.isSignReturnAddressScopeAll())
964 Value |= 1 << 2;
965 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value));
968 switch (ArchKind) {
969 default:
970 break;
971 case llvm::ARM::ArchKind::ARMV8_1A:
972 getTargetDefinesARMV81A(Opts, Builder);
973 break;
974 case llvm::ARM::ArchKind::ARMV8_2A:
975 getTargetDefinesARMV82A(Opts, Builder);
976 break;
977 case llvm::ARM::ArchKind::ARMV8_3A:
978 case llvm::ARM::ArchKind::ARMV8_4A:
979 case llvm::ARM::ArchKind::ARMV8_5A:
980 case llvm::ARM::ArchKind::ARMV8_6A:
981 case llvm::ARM::ArchKind::ARMV8_7A:
982 case llvm::ARM::ArchKind::ARMV8_8A:
983 case llvm::ARM::ArchKind::ARMV8_9A:
984 case llvm::ARM::ArchKind::ARMV9A:
985 case llvm::ARM::ArchKind::ARMV9_1A:
986 case llvm::ARM::ArchKind::ARMV9_2A:
987 case llvm::ARM::ArchKind::ARMV9_3A:
988 case llvm::ARM::ArchKind::ARMV9_4A:
989 getTargetDefinesARMV83A(Opts, Builder);
990 break;
994 static constexpr Builtin::Info BuiltinInfo[] = {
995 #define BUILTIN(ID, TYPE, ATTRS) \
996 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
997 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
998 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
999 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1000 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1001 #include "clang/Basic/BuiltinsNEON.def"
1003 #define BUILTIN(ID, TYPE, ATTRS) \
1004 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1005 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
1006 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
1007 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1008 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1009 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1010 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1011 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
1012 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
1013 #include "clang/Basic/BuiltinsARM.def"
1016 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
1017 return llvm::ArrayRef(BuiltinInfo,
1018 clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
1021 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
1022 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
1023 return IsAAPCS
1024 ? AAPCSABIBuiltinVaList
1025 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
1026 : TargetInfo::VoidPtrBuiltinVaList);
1029 const char *const ARMTargetInfo::GCCRegNames[] = {
1030 // Integer registers
1031 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1032 "r12", "sp", "lr", "pc",
1034 // Float registers
1035 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1036 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1037 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1039 // Double registers
1040 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1041 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1042 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1044 // Quad registers
1045 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1046 "q12", "q13", "q14", "q15"};
1048 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
1049 return llvm::ArrayRef(GCCRegNames);
1052 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1053 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
1054 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
1055 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1056 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
1057 // The S, D and Q registers overlap, but aren't really aliases; we
1058 // don't want to substitute one of these for a different-sized one.
1061 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
1062 return llvm::ArrayRef(GCCRegAliases);
1065 bool ARMTargetInfo::validateAsmConstraint(
1066 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1067 switch (*Name) {
1068 default:
1069 break;
1070 case 'l': // r0-r7 if thumb, r0-r15 if ARM
1071 Info.setAllowsRegister();
1072 return true;
1073 case 'h': // r8-r15, thumb only
1074 if (isThumb()) {
1075 Info.setAllowsRegister();
1076 return true;
1078 break;
1079 case 's': // An integer constant, but allowing only relocatable values.
1080 return true;
1081 case 't': // s0-s31, d0-d31, or q0-q15
1082 case 'w': // s0-s15, d0-d7, or q0-q3
1083 case 'x': // s0-s31, d0-d15, or q0-q7
1084 if (FPRegsDisabled)
1085 return false;
1086 Info.setAllowsRegister();
1087 return true;
1088 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1089 // only available in ARMv6T2 and above
1090 if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
1091 Info.setRequiresImmediate(0, 65535);
1092 return true;
1094 break;
1095 case 'I':
1096 if (isThumb()) {
1097 if (!supportsThumb2())
1098 Info.setRequiresImmediate(0, 255);
1099 else
1100 // FIXME: should check if immediate value would be valid for a Thumb2
1101 // data-processing instruction
1102 Info.setRequiresImmediate();
1103 } else
1104 // FIXME: should check if immediate value would be valid for an ARM
1105 // data-processing instruction
1106 Info.setRequiresImmediate();
1107 return true;
1108 case 'J':
1109 if (isThumb() && !supportsThumb2())
1110 Info.setRequiresImmediate(-255, -1);
1111 else
1112 Info.setRequiresImmediate(-4095, 4095);
1113 return true;
1114 case 'K':
1115 if (isThumb()) {
1116 if (!supportsThumb2())
1117 // FIXME: should check if immediate value can be obtained from shifting
1118 // a value between 0 and 255 left by any amount
1119 Info.setRequiresImmediate();
1120 else
1121 // FIXME: should check if immediate value would be valid for a Thumb2
1122 // data-processing instruction when inverted
1123 Info.setRequiresImmediate();
1124 } else
1125 // FIXME: should check if immediate value would be valid for an ARM
1126 // data-processing instruction when inverted
1127 Info.setRequiresImmediate();
1128 return true;
1129 case 'L':
1130 if (isThumb()) {
1131 if (!supportsThumb2())
1132 Info.setRequiresImmediate(-7, 7);
1133 else
1134 // FIXME: should check if immediate value would be valid for a Thumb2
1135 // data-processing instruction when negated
1136 Info.setRequiresImmediate();
1137 } else
1138 // FIXME: should check if immediate value would be valid for an ARM
1139 // data-processing instruction when negated
1140 Info.setRequiresImmediate();
1141 return true;
1142 case 'M':
1143 if (isThumb() && !supportsThumb2())
1144 // FIXME: should check if immediate value is a multiple of 4 between 0 and
1145 // 1020
1146 Info.setRequiresImmediate();
1147 else
1148 // FIXME: should check if immediate value is a power of two or a integer
1149 // between 0 and 32
1150 Info.setRequiresImmediate();
1151 return true;
1152 case 'N':
1153 // Thumb1 only
1154 if (isThumb() && !supportsThumb2()) {
1155 Info.setRequiresImmediate(0, 31);
1156 return true;
1158 break;
1159 case 'O':
1160 // Thumb1 only
1161 if (isThumb() && !supportsThumb2()) {
1162 // FIXME: should check if immediate value is a multiple of 4 between -508
1163 // and 508
1164 Info.setRequiresImmediate();
1165 return true;
1167 break;
1168 case 'Q': // A memory address that is a single base register.
1169 Info.setAllowsMemory();
1170 return true;
1171 case 'T':
1172 switch (Name[1]) {
1173 default:
1174 break;
1175 case 'e': // Even general-purpose register
1176 case 'o': // Odd general-purpose register
1177 Info.setAllowsRegister();
1178 Name++;
1179 return true;
1181 break;
1182 case 'U': // a memory reference...
1183 switch (Name[1]) {
1184 case 'q': // ...ARMV4 ldrsb
1185 case 'v': // ...VFP load/store (reg+constant offset)
1186 case 'y': // ...iWMMXt load/store
1187 case 't': // address valid for load/store opaque types wider
1188 // than 128-bits
1189 case 'n': // valid address for Neon doubleword vector load/store
1190 case 'm': // valid address for Neon element and structure load/store
1191 case 's': // valid address for non-offset loads/stores of quad-word
1192 // values in four ARM registers
1193 Info.setAllowsMemory();
1194 Name++;
1195 return true;
1197 break;
1199 return false;
1202 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
1203 std::string R;
1204 switch (*Constraint) {
1205 case 'U': // Two-character constraint; add "^" hint for later parsing.
1206 case 'T':
1207 R = std::string("^") + std::string(Constraint, 2);
1208 Constraint++;
1209 break;
1210 case 'p': // 'p' should be translated to 'r' by default.
1211 R = std::string("r");
1212 break;
1213 default:
1214 return std::string(1, *Constraint);
1216 return R;
1219 bool ARMTargetInfo::validateConstraintModifier(
1220 StringRef Constraint, char Modifier, unsigned Size,
1221 std::string &SuggestedModifier) const {
1222 bool isOutput = (Constraint[0] == '=');
1223 bool isInOut = (Constraint[0] == '+');
1225 // Strip off constraint modifiers.
1226 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
1227 Constraint = Constraint.substr(1);
1229 switch (Constraint[0]) {
1230 default:
1231 break;
1232 case 'r': {
1233 switch (Modifier) {
1234 default:
1235 return (isInOut || isOutput || Size <= 64);
1236 case 'q':
1237 // A register of size 32 cannot fit a vector type.
1238 return false;
1243 return true;
1245 const char *ARMTargetInfo::getClobbers() const {
1246 // FIXME: Is this really right?
1247 return "";
1250 TargetInfo::CallingConvCheckResult
1251 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1252 switch (CC) {
1253 case CC_AAPCS:
1254 case CC_AAPCS_VFP:
1255 case CC_Swift:
1256 case CC_SwiftAsync:
1257 case CC_OpenCLKernel:
1258 return CCCR_OK;
1259 default:
1260 return CCCR_Warning;
1264 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1265 if (RegNo == 0)
1266 return 0;
1267 if (RegNo == 1)
1268 return 1;
1269 return -1;
1272 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1274 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1275 const TargetOptions &Opts)
1276 : ARMTargetInfo(Triple, Opts) {}
1278 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1279 MacroBuilder &Builder) const {
1280 Builder.defineMacro("__ARMEL__");
1281 ARMTargetInfo::getTargetDefines(Opts, Builder);
1284 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1285 const TargetOptions &Opts)
1286 : ARMTargetInfo(Triple, Opts) {}
1288 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1289 MacroBuilder &Builder) const {
1290 Builder.defineMacro("__ARMEB__");
1291 Builder.defineMacro("__ARM_BIG_ENDIAN");
1292 ARMTargetInfo::getTargetDefines(Opts, Builder);
1295 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1296 const TargetOptions &Opts)
1297 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1300 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1301 MacroBuilder &Builder) const {
1302 // FIXME: this is invalid for WindowsCE
1303 Builder.defineMacro("_M_ARM_NT", "1");
1304 Builder.defineMacro("_M_ARMT", "_M_ARM");
1305 Builder.defineMacro("_M_THUMB", "_M_ARM");
1307 assert((Triple.getArch() == llvm::Triple::arm ||
1308 Triple.getArch() == llvm::Triple::thumb) &&
1309 "invalid architecture for Windows ARM target info");
1310 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1311 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1313 // TODO map the complete set of values
1314 // 31: VFPv3 40: VFPv4
1315 Builder.defineMacro("_M_ARM_FP", "31");
1318 TargetInfo::BuiltinVaListKind
1319 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1320 return TargetInfo::CharPtrBuiltinVaList;
1323 TargetInfo::CallingConvCheckResult
1324 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1325 switch (CC) {
1326 case CC_X86StdCall:
1327 case CC_X86ThisCall:
1328 case CC_X86FastCall:
1329 case CC_X86VectorCall:
1330 return CCCR_Ignore;
1331 case CC_C:
1332 case CC_OpenCLKernel:
1333 case CC_PreserveMost:
1334 case CC_PreserveAll:
1335 case CC_Swift:
1336 case CC_SwiftAsync:
1337 return CCCR_OK;
1338 default:
1339 return CCCR_Warning;
1343 // Windows ARM + Itanium C++ ABI Target
1344 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1345 const llvm::Triple &Triple, const TargetOptions &Opts)
1346 : WindowsARMTargetInfo(Triple, Opts) {
1347 TheCXXABI.set(TargetCXXABI::GenericARM);
1350 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1351 const LangOptions &Opts, MacroBuilder &Builder) const {
1352 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1354 if (Opts.MSVCCompat)
1355 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1358 // Windows ARM, MS (C++) ABI
1359 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1360 const TargetOptions &Opts)
1361 : WindowsARMTargetInfo(Triple, Opts) {
1362 TheCXXABI.set(TargetCXXABI::Microsoft);
1365 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1366 MacroBuilder &Builder) const {
1367 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1368 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1371 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1372 const TargetOptions &Opts)
1373 : WindowsARMTargetInfo(Triple, Opts) {
1374 TheCXXABI.set(TargetCXXABI::GenericARM);
1377 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1378 MacroBuilder &Builder) const {
1379 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1380 Builder.defineMacro("_ARM_");
1383 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1384 const TargetOptions &Opts)
1385 : ARMleTargetInfo(Triple, Opts) {
1386 this->WCharType = TargetInfo::UnsignedShort;
1387 TLSSupported = false;
1388 DoubleAlign = LongLongAlign = 64;
1389 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1392 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1393 MacroBuilder &Builder) const {
1394 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1395 Builder.defineMacro("_ARM_");
1396 Builder.defineMacro("__CYGWIN__");
1397 Builder.defineMacro("__CYGWIN32__");
1398 DefineStd(Builder, "unix", Opts);
1399 if (Opts.CPlusPlus)
1400 Builder.defineMacro("_GNU_SOURCE");
1403 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1404 const TargetOptions &Opts)
1405 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1406 HasAlignMac68kSupport = true;
1407 // iOS always has 64-bit atomic instructions.
1408 // FIXME: This should be based off of the target features in
1409 // ARMleTargetInfo.
1410 MaxAtomicInlineWidth = 64;
1412 if (Triple.isWatchABI()) {
1413 // Darwin on iOS uses a variant of the ARM C++ ABI.
1414 TheCXXABI.set(TargetCXXABI::WatchOS);
1416 // BOOL should be a real boolean on the new ABI
1417 UseSignedCharForObjCBool = false;
1418 } else
1419 TheCXXABI.set(TargetCXXABI::iOS);
1422 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1423 const llvm::Triple &Triple,
1424 MacroBuilder &Builder) const {
1425 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1428 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1429 const TargetOptions &Opts)
1430 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1431 Triple.getOSName(),
1432 Triple.getEnvironmentName()),
1433 Opts) {
1434 IsRenderScriptTarget = true;
1435 LongWidth = LongAlign = 64;
1438 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1439 MacroBuilder &Builder) const {
1440 Builder.defineMacro("__RENDERSCRIPT__");
1441 ARMleTargetInfo::getTargetDefines(Opts, Builder);