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   SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
328 }
329 
330 StringRef ARMTargetInfo::getABI() const { return ABI; }
331 
332 bool ARMTargetInfo::setABI(const std::string &Name) {
333   ABI = Name;
334 
335   // The defaults (above) are for AAPCS, check if we need to change them.
336   //
337   // FIXME: We need support for -meabi... we could just mangle it into the
338   // name.
339   if (Name == "apcs-gnu" || Name == "aapcs16") {
340     setABIAPCS(Name == "aapcs16");
341     return true;
342   }
343   if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
344     setABIAAPCS();
345     return true;
346   }
347   return false;
348 }
349 
350 // FIXME: This should be based on Arch attributes, not CPU names.
351 bool ARMTargetInfo::initFeatureMap(
352     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
353     const std::vector<std::string> &FeaturesVec) const {
354 
355   std::string ArchFeature;
356   std::vector<StringRef> TargetFeatures;
357   llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
358 
359   // Map the base architecture to an appropriate target feature, so we don't
360   // rely on the target triple.
361   llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
362   if (CPUArch == llvm::ARM::ArchKind::INVALID)
363     CPUArch = Arch;
364   if (CPUArch != llvm::ARM::ArchKind::INVALID) {
365     ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
366     TargetFeatures.push_back(ArchFeature);
367   }
368 
369   // get default FPU features
370   unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
371   llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
372 
373   // get default Extension features
374   unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
375   llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
376 
377   for (auto Feature : TargetFeatures)
378     if (Feature[0] == '+')
379       Features[Feature.drop_front(1)] = true;
380 
381   // Enable or disable thumb-mode explicitly per function to enable mixed
382   // ARM and Thumb code generation.
383   if (isThumb())
384     Features["thumb-mode"] = true;
385   else
386     Features["thumb-mode"] = false;
387 
388   // Convert user-provided arm and thumb GNU target attributes to
389   // [-|+]thumb-mode target features respectively.
390   std::vector<std::string> UpdatedFeaturesVec;
391   for (const auto &Feature : FeaturesVec) {
392     // Skip soft-float-abi; it's something we only use to initialize a bit of
393     // class state, and is otherwise unrecognized.
394     if (Feature == "+soft-float-abi")
395       continue;
396 
397     StringRef FixedFeature;
398     if (Feature == "+arm")
399       FixedFeature = "-thumb-mode";
400     else if (Feature == "+thumb")
401       FixedFeature = "+thumb-mode";
402     else
403       FixedFeature = Feature;
404     UpdatedFeaturesVec.push_back(FixedFeature.str());
405   }
406 
407   return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
408 }
409 
410 
411 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
412                                          DiagnosticsEngine &Diags) {
413   FPU = 0;
414   MVE = 0;
415   CRC = 0;
416   Crypto = 0;
417   DSP = 0;
418   Unaligned = 1;
419   SoftFloat = false;
420   // Note that SoftFloatABI is initialized in our constructor.
421   HWDiv = 0;
422   DotProd = 0;
423   HasFloat16 = true;
424 
425   // This does not diagnose illegal cases like having both
426   // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
427   for (const auto &Feature : Features) {
428     if (Feature == "+soft-float") {
429       SoftFloat = true;
430     } else if (Feature == "+vfp2sp" || Feature == "+vfp2d16sp" ||
431                Feature == "+vfp2" || Feature == "+vfp2d16") {
432       FPU |= VFP2FPU;
433       HW_FP |= HW_FP_SP;
434       if (Feature == "+vfp2" || Feature == "+vfp2d16")
435           HW_FP |= HW_FP_DP;
436     } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
437                Feature == "+vfp3" || Feature == "+vfp3d16") {
438       FPU |= VFP3FPU;
439       HW_FP |= HW_FP_SP;
440       if (Feature == "+vfp3" || Feature == "+vfp3d16")
441           HW_FP |= HW_FP_DP;
442     } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
443                Feature == "+vfp4" || Feature == "+vfp4d16") {
444       FPU |= VFP4FPU;
445       HW_FP |= HW_FP_SP | HW_FP_HP;
446       if (Feature == "+vfp4" || Feature == "+vfp4d16")
447           HW_FP |= HW_FP_DP;
448     } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
449                Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
450       FPU |= FPARMV8;
451       HW_FP |= HW_FP_SP | HW_FP_HP;
452       if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
453           HW_FP |= HW_FP_DP;
454     } else if (Feature == "+neon") {
455       FPU |= NeonFPU;
456       HW_FP |= HW_FP_SP;
457     } else if (Feature == "+hwdiv") {
458       HWDiv |= HWDivThumb;
459     } else if (Feature == "+hwdiv-arm") {
460       HWDiv |= HWDivARM;
461     } else if (Feature == "+crc") {
462       CRC = 1;
463     } else if (Feature == "+crypto") {
464       Crypto = 1;
465     } else if (Feature == "+dsp") {
466       DSP = 1;
467     } else if (Feature == "+fp64") {
468       HW_FP |= HW_FP_DP;
469     } else if (Feature == "+8msecext") {
470       if (CPUProfile != "M" || ArchVersion != 8) {
471         Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
472         return false;
473       }
474     } else if (Feature == "+strict-align") {
475       Unaligned = 0;
476     } else if (Feature == "+fp16") {
477       HW_FP |= HW_FP_HP;
478     } else if (Feature == "+fullfp16") {
479       HasLegalHalfType = true;
480     } else if (Feature == "+dotprod") {
481       DotProd = true;
482     } else if (Feature == "+mve") {
483       DSP = 1;
484       MVE |= MVE_INT;
485     } else if (Feature == "+mve.fp") {
486       DSP = 1;
487       HasLegalHalfType = true;
488       FPU |= FPARMV8;
489       MVE |= MVE_INT | MVE_FP;
490       HW_FP |= HW_FP_SP | HW_FP_HP;
491     }
492   }
493 
494   switch (ArchVersion) {
495   case 6:
496     if (ArchProfile == llvm::ARM::ProfileKind::M)
497       LDREX = 0;
498     else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
499       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
500     else
501       LDREX = LDREX_W;
502     break;
503   case 7:
504     if (ArchProfile == llvm::ARM::ProfileKind::M)
505       LDREX = LDREX_W | LDREX_H | LDREX_B;
506     else
507       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
508     break;
509   case 8:
510     LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
511   }
512 
513   if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
514     Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
515     return false;
516   }
517 
518   if (FPMath == FP_Neon)
519     Features.push_back("+neonfp");
520   else if (FPMath == FP_VFP)
521     Features.push_back("-neonfp");
522 
523   return true;
524 }
525 
526 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
527   return llvm::StringSwitch<bool>(Feature)
528       .Case("arm", true)
529       .Case("aarch32", true)
530       .Case("softfloat", SoftFloat)
531       .Case("thumb", isThumb())
532       .Case("neon", (FPU & NeonFPU) && !SoftFloat)
533       .Case("vfp", FPU && !SoftFloat)
534       .Case("hwdiv", HWDiv & HWDivThumb)
535       .Case("hwdiv-arm", HWDiv & HWDivARM)
536       .Case("mve", hasMVE())
537       .Default(false);
538 }
539 
540 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
541   return Name == "generic" ||
542          llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
543 }
544 
545 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
546   llvm::ARM::fillValidCPUArchList(Values);
547 }
548 
549 bool ARMTargetInfo::setCPU(const std::string &Name) {
550   if (Name != "generic")
551     setArchInfo(llvm::ARM::parseCPUArch(Name));
552 
553   if (ArchKind == llvm::ARM::ArchKind::INVALID)
554     return false;
555   setAtomic();
556   CPU = Name;
557   return true;
558 }
559 
560 bool ARMTargetInfo::setFPMath(StringRef Name) {
561   if (Name == "neon") {
562     FPMath = FP_Neon;
563     return true;
564   } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
565              Name == "vfp4") {
566     FPMath = FP_VFP;
567     return true;
568   }
569   return false;
570 }
571 
572 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
573                                             MacroBuilder &Builder) const {
574   Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
575 }
576 
577 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
578                                             MacroBuilder &Builder) const {
579   // Also include the ARMv8.1-A defines
580   getTargetDefinesARMV81A(Opts, Builder);
581 }
582 
583 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
584                                      MacroBuilder &Builder) const {
585   // Target identification.
586   Builder.defineMacro("__arm");
587   Builder.defineMacro("__arm__");
588   // For bare-metal none-eabi.
589   if (getTriple().getOS() == llvm::Triple::UnknownOS &&
590       (getTriple().getEnvironment() == llvm::Triple::EABI ||
591        getTriple().getEnvironment() == llvm::Triple::EABIHF))
592     Builder.defineMacro("__ELF__");
593 
594   // Target properties.
595   Builder.defineMacro("__REGISTER_PREFIX__", "");
596 
597   // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
598   // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
599   if (getTriple().isWatchABI())
600     Builder.defineMacro("__ARM_ARCH_7K__", "2");
601 
602   if (!CPUAttr.empty())
603     Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
604 
605   // ACLE 6.4.1 ARM/Thumb instruction set architecture
606   // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
607   Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
608 
609   if (ArchVersion >= 8) {
610     // ACLE 6.5.7 Crypto Extension
611     if (Crypto)
612       Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
613     // ACLE 6.5.8 CRC32 Extension
614     if (CRC)
615       Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
616     // ACLE 6.5.10 Numeric Maximum and Minimum
617     Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
618     // ACLE 6.5.9 Directed Rounding
619     Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
620   }
621 
622   // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
623   // is not defined for the M-profile.
624   // NOTE that the default profile is assumed to be 'A'
625   if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
626     Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
627 
628   // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
629   // Thumb ISA (including v6-M and v8-M Baseline).  It is set to 2 if the
630   // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
631   // v7 and v8 architectures excluding v8-M Baseline.
632   if (supportsThumb2())
633     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
634   else if (supportsThumb())
635     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
636 
637   // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
638   // instruction set such as ARM or Thumb.
639   Builder.defineMacro("__ARM_32BIT_STATE", "1");
640 
641   // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
642 
643   // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
644   if (!CPUProfile.empty())
645     Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
646 
647   // ACLE 6.4.3 Unaligned access supported in hardware
648   if (Unaligned)
649     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
650 
651   // ACLE 6.4.4 LDREX/STREX
652   if (LDREX)
653     Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
654 
655   // ACLE 6.4.5 CLZ
656   if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
657       ArchVersion > 6)
658     Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
659 
660   // ACLE 6.5.1 Hardware Floating Point
661   if (HW_FP)
662     Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
663 
664   // ACLE predefines.
665   Builder.defineMacro("__ARM_ACLE", "200");
666 
667   // FP16 support (we currently only support IEEE format).
668   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
669   Builder.defineMacro("__ARM_FP16_ARGS", "1");
670 
671   // ACLE 6.5.3 Fused multiply-accumulate (FMA)
672   if (ArchVersion >= 7 && (FPU & VFP4FPU))
673     Builder.defineMacro("__ARM_FEATURE_FMA", "1");
674 
675   // Subtarget options.
676 
677   // FIXME: It's more complicated than this and we don't really support
678   // interworking.
679   // Windows on ARM does not "support" interworking
680   if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
681     Builder.defineMacro("__THUMB_INTERWORK__");
682 
683   if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
684     // Embedded targets on Darwin follow AAPCS, but not EABI.
685     // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
686     if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
687       Builder.defineMacro("__ARM_EABI__");
688     Builder.defineMacro("__ARM_PCS", "1");
689   }
690 
691   if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
692     Builder.defineMacro("__ARM_PCS_VFP", "1");
693 
694   if (SoftFloat)
695     Builder.defineMacro("__SOFTFP__");
696 
697   // ACLE position independent code macros.
698   if (Opts.ROPI)
699     Builder.defineMacro("__ARM_ROPI", "1");
700   if (Opts.RWPI)
701     Builder.defineMacro("__ARM_RWPI", "1");
702 
703   if (ArchKind == llvm::ARM::ArchKind::XSCALE)
704     Builder.defineMacro("__XSCALE__");
705 
706   if (isThumb()) {
707     Builder.defineMacro("__THUMBEL__");
708     Builder.defineMacro("__thumb__");
709     if (supportsThumb2())
710       Builder.defineMacro("__thumb2__");
711   }
712 
713   // ACLE 6.4.9 32-bit SIMD instructions
714   if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
715     Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
716 
717   // ACLE 6.4.10 Hardware Integer Divide
718   if (((HWDiv & HWDivThumb) && isThumb()) ||
719       ((HWDiv & HWDivARM) && !isThumb())) {
720     Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
721     Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
722   }
723 
724   // Note, this is always on in gcc, even though it doesn't make sense.
725   Builder.defineMacro("__APCS_32__");
726 
727   if (FPUModeIsVFP((FPUMode)FPU)) {
728     Builder.defineMacro("__VFP_FP__");
729     if (FPU & VFP2FPU)
730       Builder.defineMacro("__ARM_VFPV2__");
731     if (FPU & VFP3FPU)
732       Builder.defineMacro("__ARM_VFPV3__");
733     if (FPU & VFP4FPU)
734       Builder.defineMacro("__ARM_VFPV4__");
735     if (FPU & FPARMV8)
736       Builder.defineMacro("__ARM_FPV5__");
737   }
738 
739   // This only gets set when Neon instructions are actually available, unlike
740   // the VFP define, hence the soft float and arch check. This is subtly
741   // different from gcc, we follow the intent which was that it should be set
742   // when Neon instructions are actually available.
743   if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
744     Builder.defineMacro("__ARM_NEON", "1");
745     Builder.defineMacro("__ARM_NEON__");
746     // current AArch32 NEON implementations do not support double-precision
747     // floating-point even when it is present in VFP.
748     Builder.defineMacro("__ARM_NEON_FP",
749                         "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
750   }
751 
752   if (hasMVE()) {
753     Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
754   }
755 
756   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
757                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
758 
759   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
760 
761   // CMSE
762   if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
763     Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
764 
765   if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
766     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
767     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
768     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
769     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
770   }
771 
772   // ACLE 6.4.7 DSP instructions
773   if (DSP) {
774     Builder.defineMacro("__ARM_FEATURE_DSP", "1");
775   }
776 
777   // ACLE 6.4.8 Saturation instructions
778   bool SAT = false;
779   if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
780     Builder.defineMacro("__ARM_FEATURE_SAT", "1");
781     SAT = true;
782   }
783 
784   // ACLE 6.4.6 Q (saturation) flag
785   if (DSP || SAT)
786     Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
787 
788   if (Opts.UnsafeFPMath)
789     Builder.defineMacro("__ARM_FP_FAST", "1");
790 
791   // Armv8.2-A FP16 vector intrinsic
792   if ((FPU & NeonFPU) && HasLegalHalfType)
793     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
794 
795   // Armv8.2-A FP16 scalar intrinsics
796   if (HasLegalHalfType)
797     Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
798 
799   // Armv8.2-A dot product intrinsics
800   if (DotProd)
801     Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
802 
803   switch (ArchKind) {
804   default:
805     break;
806   case llvm::ARM::ArchKind::ARMV8_1A:
807     getTargetDefinesARMV81A(Opts, Builder);
808     break;
809   case llvm::ARM::ArchKind::ARMV8_2A:
810     getTargetDefinesARMV82A(Opts, Builder);
811     break;
812   }
813 }
814 
815 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
816 #define BUILTIN(ID, TYPE, ATTRS)                                               \
817   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
818 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
819   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
820 #include "clang/Basic/BuiltinsNEON.def"
821 
822 #define BUILTIN(ID, TYPE, ATTRS)                                               \
823   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
824 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
825   {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
826 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
827   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
828 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
829   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
830 #include "clang/Basic/BuiltinsARM.def"
831 };
832 
833 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
834   return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
835                                              Builtin::FirstTSBuiltin);
836 }
837 
838 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
839 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
840   return IsAAPCS
841              ? AAPCSABIBuiltinVaList
842              : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
843                                          : TargetInfo::VoidPtrBuiltinVaList);
844 }
845 
846 const char *const ARMTargetInfo::GCCRegNames[] = {
847     // Integer registers
848     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
849     "r12", "sp", "lr", "pc",
850 
851     // Float registers
852     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
853     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
854     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
855 
856     // Double registers
857     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
858     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
859     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
860 
861     // Quad registers
862     "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
863     "q12", "q13", "q14", "q15"};
864 
865 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
866   return llvm::makeArrayRef(GCCRegNames);
867 }
868 
869 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
870     {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},
871     {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},
872     {{"v5"}, "r8"},  {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
873     {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},
874     // The S, D and Q registers overlap, but aren't really aliases; we
875     // don't want to substitute one of these for a different-sized one.
876 };
877 
878 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
879   return llvm::makeArrayRef(GCCRegAliases);
880 }
881 
882 bool ARMTargetInfo::validateAsmConstraint(
883     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
884   switch (*Name) {
885   default:
886     break;
887   case 'l': // r0-r7
888   case 'h': // r8-r15
889   case 't': // VFP Floating point register single precision
890   case 'w': // VFP Floating point register double precision
891     Info.setAllowsRegister();
892     return true;
893   case 'I':
894   case 'J':
895   case 'K':
896   case 'L':
897   case 'M':
898     // FIXME
899     return true;
900   case 'Q': // A memory address that is a single base register.
901     Info.setAllowsMemory();
902     return true;
903   case 'U': // a memory reference...
904     switch (Name[1]) {
905     case 'q': // ...ARMV4 ldrsb
906     case 'v': // ...VFP load/store (reg+constant offset)
907     case 'y': // ...iWMMXt load/store
908     case 't': // address valid for load/store opaque types wider
909               // than 128-bits
910     case 'n': // valid address for Neon doubleword vector load/store
911     case 'm': // valid address for Neon element and structure load/store
912     case 's': // valid address for non-offset loads/stores of quad-word
913               // values in four ARM registers
914       Info.setAllowsMemory();
915       Name++;
916       return true;
917     }
918   }
919   return false;
920 }
921 
922 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
923   std::string R;
924   switch (*Constraint) {
925   case 'U': // Two-character constraint; add "^" hint for later parsing.
926     R = std::string("^") + std::string(Constraint, 2);
927     Constraint++;
928     break;
929   case 'p': // 'p' should be translated to 'r' by default.
930     R = std::string("r");
931     break;
932   default:
933     return std::string(1, *Constraint);
934   }
935   return R;
936 }
937 
938 bool ARMTargetInfo::validateConstraintModifier(
939     StringRef Constraint, char Modifier, unsigned Size,
940     std::string &SuggestedModifier) const {
941   bool isOutput = (Constraint[0] == '=');
942   bool isInOut = (Constraint[0] == '+');
943 
944   // Strip off constraint modifiers.
945   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
946     Constraint = Constraint.substr(1);
947 
948   switch (Constraint[0]) {
949   default:
950     break;
951   case 'r': {
952     switch (Modifier) {
953     default:
954       return (isInOut || isOutput || Size <= 64);
955     case 'q':
956       // A register of size 32 cannot fit a vector type.
957       return false;
958     }
959   }
960   }
961 
962   return true;
963 }
964 const char *ARMTargetInfo::getClobbers() const {
965   // FIXME: Is this really right?
966   return "";
967 }
968 
969 TargetInfo::CallingConvCheckResult
970 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
971   switch (CC) {
972   case CC_AAPCS:
973   case CC_AAPCS_VFP:
974   case CC_Swift:
975   case CC_OpenCLKernel:
976     return CCCR_OK;
977   default:
978     return CCCR_Warning;
979   }
980 }
981 
982 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
983   if (RegNo == 0)
984     return 0;
985   if (RegNo == 1)
986     return 1;
987   return -1;
988 }
989 
990 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
991 
992 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
993                                  const TargetOptions &Opts)
994     : ARMTargetInfo(Triple, Opts) {}
995 
996 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
997                                        MacroBuilder &Builder) const {
998   Builder.defineMacro("__ARMEL__");
999   ARMTargetInfo::getTargetDefines(Opts, Builder);
1000 }
1001 
1002 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1003                                  const TargetOptions &Opts)
1004     : ARMTargetInfo(Triple, Opts) {}
1005 
1006 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1007                                        MacroBuilder &Builder) const {
1008   Builder.defineMacro("__ARMEB__");
1009   Builder.defineMacro("__ARM_BIG_ENDIAN");
1010   ARMTargetInfo::getTargetDefines(Opts, Builder);
1011 }
1012 
1013 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1014                                            const TargetOptions &Opts)
1015     : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1016 }
1017 
1018 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1019                                                   MacroBuilder &Builder) const {
1020   WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
1021 
1022   // FIXME: this is invalid for WindowsCE
1023   Builder.defineMacro("_M_ARM_NT", "1");
1024   Builder.defineMacro("_M_ARMT", "_M_ARM");
1025   Builder.defineMacro("_M_THUMB", "_M_ARM");
1026 
1027   assert((Triple.getArch() == llvm::Triple::arm ||
1028           Triple.getArch() == llvm::Triple::thumb) &&
1029          "invalid architecture for Windows ARM target info");
1030   unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1031   Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1032 
1033   // TODO map the complete set of values
1034   // 31: VFPv3 40: VFPv4
1035   Builder.defineMacro("_M_ARM_FP", "31");
1036 }
1037 
1038 TargetInfo::BuiltinVaListKind
1039 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1040   return TargetInfo::CharPtrBuiltinVaList;
1041 }
1042 
1043 TargetInfo::CallingConvCheckResult
1044 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1045   switch (CC) {
1046   case CC_X86StdCall:
1047   case CC_X86ThisCall:
1048   case CC_X86FastCall:
1049   case CC_X86VectorCall:
1050     return CCCR_Ignore;
1051   case CC_C:
1052   case CC_OpenCLKernel:
1053   case CC_PreserveMost:
1054   case CC_PreserveAll:
1055   case CC_Swift:
1056     return CCCR_OK;
1057   default:
1058     return CCCR_Warning;
1059   }
1060 }
1061 
1062 // Windows ARM + Itanium C++ ABI Target
1063 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1064     const llvm::Triple &Triple, const TargetOptions &Opts)
1065     : WindowsARMTargetInfo(Triple, Opts) {
1066   TheCXXABI.set(TargetCXXABI::GenericARM);
1067 }
1068 
1069 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1070     const LangOptions &Opts, MacroBuilder &Builder) const {
1071   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1072 
1073   if (Opts.MSVCCompat)
1074     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1075 }
1076 
1077 // Windows ARM, MS (C++) ABI
1078 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1079                                                    const TargetOptions &Opts)
1080     : WindowsARMTargetInfo(Triple, Opts) {
1081   TheCXXABI.set(TargetCXXABI::Microsoft);
1082 }
1083 
1084 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1085                                                 MacroBuilder &Builder) const {
1086   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1087   WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1088 }
1089 
1090 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1091                                        const TargetOptions &Opts)
1092     : WindowsARMTargetInfo(Triple, Opts) {
1093   TheCXXABI.set(TargetCXXABI::GenericARM);
1094 }
1095 
1096 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1097                                           MacroBuilder &Builder) const {
1098   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1099   Builder.defineMacro("_ARM_");
1100 }
1101 
1102 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1103                                          const TargetOptions &Opts)
1104     : ARMleTargetInfo(Triple, Opts) {
1105   this->WCharType = TargetInfo::UnsignedShort;
1106   TLSSupported = false;
1107   DoubleAlign = LongLongAlign = 64;
1108   resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1109 }
1110 
1111 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1112                                            MacroBuilder &Builder) const {
1113   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1114   Builder.defineMacro("_ARM_");
1115   Builder.defineMacro("__CYGWIN__");
1116   Builder.defineMacro("__CYGWIN32__");
1117   DefineStd(Builder, "unix", Opts);
1118   if (Opts.CPlusPlus)
1119     Builder.defineMacro("_GNU_SOURCE");
1120 }
1121 
1122 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1123                                          const TargetOptions &Opts)
1124     : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1125   HasAlignMac68kSupport = true;
1126   // iOS always has 64-bit atomic instructions.
1127   // FIXME: This should be based off of the target features in
1128   // ARMleTargetInfo.
1129   MaxAtomicInlineWidth = 64;
1130 
1131   if (Triple.isWatchABI()) {
1132     // Darwin on iOS uses a variant of the ARM C++ ABI.
1133     TheCXXABI.set(TargetCXXABI::WatchOS);
1134 
1135     // BOOL should be a real boolean on the new ABI
1136     UseSignedCharForObjCBool = false;
1137   } else
1138     TheCXXABI.set(TargetCXXABI::iOS);
1139 }
1140 
1141 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1142                                        const llvm::Triple &Triple,
1143                                        MacroBuilder &Builder) const {
1144   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1145 }
1146 
1147 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1148                                                    const TargetOptions &Opts)
1149     : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1150                                    Triple.getOSName(),
1151                                    Triple.getEnvironmentName()),
1152                       Opts) {
1153   IsRenderScriptTarget = true;
1154   LongWidth = LongAlign = 64;
1155 }
1156 
1157 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1158                                                 MacroBuilder &Builder) const {
1159   Builder.defineMacro("__RENDERSCRIPT__");
1160   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1161 }
1162