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