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