xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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                                 StringRef &Err) const override;
159 
160   // FIXME: This should be based on Arch attributes, not CPU names.
161   bool
162   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
163                  StringRef CPU,
164                  const std::vector<std::string> &FeaturesVec) const override;
165 
isValidFeatureName(StringRef Feature)166   bool isValidFeatureName(StringRef Feature) const override {
167     // We pass soft-float-abi in as a -target-feature, but the backend figures
168     // this out through other means.
169     return Feature != "soft-float-abi";
170   }
171 
172   bool handleTargetFeatures(std::vector<std::string> &Features,
173                             DiagnosticsEngine &Diags) override;
174 
175   bool hasFeature(StringRef Feature) const override;
176 
177   bool hasBFloat16Type() const override;
178 
179   bool isValidCPUName(StringRef Name) const override;
180   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
181 
182   bool setCPU(const std::string &Name) override;
183 
184   bool setFPMath(StringRef Name) override;
185 
useFP16ConversionIntrinsics()186   bool useFP16ConversionIntrinsics() const override {
187     return false;
188   }
189 
190   void getTargetDefinesARMV81A(const LangOptions &Opts,
191                                MacroBuilder &Builder) const;
192   void getTargetDefinesARMV82A(const LangOptions &Opts,
193                                MacroBuilder &Builder) const;
194   void getTargetDefinesARMV83A(const LangOptions &Opts,
195                                  MacroBuilder &Builder) const;
196   void getTargetDefines(const LangOptions &Opts,
197                         MacroBuilder &Builder) const override;
198 
199   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
200 
201   bool isCLZForZeroUndef() const override;
202   BuiltinVaListKind getBuiltinVaListKind() const override;
203 
204   ArrayRef<const char *> getGCCRegNames() const override;
205   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
206   bool validateAsmConstraint(const char *&Name,
207                              TargetInfo::ConstraintInfo &Info) const override;
208   std::string convertConstraint(const char *&Constraint) const override;
209   bool
210   validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
211                              std::string &SuggestedModifier) const override;
212   std::string_view getClobbers() const override;
213 
getConstraintRegister(StringRef Constraint,StringRef Expression)214   StringRef getConstraintRegister(StringRef Constraint,
215                                   StringRef Expression) const override {
216     return Expression;
217   }
218 
219   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
220 
221   int getEHDataRegisterNumber(unsigned RegNo) const override;
222 
223   bool hasSjLjLowering() const override;
224 
hasBitIntType()225   bool hasBitIntType() const override { return true; }
226 
getBFloat16Mangling()227   const char *getBFloat16Mangling() const override { return "u6__bf16"; };
228 
hardwareInterferenceSizes()229   std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
230     return std::make_pair(getTriple().isArch64Bit() ? 256 : 64, 64);
231   }
232 };
233 
234 class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {
235 public:
236   ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
237   void getTargetDefines(const LangOptions &Opts,
238                         MacroBuilder &Builder) const override;
239 };
240 
241 class LLVM_LIBRARY_VISIBILITY ARMbeTargetInfo : public ARMTargetInfo {
242 public:
243   ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
244   void getTargetDefines(const LangOptions &Opts,
245                         MacroBuilder &Builder) const override;
246 };
247 
248 class LLVM_LIBRARY_VISIBILITY WindowsARMTargetInfo
249     : public WindowsTargetInfo<ARMleTargetInfo> {
250   const llvm::Triple Triple;
251 
252 public:
253   WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
254 
255   void getVisualStudioDefines(const LangOptions &Opts,
256                               MacroBuilder &Builder) const;
257 
258   BuiltinVaListKind getBuiltinVaListKind() const override;
259 
260   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
261 };
262 
263 // Windows ARM + Itanium C++ ABI Target
264 class LLVM_LIBRARY_VISIBILITY ItaniumWindowsARMleTargetInfo
265     : public WindowsARMTargetInfo {
266 public:
267   ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple,
268                                 const TargetOptions &Opts);
269 
270   void getTargetDefines(const LangOptions &Opts,
271                         MacroBuilder &Builder) const override;
272 };
273 
274 // Windows ARM, MS (C++) ABI
275 class LLVM_LIBRARY_VISIBILITY MicrosoftARMleTargetInfo
276     : public WindowsARMTargetInfo {
277 public:
278   MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
279                            const TargetOptions &Opts);
280 
281   void getTargetDefines(const LangOptions &Opts,
282                         MacroBuilder &Builder) const override;
283 };
284 
285 // ARM MinGW target
286 class LLVM_LIBRARY_VISIBILITY MinGWARMTargetInfo : public WindowsARMTargetInfo {
287 public:
288   MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
289 
290   void getTargetDefines(const LangOptions &Opts,
291                         MacroBuilder &Builder) const override;
292 };
293 
294 // ARM Cygwin target
295 class LLVM_LIBRARY_VISIBILITY CygwinARMTargetInfo : public ARMleTargetInfo {
296 public:
297   CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
298 
299   void getTargetDefines(const LangOptions &Opts,
300                         MacroBuilder &Builder) const override;
301 };
302 
303 class LLVM_LIBRARY_VISIBILITY DarwinARMTargetInfo
304     : public DarwinTargetInfo<ARMleTargetInfo> {
305 protected:
306   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
307                     MacroBuilder &Builder) const override;
308 
309 public:
310   DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
311 };
312 
313 // 32-bit RenderScript is armv7 with width and align of 'long' set to 8-bytes
314 class LLVM_LIBRARY_VISIBILITY RenderScript32TargetInfo
315     : public ARMleTargetInfo {
316 public:
317   RenderScript32TargetInfo(const llvm::Triple &Triple,
318                            const TargetOptions &Opts);
319 
320   void getTargetDefines(const LangOptions &Opts,
321                         MacroBuilder &Builder) const override;
322 };
323 
324 } // namespace targets
325 } // namespace clang
326 
327 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H
328