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