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