1 //===--- ARM.cpp - Implement ARM target feature support -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements ARM TargetInfo objects.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARM.h"
15 #include "clang/Basic/Builtins.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/TargetBuiltins.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.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   const llvm::Triple &T = getTriple();
30 
31   bool IsNetBSD = T.isOSNetBSD();
32   bool IsOpenBSD = T.isOSOpenBSD();
33   if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
34     WCharType = UnsignedInt;
35 
36   UseBitFieldTypeAlignment = true;
37 
38   ZeroLengthBitfieldBoundary = 0;
39 
40   // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
41   // so set preferred for small types to 32.
42   if (T.isOSBinFormatMachO()) {
43     resetDataLayout(BigEndian
44                         ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
45                         : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
46   } else if (T.isOSWindows()) {
47     assert(!BigEndian && "Windows on ARM does not support big endian");
48     resetDataLayout("e"
49                     "-m:w"
50                     "-p:32:32"
51                     "-i64:64"
52                     "-v128:64:128"
53                     "-a:0:32"
54                     "-n32"
55                     "-S64");
56   } else if (T.isOSNaCl()) {
57     assert(!BigEndian && "NaCl on ARM does not support big endian");
58     resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
59   } else {
60     resetDataLayout(BigEndian
61                         ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
62                         : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
63   }
64 
65   // FIXME: Enumerated types are variable width in straight AAPCS.
66 }
67 
setABIAPCS(bool IsAAPCS16)68 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
69   const llvm::Triple &T = getTriple();
70 
71   IsAAPCS = false;
72 
73   if (IsAAPCS16)
74     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
75   else
76     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
77 
78   WCharType = SignedInt;
79 
80   // Do not respect the alignment of bit-field types when laying out
81   // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
82   UseBitFieldTypeAlignment = false;
83 
84   /// gcc forces the alignment to 4 bytes, regardless of the type of the
85   /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
86   /// gcc.
87   ZeroLengthBitfieldBoundary = 32;
88 
89   if (T.isOSBinFormatMachO() && IsAAPCS16) {
90     assert(!BigEndian && "AAPCS16 does not support big-endian");
91     resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
92   } else if (T.isOSBinFormatMachO())
93     resetDataLayout(
94         BigEndian
95             ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
96             : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
97   else
98     resetDataLayout(
99         BigEndian
100             ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
101             : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
102 
103   // FIXME: Override "preferred align" for double and long long.
104 }
105 
setArchInfo()106 void ARMTargetInfo::setArchInfo() {
107   StringRef ArchName = getTriple().getArchName();
108 
109   ArchISA = llvm::ARM::parseArchISA(ArchName);
110   CPU = llvm::ARM::getDefaultCPU(ArchName);
111   llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
112   if (AK != llvm::ARM::ArchKind::INVALID)
113     ArchKind = AK;
114   setArchInfo(ArchKind);
115 }
116 
setArchInfo(llvm::ARM::ArchKind Kind)117 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
118   StringRef SubArch;
119 
120   // cache TargetParser info
121   ArchKind = Kind;
122   SubArch = llvm::ARM::getSubArch(ArchKind);
123   ArchProfile = llvm::ARM::parseArchProfile(SubArch);
124   ArchVersion = llvm::ARM::parseArchVersion(SubArch);
125 
126   // cache CPU related strings
127   CPUAttr = getCPUAttr();
128   CPUProfile = getCPUProfile();
129 }
130 
setAtomic()131 void ARMTargetInfo::setAtomic() {
132   // when triple does not specify a sub arch,
133   // then we are not using inline atomics
134   bool ShouldUseInlineAtomic =
135       (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
136       (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
137   // Cortex M does not support 8 byte atomics, while general Thumb2 does.
138   if (ArchProfile == llvm::ARM::ProfileKind::M) {
139     MaxAtomicPromoteWidth = 32;
140     if (ShouldUseInlineAtomic)
141       MaxAtomicInlineWidth = 32;
142   } else {
143     MaxAtomicPromoteWidth = 64;
144     if (ShouldUseInlineAtomic)
145       MaxAtomicInlineWidth = 64;
146   }
147 }
148 
isThumb() const149 bool ARMTargetInfo::isThumb() const {
150   return ArchISA == llvm::ARM::ISAKind::THUMB;
151 }
152 
supportsThumb() const153 bool ARMTargetInfo::supportsThumb() const {
154   return CPUAttr.count('T') || ArchVersion >= 6;
155 }
156 
supportsThumb2() const157 bool ARMTargetInfo::supportsThumb2() const {
158   return CPUAttr.equals("6T2") ||
159          (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
160 }
161 
getCPUAttr() const162 StringRef ARMTargetInfo::getCPUAttr() const {
163   // For most sub-arches, the build attribute CPU name is enough.
164   // For Cortex variants, it's slightly different.
165   switch (ArchKind) {
166   default:
167     return llvm::ARM::getCPUAttr(ArchKind);
168   case llvm::ARM::ArchKind::ARMV6M:
169     return "6M";
170   case llvm::ARM::ArchKind::ARMV7S:
171     return "7S";
172   case llvm::ARM::ArchKind::ARMV7A:
173     return "7A";
174   case llvm::ARM::ArchKind::ARMV7R:
175     return "7R";
176   case llvm::ARM::ArchKind::ARMV7M:
177     return "7M";
178   case llvm::ARM::ArchKind::ARMV7EM:
179     return "7EM";
180   case llvm::ARM::ArchKind::ARMV7VE:
181     return "7VE";
182   case llvm::ARM::ArchKind::ARMV8A:
183     return "8A";
184   case llvm::ARM::ArchKind::ARMV8_1A:
185     return "8_1A";
186   case llvm::ARM::ArchKind::ARMV8_2A:
187     return "8_2A";
188   case llvm::ARM::ArchKind::ARMV8_3A:
189     return "8_3A";
190   case llvm::ARM::ArchKind::ARMV8_4A:
191     return "8_4A";
192   case llvm::ARM::ArchKind::ARMV8_5A:
193     return "8_5A";
194   case llvm::ARM::ArchKind::ARMV8MBaseline:
195     return "8M_BASE";
196   case llvm::ARM::ArchKind::ARMV8MMainline:
197     return "8M_MAIN";
198   case llvm::ARM::ArchKind::ARMV8R:
199     return "8R";
200   }
201 }
202 
getCPUProfile() const203 StringRef ARMTargetInfo::getCPUProfile() const {
204   switch (ArchProfile) {
205   case llvm::ARM::ProfileKind::A:
206     return "A";
207   case llvm::ARM::ProfileKind::R:
208     return "R";
209   case llvm::ARM::ProfileKind::M:
210     return "M";
211   default:
212     return "";
213   }
214 }
215 
ARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)216 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
217                              const TargetOptions &Opts)
218     : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
219       HW_FP(0) {
220   bool IsOpenBSD = Triple.isOSOpenBSD();
221   bool IsNetBSD = Triple.isOSNetBSD();
222 
223   // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
224   // environment where size_t is `unsigned long` rather than `unsigned int`
225 
226   PtrDiffType = IntPtrType =
227       (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
228        IsNetBSD)
229           ? SignedLong
230           : SignedInt;
231 
232   SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
233               IsNetBSD)
234                  ? UnsignedLong
235                  : UnsignedInt;
236 
237   // ptrdiff_t is inconsistent on Darwin
238   if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
239       !Triple.isWatchABI())
240     PtrDiffType = SignedInt;
241 
242   // Cache arch related info.
243   setArchInfo();
244 
245   // {} in inline assembly are neon specifiers, not assembly variant
246   // specifiers.
247   NoAsmVariants = true;
248 
249   // FIXME: This duplicates code from the driver that sets the -target-abi
250   // option - this code is used if -target-abi isn't passed and should
251   // be unified in some way.
252   if (Triple.isOSBinFormatMachO()) {
253     // The backend is hardwired to assume AAPCS for M-class processors, ensure
254     // the frontend matches that.
255     if (Triple.getEnvironment() == llvm::Triple::EABI ||
256         Triple.getOS() == llvm::Triple::UnknownOS ||
257         ArchProfile == llvm::ARM::ProfileKind::M) {
258       setABI("aapcs");
259     } else if (Triple.isWatchABI()) {
260       setABI("aapcs16");
261     } else {
262       setABI("apcs-gnu");
263     }
264   } else if (Triple.isOSWindows()) {
265     // FIXME: this is invalid for WindowsCE
266     setABI("aapcs");
267   } else {
268     // Select the default based on the platform.
269     switch (Triple.getEnvironment()) {
270     case llvm::Triple::Android:
271     case llvm::Triple::GNUEABI:
272     case llvm::Triple::GNUEABIHF:
273     case llvm::Triple::MuslEABI:
274     case llvm::Triple::MuslEABIHF:
275       setABI("aapcs-linux");
276       break;
277     case llvm::Triple::EABIHF:
278     case llvm::Triple::EABI:
279       setABI("aapcs");
280       break;
281     case llvm::Triple::GNU:
282       setABI("apcs-gnu");
283       break;
284     default:
285       if (IsNetBSD)
286         setABI("apcs-gnu");
287       else if (IsOpenBSD)
288         setABI("aapcs-linux");
289       else
290         setABI("aapcs");
291       break;
292     }
293   }
294 
295   // ARM targets default to using the ARM C++ ABI.
296   TheCXXABI.set(TargetCXXABI::GenericARM);
297 
298   // ARM has atomics up to 8 bytes
299   setAtomic();
300 
301   // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
302   if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
303     MaxVectorAlign = 64;
304 
305   // Do force alignment of members that follow zero length bitfields.  If
306   // the alignment of the zero-length bitfield is greater than the member
307   // that follows it, `bar', `bar' will be aligned as the  type of the
308   // zero length bitfield.
309   UseZeroLengthBitfieldAlignment = true;
310 
311   if (Triple.getOS() == llvm::Triple::Linux ||
312       Triple.getOS() == llvm::Triple::UnknownOS)
313     this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
314                            ? "\01__gnu_mcount_nc"
315                            : "\01mcount";
316 }
317 
getABI() const318 StringRef ARMTargetInfo::getABI() const { return ABI; }
319 
setABI(const std::string & Name)320 bool ARMTargetInfo::setABI(const std::string &Name) {
321   ABI = Name;
322 
323   // The defaults (above) are for AAPCS, check if we need to change them.
324   //
325   // FIXME: We need support for -meabi... we could just mangle it into the
326   // name.
327   if (Name == "apcs-gnu" || Name == "aapcs16") {
328     setABIAPCS(Name == "aapcs16");
329     return true;
330   }
331   if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
332     setABIAAPCS();
333     return true;
334   }
335   return false;
336 }
337 
338 // 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) const339 bool ARMTargetInfo::initFeatureMap(
340     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
341     const std::vector<std::string> &FeaturesVec) const {
342 
343   std::string ArchFeature;
344   std::vector<StringRef> TargetFeatures;
345   llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
346 
347   // Map the base architecture to an appropriate target feature, so we don't
348   // rely on the target triple.
349   llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
350   if (CPUArch == llvm::ARM::ArchKind::INVALID)
351     CPUArch = Arch;
352   if (CPUArch != llvm::ARM::ArchKind::INVALID) {
353     ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
354     TargetFeatures.push_back(ArchFeature);
355   }
356 
357   // get default FPU features
358   unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
359   llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
360 
361   // get default Extension features
362   unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
363   llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
364 
365   for (auto Feature : TargetFeatures)
366     if (Feature[0] == '+')
367       Features[Feature.drop_front(1)] = true;
368 
369   // Enable or disable thumb-mode explicitly per function to enable mixed
370   // ARM and Thumb code generation.
371   if (isThumb())
372     Features["thumb-mode"] = true;
373   else
374     Features["thumb-mode"] = false;
375 
376   // Convert user-provided arm and thumb GNU target attributes to
377   // [-|+]thumb-mode target features respectively.
378   std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
379   for (auto &Feature : UpdatedFeaturesVec) {
380     if (Feature.compare("+arm") == 0)
381       Feature = "-thumb-mode";
382     else if (Feature.compare("+thumb") == 0)
383       Feature = "+thumb-mode";
384   }
385 
386   return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
387 }
388 
389 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)390 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
391                                          DiagnosticsEngine &Diags) {
392   FPU = 0;
393   CRC = 0;
394   Crypto = 0;
395   DSP = 0;
396   Unaligned = 1;
397   SoftFloat = SoftFloatABI = false;
398   HWDiv = 0;
399   DotProd = 0;
400   HasFloat16 = true;
401 
402   // This does not diagnose illegal cases like having both
403   // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
404   uint32_t HW_FP_remove = 0;
405   for (const auto &Feature : Features) {
406     if (Feature == "+soft-float") {
407       SoftFloat = true;
408     } else if (Feature == "+soft-float-abi") {
409       SoftFloatABI = true;
410     } else if (Feature == "+vfp2") {
411       FPU |= VFP2FPU;
412       HW_FP |= HW_FP_SP | HW_FP_DP;
413     } else if (Feature == "+vfp3") {
414       FPU |= VFP3FPU;
415       HW_FP |= HW_FP_SP | HW_FP_DP;
416     } else if (Feature == "+vfp4") {
417       FPU |= VFP4FPU;
418       HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
419     } else if (Feature == "+fp-armv8") {
420       FPU |= FPARMV8;
421       HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
422     } else if (Feature == "+neon") {
423       FPU |= NeonFPU;
424       HW_FP |= HW_FP_SP | HW_FP_DP;
425     } else if (Feature == "+hwdiv") {
426       HWDiv |= HWDivThumb;
427     } else if (Feature == "+hwdiv-arm") {
428       HWDiv |= HWDivARM;
429     } else if (Feature == "+crc") {
430       CRC = 1;
431     } else if (Feature == "+crypto") {
432       Crypto = 1;
433     } else if (Feature == "+dsp") {
434       DSP = 1;
435     } else if (Feature == "+fp-only-sp") {
436       HW_FP_remove |= HW_FP_DP;
437     } else if (Feature == "+strict-align") {
438       Unaligned = 0;
439     } else if (Feature == "+fp16") {
440       HW_FP |= HW_FP_HP;
441     } else if (Feature == "+fullfp16") {
442       HasLegalHalfType = true;
443     } else if (Feature == "+dotprod") {
444       DotProd = true;
445     }
446   }
447   HW_FP &= ~HW_FP_remove;
448 
449   switch (ArchVersion) {
450   case 6:
451     if (ArchProfile == llvm::ARM::ProfileKind::M)
452       LDREX = 0;
453     else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
454       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
455     else
456       LDREX = LDREX_W;
457     break;
458   case 7:
459     if (ArchProfile == llvm::ARM::ProfileKind::M)
460       LDREX = LDREX_W | LDREX_H | LDREX_B;
461     else
462       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
463     break;
464   case 8:
465     LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
466   }
467 
468   if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
469     Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
470     return false;
471   }
472 
473   if (FPMath == FP_Neon)
474     Features.push_back("+neonfp");
475   else if (FPMath == FP_VFP)
476     Features.push_back("-neonfp");
477 
478   // Remove front-end specific options which the backend handles differently.
479   auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
480   if (Feature != Features.end())
481     Features.erase(Feature);
482 
483   return true;
484 }
485 
hasFeature(StringRef Feature) const486 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
487   return llvm::StringSwitch<bool>(Feature)
488       .Case("arm", true)
489       .Case("aarch32", true)
490       .Case("softfloat", SoftFloat)
491       .Case("thumb", isThumb())
492       .Case("neon", (FPU & NeonFPU) && !SoftFloat)
493       .Case("vfp", FPU && !SoftFloat)
494       .Case("hwdiv", HWDiv & HWDivThumb)
495       .Case("hwdiv-arm", HWDiv & HWDivARM)
496       .Default(false);
497 }
498 
isValidCPUName(StringRef Name) const499 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
500   return Name == "generic" ||
501          llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
502 }
503 
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const504 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
505   llvm::ARM::fillValidCPUArchList(Values);
506 }
507 
setCPU(const std::string & Name)508 bool ARMTargetInfo::setCPU(const std::string &Name) {
509   if (Name != "generic")
510     setArchInfo(llvm::ARM::parseCPUArch(Name));
511 
512   if (ArchKind == llvm::ARM::ArchKind::INVALID)
513     return false;
514   setAtomic();
515   CPU = Name;
516   return true;
517 }
518 
setFPMath(StringRef Name)519 bool ARMTargetInfo::setFPMath(StringRef Name) {
520   if (Name == "neon") {
521     FPMath = FP_Neon;
522     return true;
523   } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
524              Name == "vfp4") {
525     FPMath = FP_VFP;
526     return true;
527   }
528   return false;
529 }
530 
getTargetDefinesARMV81A(const LangOptions & Opts,MacroBuilder & Builder) const531 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
532                                             MacroBuilder &Builder) const {
533   Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
534 }
535 
getTargetDefinesARMV82A(const LangOptions & Opts,MacroBuilder & Builder) const536 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
537                                             MacroBuilder &Builder) const {
538   // Also include the ARMv8.1-A defines
539   getTargetDefinesARMV81A(Opts, Builder);
540 }
541 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const542 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
543                                      MacroBuilder &Builder) const {
544   // Target identification.
545   Builder.defineMacro("__arm");
546   Builder.defineMacro("__arm__");
547   // For bare-metal none-eabi.
548   if (getTriple().getOS() == llvm::Triple::UnknownOS &&
549       (getTriple().getEnvironment() == llvm::Triple::EABI ||
550        getTriple().getEnvironment() == llvm::Triple::EABIHF))
551     Builder.defineMacro("__ELF__");
552 
553   // Target properties.
554   Builder.defineMacro("__REGISTER_PREFIX__", "");
555 
556   // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
557   // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
558   if (getTriple().isWatchABI())
559     Builder.defineMacro("__ARM_ARCH_7K__", "2");
560 
561   if (!CPUAttr.empty())
562     Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
563 
564   // ACLE 6.4.1 ARM/Thumb instruction set architecture
565   // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
566   Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
567 
568   if (ArchVersion >= 8) {
569     // ACLE 6.5.7 Crypto Extension
570     if (Crypto)
571       Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
572     // ACLE 6.5.8 CRC32 Extension
573     if (CRC)
574       Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
575     // ACLE 6.5.10 Numeric Maximum and Minimum
576     Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
577     // ACLE 6.5.9 Directed Rounding
578     Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
579   }
580 
581   // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
582   // is not defined for the M-profile.
583   // NOTE that the default profile is assumed to be 'A'
584   if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
585     Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
586 
587   // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
588   // Thumb ISA (including v6-M and v8-M Baseline).  It is set to 2 if the
589   // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
590   // v7 and v8 architectures excluding v8-M Baseline.
591   if (supportsThumb2())
592     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
593   else if (supportsThumb())
594     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
595 
596   // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
597   // instruction set such as ARM or Thumb.
598   Builder.defineMacro("__ARM_32BIT_STATE", "1");
599 
600   // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
601 
602   // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
603   if (!CPUProfile.empty())
604     Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
605 
606   // ACLE 6.4.3 Unaligned access supported in hardware
607   if (Unaligned)
608     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
609 
610   // ACLE 6.4.4 LDREX/STREX
611   if (LDREX)
612     Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
613 
614   // ACLE 6.4.5 CLZ
615   if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
616       ArchVersion > 6)
617     Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
618 
619   // ACLE 6.5.1 Hardware Floating Point
620   if (HW_FP)
621     Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
622 
623   // ACLE predefines.
624   Builder.defineMacro("__ARM_ACLE", "200");
625 
626   // FP16 support (we currently only support IEEE format).
627   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
628   Builder.defineMacro("__ARM_FP16_ARGS", "1");
629 
630   // ACLE 6.5.3 Fused multiply-accumulate (FMA)
631   if (ArchVersion >= 7 && (FPU & VFP4FPU))
632     Builder.defineMacro("__ARM_FEATURE_FMA", "1");
633 
634   // Subtarget options.
635 
636   // FIXME: It's more complicated than this and we don't really support
637   // interworking.
638   // Windows on ARM does not "support" interworking
639   if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
640     Builder.defineMacro("__THUMB_INTERWORK__");
641 
642   if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
643     // Embedded targets on Darwin follow AAPCS, but not EABI.
644     // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
645     if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
646       Builder.defineMacro("__ARM_EABI__");
647     Builder.defineMacro("__ARM_PCS", "1");
648   }
649 
650   if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
651     Builder.defineMacro("__ARM_PCS_VFP", "1");
652 
653   if (SoftFloat)
654     Builder.defineMacro("__SOFTFP__");
655 
656   if (ArchKind == llvm::ARM::ArchKind::XSCALE)
657     Builder.defineMacro("__XSCALE__");
658 
659   if (isThumb()) {
660     Builder.defineMacro("__THUMBEL__");
661     Builder.defineMacro("__thumb__");
662     if (supportsThumb2())
663       Builder.defineMacro("__thumb2__");
664   }
665 
666   // ACLE 6.4.9 32-bit SIMD instructions
667   if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
668     Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
669 
670   // ACLE 6.4.10 Hardware Integer Divide
671   if (((HWDiv & HWDivThumb) && isThumb()) ||
672       ((HWDiv & HWDivARM) && !isThumb())) {
673     Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
674     Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
675   }
676 
677   // Note, this is always on in gcc, even though it doesn't make sense.
678   Builder.defineMacro("__APCS_32__");
679 
680   if (FPUModeIsVFP((FPUMode)FPU)) {
681     Builder.defineMacro("__VFP_FP__");
682     if (FPU & VFP2FPU)
683       Builder.defineMacro("__ARM_VFPV2__");
684     if (FPU & VFP3FPU)
685       Builder.defineMacro("__ARM_VFPV3__");
686     if (FPU & VFP4FPU)
687       Builder.defineMacro("__ARM_VFPV4__");
688     if (FPU & FPARMV8)
689       Builder.defineMacro("__ARM_FPV5__");
690   }
691 
692   // This only gets set when Neon instructions are actually available, unlike
693   // the VFP define, hence the soft float and arch check. This is subtly
694   // different from gcc, we follow the intent which was that it should be set
695   // when Neon instructions are actually available.
696   if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
697     Builder.defineMacro("__ARM_NEON", "1");
698     Builder.defineMacro("__ARM_NEON__");
699     // current AArch32 NEON implementations do not support double-precision
700     // floating-point even when it is present in VFP.
701     Builder.defineMacro("__ARM_NEON_FP",
702                         "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
703   }
704 
705   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
706                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
707 
708   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
709 
710   if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
711     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
712     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
713     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
714     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
715   }
716 
717   // ACLE 6.4.7 DSP instructions
718   if (DSP) {
719     Builder.defineMacro("__ARM_FEATURE_DSP", "1");
720   }
721 
722   // ACLE 6.4.8 Saturation instructions
723   bool SAT = false;
724   if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
725     Builder.defineMacro("__ARM_FEATURE_SAT", "1");
726     SAT = true;
727   }
728 
729   // ACLE 6.4.6 Q (saturation) flag
730   if (DSP || SAT)
731     Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
732 
733   if (Opts.UnsafeFPMath)
734     Builder.defineMacro("__ARM_FP_FAST", "1");
735 
736   // Armv8.2-A FP16 vector intrinsic
737   if ((FPU & NeonFPU) && HasLegalHalfType)
738     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
739 
740   // Armv8.2-A FP16 scalar intrinsics
741   if (HasLegalHalfType)
742     Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
743 
744   // Armv8.2-A dot product intrinsics
745   if (DotProd)
746     Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
747 
748   switch (ArchKind) {
749   default:
750     break;
751   case llvm::ARM::ArchKind::ARMV8_1A:
752     getTargetDefinesARMV81A(Opts, Builder);
753     break;
754   case llvm::ARM::ArchKind::ARMV8_2A:
755     getTargetDefinesARMV82A(Opts, Builder);
756     break;
757   }
758 }
759 
760 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
761 #define BUILTIN(ID, TYPE, ATTRS)                                               \
762   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
763 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
764   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
765 #include "clang/Basic/BuiltinsNEON.def"
766 
767 #define BUILTIN(ID, TYPE, ATTRS)                                               \
768   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
769 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
770   {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
771 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
772   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
773 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
774   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
775 #include "clang/Basic/BuiltinsARM.def"
776 };
777 
getTargetBuiltins() const778 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
779   return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
780                                              Builtin::FirstTSBuiltin);
781 }
782 
isCLZForZeroUndef() const783 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
getBuiltinVaListKind() const784 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
785   return IsAAPCS
786              ? AAPCSABIBuiltinVaList
787              : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
788                                          : TargetInfo::VoidPtrBuiltinVaList);
789 }
790 
791 const char *const ARMTargetInfo::GCCRegNames[] = {
792     // Integer registers
793     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
794     "r12", "sp", "lr", "pc",
795 
796     // Float registers
797     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
798     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
799     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
800 
801     // Double registers
802     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
803     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
804     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
805 
806     // Quad registers
807     "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
808     "q12", "q13", "q14", "q15"};
809 
getGCCRegNames() const810 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
811   return llvm::makeArrayRef(GCCRegNames);
812 }
813 
814 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
815     {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},
816     {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},
817     {{"v5"}, "r8"},  {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
818     {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},
819     // The S, D and Q registers overlap, but aren't really aliases; we
820     // don't want to substitute one of these for a different-sized one.
821 };
822 
getGCCRegAliases() const823 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
824   return llvm::makeArrayRef(GCCRegAliases);
825 }
826 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const827 bool ARMTargetInfo::validateAsmConstraint(
828     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
829   switch (*Name) {
830   default:
831     break;
832   case 'l': // r0-r7
833   case 'h': // r8-r15
834   case 't': // VFP Floating point register single precision
835   case 'w': // VFP Floating point register double precision
836     Info.setAllowsRegister();
837     return true;
838   case 'I':
839   case 'J':
840   case 'K':
841   case 'L':
842   case 'M':
843     // FIXME
844     return true;
845   case 'Q': // A memory address that is a single base register.
846     Info.setAllowsMemory();
847     return true;
848   case 'U': // a memory reference...
849     switch (Name[1]) {
850     case 'q': // ...ARMV4 ldrsb
851     case 'v': // ...VFP load/store (reg+constant offset)
852     case 'y': // ...iWMMXt load/store
853     case 't': // address valid for load/store opaque types wider
854               // than 128-bits
855     case 'n': // valid address for Neon doubleword vector load/store
856     case 'm': // valid address for Neon element and structure load/store
857     case 's': // valid address for non-offset loads/stores of quad-word
858               // values in four ARM registers
859       Info.setAllowsMemory();
860       Name++;
861       return true;
862     }
863   }
864   return false;
865 }
866 
convertConstraint(const char * & Constraint) const867 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
868   std::string R;
869   switch (*Constraint) {
870   case 'U': // Two-character constraint; add "^" hint for later parsing.
871     R = std::string("^") + std::string(Constraint, 2);
872     Constraint++;
873     break;
874   case 'p': // 'p' should be translated to 'r' by default.
875     R = std::string("r");
876     break;
877   default:
878     return std::string(1, *Constraint);
879   }
880   return R;
881 }
882 
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const883 bool ARMTargetInfo::validateConstraintModifier(
884     StringRef Constraint, char Modifier, unsigned Size,
885     std::string &SuggestedModifier) const {
886   bool isOutput = (Constraint[0] == '=');
887   bool isInOut = (Constraint[0] == '+');
888 
889   // Strip off constraint modifiers.
890   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
891     Constraint = Constraint.substr(1);
892 
893   switch (Constraint[0]) {
894   default:
895     break;
896   case 'r': {
897     switch (Modifier) {
898     default:
899       return (isInOut || isOutput || Size <= 64);
900     case 'q':
901       // A register of size 32 cannot fit a vector type.
902       return false;
903     }
904   }
905   }
906 
907   return true;
908 }
getClobbers() const909 const char *ARMTargetInfo::getClobbers() const {
910   // FIXME: Is this really right?
911   return "";
912 }
913 
914 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const915 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
916   switch (CC) {
917   case CC_AAPCS:
918   case CC_AAPCS_VFP:
919   case CC_Swift:
920   case CC_OpenCLKernel:
921     return CCCR_OK;
922   default:
923     return CCCR_Warning;
924   }
925 }
926 
getEHDataRegisterNumber(unsigned RegNo) const927 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
928   if (RegNo == 0)
929     return 0;
930   if (RegNo == 1)
931     return 1;
932   return -1;
933 }
934 
hasSjLjLowering() const935 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
936 
ARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)937 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
938                                  const TargetOptions &Opts)
939     : ARMTargetInfo(Triple, Opts) {}
940 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const941 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
942                                        MacroBuilder &Builder) const {
943   Builder.defineMacro("__ARMEL__");
944   ARMTargetInfo::getTargetDefines(Opts, Builder);
945 }
946 
ARMbeTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)947 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
948                                  const TargetOptions &Opts)
949     : ARMTargetInfo(Triple, Opts) {}
950 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const951 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
952                                        MacroBuilder &Builder) const {
953   Builder.defineMacro("__ARMEB__");
954   Builder.defineMacro("__ARM_BIG_ENDIAN");
955   ARMTargetInfo::getTargetDefines(Opts, Builder);
956 }
957 
WindowsARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)958 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
959                                            const TargetOptions &Opts)
960     : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
961 }
962 
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const963 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
964                                                   MacroBuilder &Builder) const {
965   WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
966 
967   // FIXME: this is invalid for WindowsCE
968   Builder.defineMacro("_M_ARM_NT", "1");
969   Builder.defineMacro("_M_ARMT", "_M_ARM");
970   Builder.defineMacro("_M_THUMB", "_M_ARM");
971 
972   assert((Triple.getArch() == llvm::Triple::arm ||
973           Triple.getArch() == llvm::Triple::thumb) &&
974          "invalid architecture for Windows ARM target info");
975   unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
976   Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
977 
978   // TODO map the complete set of values
979   // 31: VFPv3 40: VFPv4
980   Builder.defineMacro("_M_ARM_FP", "31");
981 }
982 
983 TargetInfo::BuiltinVaListKind
getBuiltinVaListKind() const984 WindowsARMTargetInfo::getBuiltinVaListKind() const {
985   return TargetInfo::CharPtrBuiltinVaList;
986 }
987 
988 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const989 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
990   switch (CC) {
991   case CC_X86StdCall:
992   case CC_X86ThisCall:
993   case CC_X86FastCall:
994   case CC_X86VectorCall:
995     return CCCR_Ignore;
996   case CC_C:
997   case CC_OpenCLKernel:
998   case CC_PreserveMost:
999   case CC_PreserveAll:
1000   case CC_Swift:
1001     return CCCR_OK;
1002   default:
1003     return CCCR_Warning;
1004   }
1005 }
1006 
1007 // Windows ARM + Itanium C++ ABI Target
ItaniumWindowsARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1008 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1009     const llvm::Triple &Triple, const TargetOptions &Opts)
1010     : WindowsARMTargetInfo(Triple, Opts) {
1011   TheCXXABI.set(TargetCXXABI::GenericARM);
1012 }
1013 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1014 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1015     const LangOptions &Opts, MacroBuilder &Builder) const {
1016   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1017 
1018   if (Opts.MSVCCompat)
1019     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1020 }
1021 
1022 // Windows ARM, MS (C++) ABI
MicrosoftARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1023 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1024                                                    const TargetOptions &Opts)
1025     : WindowsARMTargetInfo(Triple, Opts) {
1026   TheCXXABI.set(TargetCXXABI::Microsoft);
1027 }
1028 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1029 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1030                                                 MacroBuilder &Builder) const {
1031   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1032   WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1033 }
1034 
MinGWARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1035 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1036                                        const TargetOptions &Opts)
1037     : WindowsARMTargetInfo(Triple, Opts) {
1038   TheCXXABI.set(TargetCXXABI::GenericARM);
1039 }
1040 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1041 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1042                                           MacroBuilder &Builder) const {
1043   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1044   Builder.defineMacro("_ARM_");
1045 }
1046 
CygwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1047 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1048                                          const TargetOptions &Opts)
1049     : ARMleTargetInfo(Triple, Opts) {
1050   this->WCharType = TargetInfo::UnsignedShort;
1051   TLSSupported = false;
1052   DoubleAlign = LongLongAlign = 64;
1053   resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1054 }
1055 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1056 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1057                                            MacroBuilder &Builder) const {
1058   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1059   Builder.defineMacro("_ARM_");
1060   Builder.defineMacro("__CYGWIN__");
1061   Builder.defineMacro("__CYGWIN32__");
1062   DefineStd(Builder, "unix", Opts);
1063   if (Opts.CPlusPlus)
1064     Builder.defineMacro("_GNU_SOURCE");
1065 }
1066 
DarwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1067 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1068                                          const TargetOptions &Opts)
1069     : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1070   HasAlignMac68kSupport = true;
1071   // iOS always has 64-bit atomic instructions.
1072   // FIXME: This should be based off of the target features in
1073   // ARMleTargetInfo.
1074   MaxAtomicInlineWidth = 64;
1075 
1076   if (Triple.isWatchABI()) {
1077     // Darwin on iOS uses a variant of the ARM C++ ABI.
1078     TheCXXABI.set(TargetCXXABI::WatchOS);
1079 
1080     // BOOL should be a real boolean on the new ABI
1081     UseSignedCharForObjCBool = false;
1082   } else
1083     TheCXXABI.set(TargetCXXABI::iOS);
1084 }
1085 
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const1086 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1087                                        const llvm::Triple &Triple,
1088                                        MacroBuilder &Builder) const {
1089   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1090 }
1091 
RenderScript32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1092 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1093                                                    const TargetOptions &Opts)
1094     : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1095                                    Triple.getOSName(),
1096                                    Triple.getEnvironmentName()),
1097                       Opts) {
1098   IsRenderScriptTarget = true;
1099   LongWidth = LongAlign = 64;
1100 }
1101 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1102 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1103                                                 MacroBuilder &Builder) const {
1104   Builder.defineMacro("__RENDERSCRIPT__");
1105   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1106 }
1107