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