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