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   bool IsNetBSD = T.getOS() == llvm::Triple::NetBSD;
40   bool IsOpenBSD = T.getOS() == llvm::Triple::OpenBSD;
41   if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
42     WCharType = UnsignedInt;
43 
44   UseBitFieldTypeAlignment = true;
45 
46   ZeroLengthBitfieldBoundary = 0;
47 
48   // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
49   // so set preferred for small types to 32.
50   if (T.isOSBinFormatMachO()) {
51     resetDataLayout(BigEndian
52                         ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
53                         : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
54   } else if (T.isOSWindows()) {
55     assert(!BigEndian && "Windows on ARM does not support big endian");
56     resetDataLayout("e"
57                     "-m:w"
58                     "-p:32:32"
59                     "-i64:64"
60                     "-v128:64:128"
61                     "-a:0:32"
62                     "-n32"
63                     "-S64");
64   } else if (T.isOSNaCl()) {
65     assert(!BigEndian && "NaCl on ARM does not support big endian");
66     resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
67   } else {
68     resetDataLayout(BigEndian
69                         ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
70                         : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
71   }
72 
73   // FIXME: Enumerated types are variable width in straight AAPCS.
74 }
75 
76 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
77   const llvm::Triple &T = getTriple();
78 
79   IsAAPCS = false;
80 
81   if (IsAAPCS16)
82     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
83   else
84     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
85 
86   // size_t is unsigned int on FreeBSD.
87   if (T.getOS() == llvm::Triple::FreeBSD)
88     SizeType = UnsignedInt;
89   else
90     SizeType = UnsignedLong;
91 
92   WCharType = SignedInt;
93 
94   // Do not respect the alignment of bit-field types when laying out
95   // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
96   UseBitFieldTypeAlignment = false;
97 
98   /// gcc forces the alignment to 4 bytes, regardless of the type of the
99   /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
100   /// gcc.
101   ZeroLengthBitfieldBoundary = 32;
102 
103   if (T.isOSBinFormatMachO() && IsAAPCS16) {
104     assert(!BigEndian && "AAPCS16 does not support big-endian");
105     resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
106   } else if (T.isOSBinFormatMachO())
107     resetDataLayout(
108         BigEndian
109             ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
110             : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
111   else
112     resetDataLayout(
113         BigEndian
114             ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
115             : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
116 
117   // FIXME: Override "preferred align" for double and long long.
118 }
119 
120 void ARMTargetInfo::setArchInfo() {
121   StringRef ArchName = getTriple().getArchName();
122 
123   ArchISA = llvm::ARM::parseArchISA(ArchName);
124   CPU = llvm::ARM::getDefaultCPU(ArchName);
125   llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
126   if (AK != llvm::ARM::ArchKind::INVALID)
127     ArchKind = AK;
128   setArchInfo(ArchKind);
129 }
130 
131 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
132   StringRef SubArch;
133 
134   // cache TargetParser info
135   ArchKind = Kind;
136   SubArch = llvm::ARM::getSubArch(ArchKind);
137   ArchProfile = llvm::ARM::parseArchProfile(SubArch);
138   ArchVersion = llvm::ARM::parseArchVersion(SubArch);
139 
140   // cache CPU related strings
141   CPUAttr = getCPUAttr();
142   CPUProfile = getCPUProfile();
143 }
144 
145 void ARMTargetInfo::setAtomic() {
146   // when triple does not specify a sub arch,
147   // then we are not using inline atomics
148   bool ShouldUseInlineAtomic =
149       (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
150       (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
151   // Cortex M does not support 8 byte atomics, while general Thumb2 does.
152   if (ArchProfile == llvm::ARM::ProfileKind::M) {
153     MaxAtomicPromoteWidth = 32;
154     if (ShouldUseInlineAtomic)
155       MaxAtomicInlineWidth = 32;
156   } else {
157     MaxAtomicPromoteWidth = 64;
158     if (ShouldUseInlineAtomic)
159       MaxAtomicInlineWidth = 64;
160   }
161 }
162 
163 bool ARMTargetInfo::isThumb() const {
164   return ArchISA == llvm::ARM::ISAKind::THUMB;
165 }
166 
167 bool ARMTargetInfo::supportsThumb() const {
168   return CPUAttr.count('T') || ArchVersion >= 6;
169 }
170 
171 bool ARMTargetInfo::supportsThumb2() const {
172   return CPUAttr.equals("6T2") ||
173          (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
174 }
175 
176 StringRef ARMTargetInfo::getCPUAttr() const {
177   // For most sub-arches, the build attribute CPU name is enough.
178   // For Cortex variants, it's slightly different.
179   switch (ArchKind) {
180   default:
181     return llvm::ARM::getCPUAttr(ArchKind);
182   case llvm::ARM::ArchKind::ARMV6M:
183     return "6M";
184   case llvm::ARM::ArchKind::ARMV7S:
185     return "7S";
186   case llvm::ARM::ArchKind::ARMV7A:
187     return "7A";
188   case llvm::ARM::ArchKind::ARMV7R:
189     return "7R";
190   case llvm::ARM::ArchKind::ARMV7M:
191     return "7M";
192   case llvm::ARM::ArchKind::ARMV7EM:
193     return "7EM";
194   case llvm::ARM::ArchKind::ARMV7VE:
195     return "7VE";
196   case llvm::ARM::ArchKind::ARMV8A:
197     return "8A";
198   case llvm::ARM::ArchKind::ARMV8_1A:
199     return "8_1A";
200   case llvm::ARM::ArchKind::ARMV8_2A:
201     return "8_2A";
202   case llvm::ARM::ArchKind::ARMV8MBaseline:
203     return "8M_BASE";
204   case llvm::ARM::ArchKind::ARMV8MMainline:
205     return "8M_MAIN";
206   case llvm::ARM::ArchKind::ARMV8R:
207     return "8R";
208   }
209 }
210 
211 StringRef ARMTargetInfo::getCPUProfile() const {
212   switch (ArchProfile) {
213   case llvm::ARM::ProfileKind::A:
214     return "A";
215   case llvm::ARM::ProfileKind::R:
216     return "R";
217   case llvm::ARM::ProfileKind::M:
218     return "M";
219   default:
220     return "";
221   }
222 }
223 
224 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
225                              const TargetOptions &Opts)
226     : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
227       HW_FP(0) {
228 
229   switch (getTriple().getOS()) {
230   case llvm::Triple::NetBSD:
231   case llvm::Triple::OpenBSD:
232     PtrDiffType = SignedLong;
233     break;
234   default:
235     PtrDiffType = SignedInt;
236     break;
237   }
238 
239   bool IsOpenBSD = Triple.getOS() == llvm::Triple::OpenBSD;
240   bool IsNetBSD = Triple.getOS() == llvm::Triple::NetBSD;
241   IntPtrType =
242       (Triple.isOSDarwin() || IsOpenBSD || IsNetBSD) ? SignedLong : SignedInt;
243 
244   // Cache arch related info.
245   setArchInfo();
246 
247   // {} in inline assembly are neon specifiers, not assembly variant
248   // specifiers.
249   NoAsmVariants = true;
250 
251   // FIXME: This duplicates code from the driver that sets the -target-abi
252   // option - this code is used if -target-abi isn't passed and should
253   // be unified in some way.
254   if (Triple.isOSBinFormatMachO()) {
255     // The backend is hardwired to assume AAPCS for M-class processors, ensure
256     // the frontend matches that.
257     if (Triple.getEnvironment() == llvm::Triple::EABI ||
258         Triple.getOS() == llvm::Triple::UnknownOS ||
259         ArchProfile == llvm::ARM::ProfileKind::M) {
260       setABI("aapcs");
261     } else if (Triple.isWatchABI()) {
262       setABI("aapcs16");
263     } else {
264       setABI("apcs-gnu");
265     }
266   } else if (Triple.isOSWindows()) {
267     // FIXME: this is invalid for WindowsCE
268     setABI("aapcs");
269   } else {
270     // Select the default based on the platform.
271     switch (Triple.getEnvironment()) {
272     case llvm::Triple::Android:
273     case llvm::Triple::GNUEABI:
274     case llvm::Triple::GNUEABIHF:
275     case llvm::Triple::MuslEABI:
276     case llvm::Triple::MuslEABIHF:
277       setABI("aapcs-linux");
278       break;
279     case llvm::Triple::EABIHF:
280     case llvm::Triple::EABI:
281       setABI("aapcs");
282       break;
283     case llvm::Triple::GNU:
284       setABI("apcs-gnu");
285       break;
286     default:
287       if (Triple.getOS() == llvm::Triple::NetBSD)
288         setABI("apcs-gnu");
289       else if (Triple.getOS() == llvm::Triple::OpenBSD)
290         setABI("aapcs-linux");
291       else
292         setABI("aapcs");
293       break;
294     }
295   }
296 
297   // ARM targets default to using the ARM C++ ABI.
298   TheCXXABI.set(TargetCXXABI::GenericARM);
299 
300   // ARM has atomics up to 8 bytes
301   setAtomic();
302 
303   // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
304   if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
305     MaxVectorAlign = 64;
306 
307   // Do force alignment of members that follow zero length bitfields.  If
308   // the alignment of the zero-length bitfield is greater than the member
309   // that follows it, `bar', `bar' will be aligned as the  type of the
310   // zero length bitfield.
311   UseZeroLengthBitfieldAlignment = true;
312 
313   if (Triple.getOS() == llvm::Triple::Linux ||
314       Triple.getOS() == llvm::Triple::UnknownOS)
315     this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
316                            ? "\01__gnu_mcount_nc"
317                            : "\01mcount";
318 }
319 
320 StringRef ARMTargetInfo::getABI() const { return ABI; }
321 
322 bool ARMTargetInfo::setABI(const std::string &Name) {
323   ABI = Name;
324 
325   // The defaults (above) are for AAPCS, check if we need to change them.
326   //
327   // FIXME: We need support for -meabi... we could just mangle it into the
328   // name.
329   if (Name == "apcs-gnu" || Name == "aapcs16") {
330     setABIAPCS(Name == "aapcs16");
331     return true;
332   }
333   if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
334     setABIAAPCS();
335     return true;
336   }
337   return false;
338 }
339 
340 // FIXME: This should be based on Arch attributes, not CPU names.
341 bool ARMTargetInfo::initFeatureMap(
342     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
343     const std::vector<std::string> &FeaturesVec) const {
344 
345   std::vector<StringRef> TargetFeatures;
346   llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
347 
348   // get default FPU features
349   unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
350   llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
351 
352   // get default Extension features
353   unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
354   llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
355 
356   for (auto Feature : TargetFeatures)
357     if (Feature[0] == '+')
358       Features[Feature.drop_front(1)] = true;
359 
360   // Enable or disable thumb-mode explicitly per function to enable mixed
361   // ARM and Thumb code generation.
362   if (isThumb())
363     Features["thumb-mode"] = true;
364   else
365     Features["thumb-mode"] = false;
366 
367   // Convert user-provided arm and thumb GNU target attributes to
368   // [-|+]thumb-mode target features respectively.
369   std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
370   for (auto &Feature : UpdatedFeaturesVec) {
371     if (Feature.compare("+arm") == 0)
372       Feature = "-thumb-mode";
373     else if (Feature.compare("+thumb") == 0)
374       Feature = "+thumb-mode";
375   }
376 
377   return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
378 }
379 
380 
381 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
382                                          DiagnosticsEngine &Diags) {
383   FPU = 0;
384   CRC = 0;
385   Crypto = 0;
386   DSP = 0;
387   Unaligned = 1;
388   SoftFloat = SoftFloatABI = false;
389   HWDiv = 0;
390 
391   // This does not diagnose illegal cases like having both
392   // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
393   uint32_t HW_FP_remove = 0;
394   for (const auto &Feature : Features) {
395     if (Feature == "+soft-float") {
396       SoftFloat = true;
397     } else if (Feature == "+soft-float-abi") {
398       SoftFloatABI = true;
399     } else if (Feature == "+vfp2") {
400       FPU |= VFP2FPU;
401       HW_FP |= HW_FP_SP | HW_FP_DP;
402     } else if (Feature == "+vfp3") {
403       FPU |= VFP3FPU;
404       HW_FP |= HW_FP_SP | HW_FP_DP;
405     } else if (Feature == "+vfp4") {
406       FPU |= VFP4FPU;
407       HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
408     } else if (Feature == "+fp-armv8") {
409       FPU |= FPARMV8;
410       HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
411     } else if (Feature == "+neon") {
412       FPU |= NeonFPU;
413       HW_FP |= HW_FP_SP | HW_FP_DP;
414     } else if (Feature == "+hwdiv") {
415       HWDiv |= HWDivThumb;
416     } else if (Feature == "+hwdiv-arm") {
417       HWDiv |= HWDivARM;
418     } else if (Feature == "+crc") {
419       CRC = 1;
420     } else if (Feature == "+crypto") {
421       Crypto = 1;
422     } else if (Feature == "+dsp") {
423       DSP = 1;
424     } else if (Feature == "+fp-only-sp") {
425       HW_FP_remove |= HW_FP_DP;
426     } else if (Feature == "+strict-align") {
427       Unaligned = 0;
428     } else if (Feature == "+fp16") {
429       HW_FP |= HW_FP_HP;
430     }
431   }
432   HW_FP &= ~HW_FP_remove;
433 
434   switch (ArchVersion) {
435   case 6:
436     if (ArchProfile == llvm::ARM::ProfileKind::M)
437       LDREX = 0;
438     else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
439       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
440     else
441       LDREX = LDREX_W;
442     break;
443   case 7:
444     if (ArchProfile == llvm::ARM::ProfileKind::M)
445       LDREX = LDREX_W | LDREX_H | LDREX_B;
446     else
447       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
448     break;
449   case 8:
450     LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
451   }
452 
453   if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
454     Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
455     return false;
456   }
457 
458   if (FPMath == FP_Neon)
459     Features.push_back("+neonfp");
460   else if (FPMath == FP_VFP)
461     Features.push_back("-neonfp");
462 
463   // Remove front-end specific options which the backend handles differently.
464   auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
465   if (Feature != Features.end())
466     Features.erase(Feature);
467 
468   return true;
469 }
470 
471 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
472   return llvm::StringSwitch<bool>(Feature)
473       .Case("arm", true)
474       .Case("aarch32", true)
475       .Case("softfloat", SoftFloat)
476       .Case("thumb", isThumb())
477       .Case("neon", (FPU & NeonFPU) && !SoftFloat)
478       .Case("vfp", FPU && !SoftFloat)
479       .Case("hwdiv", HWDiv & HWDivThumb)
480       .Case("hwdiv-arm", HWDiv & HWDivARM)
481       .Default(false);
482 }
483 
484 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
485   return Name == "generic" ||
486          llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
487 }
488 
489 bool ARMTargetInfo::setCPU(const std::string &Name) {
490   if (Name != "generic")
491     setArchInfo(llvm::ARM::parseCPUArch(Name));
492 
493   if (ArchKind == llvm::ARM::ArchKind::INVALID)
494     return false;
495   setAtomic();
496   CPU = Name;
497   return true;
498 }
499 
500 bool ARMTargetInfo::setFPMath(StringRef Name) {
501   if (Name == "neon") {
502     FPMath = FP_Neon;
503     return true;
504   } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
505              Name == "vfp4") {
506     FPMath = FP_VFP;
507     return true;
508   }
509   return false;
510 }
511 
512 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
513                                             MacroBuilder &Builder) const {
514   Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
515 }
516 
517 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
518                                             MacroBuilder &Builder) const {
519   // Also include the ARMv8.1-A defines
520   getTargetDefinesARMV81A(Opts, Builder);
521 }
522 
523 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
524                                      MacroBuilder &Builder) const {
525   // Target identification.
526   Builder.defineMacro("__arm");
527   Builder.defineMacro("__arm__");
528   // For bare-metal none-eabi.
529   if (getTriple().getOS() == llvm::Triple::UnknownOS &&
530       (getTriple().getEnvironment() == llvm::Triple::EABI ||
531        getTriple().getEnvironment() == llvm::Triple::EABIHF))
532     Builder.defineMacro("__ELF__");
533 
534   // Target properties.
535   Builder.defineMacro("__REGISTER_PREFIX__", "");
536 
537   // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
538   // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
539   if (getTriple().isWatchABI())
540     Builder.defineMacro("__ARM_ARCH_7K__", "2");
541 
542   if (!CPUAttr.empty())
543     Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
544 
545   // ACLE 6.4.1 ARM/Thumb instruction set architecture
546   // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
547   Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
548 
549   if (ArchVersion >= 8) {
550     // ACLE 6.5.7 Crypto Extension
551     if (Crypto)
552       Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
553     // ACLE 6.5.8 CRC32 Extension
554     if (CRC)
555       Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
556     // ACLE 6.5.10 Numeric Maximum and Minimum
557     Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
558     // ACLE 6.5.9 Directed Rounding
559     Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
560   }
561 
562   // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
563   // is not defined for the M-profile.
564   // NOTE that the default profile is assumed to be 'A'
565   if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
566     Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
567 
568   // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
569   // Thumb ISA (including v6-M and v8-M Baseline).  It is set to 2 if the
570   // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
571   // v7 and v8 architectures excluding v8-M Baseline.
572   if (supportsThumb2())
573     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
574   else if (supportsThumb())
575     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
576 
577   // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
578   // instruction set such as ARM or Thumb.
579   Builder.defineMacro("__ARM_32BIT_STATE", "1");
580 
581   // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
582 
583   // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
584   if (!CPUProfile.empty())
585     Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
586 
587   // ACLE 6.4.3 Unaligned access supported in hardware
588   if (Unaligned)
589     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
590 
591   // ACLE 6.4.4 LDREX/STREX
592   if (LDREX)
593     Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + llvm::utohexstr(LDREX));
594 
595   // ACLE 6.4.5 CLZ
596   if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
597       ArchVersion > 6)
598     Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
599 
600   // ACLE 6.5.1 Hardware Floating Point
601   if (HW_FP)
602     Builder.defineMacro("__ARM_FP", "0x" + llvm::utohexstr(HW_FP));
603 
604   // ACLE predefines.
605   Builder.defineMacro("__ARM_ACLE", "200");
606 
607   // FP16 support (we currently only support IEEE format).
608   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
609   Builder.defineMacro("__ARM_FP16_ARGS", "1");
610 
611   // ACLE 6.5.3 Fused multiply-accumulate (FMA)
612   if (ArchVersion >= 7 && (FPU & VFP4FPU))
613     Builder.defineMacro("__ARM_FEATURE_FMA", "1");
614 
615   // Subtarget options.
616 
617   // FIXME: It's more complicated than this and we don't really support
618   // interworking.
619   // Windows on ARM does not "support" interworking
620   if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
621     Builder.defineMacro("__THUMB_INTERWORK__");
622 
623   if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
624     // Embedded targets on Darwin follow AAPCS, but not EABI.
625     // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
626     if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
627       Builder.defineMacro("__ARM_EABI__");
628     Builder.defineMacro("__ARM_PCS", "1");
629   }
630 
631   if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
632     Builder.defineMacro("__ARM_PCS_VFP", "1");
633 
634   if (SoftFloat)
635     Builder.defineMacro("__SOFTFP__");
636 
637   if (ArchKind == llvm::ARM::ArchKind::XSCALE)
638     Builder.defineMacro("__XSCALE__");
639 
640   if (isThumb()) {
641     Builder.defineMacro("__THUMBEL__");
642     Builder.defineMacro("__thumb__");
643     if (supportsThumb2())
644       Builder.defineMacro("__thumb2__");
645   }
646 
647   // ACLE 6.4.9 32-bit SIMD instructions
648   if (ArchVersion >= 6 && (CPUProfile != "M" || CPUAttr == "7EM"))
649     Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
650 
651   // ACLE 6.4.10 Hardware Integer Divide
652   if (((HWDiv & HWDivThumb) && isThumb()) ||
653       ((HWDiv & HWDivARM) && !isThumb())) {
654     Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
655     Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
656   }
657 
658   // Note, this is always on in gcc, even though it doesn't make sense.
659   Builder.defineMacro("__APCS_32__");
660 
661   if (FPUModeIsVFP((FPUMode)FPU)) {
662     Builder.defineMacro("__VFP_FP__");
663     if (FPU & VFP2FPU)
664       Builder.defineMacro("__ARM_VFPV2__");
665     if (FPU & VFP3FPU)
666       Builder.defineMacro("__ARM_VFPV3__");
667     if (FPU & VFP4FPU)
668       Builder.defineMacro("__ARM_VFPV4__");
669     if (FPU & FPARMV8)
670       Builder.defineMacro("__ARM_FPV5__");
671   }
672 
673   // This only gets set when Neon instructions are actually available, unlike
674   // the VFP define, hence the soft float and arch check. This is subtly
675   // different from gcc, we follow the intent which was that it should be set
676   // when Neon instructions are actually available.
677   if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
678     Builder.defineMacro("__ARM_NEON", "1");
679     Builder.defineMacro("__ARM_NEON__");
680     // current AArch32 NEON implementations do not support double-precision
681     // floating-point even when it is present in VFP.
682     Builder.defineMacro("__ARM_NEON_FP",
683                         "0x" + llvm::utohexstr(HW_FP & ~HW_FP_DP));
684   }
685 
686   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
687                       llvm::utostr(Opts.WCharSize ? Opts.WCharSize : 4));
688 
689   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
690 
691   if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
692     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
693     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
694     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
695     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
696   }
697 
698   // ACLE 6.4.7 DSP instructions
699   if (DSP) {
700     Builder.defineMacro("__ARM_FEATURE_DSP", "1");
701   }
702 
703   // ACLE 6.4.8 Saturation instructions
704   bool SAT = false;
705   if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
706     Builder.defineMacro("__ARM_FEATURE_SAT", "1");
707     SAT = true;
708   }
709 
710   // ACLE 6.4.6 Q (saturation) flag
711   if (DSP || SAT)
712     Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
713 
714   if (Opts.UnsafeFPMath)
715     Builder.defineMacro("__ARM_FP_FAST", "1");
716 
717   switch (ArchKind) {
718   default:
719     break;
720   case llvm::ARM::ArchKind::ARMV8_1A:
721     getTargetDefinesARMV81A(Opts, Builder);
722     break;
723   case llvm::ARM::ArchKind::ARMV8_2A:
724     getTargetDefinesARMV82A(Opts, Builder);
725     break;
726   }
727 }
728 
729 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
730 #define BUILTIN(ID, TYPE, ATTRS)                                               \
731   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
732 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
733   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
734 #include "clang/Basic/BuiltinsNEON.def"
735 
736 #define BUILTIN(ID, TYPE, ATTRS)                                               \
737   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
738 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
739   {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
740 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
741   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
742 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
743   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
744 #include "clang/Basic/BuiltinsARM.def"
745 };
746 
747 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
748   return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
749                                              Builtin::FirstTSBuiltin);
750 }
751 
752 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
753 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
754   return IsAAPCS
755              ? AAPCSABIBuiltinVaList
756              : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
757                                          : TargetInfo::VoidPtrBuiltinVaList);
758 }
759 
760 const char *const ARMTargetInfo::GCCRegNames[] = {
761     // Integer registers
762     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
763     "r12", "sp", "lr", "pc",
764 
765     // Float registers
766     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
767     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
768     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
769 
770     // Double registers
771     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
772     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
773     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
774 
775     // Quad registers
776     "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
777     "q12", "q13", "q14", "q15"};
778 
779 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
780   return llvm::makeArrayRef(GCCRegNames);
781 }
782 
783 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
784     {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},
785     {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},
786     {{"v5"}, "r8"},  {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
787     {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},
788     // The S, D and Q registers overlap, but aren't really aliases; we
789     // don't want to substitute one of these for a different-sized one.
790 };
791 
792 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
793   return llvm::makeArrayRef(GCCRegAliases);
794 }
795 
796 bool ARMTargetInfo::validateAsmConstraint(
797     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
798   switch (*Name) {
799   default:
800     break;
801   case 'l': // r0-r7
802   case 'h': // r8-r15
803   case 't': // VFP Floating point register single precision
804   case 'w': // VFP Floating point register double precision
805     Info.setAllowsRegister();
806     return true;
807   case 'I':
808   case 'J':
809   case 'K':
810   case 'L':
811   case 'M':
812     // FIXME
813     return true;
814   case 'Q': // A memory address that is a single base register.
815     Info.setAllowsMemory();
816     return true;
817   case 'U': // a memory reference...
818     switch (Name[1]) {
819     case 'q': // ...ARMV4 ldrsb
820     case 'v': // ...VFP load/store (reg+constant offset)
821     case 'y': // ...iWMMXt load/store
822     case 't': // address valid for load/store opaque types wider
823               // than 128-bits
824     case 'n': // valid address for Neon doubleword vector load/store
825     case 'm': // valid address for Neon element and structure load/store
826     case 's': // valid address for non-offset loads/stores of quad-word
827               // values in four ARM registers
828       Info.setAllowsMemory();
829       Name++;
830       return true;
831     }
832   }
833   return false;
834 }
835 
836 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
837   std::string R;
838   switch (*Constraint) {
839   case 'U': // Two-character constraint; add "^" hint for later parsing.
840     R = std::string("^") + std::string(Constraint, 2);
841     Constraint++;
842     break;
843   case 'p': // 'p' should be translated to 'r' by default.
844     R = std::string("r");
845     break;
846   default:
847     return std::string(1, *Constraint);
848   }
849   return R;
850 }
851 
852 bool ARMTargetInfo::validateConstraintModifier(
853     StringRef Constraint, char Modifier, unsigned Size,
854     std::string &SuggestedModifier) const {
855   bool isOutput = (Constraint[0] == '=');
856   bool isInOut = (Constraint[0] == '+');
857 
858   // Strip off constraint modifiers.
859   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
860     Constraint = Constraint.substr(1);
861 
862   switch (Constraint[0]) {
863   default:
864     break;
865   case 'r': {
866     switch (Modifier) {
867     default:
868       return (isInOut || isOutput || Size <= 64);
869     case 'q':
870       // A register of size 32 cannot fit a vector type.
871       return false;
872     }
873   }
874   }
875 
876   return true;
877 }
878 const char *ARMTargetInfo::getClobbers() const {
879   // FIXME: Is this really right?
880   return "";
881 }
882 
883 TargetInfo::CallingConvCheckResult
884 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
885   switch (CC) {
886   case CC_AAPCS:
887   case CC_AAPCS_VFP:
888   case CC_Swift:
889   case CC_OpenCLKernel:
890     return CCCR_OK;
891   default:
892     return CCCR_Warning;
893   }
894 }
895 
896 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
897   if (RegNo == 0)
898     return 0;
899   if (RegNo == 1)
900     return 1;
901   return -1;
902 }
903 
904 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
905 
906 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
907                                  const TargetOptions &Opts)
908     : ARMTargetInfo(Triple, Opts) {}
909 
910 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
911                                        MacroBuilder &Builder) const {
912   Builder.defineMacro("__ARMEL__");
913   ARMTargetInfo::getTargetDefines(Opts, Builder);
914 }
915 
916 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
917                                  const TargetOptions &Opts)
918     : ARMTargetInfo(Triple, Opts) {}
919 
920 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
921                                        MacroBuilder &Builder) const {
922   Builder.defineMacro("__ARMEB__");
923   Builder.defineMacro("__ARM_BIG_ENDIAN");
924   ARMTargetInfo::getTargetDefines(Opts, Builder);
925 }
926 
927 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
928                                            const TargetOptions &Opts)
929     : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
930   SizeType = UnsignedInt;
931 }
932 
933 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
934                                                   MacroBuilder &Builder) const {
935   WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
936 
937   // FIXME: this is invalid for WindowsCE
938   Builder.defineMacro("_M_ARM_NT", "1");
939   Builder.defineMacro("_M_ARMT", "_M_ARM");
940   Builder.defineMacro("_M_THUMB", "_M_ARM");
941 
942   assert((Triple.getArch() == llvm::Triple::arm ||
943           Triple.getArch() == llvm::Triple::thumb) &&
944          "invalid architecture for Windows ARM target info");
945   unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
946   Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
947 
948   // TODO map the complete set of values
949   // 31: VFPv3 40: VFPv4
950   Builder.defineMacro("_M_ARM_FP", "31");
951 }
952 
953 TargetInfo::BuiltinVaListKind
954 WindowsARMTargetInfo::getBuiltinVaListKind() const {
955   return TargetInfo::CharPtrBuiltinVaList;
956 }
957 
958 TargetInfo::CallingConvCheckResult
959 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
960   switch (CC) {
961   case CC_X86StdCall:
962   case CC_X86ThisCall:
963   case CC_X86FastCall:
964   case CC_X86VectorCall:
965     return CCCR_Ignore;
966   case CC_C:
967   case CC_OpenCLKernel:
968     return CCCR_OK;
969   default:
970     return CCCR_Warning;
971   }
972 }
973 
974 // Windows ARM + Itanium C++ ABI Target
975 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
976     const llvm::Triple &Triple, const TargetOptions &Opts)
977     : WindowsARMTargetInfo(Triple, Opts) {
978   TheCXXABI.set(TargetCXXABI::GenericARM);
979 }
980 
981 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
982     const LangOptions &Opts, MacroBuilder &Builder) const {
983   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
984 
985   if (Opts.MSVCCompat)
986     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
987 }
988 
989 // Windows ARM, MS (C++) ABI
990 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
991                                                    const TargetOptions &Opts)
992     : WindowsARMTargetInfo(Triple, Opts) {
993   TheCXXABI.set(TargetCXXABI::Microsoft);
994 }
995 
996 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
997                                                 MacroBuilder &Builder) const {
998   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
999   WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1000 }
1001 
1002 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1003                                        const TargetOptions &Opts)
1004     : WindowsARMTargetInfo(Triple, Opts) {
1005   TheCXXABI.set(TargetCXXABI::GenericARM);
1006 }
1007 
1008 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1009                                           MacroBuilder &Builder) const {
1010   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1011   DefineStd(Builder, "WIN32", Opts);
1012   DefineStd(Builder, "WINNT", Opts);
1013   Builder.defineMacro("_ARM_");
1014   addMinGWDefines(Opts, Builder);
1015 }
1016 
1017 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1018                                          const TargetOptions &Opts)
1019     : ARMleTargetInfo(Triple, Opts) {
1020   this->WCharType = TargetInfo::UnsignedShort;
1021   TLSSupported = false;
1022   DoubleAlign = LongLongAlign = 64;
1023   resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1024 }
1025 
1026 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1027                                            MacroBuilder &Builder) const {
1028   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1029   Builder.defineMacro("_ARM_");
1030   Builder.defineMacro("__CYGWIN__");
1031   Builder.defineMacro("__CYGWIN32__");
1032   DefineStd(Builder, "unix", Opts);
1033   if (Opts.CPlusPlus)
1034     Builder.defineMacro("_GNU_SOURCE");
1035 }
1036 
1037 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1038                                          const TargetOptions &Opts)
1039     : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1040   HasAlignMac68kSupport = true;
1041   // iOS always has 64-bit atomic instructions.
1042   // FIXME: This should be based off of the target features in
1043   // ARMleTargetInfo.
1044   MaxAtomicInlineWidth = 64;
1045 
1046   if (Triple.isWatchABI()) {
1047     // Darwin on iOS uses a variant of the ARM C++ ABI.
1048     TheCXXABI.set(TargetCXXABI::WatchOS);
1049 
1050     // The 32-bit ABI is silent on what ptrdiff_t should be, but given that
1051     // size_t is long, it's a bit weird for it to be int.
1052     PtrDiffType = SignedLong;
1053 
1054     // BOOL should be a real boolean on the new ABI
1055     UseSignedCharForObjCBool = false;
1056   } else
1057     TheCXXABI.set(TargetCXXABI::iOS);
1058 }
1059 
1060 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1061                                        const llvm::Triple &Triple,
1062                                        MacroBuilder &Builder) const {
1063   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1064 }
1065 
1066 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1067                                                    const TargetOptions &Opts)
1068     : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1069                                    Triple.getOSName(),
1070                                    Triple.getEnvironmentName()),
1071                       Opts) {
1072   IsRenderScriptTarget = true;
1073   LongWidth = LongAlign = 64;
1074 }
1075 
1076 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1077                                                 MacroBuilder &Builder) const {
1078   Builder.defineMacro("__RENDERSCRIPT__");
1079   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1080 }
1081