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