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