[AMDGPU][AsmParser][NFC] Get rid of custom default operand handlers.
[llvm-project.git] / clang / lib / Basic / Targets / ARM.cpp
blob06e99e67c875584bbc19d93cb104ea08a498c737
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 IsFreeBSD = Triple.isOSFreeBSD();
258 bool IsOpenBSD = Triple.isOSOpenBSD();
259 bool IsNetBSD = Triple.isOSNetBSD();
261 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
262 // environment where size_t is `unsigned long` rather than `unsigned int`
264 PtrDiffType = IntPtrType =
265 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
266 IsNetBSD)
267 ? SignedLong
268 : SignedInt;
270 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
271 IsNetBSD)
272 ? UnsignedLong
273 : UnsignedInt;
275 // ptrdiff_t is inconsistent on Darwin
276 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
277 !Triple.isWatchABI())
278 PtrDiffType = SignedInt;
280 // Cache arch related info.
281 setArchInfo();
283 // {} in inline assembly are neon specifiers, not assembly variant
284 // specifiers.
285 NoAsmVariants = true;
287 // FIXME: This duplicates code from the driver that sets the -target-abi
288 // option - this code is used if -target-abi isn't passed and should
289 // be unified in some way.
290 if (Triple.isOSBinFormatMachO()) {
291 // The backend is hardwired to assume AAPCS for M-class processors, ensure
292 // the frontend matches that.
293 if (Triple.getEnvironment() == llvm::Triple::EABI ||
294 Triple.getOS() == llvm::Triple::UnknownOS ||
295 ArchProfile == llvm::ARM::ProfileKind::M) {
296 setABI("aapcs");
297 } else if (Triple.isWatchABI()) {
298 setABI("aapcs16");
299 } else {
300 setABI("apcs-gnu");
302 } else if (Triple.isOSWindows()) {
303 // FIXME: this is invalid for WindowsCE
304 setABI("aapcs");
305 } else {
306 // Select the default based on the platform.
307 switch (Triple.getEnvironment()) {
308 case llvm::Triple::Android:
309 case llvm::Triple::GNUEABI:
310 case llvm::Triple::GNUEABIHF:
311 case llvm::Triple::MuslEABI:
312 case llvm::Triple::MuslEABIHF:
313 case llvm::Triple::OpenHOS:
314 setABI("aapcs-linux");
315 break;
316 case llvm::Triple::EABIHF:
317 case llvm::Triple::EABI:
318 setABI("aapcs");
319 break;
320 case llvm::Triple::GNU:
321 setABI("apcs-gnu");
322 break;
323 default:
324 if (IsNetBSD)
325 setABI("apcs-gnu");
326 else if (IsFreeBSD || IsOpenBSD)
327 setABI("aapcs-linux");
328 else
329 setABI("aapcs");
330 break;
334 // ARM targets default to using the ARM C++ ABI.
335 TheCXXABI.set(TargetCXXABI::GenericARM);
337 // ARM has atomics up to 8 bytes
338 setAtomic();
340 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
341 // as well the default alignment
342 if (IsAAPCS && !Triple.isAndroid())
343 DefaultAlignForAttributeAligned = MaxVectorAlign = 64;
345 // Do force alignment of members that follow zero length bitfields. If
346 // the alignment of the zero-length bitfield is greater than the member
347 // that follows it, `bar', `bar' will be aligned as the type of the
348 // zero length bitfield.
349 UseZeroLengthBitfieldAlignment = true;
351 if (Triple.getOS() == llvm::Triple::Linux ||
352 Triple.getOS() == llvm::Triple::UnknownOS)
353 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
354 ? "llvm.arm.gnu.eabi.mcount"
355 : "\01mcount";
357 SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
360 StringRef ARMTargetInfo::getABI() const { return ABI; }
362 bool ARMTargetInfo::setABI(const std::string &Name) {
363 ABI = Name;
365 // The defaults (above) are for AAPCS, check if we need to change them.
367 // FIXME: We need support for -meabi... we could just mangle it into the
368 // name.
369 if (Name == "apcs-gnu" || Name == "aapcs16") {
370 setABIAPCS(Name == "aapcs16");
371 return true;
373 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
374 setABIAAPCS();
375 return true;
377 return false;
380 bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {
381 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);
382 if (CPUArch == llvm::ARM::ArchKind::INVALID)
383 CPUArch = llvm::ARM::parseArch(getTriple().getArchName());
385 if (CPUArch == llvm::ARM::ArchKind::INVALID)
386 return false;
388 StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
389 auto a =
390 llvm::Triple(ArchFeature, getTriple().getVendorName(),
391 getTriple().getOSName(), getTriple().getEnvironmentName());
393 StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
394 llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
395 return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
398 bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
399 BranchProtectionInfo &BPI,
400 StringRef &Err) const {
401 llvm::ARM::ParsedBranchProtection PBP;
402 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
403 return false;
405 if (!isBranchProtectionSupportedArch(Arch))
406 return false;
408 BPI.SignReturnAddr =
409 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
410 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
411 .Case("all", LangOptions::SignReturnAddressScopeKind::All)
412 .Default(LangOptions::SignReturnAddressScopeKind::None);
414 // Don't care for the sign key, beyond issuing a warning.
415 if (PBP.Key == "b_key")
416 Err = "b-key";
417 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
419 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
420 return true;
423 // FIXME: This should be based on Arch attributes, not CPU names.
424 bool ARMTargetInfo::initFeatureMap(
425 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
426 const std::vector<std::string> &FeaturesVec) const {
428 std::string ArchFeature;
429 std::vector<StringRef> TargetFeatures;
430 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
432 // Map the base architecture to an appropriate target feature, so we don't
433 // rely on the target triple.
434 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
435 if (CPUArch == llvm::ARM::ArchKind::INVALID)
436 CPUArch = Arch;
437 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
438 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
439 TargetFeatures.push_back(ArchFeature);
441 // These features are added to allow arm_neon.h target(..) attributes to
442 // match with both arm and aarch64. We need to add all previous architecture
443 // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
444 // v8.x counterparts are added too. We only need these for anything > 8.0-A.
445 for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch);
446 I != llvm::ARM::ArchKind::INVALID; --I)
447 Features[llvm::ARM::getSubArch(I)] = true;
448 if (CPUArch > llvm::ARM::ArchKind::ARMV8A &&
449 CPUArch <= llvm::ARM::ArchKind::ARMV9_3A)
450 for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID;
451 --I)
452 Features[llvm::ARM::getSubArch(I)] = true;
455 // get default FPU features
456 llvm::ARM::FPUKind FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
457 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
459 // get default Extension features
460 uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
461 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
463 for (auto Feature : TargetFeatures)
464 if (Feature[0] == '+')
465 Features[Feature.drop_front(1)] = true;
467 // Enable or disable thumb-mode explicitly per function to enable mixed
468 // ARM and Thumb code generation.
469 if (isThumb())
470 Features["thumb-mode"] = true;
471 else
472 Features["thumb-mode"] = false;
474 // Convert user-provided arm and thumb GNU target attributes to
475 // [-|+]thumb-mode target features respectively.
476 std::vector<std::string> UpdatedFeaturesVec;
477 for (const auto &Feature : FeaturesVec) {
478 // Skip soft-float-abi; it's something we only use to initialize a bit of
479 // class state, and is otherwise unrecognized.
480 if (Feature == "+soft-float-abi")
481 continue;
483 StringRef FixedFeature;
484 if (Feature == "+arm")
485 FixedFeature = "-thumb-mode";
486 else if (Feature == "+thumb")
487 FixedFeature = "+thumb-mode";
488 else
489 FixedFeature = Feature;
490 UpdatedFeaturesVec.push_back(FixedFeature.str());
493 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
497 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
498 DiagnosticsEngine &Diags) {
499 FPU = 0;
500 MVE = 0;
501 CRC = 0;
502 Crypto = 0;
503 SHA2 = 0;
504 AES = 0;
505 DSP = 0;
506 Unaligned = 1;
507 SoftFloat = false;
508 // Note that SoftFloatABI is initialized in our constructor.
509 HWDiv = 0;
510 DotProd = 0;
511 HasMatMul = 0;
512 HasPAC = 0;
513 HasBTI = 0;
514 HasFloat16 = true;
515 ARMCDECoprocMask = 0;
516 HasBFloat16 = false;
517 HasFullBFloat16 = false;
518 FPRegsDisabled = false;
520 // This does not diagnose illegal cases like having both
521 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
522 for (const auto &Feature : Features) {
523 if (Feature == "+soft-float") {
524 SoftFloat = true;
525 } else if (Feature == "+vfp2sp" || Feature == "+vfp2") {
526 FPU |= VFP2FPU;
527 HW_FP |= HW_FP_SP;
528 if (Feature == "+vfp2")
529 HW_FP |= HW_FP_DP;
530 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
531 Feature == "+vfp3" || Feature == "+vfp3d16") {
532 FPU |= VFP3FPU;
533 HW_FP |= HW_FP_SP;
534 if (Feature == "+vfp3" || Feature == "+vfp3d16")
535 HW_FP |= HW_FP_DP;
536 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
537 Feature == "+vfp4" || Feature == "+vfp4d16") {
538 FPU |= VFP4FPU;
539 HW_FP |= HW_FP_SP | HW_FP_HP;
540 if (Feature == "+vfp4" || Feature == "+vfp4d16")
541 HW_FP |= HW_FP_DP;
542 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
543 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
544 FPU |= FPARMV8;
545 HW_FP |= HW_FP_SP | HW_FP_HP;
546 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
547 HW_FP |= HW_FP_DP;
548 } else if (Feature == "+neon") {
549 FPU |= NeonFPU;
550 HW_FP |= HW_FP_SP;
551 } else if (Feature == "+hwdiv") {
552 HWDiv |= HWDivThumb;
553 } else if (Feature == "+hwdiv-arm") {
554 HWDiv |= HWDivARM;
555 } else if (Feature == "+crc") {
556 CRC = 1;
557 } else if (Feature == "+crypto") {
558 Crypto = 1;
559 } else if (Feature == "+sha2") {
560 SHA2 = 1;
561 } else if (Feature == "+aes") {
562 AES = 1;
563 } else if (Feature == "+dsp") {
564 DSP = 1;
565 } else if (Feature == "+fp64") {
566 HW_FP |= HW_FP_DP;
567 } else if (Feature == "+8msecext") {
568 if (CPUProfile != "M" || ArchVersion != 8) {
569 Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
570 return false;
572 } else if (Feature == "+strict-align") {
573 Unaligned = 0;
574 } else if (Feature == "+fp16") {
575 HW_FP |= HW_FP_HP;
576 } else if (Feature == "+fullfp16") {
577 HasLegalHalfType = true;
578 } else if (Feature == "+dotprod") {
579 DotProd = true;
580 } else if (Feature == "+mve") {
581 MVE |= MVE_INT;
582 } else if (Feature == "+mve.fp") {
583 HasLegalHalfType = true;
584 FPU |= FPARMV8;
585 MVE |= MVE_INT | MVE_FP;
586 HW_FP |= HW_FP_SP | HW_FP_HP;
587 } else if (Feature == "+i8mm") {
588 HasMatMul = 1;
589 } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" &&
590 Feature <= "+cdecp7") {
591 unsigned Coproc = Feature.back() - '0';
592 ARMCDECoprocMask |= (1U << Coproc);
593 } else if (Feature == "+bf16") {
594 HasBFloat16 = true;
595 } else if (Feature == "-fpregs") {
596 FPRegsDisabled = true;
597 } else if (Feature == "+pacbti") {
598 HasPAC = 1;
599 HasBTI = 1;
600 } else if (Feature == "+fullbf16") {
601 HasFullBFloat16 = true;
605 HalfArgsAndReturns = true;
607 switch (ArchVersion) {
608 case 6:
609 if (ArchProfile == llvm::ARM::ProfileKind::M)
610 LDREX = 0;
611 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
612 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
613 else
614 LDREX = LDREX_W;
615 break;
616 case 7:
617 if (ArchProfile == llvm::ARM::ProfileKind::M)
618 LDREX = LDREX_W | LDREX_H | LDREX_B;
619 else
620 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
621 break;
622 case 8:
623 case 9:
624 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
627 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
628 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
629 return false;
632 if (FPMath == FP_Neon)
633 Features.push_back("+neonfp");
634 else if (FPMath == FP_VFP)
635 Features.push_back("-neonfp");
637 return true;
640 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
641 return llvm::StringSwitch<bool>(Feature)
642 .Case("arm", true)
643 .Case("aarch32", true)
644 .Case("softfloat", SoftFloat)
645 .Case("thumb", isThumb())
646 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
647 .Case("vfp", FPU && !SoftFloat)
648 .Case("hwdiv", HWDiv & HWDivThumb)
649 .Case("hwdiv-arm", HWDiv & HWDivARM)
650 .Case("mve", hasMVE())
651 .Default(false);
654 bool ARMTargetInfo::hasBFloat16Type() const {
655 // The __bf16 type is generally available so long as we have any fp registers.
656 return HasBFloat16 || (FPU && !SoftFloat);
659 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
660 return Name == "generic" ||
661 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
664 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
665 llvm::ARM::fillValidCPUArchList(Values);
668 bool ARMTargetInfo::setCPU(const std::string &Name) {
669 if (Name != "generic")
670 setArchInfo(llvm::ARM::parseCPUArch(Name));
672 if (ArchKind == llvm::ARM::ArchKind::INVALID)
673 return false;
674 setAtomic();
675 CPU = Name;
676 return true;
679 bool ARMTargetInfo::setFPMath(StringRef Name) {
680 if (Name == "neon") {
681 FPMath = FP_Neon;
682 return true;
683 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
684 Name == "vfp4") {
685 FPMath = FP_VFP;
686 return true;
688 return false;
691 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
692 MacroBuilder &Builder) const {
693 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
696 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
697 MacroBuilder &Builder) const {
698 // Also include the ARMv8.1-A defines
699 getTargetDefinesARMV81A(Opts, Builder);
702 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
703 MacroBuilder &Builder) const {
704 // Also include the ARMv8.2-A defines
705 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
706 getTargetDefinesARMV82A(Opts, Builder);
709 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
710 MacroBuilder &Builder) const {
711 // Target identification.
712 Builder.defineMacro("__arm");
713 Builder.defineMacro("__arm__");
714 // For bare-metal none-eabi.
715 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
716 (getTriple().getEnvironment() == llvm::Triple::EABI ||
717 getTriple().getEnvironment() == llvm::Triple::EABIHF) &&
718 Opts.CPlusPlus) {
719 Builder.defineMacro("_GNU_SOURCE");
722 // Target properties.
723 Builder.defineMacro("__REGISTER_PREFIX__", "");
725 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
726 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
727 if (getTriple().isWatchABI())
728 Builder.defineMacro("__ARM_ARCH_7K__", "2");
730 if (!CPUAttr.empty())
731 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
733 // ACLE 6.4.1 ARM/Thumb instruction set architecture
734 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
735 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
737 if (ArchVersion >= 8) {
738 // ACLE 6.5.7 Crypto Extension
739 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
740 // feature macros for AES and SHA2
741 if (SHA2 && AES)
742 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
743 if (SHA2)
744 Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
745 if (AES)
746 Builder.defineMacro("__ARM_FEATURE_AES", "1");
747 // ACLE 6.5.8 CRC32 Extension
748 if (CRC)
749 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
750 // ACLE 6.5.10 Numeric Maximum and Minimum
751 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
752 // ACLE 6.5.9 Directed Rounding
753 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
756 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
757 // is not defined for the M-profile.
758 // NOTE that the default profile is assumed to be 'A'
759 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
760 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
762 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
763 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
764 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
765 // v7 and v8 architectures excluding v8-M Baseline.
766 if (supportsThumb2())
767 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
768 else if (supportsThumb())
769 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
771 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
772 // instruction set such as ARM or Thumb.
773 Builder.defineMacro("__ARM_32BIT_STATE", "1");
775 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
777 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
778 if (!CPUProfile.empty())
779 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
781 // ACLE 6.4.3 Unaligned access supported in hardware
782 if (Unaligned)
783 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
785 // ACLE 6.4.4 LDREX/STREX
786 if (LDREX)
787 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
789 // ACLE 6.4.5 CLZ
790 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
791 ArchVersion > 6)
792 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
794 // ACLE 6.5.1 Hardware Floating Point
795 if (HW_FP)
796 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
798 // ACLE predefines.
799 Builder.defineMacro("__ARM_ACLE", "200");
801 // FP16 support (we currently only support IEEE format).
802 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
803 Builder.defineMacro("__ARM_FP16_ARGS", "1");
805 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
806 if (ArchVersion >= 7 && (FPU & VFP4FPU))
807 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
809 // Subtarget options.
811 // FIXME: It's more complicated than this and we don't really support
812 // interworking.
813 // Windows on ARM does not "support" interworking
814 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
815 Builder.defineMacro("__THUMB_INTERWORK__");
817 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
818 // Embedded targets on Darwin follow AAPCS, but not EABI.
819 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
820 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
821 Builder.defineMacro("__ARM_EABI__");
822 Builder.defineMacro("__ARM_PCS", "1");
825 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
826 Builder.defineMacro("__ARM_PCS_VFP", "1");
828 if (SoftFloat || (SoftFloatABI && !FPU))
829 Builder.defineMacro("__SOFTFP__");
831 // ACLE position independent code macros.
832 if (Opts.ROPI)
833 Builder.defineMacro("__ARM_ROPI", "1");
834 if (Opts.RWPI)
835 Builder.defineMacro("__ARM_RWPI", "1");
837 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
838 Builder.defineMacro("__XSCALE__");
840 if (isThumb()) {
841 Builder.defineMacro("__THUMBEL__");
842 Builder.defineMacro("__thumb__");
843 if (supportsThumb2())
844 Builder.defineMacro("__thumb2__");
847 // ACLE 6.4.9 32-bit SIMD instructions
848 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
849 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
851 // ACLE 6.4.10 Hardware Integer Divide
852 if (((HWDiv & HWDivThumb) && isThumb()) ||
853 ((HWDiv & HWDivARM) && !isThumb())) {
854 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
855 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
858 // Note, this is always on in gcc, even though it doesn't make sense.
859 Builder.defineMacro("__APCS_32__");
861 // __VFP_FP__ means that the floating-point format is VFP, not that a hardware
862 // FPU is present. Moreover, the VFP format is the only one supported by
863 // clang. For these reasons, this macro is always defined.
864 Builder.defineMacro("__VFP_FP__");
866 if (FPUModeIsVFP((FPUMode)FPU)) {
867 if (FPU & VFP2FPU)
868 Builder.defineMacro("__ARM_VFPV2__");
869 if (FPU & VFP3FPU)
870 Builder.defineMacro("__ARM_VFPV3__");
871 if (FPU & VFP4FPU)
872 Builder.defineMacro("__ARM_VFPV4__");
873 if (FPU & FPARMV8)
874 Builder.defineMacro("__ARM_FPV5__");
877 // This only gets set when Neon instructions are actually available, unlike
878 // the VFP define, hence the soft float and arch check. This is subtly
879 // different from gcc, we follow the intent which was that it should be set
880 // when Neon instructions are actually available.
881 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
882 Builder.defineMacro("__ARM_NEON", "1");
883 Builder.defineMacro("__ARM_NEON__");
884 // current AArch32 NEON implementations do not support double-precision
885 // floating-point even when it is present in VFP.
886 Builder.defineMacro("__ARM_NEON_FP",
887 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
890 if (hasMVE()) {
891 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
894 if (hasCDE()) {
895 Builder.defineMacro("__ARM_FEATURE_CDE", "1");
896 Builder.defineMacro("__ARM_FEATURE_CDE_COPROC",
897 "0x" + Twine::utohexstr(getARMCDECoprocMask()));
900 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
901 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
903 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
905 // CMSE
906 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
907 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
909 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
910 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
911 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
912 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
913 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
916 // ACLE 6.4.7 DSP instructions
917 if (DSP) {
918 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
921 // ACLE 6.4.8 Saturation instructions
922 bool SAT = false;
923 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
924 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
925 SAT = true;
928 // ACLE 6.4.6 Q (saturation) flag
929 if (DSP || SAT)
930 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
932 if (Opts.UnsafeFPMath)
933 Builder.defineMacro("__ARM_FP_FAST", "1");
935 // Armv8.2-A FP16 vector intrinsic
936 if ((FPU & NeonFPU) && HasLegalHalfType)
937 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
939 // Armv8.2-A FP16 scalar intrinsics
940 if (HasLegalHalfType)
941 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
943 // Armv8.2-A dot product intrinsics
944 if (DotProd)
945 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
947 if (HasMatMul)
948 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
950 if (HasPAC)
951 Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
953 if (HasBTI)
954 Builder.defineMacro("__ARM_FEATURE_BTI", "1");
956 if (HasBFloat16) {
957 Builder.defineMacro("__ARM_FEATURE_BF16", "1");
958 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
959 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
962 if (Opts.BranchTargetEnforcement)
963 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
965 if (Opts.hasSignReturnAddress()) {
966 unsigned Value = 1;
967 if (Opts.isSignReturnAddressScopeAll())
968 Value |= 1 << 2;
969 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value));
972 switch (ArchKind) {
973 default:
974 break;
975 case llvm::ARM::ArchKind::ARMV8_1A:
976 getTargetDefinesARMV81A(Opts, Builder);
977 break;
978 case llvm::ARM::ArchKind::ARMV8_2A:
979 getTargetDefinesARMV82A(Opts, Builder);
980 break;
981 case llvm::ARM::ArchKind::ARMV8_3A:
982 case llvm::ARM::ArchKind::ARMV8_4A:
983 case llvm::ARM::ArchKind::ARMV8_5A:
984 case llvm::ARM::ArchKind::ARMV8_6A:
985 case llvm::ARM::ArchKind::ARMV8_7A:
986 case llvm::ARM::ArchKind::ARMV8_8A:
987 case llvm::ARM::ArchKind::ARMV8_9A:
988 case llvm::ARM::ArchKind::ARMV9A:
989 case llvm::ARM::ArchKind::ARMV9_1A:
990 case llvm::ARM::ArchKind::ARMV9_2A:
991 case llvm::ARM::ArchKind::ARMV9_3A:
992 case llvm::ARM::ArchKind::ARMV9_4A:
993 getTargetDefinesARMV83A(Opts, Builder);
994 break;
998 static constexpr Builtin::Info BuiltinInfo[] = {
999 #define BUILTIN(ID, TYPE, ATTRS) \
1000 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1001 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1002 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1003 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1004 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1005 #include "clang/Basic/BuiltinsNEON.def"
1007 #define BUILTIN(ID, TYPE, ATTRS) \
1008 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1009 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
1010 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
1011 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1012 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1013 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1014 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1015 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
1016 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
1017 #include "clang/Basic/BuiltinsARM.def"
1020 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
1021 return llvm::ArrayRef(BuiltinInfo,
1022 clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
1025 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
1026 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
1027 return IsAAPCS
1028 ? AAPCSABIBuiltinVaList
1029 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
1030 : TargetInfo::VoidPtrBuiltinVaList);
1033 const char *const ARMTargetInfo::GCCRegNames[] = {
1034 // Integer registers
1035 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1036 "r12", "sp", "lr", "pc",
1038 // Float registers
1039 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1040 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1041 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1043 // Double registers
1044 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1045 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1046 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1048 // Quad registers
1049 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1050 "q12", "q13", "q14", "q15"};
1052 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
1053 return llvm::ArrayRef(GCCRegNames);
1056 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1057 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
1058 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
1059 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1060 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
1061 // The S, D and Q registers overlap, but aren't really aliases; we
1062 // don't want to substitute one of these for a different-sized one.
1065 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
1066 return llvm::ArrayRef(GCCRegAliases);
1069 bool ARMTargetInfo::validateAsmConstraint(
1070 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1071 switch (*Name) {
1072 default:
1073 break;
1074 case 'l': // r0-r7 if thumb, r0-r15 if ARM
1075 Info.setAllowsRegister();
1076 return true;
1077 case 'h': // r8-r15, thumb only
1078 if (isThumb()) {
1079 Info.setAllowsRegister();
1080 return true;
1082 break;
1083 case 's': // An integer constant, but allowing only relocatable values.
1084 return true;
1085 case 't': // s0-s31, d0-d31, or q0-q15
1086 case 'w': // s0-s15, d0-d7, or q0-q3
1087 case 'x': // s0-s31, d0-d15, or q0-q7
1088 if (FPRegsDisabled)
1089 return false;
1090 Info.setAllowsRegister();
1091 return true;
1092 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1093 // only available in ARMv6T2 and above
1094 if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
1095 Info.setRequiresImmediate(0, 65535);
1096 return true;
1098 break;
1099 case 'I':
1100 if (isThumb()) {
1101 if (!supportsThumb2())
1102 Info.setRequiresImmediate(0, 255);
1103 else
1104 // FIXME: should check if immediate value would be valid for a Thumb2
1105 // data-processing instruction
1106 Info.setRequiresImmediate();
1107 } else
1108 // FIXME: should check if immediate value would be valid for an ARM
1109 // data-processing instruction
1110 Info.setRequiresImmediate();
1111 return true;
1112 case 'J':
1113 if (isThumb() && !supportsThumb2())
1114 Info.setRequiresImmediate(-255, -1);
1115 else
1116 Info.setRequiresImmediate(-4095, 4095);
1117 return true;
1118 case 'K':
1119 if (isThumb()) {
1120 if (!supportsThumb2())
1121 // FIXME: should check if immediate value can be obtained from shifting
1122 // a value between 0 and 255 left by any amount
1123 Info.setRequiresImmediate();
1124 else
1125 // FIXME: should check if immediate value would be valid for a Thumb2
1126 // data-processing instruction when inverted
1127 Info.setRequiresImmediate();
1128 } else
1129 // FIXME: should check if immediate value would be valid for an ARM
1130 // data-processing instruction when inverted
1131 Info.setRequiresImmediate();
1132 return true;
1133 case 'L':
1134 if (isThumb()) {
1135 if (!supportsThumb2())
1136 Info.setRequiresImmediate(-7, 7);
1137 else
1138 // FIXME: should check if immediate value would be valid for a Thumb2
1139 // data-processing instruction when negated
1140 Info.setRequiresImmediate();
1141 } else
1142 // FIXME: should check if immediate value would be valid for an ARM
1143 // data-processing instruction when negated
1144 Info.setRequiresImmediate();
1145 return true;
1146 case 'M':
1147 if (isThumb() && !supportsThumb2())
1148 // FIXME: should check if immediate value is a multiple of 4 between 0 and
1149 // 1020
1150 Info.setRequiresImmediate();
1151 else
1152 // FIXME: should check if immediate value is a power of two or a integer
1153 // between 0 and 32
1154 Info.setRequiresImmediate();
1155 return true;
1156 case 'N':
1157 // Thumb1 only
1158 if (isThumb() && !supportsThumb2()) {
1159 Info.setRequiresImmediate(0, 31);
1160 return true;
1162 break;
1163 case 'O':
1164 // Thumb1 only
1165 if (isThumb() && !supportsThumb2()) {
1166 // FIXME: should check if immediate value is a multiple of 4 between -508
1167 // and 508
1168 Info.setRequiresImmediate();
1169 return true;
1171 break;
1172 case 'Q': // A memory address that is a single base register.
1173 Info.setAllowsMemory();
1174 return true;
1175 case 'T':
1176 switch (Name[1]) {
1177 default:
1178 break;
1179 case 'e': // Even general-purpose register
1180 case 'o': // Odd general-purpose register
1181 Info.setAllowsRegister();
1182 Name++;
1183 return true;
1185 break;
1186 case 'U': // a memory reference...
1187 switch (Name[1]) {
1188 case 'q': // ...ARMV4 ldrsb
1189 case 'v': // ...VFP load/store (reg+constant offset)
1190 case 'y': // ...iWMMXt load/store
1191 case 't': // address valid for load/store opaque types wider
1192 // than 128-bits
1193 case 'n': // valid address for Neon doubleword vector load/store
1194 case 'm': // valid address for Neon element and structure load/store
1195 case 's': // valid address for non-offset loads/stores of quad-word
1196 // values in four ARM registers
1197 Info.setAllowsMemory();
1198 Name++;
1199 return true;
1201 break;
1203 return false;
1206 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
1207 std::string R;
1208 switch (*Constraint) {
1209 case 'U': // Two-character constraint; add "^" hint for later parsing.
1210 case 'T':
1211 R = std::string("^") + std::string(Constraint, 2);
1212 Constraint++;
1213 break;
1214 case 'p': // 'p' should be translated to 'r' by default.
1215 R = std::string("r");
1216 break;
1217 default:
1218 return std::string(1, *Constraint);
1220 return R;
1223 bool ARMTargetInfo::validateConstraintModifier(
1224 StringRef Constraint, char Modifier, unsigned Size,
1225 std::string &SuggestedModifier) const {
1226 bool isOutput = (Constraint[0] == '=');
1227 bool isInOut = (Constraint[0] == '+');
1229 // Strip off constraint modifiers.
1230 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
1231 Constraint = Constraint.substr(1);
1233 switch (Constraint[0]) {
1234 default:
1235 break;
1236 case 'r': {
1237 switch (Modifier) {
1238 default:
1239 return (isInOut || isOutput || Size <= 64);
1240 case 'q':
1241 // A register of size 32 cannot fit a vector type.
1242 return false;
1247 return true;
1249 std::string_view ARMTargetInfo::getClobbers() const {
1250 // FIXME: Is this really right?
1251 return "";
1254 TargetInfo::CallingConvCheckResult
1255 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1256 switch (CC) {
1257 case CC_AAPCS:
1258 case CC_AAPCS_VFP:
1259 case CC_Swift:
1260 case CC_SwiftAsync:
1261 case CC_OpenCLKernel:
1262 return CCCR_OK;
1263 default:
1264 return CCCR_Warning;
1268 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1269 if (RegNo == 0)
1270 return 0;
1271 if (RegNo == 1)
1272 return 1;
1273 return -1;
1276 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1278 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1279 const TargetOptions &Opts)
1280 : ARMTargetInfo(Triple, Opts) {}
1282 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1283 MacroBuilder &Builder) const {
1284 Builder.defineMacro("__ARMEL__");
1285 ARMTargetInfo::getTargetDefines(Opts, Builder);
1288 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1289 const TargetOptions &Opts)
1290 : ARMTargetInfo(Triple, Opts) {}
1292 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1293 MacroBuilder &Builder) const {
1294 Builder.defineMacro("__ARMEB__");
1295 Builder.defineMacro("__ARM_BIG_ENDIAN");
1296 ARMTargetInfo::getTargetDefines(Opts, Builder);
1299 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1300 const TargetOptions &Opts)
1301 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1304 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1305 MacroBuilder &Builder) const {
1306 // FIXME: this is invalid for WindowsCE
1307 Builder.defineMacro("_M_ARM_NT", "1");
1308 Builder.defineMacro("_M_ARMT", "_M_ARM");
1309 Builder.defineMacro("_M_THUMB", "_M_ARM");
1311 assert((Triple.getArch() == llvm::Triple::arm ||
1312 Triple.getArch() == llvm::Triple::thumb) &&
1313 "invalid architecture for Windows ARM target info");
1314 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1315 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1317 // TODO map the complete set of values
1318 // 31: VFPv3 40: VFPv4
1319 Builder.defineMacro("_M_ARM_FP", "31");
1322 TargetInfo::BuiltinVaListKind
1323 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1324 return TargetInfo::CharPtrBuiltinVaList;
1327 TargetInfo::CallingConvCheckResult
1328 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1329 switch (CC) {
1330 case CC_X86StdCall:
1331 case CC_X86ThisCall:
1332 case CC_X86FastCall:
1333 case CC_X86VectorCall:
1334 return CCCR_Ignore;
1335 case CC_C:
1336 case CC_OpenCLKernel:
1337 case CC_PreserveMost:
1338 case CC_PreserveAll:
1339 case CC_Swift:
1340 case CC_SwiftAsync:
1341 return CCCR_OK;
1342 default:
1343 return CCCR_Warning;
1347 // Windows ARM + Itanium C++ ABI Target
1348 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1349 const llvm::Triple &Triple, const TargetOptions &Opts)
1350 : WindowsARMTargetInfo(Triple, Opts) {
1351 TheCXXABI.set(TargetCXXABI::GenericARM);
1354 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1355 const LangOptions &Opts, MacroBuilder &Builder) const {
1356 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1358 if (Opts.MSVCCompat)
1359 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1362 // Windows ARM, MS (C++) ABI
1363 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1364 const TargetOptions &Opts)
1365 : WindowsARMTargetInfo(Triple, Opts) {
1366 TheCXXABI.set(TargetCXXABI::Microsoft);
1369 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1370 MacroBuilder &Builder) const {
1371 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1372 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1375 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1376 const TargetOptions &Opts)
1377 : WindowsARMTargetInfo(Triple, Opts) {
1378 TheCXXABI.set(TargetCXXABI::GenericARM);
1381 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1382 MacroBuilder &Builder) const {
1383 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1384 Builder.defineMacro("_ARM_");
1387 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1388 const TargetOptions &Opts)
1389 : ARMleTargetInfo(Triple, Opts) {
1390 this->WCharType = TargetInfo::UnsignedShort;
1391 TLSSupported = false;
1392 DoubleAlign = LongLongAlign = 64;
1393 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1396 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1397 MacroBuilder &Builder) const {
1398 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1399 Builder.defineMacro("_ARM_");
1400 Builder.defineMacro("__CYGWIN__");
1401 Builder.defineMacro("__CYGWIN32__");
1402 DefineStd(Builder, "unix", Opts);
1403 if (Opts.CPlusPlus)
1404 Builder.defineMacro("_GNU_SOURCE");
1407 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1408 const TargetOptions &Opts)
1409 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1410 HasAlignMac68kSupport = true;
1411 if (Triple.isWatchABI()) {
1412 // Darwin on iOS uses a variant of the ARM C++ ABI.
1413 TheCXXABI.set(TargetCXXABI::WatchOS);
1415 // BOOL should be a real boolean on the new ABI
1416 UseSignedCharForObjCBool = false;
1417 } else
1418 TheCXXABI.set(TargetCXXABI::iOS);
1421 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1422 const llvm::Triple &Triple,
1423 MacroBuilder &Builder) const {
1424 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1427 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1428 const TargetOptions &Opts)
1429 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1430 Triple.getOSName(),
1431 Triple.getEnvironmentName()),
1432 Opts) {
1433 IsRenderScriptTarget = true;
1434 LongWidth = LongAlign = 64;
1437 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1438 MacroBuilder &Builder) const {
1439 Builder.defineMacro("__RENDERSCRIPT__");
1440 ARMleTargetInfo::getTargetDefines(Opts, Builder);