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