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