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