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