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 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 64*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(FPUMode) 650b57cec5SDimitry Andric unsigned FPU : 5; 66*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(MVEMode) 670b57cec5SDimitry Andric unsigned MVE : 2; 680b57cec5SDimitry Andric 69*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 700b57cec5SDimitry Andric unsigned IsAAPCS : 1; 71*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(HWDivMode) 720b57cec5SDimitry Andric unsigned HWDiv : 2; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric // Initialized via features. 75*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 760b57cec5SDimitry Andric unsigned SoftFloat : 1; 77*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 780b57cec5SDimitry Andric unsigned SoftFloatABI : 1; 790b57cec5SDimitry Andric 80*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 810b57cec5SDimitry Andric unsigned CRC : 1; 82*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 830b57cec5SDimitry Andric unsigned Crypto : 1; 84*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 85fe6060f1SDimitry Andric unsigned SHA2 : 1; 86*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 87fe6060f1SDimitry Andric unsigned AES : 1; 88*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 890b57cec5SDimitry Andric unsigned DSP : 1; 90*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 910b57cec5SDimitry Andric unsigned DotProd : 1; 92*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 935ffd83dbSDimitry Andric unsigned HasMatMul : 1; 94*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 95349cc55cSDimitry Andric unsigned FPRegsDisabled : 1; 96*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 970eae32dcSDimitry Andric unsigned HasPAC : 1; 98*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 990eae32dcSDimitry Andric unsigned HasBTI : 1; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric enum { 1020b57cec5SDimitry Andric LDREX_B = (1 << 0), /// byte (8-bit) 1030b57cec5SDimitry Andric LDREX_H = (1 << 1), /// half (16-bit) 1040b57cec5SDimitry Andric LDREX_W = (1 << 2), /// word (32-bit) 1050b57cec5SDimitry Andric LDREX_D = (1 << 3), /// double (64-bit) 1060b57cec5SDimitry Andric }; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric uint32_t LDREX; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric // ACLE 6.5.1 Hardware floating point 1110b57cec5SDimitry Andric enum { 1120b57cec5SDimitry Andric HW_FP_HP = (1 << 1), /// half (16-bit) 1130b57cec5SDimitry Andric HW_FP_SP = (1 << 2), /// single (32-bit) 1140b57cec5SDimitry Andric HW_FP_DP = (1 << 3), /// double (64-bit) 1150b57cec5SDimitry Andric }; 1160b57cec5SDimitry Andric uint32_t HW_FP; 1170b57cec5SDimitry Andric 1181db9f3b2SDimitry Andric enum { 1191db9f3b2SDimitry Andric /// __arm_cdp __arm_ldc, __arm_ldcl, __arm_stc, 1201db9f3b2SDimitry Andric /// __arm_stcl, __arm_mcr and __arm_mrc 1211db9f3b2SDimitry Andric FEATURE_COPROC_B1 = (1 << 0), 1221db9f3b2SDimitry Andric /// __arm_cdp2, __arm_ldc2, __arm_stc2, __arm_ldc2l, 1231db9f3b2SDimitry Andric /// __arm_stc2l, __arm_mcr2 and __arm_mrc2 1241db9f3b2SDimitry Andric FEATURE_COPROC_B2 = (1 << 1), 1251db9f3b2SDimitry Andric /// __arm_mcrr, __arm_mrrc 1261db9f3b2SDimitry Andric FEATURE_COPROC_B3 = (1 << 2), 1271db9f3b2SDimitry Andric /// __arm_mcrr2, __arm_mrrc2 1281db9f3b2SDimitry Andric FEATURE_COPROC_B4 = (1 << 3), 1291db9f3b2SDimitry Andric }; 1301db9f3b2SDimitry Andric 1310b57cec5SDimitry Andric void setABIAAPCS(); 1320b57cec5SDimitry Andric void setABIAPCS(bool IsAAPCS16); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric void setArchInfo(); 1350b57cec5SDimitry Andric void setArchInfo(llvm::ARM::ArchKind Kind); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric void setAtomic(); 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric bool isThumb() const; 1400b57cec5SDimitry Andric bool supportsThumb() const; 1410b57cec5SDimitry Andric bool supportsThumb2() const; 1420b57cec5SDimitry Andric bool hasMVE() const; 1430b57cec5SDimitry Andric bool hasMVEFloat() const; 1445ffd83dbSDimitry Andric bool hasCDE() const; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric StringRef getCPUAttr() const; 1470b57cec5SDimitry Andric StringRef getCPUProfile() const; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric public: 1500b57cec5SDimitry Andric ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric StringRef getABI() const override; 1530b57cec5SDimitry Andric bool setABI(const std::string &Name) override; 1540b57cec5SDimitry Andric 1551fd87a68SDimitry Andric bool isBranchProtectionSupportedArch(StringRef Arch) const override; 1561fd87a68SDimitry Andric bool validateBranchProtection(StringRef Spec, StringRef Arch, 1571fd87a68SDimitry Andric BranchProtectionInfo &BPI, 1581fd87a68SDimitry Andric StringRef &Err) const override; 1594824e7fdSDimitry Andric 1600b57cec5SDimitry Andric // FIXME: This should be based on Arch attributes, not CPU names. 1610b57cec5SDimitry Andric bool 1620b57cec5SDimitry Andric initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 1630b57cec5SDimitry Andric StringRef CPU, 1640b57cec5SDimitry Andric const std::vector<std::string> &FeaturesVec) const override; 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric bool isValidFeatureName(StringRef Feature) const override { 1670b57cec5SDimitry Andric // We pass soft-float-abi in as a -target-feature, but the backend figures 1680b57cec5SDimitry Andric // this out through other means. 1690b57cec5SDimitry Andric return Feature != "soft-float-abi"; 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 1730b57cec5SDimitry Andric DiagnosticsEngine &Diags) override; 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const override; 1760b57cec5SDimitry Andric 1775ffd83dbSDimitry Andric bool hasBFloat16Type() const override; 1785ffd83dbSDimitry Andric 1790b57cec5SDimitry Andric bool isValidCPUName(StringRef Name) const override; 1800b57cec5SDimitry Andric void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric bool setCPU(const std::string &Name) override; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric bool setFPMath(StringRef Name) override; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric bool useFP16ConversionIntrinsics() const override { 1870b57cec5SDimitry Andric return false; 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric void getTargetDefinesARMV81A(const LangOptions &Opts, 1910b57cec5SDimitry Andric MacroBuilder &Builder) const; 1920b57cec5SDimitry Andric void getTargetDefinesARMV82A(const LangOptions &Opts, 1930b57cec5SDimitry Andric MacroBuilder &Builder) const; 194480093f4SDimitry Andric void getTargetDefinesARMV83A(const LangOptions &Opts, 195480093f4SDimitry Andric MacroBuilder &Builder) const; 1960b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 1970b57cec5SDimitry Andric MacroBuilder &Builder) const override; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric bool isCLZForZeroUndef() const override; 2020b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override; 2050b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; 2060b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 2070b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Info) const override; 2080b57cec5SDimitry Andric std::string convertConstraint(const char *&Constraint) const override; 2090b57cec5SDimitry Andric bool 2100b57cec5SDimitry Andric validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size, 2110b57cec5SDimitry Andric std::string &SuggestedModifier) const override; 21206c3fb27SDimitry Andric std::string_view getClobbers() const override; 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric StringRef getConstraintRegister(StringRef Constraint, 2150b57cec5SDimitry Andric StringRef Expression) const override { 2160b57cec5SDimitry Andric return Expression; 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric int getEHDataRegisterNumber(unsigned RegNo) const override; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric bool hasSjLjLowering() const override; 2245ffd83dbSDimitry Andric 2250eae32dcSDimitry Andric bool hasBitIntType() const override { return true; } 2265ffd83dbSDimitry Andric 2275ffd83dbSDimitry Andric const char *getBFloat16Mangling() const override { return "u6__bf16"; }; 228*0fca6ea1SDimitry Andric 229*0fca6ea1SDimitry Andric std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override { 230*0fca6ea1SDimitry Andric return std::make_pair(getTriple().isArch64Bit() ? 256 : 64, 64); 231*0fca6ea1SDimitry Andric } 2320b57cec5SDimitry Andric }; 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo { 2350b57cec5SDimitry Andric public: 2360b57cec5SDimitry Andric ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2370b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2380b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2390b57cec5SDimitry Andric }; 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY ARMbeTargetInfo : public ARMTargetInfo { 2420b57cec5SDimitry Andric public: 2430b57cec5SDimitry Andric ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2440b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2450b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2460b57cec5SDimitry Andric }; 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WindowsARMTargetInfo 2490b57cec5SDimitry Andric : public WindowsTargetInfo<ARMleTargetInfo> { 2500b57cec5SDimitry Andric const llvm::Triple Triple; 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric public: 2530b57cec5SDimitry Andric WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric void getVisualStudioDefines(const LangOptions &Opts, 2560b57cec5SDimitry Andric MacroBuilder &Builder) const; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; 2610b57cec5SDimitry Andric }; 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric // Windows ARM + Itanium C++ ABI Target 2640b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY ItaniumWindowsARMleTargetInfo 2650b57cec5SDimitry Andric : public WindowsARMTargetInfo { 2660b57cec5SDimitry Andric public: 2670b57cec5SDimitry Andric ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple, 2680b57cec5SDimitry Andric const TargetOptions &Opts); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2710b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2720b57cec5SDimitry Andric }; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric // Windows ARM, MS (C++) ABI 2750b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MicrosoftARMleTargetInfo 2760b57cec5SDimitry Andric : public WindowsARMTargetInfo { 2770b57cec5SDimitry Andric public: 2780b57cec5SDimitry Andric MicrosoftARMleTargetInfo(const llvm::Triple &Triple, 2790b57cec5SDimitry Andric const TargetOptions &Opts); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2820b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2830b57cec5SDimitry Andric }; 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric // ARM MinGW target 2860b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MinGWARMTargetInfo : public WindowsARMTargetInfo { 2870b57cec5SDimitry Andric public: 2880b57cec5SDimitry Andric MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2910b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2920b57cec5SDimitry Andric }; 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric // ARM Cygwin target 2950b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY CygwinARMTargetInfo : public ARMleTargetInfo { 2960b57cec5SDimitry Andric public: 2970b57cec5SDimitry Andric CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 3000b57cec5SDimitry Andric MacroBuilder &Builder) const override; 3010b57cec5SDimitry Andric }; 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinARMTargetInfo 3040b57cec5SDimitry Andric : public DarwinTargetInfo<ARMleTargetInfo> { 3050b57cec5SDimitry Andric protected: 3060b57cec5SDimitry Andric void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, 3070b57cec5SDimitry Andric MacroBuilder &Builder) const override; 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric public: 3100b57cec5SDimitry Andric DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); 3110b57cec5SDimitry Andric }; 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric // 32-bit RenderScript is armv7 with width and align of 'long' set to 8-bytes 3140b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY RenderScript32TargetInfo 3150b57cec5SDimitry Andric : public ARMleTargetInfo { 3160b57cec5SDimitry Andric public: 3170b57cec5SDimitry Andric RenderScript32TargetInfo(const llvm::Triple &Triple, 3180b57cec5SDimitry Andric const TargetOptions &Opts); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 3210b57cec5SDimitry Andric MacroBuilder &Builder) const override; 3220b57cec5SDimitry Andric }; 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric } // namespace targets 3250b57cec5SDimitry Andric } // namespace clang 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H 328