xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
FPUModeIsVFP(FPUMode Mode)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   LLVM_PREFERRED_TYPE(FPUMode)
65   unsigned FPU : 5;
66   LLVM_PREFERRED_TYPE(MVEMode)
67   unsigned MVE : 2;
68 
69   LLVM_PREFERRED_TYPE(bool)
70   unsigned IsAAPCS : 1;
71   LLVM_PREFERRED_TYPE(HWDivMode)
72   unsigned HWDiv : 2;
73 
74   // Initialized via features.
75   LLVM_PREFERRED_TYPE(bool)
76   unsigned SoftFloat : 1;
77   LLVM_PREFERRED_TYPE(bool)
78   unsigned SoftFloatABI : 1;
79 
80   LLVM_PREFERRED_TYPE(bool)
81   unsigned CRC : 1;
82   LLVM_PREFERRED_TYPE(bool)
83   unsigned Crypto : 1;
84   LLVM_PREFERRED_TYPE(bool)
85   unsigned SHA2 : 1;
86   LLVM_PREFERRED_TYPE(bool)
87   unsigned AES : 1;
88   LLVM_PREFERRED_TYPE(bool)
89   unsigned DSP : 1;
90   LLVM_PREFERRED_TYPE(bool)
91   unsigned DotProd : 1;
92   LLVM_PREFERRED_TYPE(bool)
93   unsigned HasMatMul : 1;
94   LLVM_PREFERRED_TYPE(bool)
95   unsigned FPRegsDisabled : 1;
96   LLVM_PREFERRED_TYPE(bool)
97   unsigned HasPAC : 1;
98   LLVM_PREFERRED_TYPE(bool)
99   unsigned HasBTI : 1;
100 
101   enum {
102     LDREX_B = (1 << 0), /// byte (8-bit)
103     LDREX_H = (1 << 1), /// half (16-bit)
104     LDREX_W = (1 << 2), /// word (32-bit)
105     LDREX_D = (1 << 3), /// double (64-bit)
106   };
107 
108   uint32_t LDREX;
109 
110   // ACLE 6.5.1 Hardware floating point
111   enum {
112     HW_FP_HP = (1 << 1), /// half (16-bit)
113     HW_FP_SP = (1 << 2), /// single (32-bit)
114     HW_FP_DP = (1 << 3), /// double (64-bit)
115   };
116   uint32_t HW_FP;
117 
118   enum {
119     /// __arm_cdp __arm_ldc, __arm_ldcl, __arm_stc,
120     /// __arm_stcl, __arm_mcr and __arm_mrc
121     FEATURE_COPROC_B1 = (1 << 0),
122     /// __arm_cdp2, __arm_ldc2, __arm_stc2, __arm_ldc2l,
123     /// __arm_stc2l, __arm_mcr2 and __arm_mrc2
124     FEATURE_COPROC_B2 = (1 << 1),
125     /// __arm_mcrr, __arm_mrrc
126     FEATURE_COPROC_B3 = (1 << 2),
127     /// __arm_mcrr2,  __arm_mrrc2
128     FEATURE_COPROC_B4 = (1 << 3),
129   };
130 
131   void setABIAAPCS();
132   void setABIAPCS(bool IsAAPCS16);
133 
134   void setArchInfo();
135   void setArchInfo(llvm::ARM::ArchKind Kind);
136 
137   void setAtomic();
138 
139   bool isThumb() const;
140   bool supportsThumb() const;
141   bool supportsThumb2() const;
142   bool hasMVE() const;
143   bool hasMVEFloat() const;
144   bool hasCDE() const;
145 
146   StringRef getCPUAttr() const;
147   StringRef getCPUProfile() const;
148 
149 public:
150   ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
151 
152   StringRef getABI() const override;
153   bool setABI(const std::string &Name) override;
154 
155   bool isBranchProtectionSupportedArch(StringRef Arch) const override;
156   bool validateBranchProtection(StringRef Spec, StringRef Arch,
157                                 BranchProtectionInfo &BPI,
158                                 const LangOptions &LO,
159                                 StringRef &Err) const override;
160 
161   // FIXME: This should be based on Arch attributes, not CPU names.
162   bool
163   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
164                  StringRef CPU,
165                  const std::vector<std::string> &FeaturesVec) const override;
166 
isValidFeatureName(StringRef Feature)167   bool isValidFeatureName(StringRef Feature) const override {
168     // We pass soft-float-abi in as a -target-feature, but the backend figures
169     // this out through other means.
170     return Feature != "soft-float-abi";
171   }
172 
173   bool handleTargetFeatures(std::vector<std::string> &Features,
174                             DiagnosticsEngine &Diags) override;
175 
176   bool hasFeature(StringRef Feature) const override;
177 
178   bool hasBFloat16Type() const override;
179 
180   bool isValidCPUName(StringRef Name) const override;
181   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
182 
183   bool setCPU(const std::string &Name) override;
184 
185   bool setFPMath(StringRef Name) override;
186 
useFP16ConversionIntrinsics()187   bool useFP16ConversionIntrinsics() const override {
188     return false;
189   }
190 
191   void getTargetDefinesARMV81A(const LangOptions &Opts,
192                                MacroBuilder &Builder) const;
193   void getTargetDefinesARMV82A(const LangOptions &Opts,
194                                MacroBuilder &Builder) const;
195   void getTargetDefinesARMV83A(const LangOptions &Opts,
196                                  MacroBuilder &Builder) const;
197   void getTargetDefines(const LangOptions &Opts,
198                         MacroBuilder &Builder) const override;
199 
200   llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
201 
202   bool isCLZForZeroUndef() const override;
203   BuiltinVaListKind getBuiltinVaListKind() const override;
204 
205   ArrayRef<const char *> getGCCRegNames() const override;
206   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
207   bool validateAsmConstraint(const char *&Name,
208                              TargetInfo::ConstraintInfo &Info) const override;
209   std::string convertConstraint(const char *&Constraint) const override;
210   bool
211   validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
212                              std::string &SuggestedModifier) const override;
213   std::string_view getClobbers() const override;
214 
getConstraintRegister(StringRef Constraint,StringRef Expression)215   StringRef getConstraintRegister(StringRef Constraint,
216                                   StringRef Expression) const override {
217     return Expression;
218   }
219 
220   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
221 
222   int getEHDataRegisterNumber(unsigned RegNo) const override;
223 
224   bool hasSjLjLowering() const override;
225 
hasBitIntType()226   bool hasBitIntType() const override { return true; }
227 
getBFloat16Mangling()228   const char *getBFloat16Mangling() const override { return "u6__bf16"; };
229 
hardwareInterferenceSizes()230   std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
231     return std::make_pair(64, 64);
232   }
233 };
234 
235 class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {
236 public:
237   ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
238   void getTargetDefines(const LangOptions &Opts,
239                         MacroBuilder &Builder) const override;
240 };
241 
242 class LLVM_LIBRARY_VISIBILITY ARMbeTargetInfo : public ARMTargetInfo {
243 public:
244   ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
245   void getTargetDefines(const LangOptions &Opts,
246                         MacroBuilder &Builder) const override;
247 };
248 
249 class LLVM_LIBRARY_VISIBILITY WindowsARMTargetInfo
250     : public WindowsTargetInfo<ARMleTargetInfo> {
251   const llvm::Triple Triple;
252 
253 public:
254   WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
255 
256   void getVisualStudioDefines(const LangOptions &Opts,
257                               MacroBuilder &Builder) const;
258 
259   BuiltinVaListKind getBuiltinVaListKind() const override;
260 
261   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
262 };
263 
264 // Windows ARM + Itanium C++ ABI Target
265 class LLVM_LIBRARY_VISIBILITY ItaniumWindowsARMleTargetInfo
266     : public WindowsARMTargetInfo {
267 public:
268   ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple,
269                                 const TargetOptions &Opts);
270 
271   void getTargetDefines(const LangOptions &Opts,
272                         MacroBuilder &Builder) const override;
273 };
274 
275 // Windows ARM, MS (C++) ABI
276 class LLVM_LIBRARY_VISIBILITY MicrosoftARMleTargetInfo
277     : public WindowsARMTargetInfo {
278 public:
279   MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
280                            const TargetOptions &Opts);
281 
282   void getTargetDefines(const LangOptions &Opts,
283                         MacroBuilder &Builder) const override;
284 };
285 
286 // ARM MinGW target
287 class LLVM_LIBRARY_VISIBILITY MinGWARMTargetInfo : public WindowsARMTargetInfo {
288 public:
289   MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
290 
291   void getTargetDefines(const LangOptions &Opts,
292                         MacroBuilder &Builder) const override;
293 };
294 
295 // ARM Cygwin target
296 class LLVM_LIBRARY_VISIBILITY CygwinARMTargetInfo : public ARMleTargetInfo {
297 public:
298   CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
299 
300   void getTargetDefines(const LangOptions &Opts,
301                         MacroBuilder &Builder) const override;
302 };
303 
304 class LLVM_LIBRARY_VISIBILITY AppleMachOARMTargetInfo
305     : public AppleMachOTargetInfo<ARMleTargetInfo> {
306 protected:
307   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
308                     MacroBuilder &Builder) const override;
309 
310 public:
311   AppleMachOARMTargetInfo(const llvm::Triple &Triple,
312                           const TargetOptions &Opts);
313 };
314 
315 class LLVM_LIBRARY_VISIBILITY DarwinARMTargetInfo
316     : public DarwinTargetInfo<ARMleTargetInfo> {
317 protected:
318   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
319                     MacroBuilder &Builder) const override;
320 
321 public:
322   DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
323 };
324 
325 } // namespace targets
326 } // namespace clang
327 
328 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H
329