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   if ((FPU & NeonFPU) && HasFullFP16)
717     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
718   if (HasFullFP16)
719     // fp16 ARM scalar intrinsics are not implemented yet.
720     Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
721 
722   switch (ArchKind) {
723   default:
724     break;
725   case llvm::ARM::ArchKind::ARMV8_1A:
726     getTargetDefinesARMV81A(Opts, Builder);
727     break;
728   case llvm::ARM::ArchKind::ARMV8_2A:
729     getTargetDefinesARMV82A(Opts, Builder);
730     break;
731   }
732 }
733 
734 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
735 #define BUILTIN(ID, TYPE, ATTRS)                                               \
736   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
737 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
738   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
739 #include "clang/Basic/BuiltinsNEON.def"
740 
741 #define BUILTIN(ID, TYPE, ATTRS)                                               \
742   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
743 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
744   {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
745 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
746   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
747 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
748   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
749 #include "clang/Basic/BuiltinsARM.def"
750 };
751 
752 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
753   return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
754                                              Builtin::FirstTSBuiltin);
755 }
756 
757 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
758 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
759   return IsAAPCS
760              ? AAPCSABIBuiltinVaList
761              : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
762                                          : TargetInfo::VoidPtrBuiltinVaList);
763 }
764 
765 const char *const ARMTargetInfo::GCCRegNames[] = {
766     // Integer registers
767     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
768     "r12", "sp", "lr", "pc",
769 
770     // Float registers
771     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
772     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
773     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
774 
775     // Double registers
776     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
777     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
778     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
779 
780     // Quad registers
781     "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
782     "q12", "q13", "q14", "q15"};
783 
784 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
785   return llvm::makeArrayRef(GCCRegNames);
786 }
787 
788 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
789     {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},
790     {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},
791     {{"v5"}, "r8"},  {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
792     {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},
793     // The S, D and Q registers overlap, but aren't really aliases; we
794     // don't want to substitute one of these for a different-sized one.
795 };
796 
797 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
798   return llvm::makeArrayRef(GCCRegAliases);
799 }
800 
801 bool ARMTargetInfo::validateAsmConstraint(
802     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
803   switch (*Name) {
804   default:
805     break;
806   case 'l': // r0-r7
807   case 'h': // r8-r15
808   case 't': // VFP Floating point register single precision
809   case 'w': // VFP Floating point register double precision
810     Info.setAllowsRegister();
811     return true;
812   case 'I':
813   case 'J':
814   case 'K':
815   case 'L':
816   case 'M':
817     // FIXME
818     return true;
819   case 'Q': // A memory address that is a single base register.
820     Info.setAllowsMemory();
821     return true;
822   case 'U': // a memory reference...
823     switch (Name[1]) {
824     case 'q': // ...ARMV4 ldrsb
825     case 'v': // ...VFP load/store (reg+constant offset)
826     case 'y': // ...iWMMXt load/store
827     case 't': // address valid for load/store opaque types wider
828               // than 128-bits
829     case 'n': // valid address for Neon doubleword vector load/store
830     case 'm': // valid address for Neon element and structure load/store
831     case 's': // valid address for non-offset loads/stores of quad-word
832               // values in four ARM registers
833       Info.setAllowsMemory();
834       Name++;
835       return true;
836     }
837   }
838   return false;
839 }
840 
841 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
842   std::string R;
843   switch (*Constraint) {
844   case 'U': // Two-character constraint; add "^" hint for later parsing.
845     R = std::string("^") + std::string(Constraint, 2);
846     Constraint++;
847     break;
848   case 'p': // 'p' should be translated to 'r' by default.
849     R = std::string("r");
850     break;
851   default:
852     return std::string(1, *Constraint);
853   }
854   return R;
855 }
856 
857 bool ARMTargetInfo::validateConstraintModifier(
858     StringRef Constraint, char Modifier, unsigned Size,
859     std::string &SuggestedModifier) const {
860   bool isOutput = (Constraint[0] == '=');
861   bool isInOut = (Constraint[0] == '+');
862 
863   // Strip off constraint modifiers.
864   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
865     Constraint = Constraint.substr(1);
866 
867   switch (Constraint[0]) {
868   default:
869     break;
870   case 'r': {
871     switch (Modifier) {
872     default:
873       return (isInOut || isOutput || Size <= 64);
874     case 'q':
875       // A register of size 32 cannot fit a vector type.
876       return false;
877     }
878   }
879   }
880 
881   return true;
882 }
883 const char *ARMTargetInfo::getClobbers() const {
884   // FIXME: Is this really right?
885   return "";
886 }
887 
888 TargetInfo::CallingConvCheckResult
889 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
890   switch (CC) {
891   case CC_AAPCS:
892   case CC_AAPCS_VFP:
893   case CC_Swift:
894   case CC_OpenCLKernel:
895     return CCCR_OK;
896   default:
897     return CCCR_Warning;
898   }
899 }
900 
901 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
902   if (RegNo == 0)
903     return 0;
904   if (RegNo == 1)
905     return 1;
906   return -1;
907 }
908 
909 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
910 
911 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
912                                  const TargetOptions &Opts)
913     : ARMTargetInfo(Triple, Opts) {}
914 
915 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
916                                        MacroBuilder &Builder) const {
917   Builder.defineMacro("__ARMEL__");
918   ARMTargetInfo::getTargetDefines(Opts, Builder);
919 }
920 
921 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
922                                  const TargetOptions &Opts)
923     : ARMTargetInfo(Triple, Opts) {}
924 
925 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
926                                        MacroBuilder &Builder) const {
927   Builder.defineMacro("__ARMEB__");
928   Builder.defineMacro("__ARM_BIG_ENDIAN");
929   ARMTargetInfo::getTargetDefines(Opts, Builder);
930 }
931 
932 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
933                                            const TargetOptions &Opts)
934     : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
935 }
936 
937 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
938                                                   MacroBuilder &Builder) const {
939   WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
940 
941   // FIXME: this is invalid for WindowsCE
942   Builder.defineMacro("_M_ARM_NT", "1");
943   Builder.defineMacro("_M_ARMT", "_M_ARM");
944   Builder.defineMacro("_M_THUMB", "_M_ARM");
945 
946   assert((Triple.getArch() == llvm::Triple::arm ||
947           Triple.getArch() == llvm::Triple::thumb) &&
948          "invalid architecture for Windows ARM target info");
949   unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
950   Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
951 
952   // TODO map the complete set of values
953   // 31: VFPv3 40: VFPv4
954   Builder.defineMacro("_M_ARM_FP", "31");
955 }
956 
957 TargetInfo::BuiltinVaListKind
958 WindowsARMTargetInfo::getBuiltinVaListKind() const {
959   return TargetInfo::CharPtrBuiltinVaList;
960 }
961 
962 TargetInfo::CallingConvCheckResult
963 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
964   switch (CC) {
965   case CC_X86StdCall:
966   case CC_X86ThisCall:
967   case CC_X86FastCall:
968   case CC_X86VectorCall:
969     return CCCR_Ignore;
970   case CC_C:
971   case CC_OpenCLKernel:
972     return CCCR_OK;
973   default:
974     return CCCR_Warning;
975   }
976 }
977 
978 // Windows ARM + Itanium C++ ABI Target
979 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
980     const llvm::Triple &Triple, const TargetOptions &Opts)
981     : WindowsARMTargetInfo(Triple, Opts) {
982   TheCXXABI.set(TargetCXXABI::GenericARM);
983 }
984 
985 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
986     const LangOptions &Opts, MacroBuilder &Builder) const {
987   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
988 
989   if (Opts.MSVCCompat)
990     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
991 }
992 
993 // Windows ARM, MS (C++) ABI
994 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
995                                                    const TargetOptions &Opts)
996     : WindowsARMTargetInfo(Triple, Opts) {
997   TheCXXABI.set(TargetCXXABI::Microsoft);
998 }
999 
1000 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1001                                                 MacroBuilder &Builder) const {
1002   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1003   WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1004 }
1005 
1006 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1007                                        const TargetOptions &Opts)
1008     : WindowsARMTargetInfo(Triple, Opts) {
1009   TheCXXABI.set(TargetCXXABI::GenericARM);
1010 }
1011 
1012 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1013                                           MacroBuilder &Builder) const {
1014   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1015   Builder.defineMacro("_ARM_");
1016 }
1017 
1018 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1019                                          const TargetOptions &Opts)
1020     : ARMleTargetInfo(Triple, Opts) {
1021   this->WCharType = TargetInfo::UnsignedShort;
1022   TLSSupported = false;
1023   DoubleAlign = LongLongAlign = 64;
1024   resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1025 }
1026 
1027 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1028                                            MacroBuilder &Builder) const {
1029   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1030   Builder.defineMacro("_ARM_");
1031   Builder.defineMacro("__CYGWIN__");
1032   Builder.defineMacro("__CYGWIN32__");
1033   DefineStd(Builder, "unix", Opts);
1034   if (Opts.CPlusPlus)
1035     Builder.defineMacro("_GNU_SOURCE");
1036 }
1037 
1038 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1039                                          const TargetOptions &Opts)
1040     : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1041   HasAlignMac68kSupport = true;
1042   // iOS always has 64-bit atomic instructions.
1043   // FIXME: This should be based off of the target features in
1044   // ARMleTargetInfo.
1045   MaxAtomicInlineWidth = 64;
1046 
1047   if (Triple.isWatchABI()) {
1048     // Darwin on iOS uses a variant of the ARM C++ ABI.
1049     TheCXXABI.set(TargetCXXABI::WatchOS);
1050 
1051     // BOOL should be a real boolean on the new ABI
1052     UseSignedCharForObjCBool = false;
1053   } else
1054     TheCXXABI.set(TargetCXXABI::iOS);
1055 }
1056 
1057 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1058                                        const llvm::Triple &Triple,
1059                                        MacroBuilder &Builder) const {
1060   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1061 }
1062 
1063 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1064                                                    const TargetOptions &Opts)
1065     : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1066                                    Triple.getOSName(),
1067                                    Triple.getEnvironmentName()),
1068                       Opts) {
1069   IsRenderScriptTarget = true;
1070   LongWidth = LongAlign = 64;
1071 }
1072 
1073 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1074                                                 MacroBuilder &Builder) const {
1075   Builder.defineMacro("__RENDERSCRIPT__");
1076   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1077 }
1078