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