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