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