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