[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / lib / Basic / Targets / ARM.cpp
blobb2f61cff81c9586f0cf31cb0e3c938f9f258d761
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::ARMV9A:
218 return "9A";
219 case llvm::ARM::ArchKind::ARMV9_1A:
220 return "9_1A";
221 case llvm::ARM::ArchKind::ARMV9_2A:
222 return "9_2A";
223 case llvm::ARM::ArchKind::ARMV9_3A:
224 return "9_3A";
225 case llvm::ARM::ArchKind::ARMV8MBaseline:
226 return "8M_BASE";
227 case llvm::ARM::ArchKind::ARMV8MMainline:
228 return "8M_MAIN";
229 case llvm::ARM::ArchKind::ARMV8R:
230 return "8R";
231 case llvm::ARM::ArchKind::ARMV8_1MMainline:
232 return "8_1M_MAIN";
236 StringRef ARMTargetInfo::getCPUProfile() const {
237 switch (ArchProfile) {
238 case llvm::ARM::ProfileKind::A:
239 return "A";
240 case llvm::ARM::ProfileKind::R:
241 return "R";
242 case llvm::ARM::ProfileKind::M:
243 return "M";
244 default:
245 return "";
249 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
250 const TargetOptions &Opts)
251 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
252 HW_FP(0) {
253 bool IsOpenBSD = Triple.isOSOpenBSD();
254 bool IsNetBSD = Triple.isOSNetBSD();
256 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
257 // environment where size_t is `unsigned long` rather than `unsigned int`
259 PtrDiffType = IntPtrType =
260 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
261 IsNetBSD)
262 ? SignedLong
263 : SignedInt;
265 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
266 IsNetBSD)
267 ? UnsignedLong
268 : UnsignedInt;
270 // ptrdiff_t is inconsistent on Darwin
271 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
272 !Triple.isWatchABI())
273 PtrDiffType = SignedInt;
275 // Cache arch related info.
276 setArchInfo();
278 // {} in inline assembly are neon specifiers, not assembly variant
279 // specifiers.
280 NoAsmVariants = true;
282 // FIXME: This duplicates code from the driver that sets the -target-abi
283 // option - this code is used if -target-abi isn't passed and should
284 // be unified in some way.
285 if (Triple.isOSBinFormatMachO()) {
286 // The backend is hardwired to assume AAPCS for M-class processors, ensure
287 // the frontend matches that.
288 if (Triple.getEnvironment() == llvm::Triple::EABI ||
289 Triple.getOS() == llvm::Triple::UnknownOS ||
290 ArchProfile == llvm::ARM::ProfileKind::M) {
291 setABI("aapcs");
292 } else if (Triple.isWatchABI()) {
293 setABI("aapcs16");
294 } else {
295 setABI("apcs-gnu");
297 } else if (Triple.isOSWindows()) {
298 // FIXME: this is invalid for WindowsCE
299 setABI("aapcs");
300 } else {
301 // Select the default based on the platform.
302 switch (Triple.getEnvironment()) {
303 case llvm::Triple::Android:
304 case llvm::Triple::GNUEABI:
305 case llvm::Triple::GNUEABIHF:
306 case llvm::Triple::MuslEABI:
307 case llvm::Triple::MuslEABIHF:
308 setABI("aapcs-linux");
309 break;
310 case llvm::Triple::EABIHF:
311 case llvm::Triple::EABI:
312 setABI("aapcs");
313 break;
314 case llvm::Triple::GNU:
315 setABI("apcs-gnu");
316 break;
317 default:
318 if (IsNetBSD)
319 setABI("apcs-gnu");
320 else if (IsOpenBSD)
321 setABI("aapcs-linux");
322 else
323 setABI("aapcs");
324 break;
328 // ARM targets default to using the ARM C++ ABI.
329 TheCXXABI.set(TargetCXXABI::GenericARM);
331 // ARM has atomics up to 8 bytes
332 setAtomic();
334 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
335 // as well the default alignment
336 if (IsAAPCS && !Triple.isAndroid())
337 DefaultAlignForAttributeAligned = MaxVectorAlign = 64;
339 // Do force alignment of members that follow zero length bitfields. If
340 // the alignment of the zero-length bitfield is greater than the member
341 // that follows it, `bar', `bar' will be aligned as the type of the
342 // zero length bitfield.
343 UseZeroLengthBitfieldAlignment = true;
345 if (Triple.getOS() == llvm::Triple::Linux ||
346 Triple.getOS() == llvm::Triple::UnknownOS)
347 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
348 ? "llvm.arm.gnu.eabi.mcount"
349 : "\01mcount";
351 SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
354 StringRef ARMTargetInfo::getABI() const { return ABI; }
356 bool ARMTargetInfo::setABI(const std::string &Name) {
357 ABI = Name;
359 // The defaults (above) are for AAPCS, check if we need to change them.
361 // FIXME: We need support for -meabi... we could just mangle it into the
362 // name.
363 if (Name == "apcs-gnu" || Name == "aapcs16") {
364 setABIAPCS(Name == "aapcs16");
365 return true;
367 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
368 setABIAAPCS();
369 return true;
371 return false;
374 bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {
375 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);
376 if (CPUArch == llvm::ARM::ArchKind::INVALID)
377 CPUArch = llvm::ARM::parseArch(getTriple().getArchName());
379 if (CPUArch == llvm::ARM::ArchKind::INVALID)
380 return false;
382 StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
383 auto a =
384 llvm::Triple(ArchFeature, getTriple().getVendorName(),
385 getTriple().getOSName(), getTriple().getEnvironmentName());
387 StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
388 llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
389 return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
392 bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
393 BranchProtectionInfo &BPI,
394 StringRef &Err) const {
395 llvm::ARM::ParsedBranchProtection PBP;
396 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
397 return false;
399 if (!isBranchProtectionSupportedArch(Arch))
400 return false;
402 BPI.SignReturnAddr =
403 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
404 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
405 .Case("all", LangOptions::SignReturnAddressScopeKind::All)
406 .Default(LangOptions::SignReturnAddressScopeKind::None);
408 // Don't care for the sign key, beyond issuing a warning.
409 if (PBP.Key == "b_key")
410 Err = "b-key";
411 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
413 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
414 return true;
417 // FIXME: This should be based on Arch attributes, not CPU names.
418 bool ARMTargetInfo::initFeatureMap(
419 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
420 const std::vector<std::string> &FeaturesVec) const {
422 std::string ArchFeature;
423 std::vector<StringRef> TargetFeatures;
424 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
426 // Map the base architecture to an appropriate target feature, so we don't
427 // rely on the target triple.
428 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
429 if (CPUArch == llvm::ARM::ArchKind::INVALID)
430 CPUArch = Arch;
431 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
432 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
433 TargetFeatures.push_back(ArchFeature);
436 // get default FPU features
437 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
438 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
440 // get default Extension features
441 uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
442 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
444 for (auto Feature : TargetFeatures)
445 if (Feature[0] == '+')
446 Features[Feature.drop_front(1)] = true;
448 // Enable or disable thumb-mode explicitly per function to enable mixed
449 // ARM and Thumb code generation.
450 if (isThumb())
451 Features["thumb-mode"] = true;
452 else
453 Features["thumb-mode"] = false;
455 // Convert user-provided arm and thumb GNU target attributes to
456 // [-|+]thumb-mode target features respectively.
457 std::vector<std::string> UpdatedFeaturesVec;
458 for (const auto &Feature : FeaturesVec) {
459 // Skip soft-float-abi; it's something we only use to initialize a bit of
460 // class state, and is otherwise unrecognized.
461 if (Feature == "+soft-float-abi")
462 continue;
464 StringRef FixedFeature;
465 if (Feature == "+arm")
466 FixedFeature = "-thumb-mode";
467 else if (Feature == "+thumb")
468 FixedFeature = "+thumb-mode";
469 else
470 FixedFeature = Feature;
471 UpdatedFeaturesVec.push_back(FixedFeature.str());
474 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
478 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
479 DiagnosticsEngine &Diags) {
480 FPU = 0;
481 MVE = 0;
482 CRC = 0;
483 Crypto = 0;
484 SHA2 = 0;
485 AES = 0;
486 DSP = 0;
487 Unaligned = 1;
488 SoftFloat = false;
489 // Note that SoftFloatABI is initialized in our constructor.
490 HWDiv = 0;
491 DotProd = 0;
492 HasMatMul = 0;
493 HasPAC = 0;
494 HasBTI = 0;
495 HasFloat16 = true;
496 ARMCDECoprocMask = 0;
497 HasBFloat16 = false;
498 FPRegsDisabled = false;
500 // This does not diagnose illegal cases like having both
501 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
502 for (const auto &Feature : Features) {
503 if (Feature == "+soft-float") {
504 SoftFloat = true;
505 } else if (Feature == "+vfp2sp" || Feature == "+vfp2") {
506 FPU |= VFP2FPU;
507 HW_FP |= HW_FP_SP;
508 if (Feature == "+vfp2")
509 HW_FP |= HW_FP_DP;
510 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
511 Feature == "+vfp3" || Feature == "+vfp3d16") {
512 FPU |= VFP3FPU;
513 HW_FP |= HW_FP_SP;
514 if (Feature == "+vfp3" || Feature == "+vfp3d16")
515 HW_FP |= HW_FP_DP;
516 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
517 Feature == "+vfp4" || Feature == "+vfp4d16") {
518 FPU |= VFP4FPU;
519 HW_FP |= HW_FP_SP | HW_FP_HP;
520 if (Feature == "+vfp4" || Feature == "+vfp4d16")
521 HW_FP |= HW_FP_DP;
522 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
523 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
524 FPU |= FPARMV8;
525 HW_FP |= HW_FP_SP | HW_FP_HP;
526 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
527 HW_FP |= HW_FP_DP;
528 } else if (Feature == "+neon") {
529 FPU |= NeonFPU;
530 HW_FP |= HW_FP_SP;
531 } else if (Feature == "+hwdiv") {
532 HWDiv |= HWDivThumb;
533 } else if (Feature == "+hwdiv-arm") {
534 HWDiv |= HWDivARM;
535 } else if (Feature == "+crc") {
536 CRC = 1;
537 } else if (Feature == "+crypto") {
538 Crypto = 1;
539 } else if (Feature == "+sha2") {
540 SHA2 = 1;
541 } else if (Feature == "+aes") {
542 AES = 1;
543 } else if (Feature == "+dsp") {
544 DSP = 1;
545 } else if (Feature == "+fp64") {
546 HW_FP |= HW_FP_DP;
547 } else if (Feature == "+8msecext") {
548 if (CPUProfile != "M" || ArchVersion != 8) {
549 Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
550 return false;
552 } else if (Feature == "+strict-align") {
553 Unaligned = 0;
554 } else if (Feature == "+fp16") {
555 HW_FP |= HW_FP_HP;
556 } else if (Feature == "+fullfp16") {
557 HasLegalHalfType = true;
558 } else if (Feature == "+dotprod") {
559 DotProd = true;
560 } else if (Feature == "+mve") {
561 MVE |= MVE_INT;
562 } else if (Feature == "+mve.fp") {
563 HasLegalHalfType = true;
564 FPU |= FPARMV8;
565 MVE |= MVE_INT | MVE_FP;
566 HW_FP |= HW_FP_SP | HW_FP_HP;
567 } else if (Feature == "+i8mm") {
568 HasMatMul = 1;
569 } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" &&
570 Feature <= "+cdecp7") {
571 unsigned Coproc = Feature.back() - '0';
572 ARMCDECoprocMask |= (1U << Coproc);
573 } else if (Feature == "+bf16") {
574 HasBFloat16 = true;
575 } else if (Feature == "-fpregs") {
576 FPRegsDisabled = true;
577 } else if (Feature == "+pacbti") {
578 HasPAC = 1;
579 HasBTI = 1;
583 switch (ArchVersion) {
584 case 6:
585 if (ArchProfile == llvm::ARM::ProfileKind::M)
586 LDREX = 0;
587 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
588 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
589 else
590 LDREX = LDREX_W;
591 break;
592 case 7:
593 if (ArchProfile == llvm::ARM::ProfileKind::M)
594 LDREX = LDREX_W | LDREX_H | LDREX_B;
595 else
596 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
597 break;
598 case 8:
599 case 9:
600 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
603 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
604 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
605 return false;
608 if (FPMath == FP_Neon)
609 Features.push_back("+neonfp");
610 else if (FPMath == FP_VFP)
611 Features.push_back("-neonfp");
613 return true;
616 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
617 return llvm::StringSwitch<bool>(Feature)
618 .Case("arm", true)
619 .Case("aarch32", true)
620 .Case("softfloat", SoftFloat)
621 .Case("thumb", isThumb())
622 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
623 .Case("vfp", FPU && !SoftFloat)
624 .Case("hwdiv", HWDiv & HWDivThumb)
625 .Case("hwdiv-arm", HWDiv & HWDivARM)
626 .Case("mve", hasMVE())
627 .Default(false);
630 bool ARMTargetInfo::hasBFloat16Type() const {
631 return HasBFloat16 && !SoftFloat;
634 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
635 return Name == "generic" ||
636 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
639 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
640 llvm::ARM::fillValidCPUArchList(Values);
643 bool ARMTargetInfo::setCPU(const std::string &Name) {
644 if (Name != "generic")
645 setArchInfo(llvm::ARM::parseCPUArch(Name));
647 if (ArchKind == llvm::ARM::ArchKind::INVALID)
648 return false;
649 setAtomic();
650 CPU = Name;
651 return true;
654 bool ARMTargetInfo::setFPMath(StringRef Name) {
655 if (Name == "neon") {
656 FPMath = FP_Neon;
657 return true;
658 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
659 Name == "vfp4") {
660 FPMath = FP_VFP;
661 return true;
663 return false;
666 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
667 MacroBuilder &Builder) const {
668 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
671 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
672 MacroBuilder &Builder) const {
673 // Also include the ARMv8.1-A defines
674 getTargetDefinesARMV81A(Opts, Builder);
677 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
678 MacroBuilder &Builder) const {
679 // Also include the ARMv8.2-A defines
680 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
681 getTargetDefinesARMV82A(Opts, Builder);
684 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
685 MacroBuilder &Builder) const {
686 // Target identification.
687 Builder.defineMacro("__arm");
688 Builder.defineMacro("__arm__");
689 // For bare-metal none-eabi.
690 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
691 (getTriple().getEnvironment() == llvm::Triple::EABI ||
692 getTriple().getEnvironment() == llvm::Triple::EABIHF))
693 Builder.defineMacro("__ELF__");
695 // Target properties.
696 Builder.defineMacro("__REGISTER_PREFIX__", "");
698 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
699 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
700 if (getTriple().isWatchABI())
701 Builder.defineMacro("__ARM_ARCH_7K__", "2");
703 if (!CPUAttr.empty())
704 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
706 // ACLE 6.4.1 ARM/Thumb instruction set architecture
707 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
708 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
710 if (ArchVersion >= 8) {
711 // ACLE 6.5.7 Crypto Extension
712 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
713 // feature macros for AES and SHA2
714 if (SHA2 && AES)
715 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
716 if (SHA2)
717 Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
718 if (AES)
719 Builder.defineMacro("__ARM_FEATURE_AES", "1");
720 // ACLE 6.5.8 CRC32 Extension
721 if (CRC)
722 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
723 // ACLE 6.5.10 Numeric Maximum and Minimum
724 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
725 // ACLE 6.5.9 Directed Rounding
726 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
729 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
730 // is not defined for the M-profile.
731 // NOTE that the default profile is assumed to be 'A'
732 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
733 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
735 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
736 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
737 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
738 // v7 and v8 architectures excluding v8-M Baseline.
739 if (supportsThumb2())
740 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
741 else if (supportsThumb())
742 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
744 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
745 // instruction set such as ARM or Thumb.
746 Builder.defineMacro("__ARM_32BIT_STATE", "1");
748 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
750 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
751 if (!CPUProfile.empty())
752 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
754 // ACLE 6.4.3 Unaligned access supported in hardware
755 if (Unaligned)
756 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
758 // ACLE 6.4.4 LDREX/STREX
759 if (LDREX)
760 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
762 // ACLE 6.4.5 CLZ
763 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
764 ArchVersion > 6)
765 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
767 // ACLE 6.5.1 Hardware Floating Point
768 if (HW_FP)
769 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
771 // ACLE predefines.
772 Builder.defineMacro("__ARM_ACLE", "200");
774 // FP16 support (we currently only support IEEE format).
775 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
776 Builder.defineMacro("__ARM_FP16_ARGS", "1");
778 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
779 if (ArchVersion >= 7 && (FPU & VFP4FPU))
780 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
782 // Subtarget options.
784 // FIXME: It's more complicated than this and we don't really support
785 // interworking.
786 // Windows on ARM does not "support" interworking
787 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
788 Builder.defineMacro("__THUMB_INTERWORK__");
790 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
791 // Embedded targets on Darwin follow AAPCS, but not EABI.
792 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
793 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
794 Builder.defineMacro("__ARM_EABI__");
795 Builder.defineMacro("__ARM_PCS", "1");
798 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
799 Builder.defineMacro("__ARM_PCS_VFP", "1");
801 if (SoftFloat)
802 Builder.defineMacro("__SOFTFP__");
804 // ACLE position independent code macros.
805 if (Opts.ROPI)
806 Builder.defineMacro("__ARM_ROPI", "1");
807 if (Opts.RWPI)
808 Builder.defineMacro("__ARM_RWPI", "1");
810 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
811 Builder.defineMacro("__XSCALE__");
813 if (isThumb()) {
814 Builder.defineMacro("__THUMBEL__");
815 Builder.defineMacro("__thumb__");
816 if (supportsThumb2())
817 Builder.defineMacro("__thumb2__");
820 // ACLE 6.4.9 32-bit SIMD instructions
821 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
822 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
824 // ACLE 6.4.10 Hardware Integer Divide
825 if (((HWDiv & HWDivThumb) && isThumb()) ||
826 ((HWDiv & HWDivARM) && !isThumb())) {
827 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
828 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
831 // Note, this is always on in gcc, even though it doesn't make sense.
832 Builder.defineMacro("__APCS_32__");
834 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware
835 // FPU is present. Moreover, the VFP format is the only one supported by
836 // clang. For these reasons, this macro is always defined.
837 Builder.defineMacro("__VFP_FP__");
839 if (FPUModeIsVFP((FPUMode)FPU)) {
840 if (FPU & VFP2FPU)
841 Builder.defineMacro("__ARM_VFPV2__");
842 if (FPU & VFP3FPU)
843 Builder.defineMacro("__ARM_VFPV3__");
844 if (FPU & VFP4FPU)
845 Builder.defineMacro("__ARM_VFPV4__");
846 if (FPU & FPARMV8)
847 Builder.defineMacro("__ARM_FPV5__");
850 // This only gets set when Neon instructions are actually available, unlike
851 // the VFP define, hence the soft float and arch check. This is subtly
852 // different from gcc, we follow the intent which was that it should be set
853 // when Neon instructions are actually available.
854 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
855 Builder.defineMacro("__ARM_NEON", "1");
856 Builder.defineMacro("__ARM_NEON__");
857 // current AArch32 NEON implementations do not support double-precision
858 // floating-point even when it is present in VFP.
859 Builder.defineMacro("__ARM_NEON_FP",
860 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
863 if (hasMVE()) {
864 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
867 if (hasCDE()) {
868 Builder.defineMacro("__ARM_FEATURE_CDE", "1");
869 Builder.defineMacro("__ARM_FEATURE_CDE_COPROC",
870 "0x" + Twine::utohexstr(getARMCDECoprocMask()));
873 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
874 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
876 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
878 // CMSE
879 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
880 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
882 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
883 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
884 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
885 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
886 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
889 // ACLE 6.4.7 DSP instructions
890 if (DSP) {
891 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
894 // ACLE 6.4.8 Saturation instructions
895 bool SAT = false;
896 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
897 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
898 SAT = true;
901 // ACLE 6.4.6 Q (saturation) flag
902 if (DSP || SAT)
903 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
905 if (Opts.UnsafeFPMath)
906 Builder.defineMacro("__ARM_FP_FAST", "1");
908 // Armv8.2-A FP16 vector intrinsic
909 if ((FPU & NeonFPU) && HasLegalHalfType)
910 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
912 // Armv8.2-A FP16 scalar intrinsics
913 if (HasLegalHalfType)
914 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
916 // Armv8.2-A dot product intrinsics
917 if (DotProd)
918 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
920 if (HasMatMul)
921 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
923 if (HasPAC)
924 Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
926 if (HasBTI)
927 Builder.defineMacro("__ARM_FEATURE_BTI", "1");
929 if (HasBFloat16) {
930 Builder.defineMacro("__ARM_FEATURE_BF16", "1");
931 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
932 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
935 if (Opts.BranchTargetEnforcement)
936 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
938 if (Opts.hasSignReturnAddress()) {
939 unsigned Value = 1;
940 if (Opts.isSignReturnAddressScopeAll())
941 Value |= 1 << 2;
942 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value));
945 switch (ArchKind) {
946 default:
947 break;
948 case llvm::ARM::ArchKind::ARMV8_1A:
949 getTargetDefinesARMV81A(Opts, Builder);
950 break;
951 case llvm::ARM::ArchKind::ARMV8_2A:
952 getTargetDefinesARMV82A(Opts, Builder);
953 break;
954 case llvm::ARM::ArchKind::ARMV8_3A:
955 case llvm::ARM::ArchKind::ARMV8_4A:
956 case llvm::ARM::ArchKind::ARMV8_5A:
957 case llvm::ARM::ArchKind::ARMV8_6A:
958 case llvm::ARM::ArchKind::ARMV8_7A:
959 case llvm::ARM::ArchKind::ARMV8_8A:
960 case llvm::ARM::ArchKind::ARMV9A:
961 case llvm::ARM::ArchKind::ARMV9_1A:
962 case llvm::ARM::ArchKind::ARMV9_2A:
963 case llvm::ARM::ArchKind::ARMV9_3A:
964 getTargetDefinesARMV83A(Opts, Builder);
965 break;
969 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
970 #define BUILTIN(ID, TYPE, ATTRS) \
971 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
972 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
973 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
974 #include "clang/Basic/BuiltinsNEON.def"
976 #define BUILTIN(ID, TYPE, ATTRS) \
977 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
978 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
979 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
980 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
981 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
982 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
983 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
984 #include "clang/Basic/BuiltinsARM.def"
987 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
988 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
989 Builtin::FirstTSBuiltin);
992 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
993 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
994 return IsAAPCS
995 ? AAPCSABIBuiltinVaList
996 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
997 : TargetInfo::VoidPtrBuiltinVaList);
1000 const char *const ARMTargetInfo::GCCRegNames[] = {
1001 // Integer registers
1002 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1003 "r12", "sp", "lr", "pc",
1005 // Float registers
1006 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1007 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1008 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1010 // Double registers
1011 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1012 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1013 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1015 // Quad registers
1016 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1017 "q12", "q13", "q14", "q15"};
1019 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
1020 return llvm::makeArrayRef(GCCRegNames);
1023 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1024 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
1025 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
1026 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1027 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
1028 // The S, D and Q registers overlap, but aren't really aliases; we
1029 // don't want to substitute one of these for a different-sized one.
1032 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
1033 return llvm::makeArrayRef(GCCRegAliases);
1036 bool ARMTargetInfo::validateAsmConstraint(
1037 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1038 switch (*Name) {
1039 default:
1040 break;
1041 case 'l': // r0-r7 if thumb, r0-r15 if ARM
1042 Info.setAllowsRegister();
1043 return true;
1044 case 'h': // r8-r15, thumb only
1045 if (isThumb()) {
1046 Info.setAllowsRegister();
1047 return true;
1049 break;
1050 case 's': // An integer constant, but allowing only relocatable values.
1051 return true;
1052 case 't': // s0-s31, d0-d31, or q0-q15
1053 case 'w': // s0-s15, d0-d7, or q0-q3
1054 case 'x': // s0-s31, d0-d15, or q0-q7
1055 if (FPRegsDisabled)
1056 return false;
1057 Info.setAllowsRegister();
1058 return true;
1059 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1060 // only available in ARMv6T2 and above
1061 if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
1062 Info.setRequiresImmediate(0, 65535);
1063 return true;
1065 break;
1066 case 'I':
1067 if (isThumb()) {
1068 if (!supportsThumb2())
1069 Info.setRequiresImmediate(0, 255);
1070 else
1071 // FIXME: should check if immediate value would be valid for a Thumb2
1072 // data-processing instruction
1073 Info.setRequiresImmediate();
1074 } else
1075 // FIXME: should check if immediate value would be valid for an ARM
1076 // data-processing instruction
1077 Info.setRequiresImmediate();
1078 return true;
1079 case 'J':
1080 if (isThumb() && !supportsThumb2())
1081 Info.setRequiresImmediate(-255, -1);
1082 else
1083 Info.setRequiresImmediate(-4095, 4095);
1084 return true;
1085 case 'K':
1086 if (isThumb()) {
1087 if (!supportsThumb2())
1088 // FIXME: should check if immediate value can be obtained from shifting
1089 // a value between 0 and 255 left by any amount
1090 Info.setRequiresImmediate();
1091 else
1092 // FIXME: should check if immediate value would be valid for a Thumb2
1093 // data-processing instruction when inverted
1094 Info.setRequiresImmediate();
1095 } else
1096 // FIXME: should check if immediate value would be valid for an ARM
1097 // data-processing instruction when inverted
1098 Info.setRequiresImmediate();
1099 return true;
1100 case 'L':
1101 if (isThumb()) {
1102 if (!supportsThumb2())
1103 Info.setRequiresImmediate(-7, 7);
1104 else
1105 // FIXME: should check if immediate value would be valid for a Thumb2
1106 // data-processing instruction when negated
1107 Info.setRequiresImmediate();
1108 } else
1109 // FIXME: should check if immediate value would be valid for an ARM
1110 // data-processing instruction when negated
1111 Info.setRequiresImmediate();
1112 return true;
1113 case 'M':
1114 if (isThumb() && !supportsThumb2())
1115 // FIXME: should check if immediate value is a multiple of 4 between 0 and
1116 // 1020
1117 Info.setRequiresImmediate();
1118 else
1119 // FIXME: should check if immediate value is a power of two or a integer
1120 // between 0 and 32
1121 Info.setRequiresImmediate();
1122 return true;
1123 case 'N':
1124 // Thumb1 only
1125 if (isThumb() && !supportsThumb2()) {
1126 Info.setRequiresImmediate(0, 31);
1127 return true;
1129 break;
1130 case 'O':
1131 // Thumb1 only
1132 if (isThumb() && !supportsThumb2()) {
1133 // FIXME: should check if immediate value is a multiple of 4 between -508
1134 // and 508
1135 Info.setRequiresImmediate();
1136 return true;
1138 break;
1139 case 'Q': // A memory address that is a single base register.
1140 Info.setAllowsMemory();
1141 return true;
1142 case 'T':
1143 switch (Name[1]) {
1144 default:
1145 break;
1146 case 'e': // Even general-purpose register
1147 case 'o': // Odd general-purpose register
1148 Info.setAllowsRegister();
1149 Name++;
1150 return true;
1152 break;
1153 case 'U': // a memory reference...
1154 switch (Name[1]) {
1155 case 'q': // ...ARMV4 ldrsb
1156 case 'v': // ...VFP load/store (reg+constant offset)
1157 case 'y': // ...iWMMXt load/store
1158 case 't': // address valid for load/store opaque types wider
1159 // than 128-bits
1160 case 'n': // valid address for Neon doubleword vector load/store
1161 case 'm': // valid address for Neon element and structure load/store
1162 case 's': // valid address for non-offset loads/stores of quad-word
1163 // values in four ARM registers
1164 Info.setAllowsMemory();
1165 Name++;
1166 return true;
1168 break;
1170 return false;
1173 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
1174 std::string R;
1175 switch (*Constraint) {
1176 case 'U': // Two-character constraint; add "^" hint for later parsing.
1177 case 'T':
1178 R = std::string("^") + std::string(Constraint, 2);
1179 Constraint++;
1180 break;
1181 case 'p': // 'p' should be translated to 'r' by default.
1182 R = std::string("r");
1183 break;
1184 default:
1185 return std::string(1, *Constraint);
1187 return R;
1190 bool ARMTargetInfo::validateConstraintModifier(
1191 StringRef Constraint, char Modifier, unsigned Size,
1192 std::string &SuggestedModifier) const {
1193 bool isOutput = (Constraint[0] == '=');
1194 bool isInOut = (Constraint[0] == '+');
1196 // Strip off constraint modifiers.
1197 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
1198 Constraint = Constraint.substr(1);
1200 switch (Constraint[0]) {
1201 default:
1202 break;
1203 case 'r': {
1204 switch (Modifier) {
1205 default:
1206 return (isInOut || isOutput || Size <= 64);
1207 case 'q':
1208 // A register of size 32 cannot fit a vector type.
1209 return false;
1214 return true;
1216 const char *ARMTargetInfo::getClobbers() const {
1217 // FIXME: Is this really right?
1218 return "";
1221 TargetInfo::CallingConvCheckResult
1222 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1223 switch (CC) {
1224 case CC_AAPCS:
1225 case CC_AAPCS_VFP:
1226 case CC_Swift:
1227 case CC_SwiftAsync:
1228 case CC_OpenCLKernel:
1229 return CCCR_OK;
1230 default:
1231 return CCCR_Warning;
1235 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1236 if (RegNo == 0)
1237 return 0;
1238 if (RegNo == 1)
1239 return 1;
1240 return -1;
1243 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1245 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1246 const TargetOptions &Opts)
1247 : ARMTargetInfo(Triple, Opts) {}
1249 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1250 MacroBuilder &Builder) const {
1251 Builder.defineMacro("__ARMEL__");
1252 ARMTargetInfo::getTargetDefines(Opts, Builder);
1255 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1256 const TargetOptions &Opts)
1257 : ARMTargetInfo(Triple, Opts) {}
1259 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1260 MacroBuilder &Builder) const {
1261 Builder.defineMacro("__ARMEB__");
1262 Builder.defineMacro("__ARM_BIG_ENDIAN");
1263 ARMTargetInfo::getTargetDefines(Opts, Builder);
1266 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1267 const TargetOptions &Opts)
1268 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1271 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1272 MacroBuilder &Builder) const {
1273 // FIXME: this is invalid for WindowsCE
1274 Builder.defineMacro("_M_ARM_NT", "1");
1275 Builder.defineMacro("_M_ARMT", "_M_ARM");
1276 Builder.defineMacro("_M_THUMB", "_M_ARM");
1278 assert((Triple.getArch() == llvm::Triple::arm ||
1279 Triple.getArch() == llvm::Triple::thumb) &&
1280 "invalid architecture for Windows ARM target info");
1281 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1282 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1284 // TODO map the complete set of values
1285 // 31: VFPv3 40: VFPv4
1286 Builder.defineMacro("_M_ARM_FP", "31");
1289 TargetInfo::BuiltinVaListKind
1290 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1291 return TargetInfo::CharPtrBuiltinVaList;
1294 TargetInfo::CallingConvCheckResult
1295 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1296 switch (CC) {
1297 case CC_X86StdCall:
1298 case CC_X86ThisCall:
1299 case CC_X86FastCall:
1300 case CC_X86VectorCall:
1301 return CCCR_Ignore;
1302 case CC_C:
1303 case CC_OpenCLKernel:
1304 case CC_PreserveMost:
1305 case CC_PreserveAll:
1306 case CC_Swift:
1307 case CC_SwiftAsync:
1308 return CCCR_OK;
1309 default:
1310 return CCCR_Warning;
1314 // Windows ARM + Itanium C++ ABI Target
1315 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1316 const llvm::Triple &Triple, const TargetOptions &Opts)
1317 : WindowsARMTargetInfo(Triple, Opts) {
1318 TheCXXABI.set(TargetCXXABI::GenericARM);
1321 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1322 const LangOptions &Opts, MacroBuilder &Builder) const {
1323 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1325 if (Opts.MSVCCompat)
1326 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1329 // Windows ARM, MS (C++) ABI
1330 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1331 const TargetOptions &Opts)
1332 : WindowsARMTargetInfo(Triple, Opts) {
1333 TheCXXABI.set(TargetCXXABI::Microsoft);
1336 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1337 MacroBuilder &Builder) const {
1338 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1339 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1342 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1343 const TargetOptions &Opts)
1344 : WindowsARMTargetInfo(Triple, Opts) {
1345 TheCXXABI.set(TargetCXXABI::GenericARM);
1348 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1349 MacroBuilder &Builder) const {
1350 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1351 Builder.defineMacro("_ARM_");
1354 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1355 const TargetOptions &Opts)
1356 : ARMleTargetInfo(Triple, Opts) {
1357 this->WCharType = TargetInfo::UnsignedShort;
1358 TLSSupported = false;
1359 DoubleAlign = LongLongAlign = 64;
1360 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1363 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1364 MacroBuilder &Builder) const {
1365 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1366 Builder.defineMacro("_ARM_");
1367 Builder.defineMacro("__CYGWIN__");
1368 Builder.defineMacro("__CYGWIN32__");
1369 DefineStd(Builder, "unix", Opts);
1370 if (Opts.CPlusPlus)
1371 Builder.defineMacro("_GNU_SOURCE");
1374 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1375 const TargetOptions &Opts)
1376 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1377 HasAlignMac68kSupport = true;
1378 // iOS always has 64-bit atomic instructions.
1379 // FIXME: This should be based off of the target features in
1380 // ARMleTargetInfo.
1381 MaxAtomicInlineWidth = 64;
1383 if (Triple.isWatchABI()) {
1384 // Darwin on iOS uses a variant of the ARM C++ ABI.
1385 TheCXXABI.set(TargetCXXABI::WatchOS);
1387 // BOOL should be a real boolean on the new ABI
1388 UseSignedCharForObjCBool = false;
1389 } else
1390 TheCXXABI.set(TargetCXXABI::iOS);
1393 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1394 const llvm::Triple &Triple,
1395 MacroBuilder &Builder) const {
1396 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1399 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1400 const TargetOptions &Opts)
1401 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1402 Triple.getOSName(),
1403 Triple.getEnvironmentName()),
1404 Opts) {
1405 IsRenderScriptTarget = true;
1406 LongWidth = LongAlign = 64;
1409 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1410 MacroBuilder &Builder) const {
1411 Builder.defineMacro("__RENDERSCRIPT__");
1412 ARMleTargetInfo::getTargetDefines(Opts, Builder);