]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Basic/Targets/ARM.cpp
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / lib / Basic / Targets / ARM.cpp
1 //===--- ARM.cpp - Implement ARM target feature support -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements ARM TargetInfo objects.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ARM.h"
15 #include "clang/Basic/Builtins.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/TargetBuiltins.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21
22 using namespace clang;
23 using namespace clang::targets;
24
25 void ARMTargetInfo::setABIAAPCS() {
26   IsAAPCS = true;
27
28   DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
29   const llvm::Triple &T = getTriple();
30
31   bool IsNetBSD = T.isOSNetBSD();
32   bool IsOpenBSD = T.isOSOpenBSD();
33   if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
34     WCharType = UnsignedInt;
35
36   UseBitFieldTypeAlignment = true;
37
38   ZeroLengthBitfieldBoundary = 0;
39
40   // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
41   // so set preferred for small types to 32.
42   if (T.isOSBinFormatMachO()) {
43     resetDataLayout(BigEndian
44                         ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
45                         : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
46   } else if (T.isOSWindows()) {
47     assert(!BigEndian && "Windows on ARM does not support big endian");
48     resetDataLayout("e"
49                     "-m:w"
50                     "-p:32:32"
51                     "-i64:64"
52                     "-v128:64:128"
53                     "-a:0:32"
54                     "-n32"
55                     "-S64");
56   } else if (T.isOSNaCl()) {
57     assert(!BigEndian && "NaCl on ARM does not support big endian");
58     resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
59   } else {
60     resetDataLayout(BigEndian
61                         ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
62                         : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
63   }
64
65   // FIXME: Enumerated types are variable width in straight AAPCS.
66 }
67
68 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
69   const llvm::Triple &T = getTriple();
70
71   IsAAPCS = false;
72
73   if (IsAAPCS16)
74     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
75   else
76     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
77
78   WCharType = SignedInt;
79
80   // Do not respect the alignment of bit-field types when laying out
81   // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
82   UseBitFieldTypeAlignment = false;
83
84   /// gcc forces the alignment to 4 bytes, regardless of the type of the
85   /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
86   /// gcc.
87   ZeroLengthBitfieldBoundary = 32;
88
89   if (T.isOSBinFormatMachO() && IsAAPCS16) {
90     assert(!BigEndian && "AAPCS16 does not support big-endian");
91     resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
92   } else if (T.isOSBinFormatMachO())
93     resetDataLayout(
94         BigEndian
95             ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
96             : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
97   else
98     resetDataLayout(
99         BigEndian
100             ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
101             : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
102
103   // FIXME: Override "preferred align" for double and long long.
104 }
105
106 void ARMTargetInfo::setArchInfo() {
107   StringRef ArchName = getTriple().getArchName();
108
109   ArchISA = llvm::ARM::parseArchISA(ArchName);
110   CPU = llvm::ARM::getDefaultCPU(ArchName);
111   llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
112   if (AK != llvm::ARM::ArchKind::INVALID)
113     ArchKind = AK;
114   setArchInfo(ArchKind);
115 }
116
117 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
118   StringRef SubArch;
119
120   // cache TargetParser info
121   ArchKind = Kind;
122   SubArch = llvm::ARM::getSubArch(ArchKind);
123   ArchProfile = llvm::ARM::parseArchProfile(SubArch);
124   ArchVersion = llvm::ARM::parseArchVersion(SubArch);
125
126   // cache CPU related strings
127   CPUAttr = getCPUAttr();
128   CPUProfile = getCPUProfile();
129 }
130
131 void ARMTargetInfo::setAtomic() {
132   // when triple does not specify a sub arch,
133   // then we are not using inline atomics
134   bool ShouldUseInlineAtomic =
135       (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
136       (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
137   // Cortex M does not support 8 byte atomics, while general Thumb2 does.
138   if (ArchProfile == llvm::ARM::ProfileKind::M) {
139     MaxAtomicPromoteWidth = 32;
140     if (ShouldUseInlineAtomic)
141       MaxAtomicInlineWidth = 32;
142   } else {
143     MaxAtomicPromoteWidth = 64;
144     if (ShouldUseInlineAtomic)
145       MaxAtomicInlineWidth = 64;
146   }
147 }
148
149 bool ARMTargetInfo::isThumb() const {
150   return ArchISA == llvm::ARM::ISAKind::THUMB;
151 }
152
153 bool ARMTargetInfo::supportsThumb() const {
154   return CPUAttr.count('T') || ArchVersion >= 6;
155 }
156
157 bool ARMTargetInfo::supportsThumb2() const {
158   return CPUAttr.equals("6T2") ||
159          (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
160 }
161
162 StringRef ARMTargetInfo::getCPUAttr() const {
163   // For most sub-arches, the build attribute CPU name is enough.
164   // For Cortex variants, it's slightly different.
165   switch (ArchKind) {
166   default:
167     return llvm::ARM::getCPUAttr(ArchKind);
168   case llvm::ARM::ArchKind::ARMV6M:
169     return "6M";
170   case llvm::ARM::ArchKind::ARMV7S:
171     return "7S";
172   case llvm::ARM::ArchKind::ARMV7A:
173     return "7A";
174   case llvm::ARM::ArchKind::ARMV7R:
175     return "7R";
176   case llvm::ARM::ArchKind::ARMV7M:
177     return "7M";
178   case llvm::ARM::ArchKind::ARMV7EM:
179     return "7EM";
180   case llvm::ARM::ArchKind::ARMV7VE:
181     return "7VE";
182   case llvm::ARM::ArchKind::ARMV8A:
183     return "8A";
184   case llvm::ARM::ArchKind::ARMV8_1A:
185     return "8_1A";
186   case llvm::ARM::ArchKind::ARMV8_2A:
187     return "8_2A";
188   case llvm::ARM::ArchKind::ARMV8_3A:
189     return "8_3A";
190   case llvm::ARM::ArchKind::ARMV8_4A:
191     return "8_4A";
192   case llvm::ARM::ArchKind::ARMV8_5A:
193     return "8_5A";
194   case llvm::ARM::ArchKind::ARMV8MBaseline:
195     return "8M_BASE";
196   case llvm::ARM::ArchKind::ARMV8MMainline:
197     return "8M_MAIN";
198   case llvm::ARM::ArchKind::ARMV8R:
199     return "8R";
200   }
201 }
202
203 StringRef ARMTargetInfo::getCPUProfile() const {
204   switch (ArchProfile) {
205   case llvm::ARM::ProfileKind::A:
206     return "A";
207   case llvm::ARM::ProfileKind::R:
208     return "R";
209   case llvm::ARM::ProfileKind::M:
210     return "M";
211   default:
212     return "";
213   }
214 }
215
216 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
217                              const TargetOptions &Opts)
218     : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
219       HW_FP(0) {
220   bool IsOpenBSD = Triple.isOSOpenBSD();
221   bool IsNetBSD = Triple.isOSNetBSD();
222
223   // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
224   // environment where size_t is `unsigned long` rather than `unsigned int`
225
226   PtrDiffType = IntPtrType =
227       (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
228        IsNetBSD)
229           ? SignedLong
230           : SignedInt;
231
232   SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
233               IsNetBSD)
234                  ? UnsignedLong
235                  : UnsignedInt;
236
237   // ptrdiff_t is inconsistent on Darwin
238   if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
239       !Triple.isWatchABI())
240     PtrDiffType = SignedInt;
241
242   // Cache arch related info.
243   setArchInfo();
244
245   // {} in inline assembly are neon specifiers, not assembly variant
246   // specifiers.
247   NoAsmVariants = true;
248
249   // FIXME: This duplicates code from the driver that sets the -target-abi
250   // option - this code is used if -target-abi isn't passed and should
251   // be unified in some way.
252   if (Triple.isOSBinFormatMachO()) {
253     // The backend is hardwired to assume AAPCS for M-class processors, ensure
254     // the frontend matches that.
255     if (Triple.getEnvironment() == llvm::Triple::EABI ||
256         Triple.getOS() == llvm::Triple::UnknownOS ||
257         ArchProfile == llvm::ARM::ProfileKind::M) {
258       setABI("aapcs");
259     } else if (Triple.isWatchABI()) {
260       setABI("aapcs16");
261     } else {
262       setABI("apcs-gnu");
263     }
264   } else if (Triple.isOSWindows()) {
265     // FIXME: this is invalid for WindowsCE
266     setABI("aapcs");
267   } else {
268     // Select the default based on the platform.
269     switch (Triple.getEnvironment()) {
270     case llvm::Triple::Android:
271     case llvm::Triple::GNUEABI:
272     case llvm::Triple::GNUEABIHF:
273     case llvm::Triple::MuslEABI:
274     case llvm::Triple::MuslEABIHF:
275       setABI("aapcs-linux");
276       break;
277     case llvm::Triple::EABIHF:
278     case llvm::Triple::EABI:
279       setABI("aapcs");
280       break;
281     case llvm::Triple::GNU:
282       setABI("apcs-gnu");
283       break;
284     default:
285       if (IsNetBSD)
286         setABI("apcs-gnu");
287       else if (IsOpenBSD)
288         setABI("aapcs-linux");
289       else
290         setABI("aapcs");
291       break;
292     }
293   }
294
295   // ARM targets default to using the ARM C++ ABI.
296   TheCXXABI.set(TargetCXXABI::GenericARM);
297
298   // ARM has atomics up to 8 bytes
299   setAtomic();
300
301   // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
302   if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
303     MaxVectorAlign = 64;
304
305   // Do force alignment of members that follow zero length bitfields.  If
306   // the alignment of the zero-length bitfield is greater than the member
307   // that follows it, `bar', `bar' will be aligned as the  type of the
308   // zero length bitfield.
309   UseZeroLengthBitfieldAlignment = true;
310
311   if (Triple.getOS() == llvm::Triple::Linux ||
312       Triple.getOS() == llvm::Triple::UnknownOS)
313     this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
314                            ? "\01__gnu_mcount_nc"
315                            : "\01mcount";
316 }
317
318 StringRef ARMTargetInfo::getABI() const { return ABI; }
319
320 bool ARMTargetInfo::setABI(const std::string &Name) {
321   ABI = Name;
322
323   // The defaults (above) are for AAPCS, check if we need to change them.
324   //
325   // FIXME: We need support for -meabi... we could just mangle it into the
326   // name.
327   if (Name == "apcs-gnu" || Name == "aapcs16") {
328     setABIAPCS(Name == "aapcs16");
329     return true;
330   }
331   if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
332     setABIAAPCS();
333     return true;
334   }
335   return false;
336 }
337
338 // FIXME: This should be based on Arch attributes, not CPU names.
339 bool ARMTargetInfo::initFeatureMap(
340     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
341     const std::vector<std::string> &FeaturesVec) const {
342
343   std::string ArchFeature;
344   std::vector<StringRef> TargetFeatures;
345   llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
346
347   // Map the base architecture to an appropriate target feature, so we don't
348   // rely on the target triple.
349   llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
350   if (CPUArch == llvm::ARM::ArchKind::INVALID)
351     CPUArch = Arch;
352   if (CPUArch != llvm::ARM::ArchKind::INVALID) {
353     ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
354     TargetFeatures.push_back(ArchFeature);
355   }
356
357   // get default FPU features
358   unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
359   llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
360
361   // get default Extension features
362   unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
363   llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
364
365   for (auto Feature : TargetFeatures)
366     if (Feature[0] == '+')
367       Features[Feature.drop_front(1)] = true;
368
369   // Enable or disable thumb-mode explicitly per function to enable mixed
370   // ARM and Thumb code generation.
371   if (isThumb())
372     Features["thumb-mode"] = true;
373   else
374     Features["thumb-mode"] = false;
375
376   // Convert user-provided arm and thumb GNU target attributes to
377   // [-|+]thumb-mode target features respectively.
378   std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
379   for (auto &Feature : UpdatedFeaturesVec) {
380     if (Feature.compare("+arm") == 0)
381       Feature = "-thumb-mode";
382     else if (Feature.compare("+thumb") == 0)
383       Feature = "+thumb-mode";
384   }
385
386   return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
387 }
388
389
390 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
391                                          DiagnosticsEngine &Diags) {
392   FPU = 0;
393   CRC = 0;
394   Crypto = 0;
395   DSP = 0;
396   Unaligned = 1;
397   SoftFloat = SoftFloatABI = false;
398   HWDiv = 0;
399   DotProd = 0;
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 }