10b57cec5SDimitry Andric //===--- ARM.h - Declare ARM target feature support -------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares ARM TargetInfo objects. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "OSTargets.h" 170b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 180b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 19bdd1243dSDimitry Andric #include "llvm/Support/Compiler.h" 2006c3fb27SDimitry Andric #include "llvm/TargetParser/ARMTargetParser.h" 2106c3fb27SDimitry Andric #include "llvm/TargetParser/ARMTargetParserCommon.h" 2206c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace clang { 250b57cec5SDimitry Andric namespace targets { 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { 280b57cec5SDimitry Andric // Possible FPU choices. 290b57cec5SDimitry Andric enum FPUMode { 300b57cec5SDimitry Andric VFP2FPU = (1 << 0), 310b57cec5SDimitry Andric VFP3FPU = (1 << 1), 320b57cec5SDimitry Andric VFP4FPU = (1 << 2), 330b57cec5SDimitry Andric NeonFPU = (1 << 3), 340b57cec5SDimitry Andric FPARMV8 = (1 << 4) 350b57cec5SDimitry Andric }; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric enum MVEMode { 380b57cec5SDimitry Andric MVE_INT = (1 << 0), 390b57cec5SDimitry Andric MVE_FP = (1 << 1) 400b57cec5SDimitry Andric }; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric // Possible HWDiv features. 430b57cec5SDimitry Andric enum HWDivMode { HWDivThumb = (1 << 0), HWDivARM = (1 << 1) }; 440b57cec5SDimitry Andric FPUModeIsVFP(FPUMode Mode)450b57cec5SDimitry Andric static bool FPUModeIsVFP(FPUMode Mode) { 460b57cec5SDimitry Andric return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU | FPARMV8); 470b57cec5SDimitry Andric } 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric static const TargetInfo::GCCRegAlias GCCRegAliases[]; 500b57cec5SDimitry Andric static const char *const GCCRegNames[]; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric std::string ABI, CPU; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric StringRef CPUProfile; 550b57cec5SDimitry Andric StringRef CPUAttr; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric enum { FP_Default, FP_VFP, FP_Neon } FPMath; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric llvm::ARM::ISAKind ArchISA; 600b57cec5SDimitry Andric llvm::ARM::ArchKind ArchKind = llvm::ARM::ArchKind::ARMV4T; 610b57cec5SDimitry Andric llvm::ARM::ProfileKind ArchProfile; 620b57cec5SDimitry Andric unsigned ArchVersion; 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric unsigned FPU : 5; 650b57cec5SDimitry Andric unsigned MVE : 2; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric unsigned IsAAPCS : 1; 680b57cec5SDimitry Andric unsigned HWDiv : 2; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric // Initialized via features. 710b57cec5SDimitry Andric unsigned SoftFloat : 1; 720b57cec5SDimitry Andric unsigned SoftFloatABI : 1; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric unsigned CRC : 1; 750b57cec5SDimitry Andric unsigned Crypto : 1; 76fe6060f1SDimitry Andric unsigned SHA2 : 1; 77fe6060f1SDimitry Andric unsigned AES : 1; 780b57cec5SDimitry Andric unsigned DSP : 1; 790b57cec5SDimitry Andric unsigned Unaligned : 1; 800b57cec5SDimitry Andric unsigned DotProd : 1; 815ffd83dbSDimitry Andric unsigned HasMatMul : 1; 82349cc55cSDimitry Andric unsigned FPRegsDisabled : 1; 830eae32dcSDimitry Andric unsigned HasPAC : 1; 840eae32dcSDimitry Andric unsigned HasBTI : 1; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric enum { 870b57cec5SDimitry Andric LDREX_B = (1 << 0), /// byte (8-bit) 880b57cec5SDimitry Andric LDREX_H = (1 << 1), /// half (16-bit) 890b57cec5SDimitry Andric LDREX_W = (1 << 2), /// word (32-bit) 900b57cec5SDimitry Andric LDREX_D = (1 << 3), /// double (64-bit) 910b57cec5SDimitry Andric }; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric uint32_t LDREX; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric // ACLE 6.5.1 Hardware floating point 960b57cec5SDimitry Andric enum { 970b57cec5SDimitry Andric HW_FP_HP = (1 << 1), /// half (16-bit) 980b57cec5SDimitry Andric HW_FP_SP = (1 << 2), /// single (32-bit) 990b57cec5SDimitry Andric HW_FP_DP = (1 << 3), /// double (64-bit) 1000b57cec5SDimitry Andric }; 1010b57cec5SDimitry Andric uint32_t HW_FP; 1020b57cec5SDimitry Andric 1031db9f3b2SDimitry Andric enum { 1041db9f3b2SDimitry Andric /// __arm_cdp __arm_ldc, __arm_ldcl, __arm_stc, 1051db9f3b2SDimitry Andric /// __arm_stcl, __arm_mcr and __arm_mrc 1061db9f3b2SDimitry Andric FEATURE_COPROC_B1 = (1 << 0), 1071db9f3b2SDimitry Andric /// __arm_cdp2, __arm_ldc2, __arm_stc2, __arm_ldc2l, 1081db9f3b2SDimitry Andric /// __arm_stc2l, __arm_mcr2 and __arm_mrc2 1091db9f3b2SDimitry Andric FEATURE_COPROC_B2 = (1 << 1), 1101db9f3b2SDimitry Andric /// __arm_mcrr, __arm_mrrc 1111db9f3b2SDimitry Andric FEATURE_COPROC_B3 = (1 << 2), 1121db9f3b2SDimitry Andric /// __arm_mcrr2, __arm_mrrc2 1131db9f3b2SDimitry Andric FEATURE_COPROC_B4 = (1 << 3), 1141db9f3b2SDimitry Andric }; 1151db9f3b2SDimitry Andric 1160b57cec5SDimitry Andric void setABIAAPCS(); 1170b57cec5SDimitry Andric void setABIAPCS(bool IsAAPCS16); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric void setArchInfo(); 1200b57cec5SDimitry Andric void setArchInfo(llvm::ARM::ArchKind Kind); 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric void setAtomic(); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric bool isThumb() const; 1250b57cec5SDimitry Andric bool supportsThumb() const; 1260b57cec5SDimitry Andric bool supportsThumb2() const; 1270b57cec5SDimitry Andric bool hasMVE() const; 1280b57cec5SDimitry Andric bool hasMVEFloat() const; 1295ffd83dbSDimitry Andric bool hasCDE() const; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric StringRef getCPUAttr() const; 1320b57cec5SDimitry Andric StringRef getCPUProfile() const; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric public: 1350b57cec5SDimitry Andric ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric StringRef getABI() const override; 1380b57cec5SDimitry Andric bool setABI(const std::string &Name) override; 1390b57cec5SDimitry Andric 1401fd87a68SDimitry Andric bool isBranchProtectionSupportedArch(StringRef Arch) const override; 1411fd87a68SDimitry Andric bool validateBranchProtection(StringRef Spec, StringRef Arch, 1421fd87a68SDimitry Andric BranchProtectionInfo &BPI, 1431fd87a68SDimitry Andric StringRef &Err) const override; 1444824e7fdSDimitry Andric 1450b57cec5SDimitry Andric // FIXME: This should be based on Arch attributes, not CPU names. 1460b57cec5SDimitry Andric bool 1470b57cec5SDimitry Andric initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 1480b57cec5SDimitry Andric StringRef CPU, 1490b57cec5SDimitry Andric const std::vector<std::string> &FeaturesVec) const override; 1500b57cec5SDimitry Andric isValidFeatureName(StringRef Feature)1510b57cec5SDimitry Andric bool isValidFeatureName(StringRef Feature) const override { 1520b57cec5SDimitry Andric // We pass soft-float-abi in as a -target-feature, but the backend figures 1530b57cec5SDimitry Andric // this out through other means. 1540b57cec5SDimitry Andric return Feature != "soft-float-abi"; 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 1580b57cec5SDimitry Andric DiagnosticsEngine &Diags) override; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const override; 1610b57cec5SDimitry Andric 1625ffd83dbSDimitry Andric bool hasBFloat16Type() const override; 1635ffd83dbSDimitry Andric 1640b57cec5SDimitry Andric bool isValidCPUName(StringRef Name) const override; 1650b57cec5SDimitry Andric void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric bool setCPU(const std::string &Name) override; 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric bool setFPMath(StringRef Name) override; 1700b57cec5SDimitry Andric useFP16ConversionIntrinsics()1710b57cec5SDimitry Andric bool useFP16ConversionIntrinsics() const override { 1720b57cec5SDimitry Andric return false; 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric void getTargetDefinesARMV81A(const LangOptions &Opts, 1760b57cec5SDimitry Andric MacroBuilder &Builder) const; 1770b57cec5SDimitry Andric void getTargetDefinesARMV82A(const LangOptions &Opts, 1780b57cec5SDimitry Andric MacroBuilder &Builder) const; 179480093f4SDimitry Andric void getTargetDefinesARMV83A(const LangOptions &Opts, 180480093f4SDimitry Andric MacroBuilder &Builder) const; 1810b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 1820b57cec5SDimitry Andric MacroBuilder &Builder) const override; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric bool isCLZForZeroUndef() const override; 1870b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override; 1900b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; 1910b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 1920b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Info) const override; 1930b57cec5SDimitry Andric std::string convertConstraint(const char *&Constraint) const override; 1940b57cec5SDimitry Andric bool 1950b57cec5SDimitry Andric validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size, 1960b57cec5SDimitry Andric std::string &SuggestedModifier) const override; 19706c3fb27SDimitry Andric std::string_view getClobbers() const override; 1980b57cec5SDimitry Andric getConstraintRegister(StringRef Constraint,StringRef Expression)1990b57cec5SDimitry Andric StringRef getConstraintRegister(StringRef Constraint, 2000b57cec5SDimitry Andric StringRef Expression) const override { 2010b57cec5SDimitry Andric return Expression; 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric int getEHDataRegisterNumber(unsigned RegNo) const override; 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric bool hasSjLjLowering() const override; 2095ffd83dbSDimitry Andric hasBitIntType()2100eae32dcSDimitry Andric bool hasBitIntType() const override { return true; } 2115ffd83dbSDimitry Andric getBFloat16Mangling()2125ffd83dbSDimitry Andric const char *getBFloat16Mangling() const override { return "u6__bf16"; }; 2130b57cec5SDimitry Andric }; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo { 2160b57cec5SDimitry Andric public: 2170b57cec5SDimitry Andric ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2180b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2190b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2200b57cec5SDimitry Andric }; 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY ARMbeTargetInfo : public ARMTargetInfo { 2230b57cec5SDimitry Andric public: 2240b57cec5SDimitry Andric ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2250b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2260b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2270b57cec5SDimitry Andric }; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WindowsARMTargetInfo 2300b57cec5SDimitry Andric : public WindowsTargetInfo<ARMleTargetInfo> { 2310b57cec5SDimitry Andric const llvm::Triple Triple; 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric public: 2340b57cec5SDimitry Andric WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric void getVisualStudioDefines(const LangOptions &Opts, 2370b57cec5SDimitry Andric MacroBuilder &Builder) const; 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override; 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; 2420b57cec5SDimitry Andric }; 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric // Windows ARM + Itanium C++ ABI Target 2450b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY ItaniumWindowsARMleTargetInfo 2460b57cec5SDimitry Andric : public WindowsARMTargetInfo { 2470b57cec5SDimitry Andric public: 2480b57cec5SDimitry Andric ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple, 2490b57cec5SDimitry Andric const TargetOptions &Opts); 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2520b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2530b57cec5SDimitry Andric }; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric // Windows ARM, MS (C++) ABI 2560b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MicrosoftARMleTargetInfo 2570b57cec5SDimitry Andric : public WindowsARMTargetInfo { 2580b57cec5SDimitry Andric public: 2590b57cec5SDimitry Andric MicrosoftARMleTargetInfo(const llvm::Triple &Triple, 2600b57cec5SDimitry Andric const TargetOptions &Opts); 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2630b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2640b57cec5SDimitry Andric }; 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric // ARM MinGW target 2670b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MinGWARMTargetInfo : public WindowsARMTargetInfo { 2680b57cec5SDimitry Andric public: 2690b57cec5SDimitry Andric MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2720b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2730b57cec5SDimitry Andric }; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric // ARM Cygwin target 2760b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY CygwinARMTargetInfo : public ARMleTargetInfo { 2770b57cec5SDimitry Andric public: 2780b57cec5SDimitry Andric CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2810b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2820b57cec5SDimitry Andric }; 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinARMTargetInfo 2850b57cec5SDimitry Andric : public DarwinTargetInfo<ARMleTargetInfo> { 2860b57cec5SDimitry Andric protected: 2870b57cec5SDimitry Andric void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 2880b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric public: 2910b57cec5SDimitry Andric DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2920b57cec5SDimitry Andric }; 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric // 32-bit RenderScript is armv7 with width and align of 'long' set to 8-bytes 2950b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY RenderScript32TargetInfo 2960b57cec5SDimitry Andric : public ARMleTargetInfo { 2970b57cec5SDimitry Andric public: 2980b57cec5SDimitry Andric RenderScript32TargetInfo(const llvm::Triple &Triple, 2990b57cec5SDimitry Andric const TargetOptions &Opts); 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 3020b57cec5SDimitry Andric MacroBuilder &Builder) const override; 3030b57cec5SDimitry Andric }; 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric } // namespace targets 3060b57cec5SDimitry Andric } // namespace clang 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H 309