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