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   // ACLE position independent code macros.
656   if (Opts.ROPI)
657     Builder.defineMacro("__ARM_ROPI", "1");
658   if (Opts.RWPI)
659     Builder.defineMacro("__ARM_RWPI", "1");
660 
661   if (ArchKind == llvm::ARM::ArchKind::XSCALE)
662     Builder.defineMacro("__XSCALE__");
663 
664   if (isThumb()) {
665     Builder.defineMacro("__THUMBEL__");
666     Builder.defineMacro("__thumb__");
667     if (supportsThumb2())
668       Builder.defineMacro("__thumb2__");
669   }
670 
671   // ACLE 6.4.9 32-bit SIMD instructions
672   if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
673     Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
674 
675   // ACLE 6.4.10 Hardware Integer Divide
676   if (((HWDiv & HWDivThumb) && isThumb()) ||
677       ((HWDiv & HWDivARM) && !isThumb())) {
678     Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
679     Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
680   }
681 
682   // Note, this is always on in gcc, even though it doesn't make sense.
683   Builder.defineMacro("__APCS_32__");
684 
685   if (FPUModeIsVFP((FPUMode)FPU)) {
686     Builder.defineMacro("__VFP_FP__");
687     if (FPU & VFP2FPU)
688       Builder.defineMacro("__ARM_VFPV2__");
689     if (FPU & VFP3FPU)
690       Builder.defineMacro("__ARM_VFPV3__");
691     if (FPU & VFP4FPU)
692       Builder.defineMacro("__ARM_VFPV4__");
693     if (FPU & FPARMV8)
694       Builder.defineMacro("__ARM_FPV5__");
695   }
696 
697   // This only gets set when Neon instructions are actually available, unlike
698   // the VFP define, hence the soft float and arch check. This is subtly
699   // different from gcc, we follow the intent which was that it should be set
700   // when Neon instructions are actually available.
701   if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
702     Builder.defineMacro("__ARM_NEON", "1");
703     Builder.defineMacro("__ARM_NEON__");
704     // current AArch32 NEON implementations do not support double-precision
705     // floating-point even when it is present in VFP.
706     Builder.defineMacro("__ARM_NEON_FP",
707                         "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
708   }
709 
710   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
711                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
712 
713   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
714 
715   if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
716     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
717     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
718     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
719     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
720   }
721 
722   // ACLE 6.4.7 DSP instructions
723   if (DSP) {
724     Builder.defineMacro("__ARM_FEATURE_DSP", "1");
725   }
726 
727   // ACLE 6.4.8 Saturation instructions
728   bool SAT = false;
729   if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
730     Builder.defineMacro("__ARM_FEATURE_SAT", "1");
731     SAT = true;
732   }
733 
734   // ACLE 6.4.6 Q (saturation) flag
735   if (DSP || SAT)
736     Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
737 
738   if (Opts.UnsafeFPMath)
739     Builder.defineMacro("__ARM_FP_FAST", "1");
740 
741   // Armv8.2-A FP16 vector intrinsic
742   if ((FPU & NeonFPU) && HasLegalHalfType)
743     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
744 
745   // Armv8.2-A FP16 scalar intrinsics
746   if (HasLegalHalfType)
747     Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
748 
749   // Armv8.2-A dot product intrinsics
750   if (DotProd)
751     Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
752 
753   switch (ArchKind) {
754   default:
755     break;
756   case llvm::ARM::ArchKind::ARMV8_1A:
757     getTargetDefinesARMV81A(Opts, Builder);
758     break;
759   case llvm::ARM::ArchKind::ARMV8_2A:
760     getTargetDefinesARMV82A(Opts, Builder);
761     break;
762   }
763 }
764 
765 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
766 #define BUILTIN(ID, TYPE, ATTRS)                                               \
767   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
768 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
769   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
770 #include "clang/Basic/BuiltinsNEON.def"
771 
772 #define BUILTIN(ID, TYPE, ATTRS)                                               \
773   {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
774 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
775   {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
776 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
777   {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
778 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
779   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
780 #include "clang/Basic/BuiltinsARM.def"
781 };
782 
783 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
784   return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
785                                              Builtin::FirstTSBuiltin);
786 }
787 
788 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
789 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
790   return IsAAPCS
791              ? AAPCSABIBuiltinVaList
792              : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
793                                          : TargetInfo::VoidPtrBuiltinVaList);
794 }
795 
796 const char *const ARMTargetInfo::GCCRegNames[] = {
797     // Integer registers
798     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
799     "r12", "sp", "lr", "pc",
800 
801     // Float registers
802     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
803     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
804     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
805 
806     // Double registers
807     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
808     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
809     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
810 
811     // Quad registers
812     "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
813     "q12", "q13", "q14", "q15"};
814 
815 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
816   return llvm::makeArrayRef(GCCRegNames);
817 }
818 
819 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
820     {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},
821     {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},
822     {{"v5"}, "r8"},  {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
823     {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},
824     // The S, D and Q registers overlap, but aren't really aliases; we
825     // don't want to substitute one of these for a different-sized one.
826 };
827 
828 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
829   return llvm::makeArrayRef(GCCRegAliases);
830 }
831 
832 bool ARMTargetInfo::validateAsmConstraint(
833     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
834   switch (*Name) {
835   default:
836     break;
837   case 'l': // r0-r7
838   case 'h': // r8-r15
839   case 't': // VFP Floating point register single precision
840   case 'w': // VFP Floating point register double precision
841     Info.setAllowsRegister();
842     return true;
843   case 'I':
844   case 'J':
845   case 'K':
846   case 'L':
847   case 'M':
848     // FIXME
849     return true;
850   case 'Q': // A memory address that is a single base register.
851     Info.setAllowsMemory();
852     return true;
853   case 'U': // a memory reference...
854     switch (Name[1]) {
855     case 'q': // ...ARMV4 ldrsb
856     case 'v': // ...VFP load/store (reg+constant offset)
857     case 'y': // ...iWMMXt load/store
858     case 't': // address valid for load/store opaque types wider
859               // than 128-bits
860     case 'n': // valid address for Neon doubleword vector load/store
861     case 'm': // valid address for Neon element and structure load/store
862     case 's': // valid address for non-offset loads/stores of quad-word
863               // values in four ARM registers
864       Info.setAllowsMemory();
865       Name++;
866       return true;
867     }
868   }
869   return false;
870 }
871 
872 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
873   std::string R;
874   switch (*Constraint) {
875   case 'U': // Two-character constraint; add "^" hint for later parsing.
876     R = std::string("^") + std::string(Constraint, 2);
877     Constraint++;
878     break;
879   case 'p': // 'p' should be translated to 'r' by default.
880     R = std::string("r");
881     break;
882   default:
883     return std::string(1, *Constraint);
884   }
885   return R;
886 }
887 
888 bool ARMTargetInfo::validateConstraintModifier(
889     StringRef Constraint, char Modifier, unsigned Size,
890     std::string &SuggestedModifier) const {
891   bool isOutput = (Constraint[0] == '=');
892   bool isInOut = (Constraint[0] == '+');
893 
894   // Strip off constraint modifiers.
895   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
896     Constraint = Constraint.substr(1);
897 
898   switch (Constraint[0]) {
899   default:
900     break;
901   case 'r': {
902     switch (Modifier) {
903     default:
904       return (isInOut || isOutput || Size <= 64);
905     case 'q':
906       // A register of size 32 cannot fit a vector type.
907       return false;
908     }
909   }
910   }
911 
912   return true;
913 }
914 const char *ARMTargetInfo::getClobbers() const {
915   // FIXME: Is this really right?
916   return "";
917 }
918 
919 TargetInfo::CallingConvCheckResult
920 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
921   switch (CC) {
922   case CC_AAPCS:
923   case CC_AAPCS_VFP:
924   case CC_Swift:
925   case CC_OpenCLKernel:
926     return CCCR_OK;
927   default:
928     return CCCR_Warning;
929   }
930 }
931 
932 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
933   if (RegNo == 0)
934     return 0;
935   if (RegNo == 1)
936     return 1;
937   return -1;
938 }
939 
940 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
941 
942 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
943                                  const TargetOptions &Opts)
944     : ARMTargetInfo(Triple, Opts) {}
945 
946 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
947                                        MacroBuilder &Builder) const {
948   Builder.defineMacro("__ARMEL__");
949   ARMTargetInfo::getTargetDefines(Opts, Builder);
950 }
951 
952 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
953                                  const TargetOptions &Opts)
954     : ARMTargetInfo(Triple, Opts) {}
955 
956 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
957                                        MacroBuilder &Builder) const {
958   Builder.defineMacro("__ARMEB__");
959   Builder.defineMacro("__ARM_BIG_ENDIAN");
960   ARMTargetInfo::getTargetDefines(Opts, Builder);
961 }
962 
963 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
964                                            const TargetOptions &Opts)
965     : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
966 }
967 
968 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
969                                                   MacroBuilder &Builder) const {
970   WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
971 
972   // FIXME: this is invalid for WindowsCE
973   Builder.defineMacro("_M_ARM_NT", "1");
974   Builder.defineMacro("_M_ARMT", "_M_ARM");
975   Builder.defineMacro("_M_THUMB", "_M_ARM");
976 
977   assert((Triple.getArch() == llvm::Triple::arm ||
978           Triple.getArch() == llvm::Triple::thumb) &&
979          "invalid architecture for Windows ARM target info");
980   unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
981   Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
982 
983   // TODO map the complete set of values
984   // 31: VFPv3 40: VFPv4
985   Builder.defineMacro("_M_ARM_FP", "31");
986 }
987 
988 TargetInfo::BuiltinVaListKind
989 WindowsARMTargetInfo::getBuiltinVaListKind() const {
990   return TargetInfo::CharPtrBuiltinVaList;
991 }
992 
993 TargetInfo::CallingConvCheckResult
994 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
995   switch (CC) {
996   case CC_X86StdCall:
997   case CC_X86ThisCall:
998   case CC_X86FastCall:
999   case CC_X86VectorCall:
1000     return CCCR_Ignore;
1001   case CC_C:
1002   case CC_OpenCLKernel:
1003   case CC_PreserveMost:
1004   case CC_PreserveAll:
1005   case CC_Swift:
1006     return CCCR_OK;
1007   default:
1008     return CCCR_Warning;
1009   }
1010 }
1011 
1012 // Windows ARM + Itanium C++ ABI Target
1013 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1014     const llvm::Triple &Triple, const TargetOptions &Opts)
1015     : WindowsARMTargetInfo(Triple, Opts) {
1016   TheCXXABI.set(TargetCXXABI::GenericARM);
1017 }
1018 
1019 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1020     const LangOptions &Opts, MacroBuilder &Builder) const {
1021   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1022 
1023   if (Opts.MSVCCompat)
1024     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1025 }
1026 
1027 // Windows ARM, MS (C++) ABI
1028 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1029                                                    const TargetOptions &Opts)
1030     : WindowsARMTargetInfo(Triple, Opts) {
1031   TheCXXABI.set(TargetCXXABI::Microsoft);
1032 }
1033 
1034 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1035                                                 MacroBuilder &Builder) const {
1036   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1037   WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1038 }
1039 
1040 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1041                                        const TargetOptions &Opts)
1042     : WindowsARMTargetInfo(Triple, Opts) {
1043   TheCXXABI.set(TargetCXXABI::GenericARM);
1044 }
1045 
1046 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1047                                           MacroBuilder &Builder) const {
1048   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1049   Builder.defineMacro("_ARM_");
1050 }
1051 
1052 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1053                                          const TargetOptions &Opts)
1054     : ARMleTargetInfo(Triple, Opts) {
1055   this->WCharType = TargetInfo::UnsignedShort;
1056   TLSSupported = false;
1057   DoubleAlign = LongLongAlign = 64;
1058   resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1059 }
1060 
1061 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1062                                            MacroBuilder &Builder) const {
1063   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1064   Builder.defineMacro("_ARM_");
1065   Builder.defineMacro("__CYGWIN__");
1066   Builder.defineMacro("__CYGWIN32__");
1067   DefineStd(Builder, "unix", Opts);
1068   if (Opts.CPlusPlus)
1069     Builder.defineMacro("_GNU_SOURCE");
1070 }
1071 
1072 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1073                                          const TargetOptions &Opts)
1074     : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1075   HasAlignMac68kSupport = true;
1076   // iOS always has 64-bit atomic instructions.
1077   // FIXME: This should be based off of the target features in
1078   // ARMleTargetInfo.
1079   MaxAtomicInlineWidth = 64;
1080 
1081   if (Triple.isWatchABI()) {
1082     // Darwin on iOS uses a variant of the ARM C++ ABI.
1083     TheCXXABI.set(TargetCXXABI::WatchOS);
1084 
1085     // BOOL should be a real boolean on the new ABI
1086     UseSignedCharForObjCBool = false;
1087   } else
1088     TheCXXABI.set(TargetCXXABI::iOS);
1089 }
1090 
1091 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1092                                        const llvm::Triple &Triple,
1093                                        MacroBuilder &Builder) const {
1094   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1095 }
1096 
1097 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1098                                                    const TargetOptions &Opts)
1099     : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1100                                    Triple.getOSName(),
1101                                    Triple.getEnvironmentName()),
1102                       Opts) {
1103   IsRenderScriptTarget = true;
1104   LongWidth = LongAlign = 64;
1105 }
1106 
1107 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1108                                                 MacroBuilder &Builder) const {
1109   Builder.defineMacro("__RENDERSCRIPT__");
1110   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1111 }
1112