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