xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp (revision 2f513db72b034fd5ef7f080b11be5c711c15186a)
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 'T':
904     switch (Name[1]) {
905     default:
906       break;
907     case 'e': // Even general-purpose register
908     case 'o': // Odd general-purpose register
909       Info.setAllowsRegister();
910       Name++;
911       return true;
912     }
913     break;
914   case 'U': // a memory reference...
915     switch (Name[1]) {
916     case 'q': // ...ARMV4 ldrsb
917     case 'v': // ...VFP load/store (reg+constant offset)
918     case 'y': // ...iWMMXt load/store
919     case 't': // address valid for load/store opaque types wider
920               // than 128-bits
921     case 'n': // valid address for Neon doubleword vector load/store
922     case 'm': // valid address for Neon element and structure load/store
923     case 's': // valid address for non-offset loads/stores of quad-word
924               // values in four ARM registers
925       Info.setAllowsMemory();
926       Name++;
927       return true;
928     }
929     break;
930   }
931   return false;
932 }
933 
934 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
935   std::string R;
936   switch (*Constraint) {
937   case 'U': // Two-character constraint; add "^" hint for later parsing.
938   case 'T':
939     R = std::string("^") + std::string(Constraint, 2);
940     Constraint++;
941     break;
942   case 'p': // 'p' should be translated to 'r' by default.
943     R = std::string("r");
944     break;
945   default:
946     return std::string(1, *Constraint);
947   }
948   return R;
949 }
950 
951 bool ARMTargetInfo::validateConstraintModifier(
952     StringRef Constraint, char Modifier, unsigned Size,
953     std::string &SuggestedModifier) const {
954   bool isOutput = (Constraint[0] == '=');
955   bool isInOut = (Constraint[0] == '+');
956 
957   // Strip off constraint modifiers.
958   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
959     Constraint = Constraint.substr(1);
960 
961   switch (Constraint[0]) {
962   default:
963     break;
964   case 'r': {
965     switch (Modifier) {
966     default:
967       return (isInOut || isOutput || Size <= 64);
968     case 'q':
969       // A register of size 32 cannot fit a vector type.
970       return false;
971     }
972   }
973   }
974 
975   return true;
976 }
977 const char *ARMTargetInfo::getClobbers() const {
978   // FIXME: Is this really right?
979   return "";
980 }
981 
982 TargetInfo::CallingConvCheckResult
983 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
984   switch (CC) {
985   case CC_AAPCS:
986   case CC_AAPCS_VFP:
987   case CC_Swift:
988   case CC_OpenCLKernel:
989     return CCCR_OK;
990   default:
991     return CCCR_Warning;
992   }
993 }
994 
995 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
996   if (RegNo == 0)
997     return 0;
998   if (RegNo == 1)
999     return 1;
1000   return -1;
1001 }
1002 
1003 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1004 
1005 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1006                                  const TargetOptions &Opts)
1007     : ARMTargetInfo(Triple, Opts) {}
1008 
1009 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1010                                        MacroBuilder &Builder) const {
1011   Builder.defineMacro("__ARMEL__");
1012   ARMTargetInfo::getTargetDefines(Opts, Builder);
1013 }
1014 
1015 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1016                                  const TargetOptions &Opts)
1017     : ARMTargetInfo(Triple, Opts) {}
1018 
1019 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1020                                        MacroBuilder &Builder) const {
1021   Builder.defineMacro("__ARMEB__");
1022   Builder.defineMacro("__ARM_BIG_ENDIAN");
1023   ARMTargetInfo::getTargetDefines(Opts, Builder);
1024 }
1025 
1026 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1027                                            const TargetOptions &Opts)
1028     : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1029 }
1030 
1031 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1032                                                   MacroBuilder &Builder) const {
1033   // FIXME: this is invalid for WindowsCE
1034   Builder.defineMacro("_M_ARM_NT", "1");
1035   Builder.defineMacro("_M_ARMT", "_M_ARM");
1036   Builder.defineMacro("_M_THUMB", "_M_ARM");
1037 
1038   assert((Triple.getArch() == llvm::Triple::arm ||
1039           Triple.getArch() == llvm::Triple::thumb) &&
1040          "invalid architecture for Windows ARM target info");
1041   unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1042   Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1043 
1044   // TODO map the complete set of values
1045   // 31: VFPv3 40: VFPv4
1046   Builder.defineMacro("_M_ARM_FP", "31");
1047 }
1048 
1049 TargetInfo::BuiltinVaListKind
1050 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1051   return TargetInfo::CharPtrBuiltinVaList;
1052 }
1053 
1054 TargetInfo::CallingConvCheckResult
1055 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1056   switch (CC) {
1057   case CC_X86StdCall:
1058   case CC_X86ThisCall:
1059   case CC_X86FastCall:
1060   case CC_X86VectorCall:
1061     return CCCR_Ignore;
1062   case CC_C:
1063   case CC_OpenCLKernel:
1064   case CC_PreserveMost:
1065   case CC_PreserveAll:
1066   case CC_Swift:
1067     return CCCR_OK;
1068   default:
1069     return CCCR_Warning;
1070   }
1071 }
1072 
1073 // Windows ARM + Itanium C++ ABI Target
1074 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1075     const llvm::Triple &Triple, const TargetOptions &Opts)
1076     : WindowsARMTargetInfo(Triple, Opts) {
1077   TheCXXABI.set(TargetCXXABI::GenericARM);
1078 }
1079 
1080 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1081     const LangOptions &Opts, MacroBuilder &Builder) const {
1082   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1083 
1084   if (Opts.MSVCCompat)
1085     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1086 }
1087 
1088 // Windows ARM, MS (C++) ABI
1089 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1090                                                    const TargetOptions &Opts)
1091     : WindowsARMTargetInfo(Triple, Opts) {
1092   TheCXXABI.set(TargetCXXABI::Microsoft);
1093 }
1094 
1095 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1096                                                 MacroBuilder &Builder) const {
1097   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1098   WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1099 }
1100 
1101 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1102                                        const TargetOptions &Opts)
1103     : WindowsARMTargetInfo(Triple, Opts) {
1104   TheCXXABI.set(TargetCXXABI::GenericARM);
1105 }
1106 
1107 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1108                                           MacroBuilder &Builder) const {
1109   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1110   Builder.defineMacro("_ARM_");
1111 }
1112 
1113 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1114                                          const TargetOptions &Opts)
1115     : ARMleTargetInfo(Triple, Opts) {
1116   this->WCharType = TargetInfo::UnsignedShort;
1117   TLSSupported = false;
1118   DoubleAlign = LongLongAlign = 64;
1119   resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1120 }
1121 
1122 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1123                                            MacroBuilder &Builder) const {
1124   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1125   Builder.defineMacro("_ARM_");
1126   Builder.defineMacro("__CYGWIN__");
1127   Builder.defineMacro("__CYGWIN32__");
1128   DefineStd(Builder, "unix", Opts);
1129   if (Opts.CPlusPlus)
1130     Builder.defineMacro("_GNU_SOURCE");
1131 }
1132 
1133 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1134                                          const TargetOptions &Opts)
1135     : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1136   HasAlignMac68kSupport = true;
1137   // iOS always has 64-bit atomic instructions.
1138   // FIXME: This should be based off of the target features in
1139   // ARMleTargetInfo.
1140   MaxAtomicInlineWidth = 64;
1141 
1142   if (Triple.isWatchABI()) {
1143     // Darwin on iOS uses a variant of the ARM C++ ABI.
1144     TheCXXABI.set(TargetCXXABI::WatchOS);
1145 
1146     // BOOL should be a real boolean on the new ABI
1147     UseSignedCharForObjCBool = false;
1148   } else
1149     TheCXXABI.set(TargetCXXABI::iOS);
1150 }
1151 
1152 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1153                                        const llvm::Triple &Triple,
1154                                        MacroBuilder &Builder) const {
1155   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1156 }
1157 
1158 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1159                                                    const TargetOptions &Opts)
1160     : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1161                                    Triple.getOSName(),
1162                                    Triple.getEnvironmentName()),
1163                       Opts) {
1164   IsRenderScriptTarget = true;
1165   LongWidth = LongAlign = 64;
1166 }
1167 
1168 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1169                                                 MacroBuilder &Builder) const {
1170   Builder.defineMacro("__RENDERSCRIPT__");
1171   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1172 }
1173