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