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