106c3fb27SDimitry Andric //===--- RISCV.h - Declare RISC-V 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 // 906c3fb27SDimitry Andric // This file declares RISC-V TargetInfo objects. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 170b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 180b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 19*0fca6ea1SDimitry Andric #include "llvm/TargetParser/RISCVISAInfo.h" 2006c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 21bdd1243dSDimitry Andric #include <optional> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace clang { 240b57cec5SDimitry Andric namespace targets { 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric // RISC-V Target 270b57cec5SDimitry Andric class RISCVTargetInfo : public TargetInfo { 280b57cec5SDimitry Andric protected: 29590d96feSDimitry Andric std::string ABI, CPU; 30349cc55cSDimitry Andric std::unique_ptr<llvm::RISCVISAInfo> ISAInfo; 31fe6060f1SDimitry Andric 325f757f3fSDimitry Andric private: 33*0fca6ea1SDimitry Andric bool FastScalarUnalignedAccess; 34cb14a3feSDimitry Andric bool HasExperimental = false; 355f757f3fSDimitry Andric 360b57cec5SDimitry Andric public: RISCVTargetInfo(const llvm::Triple & Triple,const TargetOptions &)370b57cec5SDimitry Andric RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 38e8d8bef9SDimitry Andric : TargetInfo(Triple) { 395f757f3fSDimitry Andric BFloat16Width = 16; 405f757f3fSDimitry Andric BFloat16Align = 16; 415f757f3fSDimitry Andric BFloat16Format = &llvm::APFloat::BFloat(); 420b57cec5SDimitry Andric LongDoubleWidth = 128; 430b57cec5SDimitry Andric LongDoubleAlign = 128; 440b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEquad(); 450b57cec5SDimitry Andric SuitableAlign = 128; 460b57cec5SDimitry Andric WCharType = SignedInt; 470b57cec5SDimitry Andric WIntType = UnsignedInt; 48fe6060f1SDimitry Andric HasRISCVVTypes = true; 49fe6060f1SDimitry Andric MCountName = "_mcount"; 50fe6060f1SDimitry Andric HasFloat16 = true; 5106c3fb27SDimitry Andric HasStrictFP = true; 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric setCPU(const std::string & Name)54590d96feSDimitry Andric bool setCPU(const std::string &Name) override { 55590d96feSDimitry Andric if (!isValidCPUName(Name)) 56590d96feSDimitry Andric return false; 57590d96feSDimitry Andric CPU = Name; 58590d96feSDimitry Andric return true; 59590d96feSDimitry Andric } 60590d96feSDimitry Andric getABI()610b57cec5SDimitry Andric StringRef getABI() const override { return ABI; } 620b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 630b57cec5SDimitry Andric MacroBuilder &Builder) const override; 640b57cec5SDimitry Andric 65fe6060f1SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 660b57cec5SDimitry Andric getBuiltinVaListKind()670b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 680b57cec5SDimitry Andric return TargetInfo::VoidPtrBuiltinVaList; 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric getClobbers()7106c3fb27SDimitry Andric std::string_view getClobbers() const override { return ""; } 720b57cec5SDimitry Andric getConstraintRegister(StringRef Constraint,StringRef Expression)73349cc55cSDimitry Andric StringRef getConstraintRegister(StringRef Constraint, 74349cc55cSDimitry Andric StringRef Expression) const override { 75349cc55cSDimitry Andric return Expression; 76349cc55cSDimitry Andric } 77349cc55cSDimitry Andric 780b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override; 790b57cec5SDimitry Andric getEHDataRegisterNumber(unsigned RegNo)800b57cec5SDimitry Andric int getEHDataRegisterNumber(unsigned RegNo) const override { 810b57cec5SDimitry Andric if (RegNo == 0) 820b57cec5SDimitry Andric return 10; 830b57cec5SDimitry Andric else if (RegNo == 1) 840b57cec5SDimitry Andric return 11; 850b57cec5SDimitry Andric else 860b57cec5SDimitry Andric return -1; 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 920b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Info) const override; 930b57cec5SDimitry Andric 94fe6060f1SDimitry Andric std::string convertConstraint(const char *&Constraint) const override; 95fe6060f1SDimitry Andric 96fe6060f1SDimitry Andric bool 97fe6060f1SDimitry Andric initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 98fe6060f1SDimitry Andric StringRef CPU, 99fe6060f1SDimitry Andric const std::vector<std::string> &FeaturesVec) const override; 100fe6060f1SDimitry Andric 101bdd1243dSDimitry Andric std::optional<std::pair<unsigned, unsigned>> 102bdd1243dSDimitry Andric getVScaleRange(const LangOptions &LangOpts) const override; 103bdd1243dSDimitry Andric 1040b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const override; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 1070b57cec5SDimitry Andric DiagnosticsEngine &Diags) override; 1085ffd83dbSDimitry Andric hasBitIntType()1090eae32dcSDimitry Andric bool hasBitIntType() const override { return true; } 11081ad6265SDimitry Andric hasBFloat16Type()1115f757f3fSDimitry Andric bool hasBFloat16Type() const override { return true; } 1125f757f3fSDimitry Andric 113*0fca6ea1SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; 114*0fca6ea1SDimitry Andric useFP16ConversionIntrinsics()11581ad6265SDimitry Andric bool useFP16ConversionIntrinsics() const override { 11681ad6265SDimitry Andric return false; 11781ad6265SDimitry Andric } 118bdd1243dSDimitry Andric 119bdd1243dSDimitry Andric bool isValidCPUName(StringRef Name) const override; 120bdd1243dSDimitry Andric void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 121bdd1243dSDimitry Andric bool isValidTuneCPUName(StringRef Name) const override; 122bdd1243dSDimitry Andric void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override; supportsTargetAttributeTune()1235f757f3fSDimitry Andric bool supportsTargetAttributeTune() const override { return true; } 1245f757f3fSDimitry Andric ParsedTargetAttr parseTargetAttr(StringRef Str) const override; 125*0fca6ea1SDimitry Andric hardwareInterferenceSizes()126*0fca6ea1SDimitry Andric std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override { 127*0fca6ea1SDimitry Andric return std::make_pair(32, 32); 128*0fca6ea1SDimitry Andric } 1290b57cec5SDimitry Andric }; 1300b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { 1310b57cec5SDimitry Andric public: RISCV32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1320b57cec5SDimitry Andric RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 1330b57cec5SDimitry Andric : RISCVTargetInfo(Triple, Opts) { 1340b57cec5SDimitry Andric IntPtrType = SignedInt; 1350b57cec5SDimitry Andric PtrDiffType = SignedInt; 1360b57cec5SDimitry Andric SizeType = UnsignedInt; 1370b57cec5SDimitry Andric resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128"); 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric setABI(const std::string & Name)1400b57cec5SDimitry Andric bool setABI(const std::string &Name) override { 1417a6dacacSDimitry Andric if (Name == "ilp32e") { 1427a6dacacSDimitry Andric ABI = Name; 1437a6dacacSDimitry Andric resetDataLayout("e-m:e-p:32:32-i64:64-n32-S32"); 1447a6dacacSDimitry Andric return true; 1457a6dacacSDimitry Andric } 1467a6dacacSDimitry Andric 1470b57cec5SDimitry Andric if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") { 1480b57cec5SDimitry Andric ABI = Name; 1490b57cec5SDimitry Andric return true; 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric return false; 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric setMaxAtomicWidth()1540b57cec5SDimitry Andric void setMaxAtomicWidth() override { 1550b57cec5SDimitry Andric MaxAtomicPromoteWidth = 128; 1560b57cec5SDimitry Andric 157349cc55cSDimitry Andric if (ISAInfo->hasExtension("a")) 1580b57cec5SDimitry Andric MaxAtomicInlineWidth = 32; 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric }; 1610b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo { 1620b57cec5SDimitry Andric public: RISCV64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1630b57cec5SDimitry Andric RISCV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 1640b57cec5SDimitry Andric : RISCVTargetInfo(Triple, Opts) { 1650b57cec5SDimitry Andric LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 1660b57cec5SDimitry Andric IntMaxType = Int64Type = SignedLong; 167bdd1243dSDimitry Andric resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"); 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric setABI(const std::string & Name)1700b57cec5SDimitry Andric bool setABI(const std::string &Name) override { 1717a6dacacSDimitry Andric if (Name == "lp64e") { 1727a6dacacSDimitry Andric ABI = Name; 1737a6dacacSDimitry Andric resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S64"); 1747a6dacacSDimitry Andric return true; 1757a6dacacSDimitry Andric } 1767a6dacacSDimitry Andric 1770b57cec5SDimitry Andric if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") { 1780b57cec5SDimitry Andric ABI = Name; 1790b57cec5SDimitry Andric return true; 1800b57cec5SDimitry Andric } 1810b57cec5SDimitry Andric return false; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric setMaxAtomicWidth()1840b57cec5SDimitry Andric void setMaxAtomicWidth() override { 1850b57cec5SDimitry Andric MaxAtomicPromoteWidth = 128; 1860b57cec5SDimitry Andric 187349cc55cSDimitry Andric if (ISAInfo->hasExtension("a")) 1880b57cec5SDimitry Andric MaxAtomicInlineWidth = 64; 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric }; 1910b57cec5SDimitry Andric } // namespace targets 1920b57cec5SDimitry Andric } // namespace clang 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H 195