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/ADT/Triple.h"
20#include "llvm/Support/ARMTargetParser.h"
21#include "llvm/Support/ARMTargetParserCommon.h"
22#include "llvm/Support/Compiler.h"
23
24namespace clang {
25namespace targets {
26
27class 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  void setABIAAPCS();
104  void setABIAPCS(bool IsAAPCS16);
105
106  void setArchInfo();
107  void setArchInfo(llvm::ARM::ArchKind Kind);
108
109  void setAtomic();
110
111  bool isThumb() const;
112  bool supportsThumb() const;
113  bool supportsThumb2() const;
114  bool hasMVE() const;
115  bool hasMVEFloat() const;
116  bool hasCDE() const;
117
118  StringRef getCPUAttr() const;
119  StringRef getCPUProfile() const;
120
121public:
122  ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
123
124  StringRef getABI() const override;
125  bool setABI(const std::string &Name) override;
126
127  bool isBranchProtectionSupportedArch(StringRef Arch) const override;
128  bool validateBranchProtection(StringRef Spec, StringRef Arch,
129                                BranchProtectionInfo &BPI,
130                                StringRef &Err) const override;
131
132  // FIXME: This should be based on Arch attributes, not CPU names.
133  bool
134  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
135                 StringRef CPU,
136                 const std::vector<std::string> &FeaturesVec) const override;
137
138  bool isValidFeatureName(StringRef Feature) const override {
139    // We pass soft-float-abi in as a -target-feature, but the backend figures
140    // this out through other means.
141    return Feature != "soft-float-abi";
142  }
143
144  bool handleTargetFeatures(std::vector<std::string> &Features,
145                            DiagnosticsEngine &Diags) override;
146
147  bool hasFeature(StringRef Feature) const override;
148
149  bool hasBFloat16Type() const override;
150
151  bool isValidCPUName(StringRef Name) const override;
152  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
153
154  bool setCPU(const std::string &Name) override;
155
156  bool setFPMath(StringRef Name) override;
157
158  bool useFP16ConversionIntrinsics() const override {
159    return false;
160  }
161
162  void getTargetDefinesARMV81A(const LangOptions &Opts,
163                               MacroBuilder &Builder) const;
164  void getTargetDefinesARMV82A(const LangOptions &Opts,
165                               MacroBuilder &Builder) const;
166  void getTargetDefinesARMV83A(const LangOptions &Opts,
167                                 MacroBuilder &Builder) const;
168  void getTargetDefines(const LangOptions &Opts,
169                        MacroBuilder &Builder) const override;
170
171  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
172
173  bool isCLZForZeroUndef() const override;
174  BuiltinVaListKind getBuiltinVaListKind() const override;
175
176  ArrayRef<const char *> getGCCRegNames() const override;
177  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
178  bool validateAsmConstraint(const char *&Name,
179                             TargetInfo::ConstraintInfo &Info) const override;
180  std::string convertConstraint(const char *&Constraint) const override;
181  bool
182  validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
183                             std::string &SuggestedModifier) const override;
184  const char *getClobbers() const override;
185
186  StringRef getConstraintRegister(StringRef Constraint,
187                                  StringRef Expression) const override {
188    return Expression;
189  }
190
191  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
192
193  int getEHDataRegisterNumber(unsigned RegNo) const override;
194
195  bool hasSjLjLowering() const override;
196
197  bool hasBitIntType() const override { return true; }
198
199  const char *getBFloat16Mangling() const override { return "u6__bf16"; };
200};
201
202class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {
203public:
204  ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
205  void getTargetDefines(const LangOptions &Opts,
206                        MacroBuilder &Builder) const override;
207};
208
209class LLVM_LIBRARY_VISIBILITY ARMbeTargetInfo : public ARMTargetInfo {
210public:
211  ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
212  void getTargetDefines(const LangOptions &Opts,
213                        MacroBuilder &Builder) const override;
214};
215
216class LLVM_LIBRARY_VISIBILITY WindowsARMTargetInfo
217    : public WindowsTargetInfo<ARMleTargetInfo> {
218  const llvm::Triple Triple;
219
220public:
221  WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
222
223  void getVisualStudioDefines(const LangOptions &Opts,
224                              MacroBuilder &Builder) const;
225
226  BuiltinVaListKind getBuiltinVaListKind() const override;
227
228  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
229};
230
231// Windows ARM + Itanium C++ ABI Target
232class LLVM_LIBRARY_VISIBILITY ItaniumWindowsARMleTargetInfo
233    : public WindowsARMTargetInfo {
234public:
235  ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple,
236                                const TargetOptions &Opts);
237
238  void getTargetDefines(const LangOptions &Opts,
239                        MacroBuilder &Builder) const override;
240};
241
242// Windows ARM, MS (C++) ABI
243class LLVM_LIBRARY_VISIBILITY MicrosoftARMleTargetInfo
244    : public WindowsARMTargetInfo {
245public:
246  MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
247                           const TargetOptions &Opts);
248
249  void getTargetDefines(const LangOptions &Opts,
250                        MacroBuilder &Builder) const override;
251};
252
253// ARM MinGW target
254class LLVM_LIBRARY_VISIBILITY MinGWARMTargetInfo : public WindowsARMTargetInfo {
255public:
256  MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
257
258  void getTargetDefines(const LangOptions &Opts,
259                        MacroBuilder &Builder) const override;
260};
261
262// ARM Cygwin target
263class LLVM_LIBRARY_VISIBILITY CygwinARMTargetInfo : public ARMleTargetInfo {
264public:
265  CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
266
267  void getTargetDefines(const LangOptions &Opts,
268                        MacroBuilder &Builder) const override;
269};
270
271class LLVM_LIBRARY_VISIBILITY DarwinARMTargetInfo
272    : public DarwinTargetInfo<ARMleTargetInfo> {
273protected:
274  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
275                    MacroBuilder &Builder) const override;
276
277public:
278  DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
279};
280
281// 32-bit RenderScript is armv7 with width and align of 'long' set to 8-bytes
282class LLVM_LIBRARY_VISIBILITY RenderScript32TargetInfo
283    : public ARMleTargetInfo {
284public:
285  RenderScript32TargetInfo(const llvm::Triple &Triple,
286                           const TargetOptions &Opts);
287
288  void getTargetDefines(const LangOptions &Opts,
289                        MacroBuilder &Builder) const override;
290};
291
292} // namespace targets
293} // namespace clang
294
295#endif // LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H
296