1 //===--- ARM.h - Declare ARM target feature support -------------*- C++ -*-===//
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 declares ARM TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H
15 
16 #include "OSTargets.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "clang/Basic/TargetOptions.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/TargetParser/ARMTargetParser.h"
21 #include "llvm/TargetParser/ARMTargetParserCommon.h"
22 #include "llvm/TargetParser/Triple.h"
23 
24 namespace clang {
25 namespace targets {
26 
27 class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
28   // Possible FPU choices.
29   enum FPUMode {
30     VFP2FPU = (1 << 0),
31     VFP3FPU = (1 << 1),
32     VFP4FPU = (1 << 2),
33     NeonFPU = (1 << 3),
34     FPARMV8 = (1 << 4)
35   };
36 
37   enum MVEMode {
38       MVE_INT = (1 << 0),
39       MVE_FP  = (1 << 1)
40   };
41 
42   // Possible HWDiv features.
43   enum HWDivMode { HWDivThumb = (1 << 0), HWDivARM = (1 << 1) };
44 
45   static bool FPUModeIsVFP(FPUMode Mode) {
46     return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU | FPARMV8);
47   }
48 
49   static const TargetInfo::GCCRegAlias GCCRegAliases[];
50   static const char *const GCCRegNames[];
51 
52   std::string ABI, CPU;
53 
54   StringRef CPUProfile;
55   StringRef CPUAttr;
56 
57   enum { FP_Default, FP_VFP, FP_Neon } FPMath;
58 
59   llvm::ARM::ISAKind ArchISA;
60   llvm::ARM::ArchKind ArchKind = llvm::ARM::ArchKind::ARMV4T;
61   llvm::ARM::ProfileKind ArchProfile;
62   unsigned ArchVersion;
63 
64   unsigned FPU : 5;
65   unsigned MVE : 2;
66 
67   unsigned IsAAPCS : 1;
68   unsigned HWDiv : 2;
69 
70   // Initialized via features.
71   unsigned SoftFloat : 1;
72   unsigned SoftFloatABI : 1;
73 
74   unsigned CRC : 1;
75   unsigned Crypto : 1;
76   unsigned SHA2 : 1;
77   unsigned AES : 1;
78   unsigned DSP : 1;
79   unsigned Unaligned : 1;
80   unsigned DotProd : 1;
81   unsigned HasMatMul : 1;
82   unsigned FPRegsDisabled : 1;
83   unsigned HasPAC : 1;
84   unsigned HasBTI : 1;
85 
86   enum {
87     LDREX_B = (1 << 0), /// byte (8-bit)
88     LDREX_H = (1 << 1), /// half (16-bit)
89     LDREX_W = (1 << 2), /// word (32-bit)
90     LDREX_D = (1 << 3), /// double (64-bit)
91   };
92 
93   uint32_t LDREX;
94 
95   // ACLE 6.5.1 Hardware floating point
96   enum {
97     HW_FP_HP = (1 << 1), /// half (16-bit)
98     HW_FP_SP = (1 << 2), /// single (32-bit)
99     HW_FP_DP = (1 << 3), /// double (64-bit)
100   };
101   uint32_t HW_FP;
102 
103   enum {
104     /// __arm_cdp __arm_ldc, __arm_ldcl, __arm_stc,
105     /// __arm_stcl, __arm_mcr and __arm_mrc
106     FEATURE_COPROC_B1 = (1 << 0),
107     /// __arm_cdp2, __arm_ldc2, __arm_stc2, __arm_ldc2l,
108     /// __arm_stc2l, __arm_mcr2 and __arm_mrc2
109     FEATURE_COPROC_B2 = (1 << 1),
110     /// __arm_mcrr, __arm_mrrc
111     FEATURE_COPROC_B3 = (1 << 2),
112     /// __arm_mcrr2,  __arm_mrrc2
113     FEATURE_COPROC_B4 = (1 << 3),
114   };
115 
116   void setABIAAPCS();
117   void setABIAPCS(bool IsAAPCS16);
118 
119   void setArchInfo();
120   void setArchInfo(llvm::ARM::ArchKind Kind);
121 
122   void setAtomic();
123 
124   bool isThumb() const;
125   bool supportsThumb() const;
126   bool supportsThumb2() const;
127   bool hasMVE() const;
128   bool hasMVEFloat() const;
129   bool hasCDE() const;
130 
131   StringRef getCPUAttr() const;
132   StringRef getCPUProfile() const;
133 
134 public:
135   ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
136 
137   StringRef getABI() const override;
138   bool setABI(const std::string &Name) override;
139 
140   bool isBranchProtectionSupportedArch(StringRef Arch) const override;
141   bool validateBranchProtection(StringRef Spec, StringRef Arch,
142                                 BranchProtectionInfo &BPI,
143                                 StringRef &Err) const override;
144 
145   // FIXME: This should be based on Arch attributes, not CPU names.
146   bool
147   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
148                  StringRef CPU,
149                  const std::vector<std::string> &FeaturesVec) const override;
150 
151   bool isValidFeatureName(StringRef Feature) const override {
152     // We pass soft-float-abi in as a -target-feature, but the backend figures
153     // this out through other means.
154     return Feature != "soft-float-abi";
155   }
156 
157   bool handleTargetFeatures(std::vector<std::string> &Features,
158                             DiagnosticsEngine &Diags) override;
159 
160   bool hasFeature(StringRef Feature) const override;
161 
162   bool hasBFloat16Type() const override;
163 
164   bool isValidCPUName(StringRef Name) const override;
165   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
166 
167   bool setCPU(const std::string &Name) override;
168 
169   bool setFPMath(StringRef Name) override;
170 
171   bool useFP16ConversionIntrinsics() const override {
172     return false;
173   }
174 
175   void getTargetDefinesARMV81A(const LangOptions &Opts,
176                                MacroBuilder &Builder) const;
177   void getTargetDefinesARMV82A(const LangOptions &Opts,
178                                MacroBuilder &Builder) const;
179   void getTargetDefinesARMV83A(const LangOptions &Opts,
180                                  MacroBuilder &Builder) const;
181   void getTargetDefines(const LangOptions &Opts,
182                         MacroBuilder &Builder) const override;
183 
184   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
185 
186   bool isCLZForZeroUndef() const override;
187   BuiltinVaListKind getBuiltinVaListKind() const override;
188 
189   ArrayRef<const char *> getGCCRegNames() const override;
190   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
191   bool validateAsmConstraint(const char *&Name,
192                              TargetInfo::ConstraintInfo &Info) const override;
193   std::string convertConstraint(const char *&Constraint) const override;
194   bool
195   validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
196                              std::string &SuggestedModifier) const override;
197   std::string_view getClobbers() const override;
198 
199   StringRef getConstraintRegister(StringRef Constraint,
200                                   StringRef Expression) const override {
201     return Expression;
202   }
203 
204   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
205 
206   int getEHDataRegisterNumber(unsigned RegNo) const override;
207 
208   bool hasSjLjLowering() const override;
209 
210   bool hasBitIntType() const override { return true; }
211 
212   const char *getBFloat16Mangling() const override { return "u6__bf16"; };
213 };
214 
215 class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {
216 public:
217   ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
218   void getTargetDefines(const LangOptions &Opts,
219                         MacroBuilder &Builder) const override;
220 };
221 
222 class LLVM_LIBRARY_VISIBILITY ARMbeTargetInfo : public ARMTargetInfo {
223 public:
224   ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
225   void getTargetDefines(const LangOptions &Opts,
226                         MacroBuilder &Builder) const override;
227 };
228 
229 class LLVM_LIBRARY_VISIBILITY WindowsARMTargetInfo
230     : public WindowsTargetInfo<ARMleTargetInfo> {
231   const llvm::Triple Triple;
232 
233 public:
234   WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
235 
236   void getVisualStudioDefines(const LangOptions &Opts,
237                               MacroBuilder &Builder) const;
238 
239   BuiltinVaListKind getBuiltinVaListKind() const override;
240 
241   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
242 };
243 
244 // Windows ARM + Itanium C++ ABI Target
245 class LLVM_LIBRARY_VISIBILITY ItaniumWindowsARMleTargetInfo
246     : public WindowsARMTargetInfo {
247 public:
248   ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple,
249                                 const TargetOptions &Opts);
250 
251   void getTargetDefines(const LangOptions &Opts,
252                         MacroBuilder &Builder) const override;
253 };
254 
255 // Windows ARM, MS (C++) ABI
256 class LLVM_LIBRARY_VISIBILITY MicrosoftARMleTargetInfo
257     : public WindowsARMTargetInfo {
258 public:
259   MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
260                            const TargetOptions &Opts);
261 
262   void getTargetDefines(const LangOptions &Opts,
263                         MacroBuilder &Builder) const override;
264 };
265 
266 // ARM MinGW target
267 class LLVM_LIBRARY_VISIBILITY MinGWARMTargetInfo : public WindowsARMTargetInfo {
268 public:
269   MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
270 
271   void getTargetDefines(const LangOptions &Opts,
272                         MacroBuilder &Builder) const override;
273 };
274 
275 // ARM Cygwin target
276 class LLVM_LIBRARY_VISIBILITY CygwinARMTargetInfo : public ARMleTargetInfo {
277 public:
278   CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
279 
280   void getTargetDefines(const LangOptions &Opts,
281                         MacroBuilder &Builder) const override;
282 };
283 
284 class LLVM_LIBRARY_VISIBILITY DarwinARMTargetInfo
285     : public DarwinTargetInfo<ARMleTargetInfo> {
286 protected:
287   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
288                     MacroBuilder &Builder) const override;
289 
290 public:
291   DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
292 };
293 
294 // 32-bit RenderScript is armv7 with width and align of 'long' set to 8-bytes
295 class LLVM_LIBRARY_VISIBILITY RenderScript32TargetInfo
296     : public ARMleTargetInfo {
297 public:
298   RenderScript32TargetInfo(const llvm::Triple &Triple,
299                            const TargetOptions &Opts);
300 
301   void getTargetDefines(const LangOptions &Opts,
302                         MacroBuilder &Builder) const override;
303 };
304 
305 } // namespace targets
306 } // namespace clang
307 
308 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H
309