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