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   // size_t is unsigned long on MachO-derived environments, NetBSD, and
32   // OpenBSD.
33   if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD ||
34       T.getOS() == llvm::Triple::OpenBSD)
35     SizeType = UnsignedLong;
36   else
37     SizeType = UnsignedInt;
38 
39   switch (T.getOS()) {
40   case llvm::Triple::NetBSD:
41   case llvm::Triple::OpenBSD:
42     WCharType = SignedInt;
43     break;
44   case llvm::Triple::Win32:
45     WCharType = UnsignedShort;
46     break;
47   case llvm::Triple::Linux:
48   default:
49     // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
50     WCharType = UnsignedInt;
51     break;
52   }
53 
54   UseBitFieldTypeAlignment = true;
55 
56   ZeroLengthBitfieldBoundary = 0;
57 
58   // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
59   // so set preferred for small types to 32.
60   if (T.isOSBinFormatMachO()) {
61     resetDataLayout(BigEndian
62                         ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
63                         : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
64   } else if (T.isOSWindows()) {
65     assert(!BigEndian && "Windows on ARM does not support big endian");
66     resetDataLayout("e"
67                     "-m:w"
68                     "-p:32:32"
69                     "-i64:64"
70                     "-v128:64:128"
71                     "-a:0:32"
72                     "-n32"
73                     "-S64");
74   } else if (T.isOSNaCl()) {
75     assert(!BigEndian && "NaCl on ARM does not support big endian");
76     resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
77   } else {
78     resetDataLayout(BigEndian
79                         ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
80                         : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
81   }
82 
83   // FIXME: Enumerated types are variable width in straight AAPCS.
84 }
85 
86 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
87   const llvm::Triple &T = getTriple();
88 
89   IsAAPCS = false;
90 
91   if (IsAAPCS16)
92     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
93   else
94     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
95 
96   // size_t is unsigned int on FreeBSD.
97   if (T.getOS() == llvm::Triple::FreeBSD)
98     SizeType = UnsignedInt;
99   else
100     SizeType = UnsignedLong;
101 
102   // Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
103   WCharType = SignedInt;
104 
105   // Do not respect the alignment of bit-field types when laying out
106   // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
107   UseBitFieldTypeAlignment = false;
108 
109   /// gcc forces the alignment to 4 bytes, regardless of the type of the
110   /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
111   /// gcc.
112   ZeroLengthBitfieldBoundary = 32;
113 
114   if (T.isOSBinFormatMachO() && IsAAPCS16) {
115     assert(!BigEndian && "AAPCS16 does not support big-endian");
116     resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
117   } else if (T.isOSBinFormatMachO())
118     resetDataLayout(
119         BigEndian
120             ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
121             : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
122   else
123     resetDataLayout(
124         BigEndian
125             ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
126             : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
127 
128   // FIXME: Override "preferred align" for double and long long.
129 }
130 
131 void ARMTargetInfo::setArchInfo() {
132   StringRef ArchName = getTriple().getArchName();
133 
134   ArchISA = llvm::ARM::parseArchISA(ArchName);
135   CPU = llvm::ARM::getDefaultCPU(ArchName);
136   llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
137   if (AK != llvm::ARM::ArchKind::INVALID)
138     ArchKind = AK;
139   setArchInfo(ArchKind);
140 }
141 
142 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
143   StringRef SubArch;
144 
145   // cache TargetParser info
146   ArchKind = Kind;
147   SubArch = llvm::ARM::getSubArch(ArchKind);
148   ArchProfile = llvm::ARM::parseArchProfile(SubArch);
149   ArchVersion = llvm::ARM::parseArchVersion(SubArch);
150 
151   // cache CPU related strings
152   CPUAttr = getCPUAttr();
153   CPUProfile = getCPUProfile();
154 }
155 
156 void ARMTargetInfo::setAtomic() {
157   // when triple does not specify a sub arch,
158   // then we are not using inline atomics
159   bool ShouldUseInlineAtomic =
160       (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
161       (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
162   // Cortex M does not support 8 byte atomics, while general Thumb2 does.
163   if (ArchProfile == llvm::ARM::ProfileKind::M) {
164     MaxAtomicPromoteWidth = 32;
165     if (ShouldUseInlineAtomic)
166       MaxAtomicInlineWidth = 32;
167   } else {
168     MaxAtomicPromoteWidth = 64;
169     if (ShouldUseInlineAtomic)
170       MaxAtomicInlineWidth = 64;
171   }
172 }
173 
174 bool ARMTargetInfo::isThumb() const {
175   return ArchISA == llvm::ARM::ISAKind::THUMB;
176 }
177 
178 bool ARMTargetInfo::supportsThumb() const {
179   return CPUAttr.count('T') || ArchVersion >= 6;
180 }
181 
182 bool ARMTargetInfo::supportsThumb2() const {
183   return CPUAttr.equals("6T2") ||
184          (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
185 }
186 
187 StringRef ARMTargetInfo::getCPUAttr() const {
188   // For most sub-arches, the build attribute CPU name is enough.
189   // For Cortex variants, it's slightly different.
190   switch (ArchKind) {
191   default:
192     return llvm::ARM::getCPUAttr(ArchKind);
193   case llvm::ARM::ArchKind::ARMV6M:
194     return "6M";
195   case llvm::ARM::ArchKind::ARMV7S:
196     return "7S";
197   case llvm::ARM::ArchKind::ARMV7A:
198     return "7A";
199   case llvm::ARM::ArchKind::ARMV7R:
200     return "7R";
201   case llvm::ARM::ArchKind::ARMV7M:
202     return "7M";
203   case llvm::ARM::ArchKind::ARMV7EM:
204     return "7EM";
205   case llvm::ARM::ArchKind::ARMV7VE:
206     return "7VE";
207   case llvm::ARM::ArchKind::ARMV8A:
208     return "8A";
209   case llvm::ARM::ArchKind::ARMV8_1A:
210     return "8_1A";
211   case llvm::ARM::ArchKind::ARMV8_2A:
212     return "8_2A";
213   case llvm::ARM::ArchKind::ARMV8MBaseline:
214     return "8M_BASE";
215   case llvm::ARM::ArchKind::ARMV8MMainline:
216     return "8M_MAIN";
217   case llvm::ARM::ArchKind::ARMV8R:
218     return "8R";
219   }
220 }
221 
222 StringRef ARMTargetInfo::getCPUProfile() const {
223   switch (ArchProfile) {
224   case llvm::ARM::ProfileKind::A:
225     return "A";
226   case llvm::ARM::ProfileKind::R:
227     return "R";
228   case llvm::ARM::ProfileKind::M:
229     return "M";
230   default:
231     return "";
232   }
233 }
234 
235 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
236                              const TargetOptions &Opts)
237     : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
238       HW_FP(0) {
239 
240   switch (getTriple().getOS()) {
241   case llvm::Triple::NetBSD:
242   case llvm::Triple::OpenBSD:
243     PtrDiffType = SignedLong;
244     break;
245   default:
246     PtrDiffType = SignedInt;
247     break;
248   }
249 
250   // Cache arch related info.
251   setArchInfo();
252 
253   // {} in inline assembly are neon specifiers, not assembly variant
254   // specifiers.
255   NoAsmVariants = true;
256 
257   // FIXME: This duplicates code from the driver that sets the -target-abi
258   // option - this code is used if -target-abi isn't passed and should
259   // be unified in some way.
260   if (Triple.isOSBinFormatMachO()) {
261     // The backend is hardwired to assume AAPCS for M-class processors, ensure
262     // the frontend matches that.
263     if (Triple.getEnvironment() == llvm::Triple::EABI ||
264         Triple.getOS() == llvm::Triple::UnknownOS ||
265         ArchProfile == llvm::ARM::ProfileKind::M) {
266       setABI("aapcs");
267     } else if (Triple.isWatchABI()) {
268       setABI("aapcs16");
269     } else {
270       setABI("apcs-gnu");
271     }
272   } else if (Triple.isOSWindows()) {
273     // FIXME: this is invalid for WindowsCE
274     setABI("aapcs");
275   } else {
276     // Select the default based on the platform.
277     switch (Triple.getEnvironment()) {
278     case llvm::Triple::Android:
279     case llvm::Triple::GNUEABI:
280     case llvm::Triple::GNUEABIHF:
281     case llvm::Triple::MuslEABI:
282     case llvm::Triple::MuslEABIHF:
283       setABI("aapcs-linux");
284       break;
285     case llvm::Triple::EABIHF:
286     case llvm::Triple::EABI:
287       setABI("aapcs");
288       break;
289     case llvm::Triple::GNU:
290       setABI("apcs-gnu");
291       break;
292     default:
293       if (Triple.getOS() == llvm::Triple::NetBSD)
294         setABI("apcs-gnu");
295       else if (Triple.getOS() == llvm::Triple::OpenBSD)
296         setABI("aapcs-linux");
297       else
298         setABI("aapcs");
299       break;
300     }
301   }
302 
303   // ARM targets default to using the ARM C++ ABI.
304   TheCXXABI.set(TargetCXXABI::GenericARM);
305 
306   // ARM has atomics up to 8 bytes
307   setAtomic();
308 
309   // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
310   if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
311     MaxVectorAlign = 64;
312 
313   // Do force alignment of members that follow zero length bitfields.  If
314   // the alignment of the zero-length bitfield is greater than the member
315   // that follows it, `bar', `bar' will be aligned as the  type of the
316   // zero length bitfield.
317   UseZeroLengthBitfieldAlignment = true;
318 
319   if (Triple.getOS() == llvm::Triple::Linux ||
320       Triple.getOS() == llvm::Triple::UnknownOS)
321     this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
322                            ? "\01__gnu_mcount_nc"
323                            : "\01mcount";
324 }
325 
326 StringRef ARMTargetInfo::getABI() const { return ABI; }
327 
328 bool ARMTargetInfo::setABI(const std::string &Name) {
329   ABI = Name;
330 
331   // The defaults (above) are for AAPCS, check if we need to change them.
332   //
333   // FIXME: We need support for -meabi... we could just mangle it into the
334   // name.
335   if (Name == "apcs-gnu" || Name == "aapcs16") {
336     setABIAPCS(Name == "aapcs16");
337     return true;
338   }
339   if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
340     setABIAAPCS();
341     return true;
342   }
343   return false;
344 }
345 
346 // FIXME: This should be based on Arch attributes, not CPU names.
347 bool ARMTargetInfo::initFeatureMap(
348     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
349     const std::vector<std::string> &FeaturesVec) const {
350 
351   std::vector<StringRef> TargetFeatures;
352   llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
353 
354   // get default FPU features
355   unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
356   llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
357 
358   // get default Extension features
359   unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
360   llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
361 
362   for (auto Feature : TargetFeatures)
363     if (Feature[0] == '+')
364       Features[Feature.drop_front(1)] = true;
365 
366   // Enable or disable thumb-mode explicitly per function to enable mixed
367   // ARM and Thumb code generation.
368   if (isThumb())
369     Features["thumb-mode"] = true;
370   else
371     Features["thumb-mode"] = false;
372 
373   // Convert user-provided arm and thumb GNU target attributes to
374   // [-|+]thumb-mode target features respectively.
375   std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
376   for (auto &Feature : UpdatedFeaturesVec) {
377     if (Feature.compare("+arm") == 0)
378       Feature = "-thumb-mode";
379     else if (Feature.compare("+thumb") == 0)
380       Feature = "+thumb-mode";
381   }
382 
383   return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
384 }
385 
386 
387 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
388                                          DiagnosticsEngine &Diags) {
389   FPU = 0;
390   CRC = 0;
391   Crypto = 0;
392   DSP = 0;
393   Unaligned = 1;
394   SoftFloat = SoftFloatABI = false;
395   HWDiv = 0;
396 
397   // This does not diagnose illegal cases like having both
398   // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
399   uint32_t HW_FP_remove = 0;
400   for (const auto &Feature : Features) {
401     if (Feature == "+soft-float") {
402       SoftFloat = true;
403     } else if (Feature == "+soft-float-abi") {
404       SoftFloatABI = true;
405     } else if (Feature == "+vfp2") {
406       FPU |= VFP2FPU;
407       HW_FP |= HW_FP_SP | HW_FP_DP;
408     } else if (Feature == "+vfp3") {
409       FPU |= VFP3FPU;
410       HW_FP |= HW_FP_SP | HW_FP_DP;
411     } else if (Feature == "+vfp4") {
412       FPU |= VFP4FPU;
413       HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
414     } else if (Feature == "+fp-armv8") {
415       FPU |= FPARMV8;
416       HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
417     } else if (Feature == "+neon") {
418       FPU |= NeonFPU;
419       HW_FP |= HW_FP_SP | HW_FP_DP;
420     } else if (Feature == "+hwdiv") {
421       HWDiv |= HWDivThumb;
422     } else if (Feature == "+hwdiv-arm") {
423       HWDiv |= HWDivARM;
424     } else if (Feature == "+crc") {
425       CRC = 1;
426     } else if (Feature == "+crypto") {
427       Crypto = 1;
428     } else if (Feature == "+dsp") {
429       DSP = 1;
430     } else if (Feature == "+fp-only-sp") {
431       HW_FP_remove |= HW_FP_DP;
432     } else if (Feature == "+strict-align") {
433       Unaligned = 0;
434     } else if (Feature == "+fp16") {
435       HW_FP |= HW_FP_HP;
436     }
437   }
438   HW_FP &= ~HW_FP_remove;
439 
440   switch (ArchVersion) {
441   case 6:
442     if (ArchProfile == llvm::ARM::ProfileKind::M)
443       LDREX = 0;
444     else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
445       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
446     else
447       LDREX = LDREX_W;
448     break;
449   case 7:
450     if (ArchProfile == llvm::ARM::ProfileKind::M)
451       LDREX = LDREX_W | LDREX_H | LDREX_B;
452     else
453       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
454     break;
455   case 8:
456     LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
457   }
458 
459   if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
460     Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
461     return false;
462   }
463 
464   if (FPMath == FP_Neon)
465     Features.push_back("+neonfp");
466   else if (FPMath == FP_VFP)
467     Features.push_back("-neonfp");
468 
469   // Remove front-end specific options which the backend handles differently.
470   auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
471   if (Feature != Features.end())
472     Features.erase(Feature);
473 
474   return true;
475 }
476 
477 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
478   return llvm::StringSwitch<bool>(Feature)
479       .Case("arm", true)
480       .Case("aarch32", true)
481       .Case("softfloat", SoftFloat)
482       .Case("thumb", isThumb())
483       .Case("neon", (FPU & NeonFPU) && !SoftFloat)
484       .Case("vfp", FPU && !SoftFloat)
485       .Case("hwdiv", HWDiv & HWDivThumb)
486       .Case("hwdiv-arm", HWDiv & HWDivARM)
487       .Default(false);
488 }
489 
490 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
491   return Name == "generic" ||
492          llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
493 }
494 
495 bool ARMTargetInfo::setCPU(const std::string &Name) {
496   if (Name != "generic")
497     setArchInfo(llvm::ARM::parseCPUArch(Name));
498 
499   if (ArchKind == llvm::ARM::ArchKind::INVALID)
500     return false;
501   setAtomic();
502   CPU = Name;
503   return true;
504 }
505 
506 bool ARMTargetInfo::setFPMath(StringRef Name) {
507   if (Name == "neon") {
508     FPMath = FP_Neon;
509     return true;
510   } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
511              Name == "vfp4") {
512     FPMath = FP_VFP;
513     return true;
514   }
515   return false;
516 }
517 
518 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
519                                             MacroBuilder &Builder) const {
520   Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
521 }
522 
523 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
524                                             MacroBuilder &Builder) const {
525   // Also include the ARMv8.1-A defines
526   getTargetDefinesARMV81A(Opts, Builder);
527 }
528 
529 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
530                                      MacroBuilder &Builder) const {
531   // Target identification.
532   Builder.defineMacro("__arm");
533   Builder.defineMacro("__arm__");
534   // For bare-metal none-eabi.
535   if (getTriple().getOS() == llvm::Triple::UnknownOS &&
536       (getTriple().getEnvironment() == llvm::Triple::EABI ||
537        getTriple().getEnvironment() == llvm::Triple::EABIHF))
538     Builder.defineMacro("__ELF__");
539 
540   // Target properties.
541   Builder.defineMacro("__REGISTER_PREFIX__", "");
542 
543   // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
544   // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
545   if (getTriple().isWatchABI())
546     Builder.defineMacro("__ARM_ARCH_7K__", "2");
547 
548   if (!CPUAttr.empty())
549     Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
550 
551   // ACLE 6.4.1 ARM/Thumb instruction set architecture
552   // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
553   Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
554 
555   if (ArchVersion >= 8) {
556     // ACLE 6.5.7 Crypto Extension
557     if (Crypto)
558       Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
559     // ACLE 6.5.8 CRC32 Extension
560     if (CRC)
561       Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
562     // ACLE 6.5.10 Numeric Maximum and Minimum
563     Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
564     // ACLE 6.5.9 Directed Rounding
565     Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
566   }
567 
568   // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
569   // is not defined for the M-profile.
570   // NOTE that the default profile is assumed to be 'A'
571   if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
572     Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
573 
574   // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
575   // Thumb ISA (including v6-M and v8-M Baseline).  It is set to 2 if the
576   // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
577   // v7 and v8 architectures excluding v8-M Baseline.
578   if (supportsThumb2())
579     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
580   else if (supportsThumb())
581     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
582 
583   // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
584   // instruction set such as ARM or Thumb.
585   Builder.defineMacro("__ARM_32BIT_STATE", "1");
586 
587   // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
588 
589   // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
590   if (!CPUProfile.empty())
591     Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
592 
593   // ACLE 6.4.3 Unaligned access supported in hardware
594   if (Unaligned)
595     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
596 
597   // ACLE 6.4.4 LDREX/STREX
598   if (LDREX)
599     Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + llvm::utohexstr(LDREX));
600 
601   // ACLE 6.4.5 CLZ
602   if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
603       ArchVersion > 6)
604     Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
605 
606   // ACLE 6.5.1 Hardware Floating Point
607   if (HW_FP)
608     Builder.defineMacro("__ARM_FP", "0x" + llvm::utohexstr(HW_FP));
609 
610   // ACLE predefines.
611   Builder.defineMacro("__ARM_ACLE", "200");
612 
613   // FP16 support (we currently only support IEEE format).
614   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
615   Builder.defineMacro("__ARM_FP16_ARGS", "1");
616 
617   // ACLE 6.5.3 Fused multiply-accumulate (FMA)
618   if (ArchVersion >= 7 && (FPU & VFP4FPU))
619     Builder.defineMacro("__ARM_FEATURE_FMA", "1");
620 
621   // Subtarget options.
622 
623   // FIXME: It's more complicated than this and we don't really support
624   // interworking.
625   // Windows on ARM does not "support" interworking
626   if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
627     Builder.defineMacro("__THUMB_INTERWORK__");
628 
629   if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
630     // Embedded targets on Darwin follow AAPCS, but not EABI.
631     // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
632     if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
633       Builder.defineMacro("__ARM_EABI__");
634     Builder.defineMacro("__ARM_PCS", "1");
635   }
636 
637   if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
638     Builder.defineMacro("__ARM_PCS_VFP", "1");
639 
640   if (SoftFloat)
641     Builder.defineMacro("__SOFTFP__");
642 
643   if (ArchKind == llvm::ARM::ArchKind::XSCALE)
644     Builder.defineMacro("__XSCALE__");
645 
646   if (isThumb()) {
647     Builder.defineMacro("__THUMBEL__");
648     Builder.defineMacro("__thumb__");
649     if (supportsThumb2())
650       Builder.defineMacro("__thumb2__");
651   }
652 
653   // ACLE 6.4.9 32-bit SIMD instructions
654   if (ArchVersion >= 6 && (CPUProfile != "M" || CPUAttr == "7EM"))
655     Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
656 
657   // ACLE 6.4.10 Hardware Integer Divide
658   if (((HWDiv & HWDivThumb) && isThumb()) ||
659       ((HWDiv & HWDivARM) && !isThumb())) {
660     Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
661     Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
662   }
663 
664   // Note, this is always on in gcc, even though it doesn't make sense.
665   Builder.defineMacro("__APCS_32__");
666 
667   if (FPUModeIsVFP((FPUMode)FPU)) {
668     Builder.defineMacro("__VFP_FP__");
669     if (FPU & VFP2FPU)
670       Builder.defineMacro("__ARM_VFPV2__");
671     if (FPU & VFP3FPU)
672       Builder.defineMacro("__ARM_VFPV3__");
673     if (FPU & VFP4FPU)
674       Builder.defineMacro("__ARM_VFPV4__");
675     if (FPU & FPARMV8)
676       Builder.defineMacro("__ARM_FPV5__");
677   }
678 
679   // This only gets set when Neon instructions are actually available, unlike
680   // the VFP define, hence the soft float and arch check. This is subtly
681   // different from gcc, we follow the intent which was that it should be set
682   // when Neon instructions are actually available.
683   if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
684     Builder.defineMacro("__ARM_NEON", "1");
685     Builder.defineMacro("__ARM_NEON__");
686     // current AArch32 NEON implementations do not support double-precision
687     // floating-point even when it is present in VFP.
688     Builder.defineMacro("__ARM_NEON_FP",
689                         "0x" + llvm::utohexstr(HW_FP & ~HW_FP_DP));
690   }
691 
692   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", Opts.ShortWChar ? "2" : "4");
693 
694   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
695 
696   if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
697     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
698     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
699     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
700     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
701   }
702 
703   // ACLE 6.4.7 DSP instructions
704   if (DSP) {
705     Builder.defineMacro("__ARM_FEATURE_DSP", "1");
706   }
707 
708   // ACLE 6.4.8 Saturation instructions
709   bool SAT = false;
710   if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
711     Builder.defineMacro("__ARM_FEATURE_SAT", "1");
712     SAT = true;
713   }
714 
715   // ACLE 6.4.6 Q (saturation) flag
716   if (DSP || SAT)
717     Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
718 
719   if (Opts.UnsafeFPMath)
720     Builder.defineMacro("__ARM_FP_FAST", "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   WCharType = UnsignedShort;
936   SizeType = UnsignedInt;
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     return CCCR_OK;
975   default:
976     return CCCR_Warning;
977   }
978 }
979 
980 // Windows ARM + Itanium C++ ABI Target
981 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
982     const llvm::Triple &Triple, const TargetOptions &Opts)
983     : WindowsARMTargetInfo(Triple, Opts) {
984   TheCXXABI.set(TargetCXXABI::GenericARM);
985 }
986 
987 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
988     const LangOptions &Opts, MacroBuilder &Builder) const {
989   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
990 
991   if (Opts.MSVCCompat)
992     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
993 }
994 
995 // Windows ARM, MS (C++) ABI
996 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
997                                                    const TargetOptions &Opts)
998     : WindowsARMTargetInfo(Triple, Opts) {
999   TheCXXABI.set(TargetCXXABI::Microsoft);
1000 }
1001 
1002 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1003                                                 MacroBuilder &Builder) const {
1004   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1005   WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1006 }
1007 
1008 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1009                                        const TargetOptions &Opts)
1010     : WindowsARMTargetInfo(Triple, Opts) {
1011   TheCXXABI.set(TargetCXXABI::GenericARM);
1012 }
1013 
1014 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1015                                           MacroBuilder &Builder) const {
1016   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1017   DefineStd(Builder, "WIN32", Opts);
1018   DefineStd(Builder, "WINNT", Opts);
1019   Builder.defineMacro("_ARM_");
1020   addMinGWDefines(Opts, Builder);
1021 }
1022 
1023 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1024                                          const TargetOptions &Opts)
1025     : ARMleTargetInfo(Triple, Opts) {
1026   TLSSupported = false;
1027   WCharType = UnsignedShort;
1028   DoubleAlign = LongLongAlign = 64;
1029   resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1030 }
1031 
1032 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1033                                            MacroBuilder &Builder) const {
1034   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1035   Builder.defineMacro("_ARM_");
1036   Builder.defineMacro("__CYGWIN__");
1037   Builder.defineMacro("__CYGWIN32__");
1038   DefineStd(Builder, "unix", Opts);
1039   if (Opts.CPlusPlus)
1040     Builder.defineMacro("_GNU_SOURCE");
1041 }
1042 
1043 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1044                                          const TargetOptions &Opts)
1045     : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1046   HasAlignMac68kSupport = true;
1047   // iOS always has 64-bit atomic instructions.
1048   // FIXME: This should be based off of the target features in
1049   // ARMleTargetInfo.
1050   MaxAtomicInlineWidth = 64;
1051 
1052   if (Triple.isWatchABI()) {
1053     // Darwin on iOS uses a variant of the ARM C++ ABI.
1054     TheCXXABI.set(TargetCXXABI::WatchOS);
1055 
1056     // The 32-bit ABI is silent on what ptrdiff_t should be, but given that
1057     // size_t is long, it's a bit weird for it to be int.
1058     PtrDiffType = SignedLong;
1059 
1060     // BOOL should be a real boolean on the new ABI
1061     UseSignedCharForObjCBool = false;
1062   } else
1063     TheCXXABI.set(TargetCXXABI::iOS);
1064 }
1065 
1066 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1067                                        const llvm::Triple &Triple,
1068                                        MacroBuilder &Builder) const {
1069   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1070 }
1071 
1072 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1073                                                    const TargetOptions &Opts)
1074     : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1075                                    Triple.getOSName(),
1076                                    Triple.getEnvironmentName()),
1077                       Opts) {
1078   IsRenderScriptTarget = true;
1079   LongWidth = LongAlign = 64;
1080 }
1081 
1082 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1083                                                 MacroBuilder &Builder) const {
1084   Builder.defineMacro("__RENDERSCRIPT__");
1085   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1086 }
1087