1e5dd7070Spatrick //===--- RISCV.h - Declare RISCV 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 RISCV TargetInfo objects. 10e5dd7070Spatrick // 11e5dd7070Spatrick //===----------------------------------------------------------------------===// 12e5dd7070Spatrick 13e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H 14e5dd7070Spatrick #define LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H 15e5dd7070Spatrick 16e5dd7070Spatrick #include "clang/Basic/TargetInfo.h" 17e5dd7070Spatrick #include "clang/Basic/TargetOptions.h" 18e5dd7070Spatrick #include "llvm/ADT/Triple.h" 19e5dd7070Spatrick #include "llvm/Support/Compiler.h" 20*12c85518Srobert #include "llvm/Support/RISCVISAInfo.h" 21*12c85518Srobert #include <optional> 22e5dd7070Spatrick 23e5dd7070Spatrick namespace clang { 24e5dd7070Spatrick namespace targets { 25e5dd7070Spatrick 26e5dd7070Spatrick // RISC-V Target 27e5dd7070Spatrick class RISCVTargetInfo : public TargetInfo { 28e5dd7070Spatrick protected: 29ec727ea7Spatrick std::string ABI, CPU; 30*12c85518Srobert std::unique_ptr<llvm::RISCVISAInfo> ISAInfo; 31e5dd7070Spatrick 32e5dd7070Spatrick public: RISCVTargetInfo(const llvm::Triple & Triple,const TargetOptions &)33e5dd7070Spatrick RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 34a9ac8606Spatrick : TargetInfo(Triple) { 35e5dd7070Spatrick LongDoubleWidth = 128; 36e5dd7070Spatrick LongDoubleAlign = 128; 37e5dd7070Spatrick LongDoubleFormat = &llvm::APFloat::IEEEquad(); 38e5dd7070Spatrick SuitableAlign = 128; 39e5dd7070Spatrick WCharType = SignedInt; 40e5dd7070Spatrick WIntType = UnsignedInt; 41a9ac8606Spatrick HasRISCVVTypes = true; 42a9ac8606Spatrick MCountName = "_mcount"; 43a9ac8606Spatrick HasFloat16 = true; 44e5dd7070Spatrick } 45e5dd7070Spatrick setCPU(const std::string & Name)46ec727ea7Spatrick bool setCPU(const std::string &Name) override { 47ec727ea7Spatrick if (!isValidCPUName(Name)) 48ec727ea7Spatrick return false; 49ec727ea7Spatrick CPU = Name; 50ec727ea7Spatrick return true; 51ec727ea7Spatrick } 52ec727ea7Spatrick getABI()53e5dd7070Spatrick StringRef getABI() const override { return ABI; } 54e5dd7070Spatrick void getTargetDefines(const LangOptions &Opts, 55e5dd7070Spatrick MacroBuilder &Builder) const override; 56e5dd7070Spatrick 57a9ac8606Spatrick ArrayRef<Builtin::Info> getTargetBuiltins() const override; 58e5dd7070Spatrick getBuiltinVaListKind()59e5dd7070Spatrick BuiltinVaListKind getBuiltinVaListKind() const override { 60e5dd7070Spatrick return TargetInfo::VoidPtrBuiltinVaList; 61e5dd7070Spatrick } 62e5dd7070Spatrick getClobbers()63e5dd7070Spatrick const char *getClobbers() const override { return ""; } 64e5dd7070Spatrick getConstraintRegister(StringRef Constraint,StringRef Expression)65*12c85518Srobert StringRef getConstraintRegister(StringRef Constraint, 66*12c85518Srobert StringRef Expression) const override { 67*12c85518Srobert return Expression; 68*12c85518Srobert } 69*12c85518Srobert 70e5dd7070Spatrick ArrayRef<const char *> getGCCRegNames() const override; 71e5dd7070Spatrick getEHDataRegisterNumber(unsigned RegNo)72e5dd7070Spatrick int getEHDataRegisterNumber(unsigned RegNo) const override { 73e5dd7070Spatrick if (RegNo == 0) 74e5dd7070Spatrick return 10; 75e5dd7070Spatrick else if (RegNo == 1) 76e5dd7070Spatrick return 11; 77e5dd7070Spatrick else 78e5dd7070Spatrick return -1; 79e5dd7070Spatrick } 80e5dd7070Spatrick 81e5dd7070Spatrick ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; 82e5dd7070Spatrick 83e5dd7070Spatrick bool validateAsmConstraint(const char *&Name, 84e5dd7070Spatrick TargetInfo::ConstraintInfo &Info) const override; 85e5dd7070Spatrick 86a9ac8606Spatrick std::string convertConstraint(const char *&Constraint) const override; 87a9ac8606Spatrick 88a9ac8606Spatrick bool 89a9ac8606Spatrick initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 90a9ac8606Spatrick StringRef CPU, 91a9ac8606Spatrick const std::vector<std::string> &FeaturesVec) const override; 92a9ac8606Spatrick 93*12c85518Srobert std::optional<std::pair<unsigned, unsigned>> 94*12c85518Srobert getVScaleRange(const LangOptions &LangOpts) const override; 95*12c85518Srobert 96e5dd7070Spatrick bool hasFeature(StringRef Feature) const override; 97e5dd7070Spatrick 98e5dd7070Spatrick bool handleTargetFeatures(std::vector<std::string> &Features, 99e5dd7070Spatrick DiagnosticsEngine &Diags) override; 100ec727ea7Spatrick hasBitIntType()101*12c85518Srobert bool hasBitIntType() const override { return true; } 102*12c85518Srobert useFP16ConversionIntrinsics()103*12c85518Srobert bool useFP16ConversionIntrinsics() const override { 104*12c85518Srobert return false; 105*12c85518Srobert } 106*12c85518Srobert 107*12c85518Srobert bool isValidCPUName(StringRef Name) const override; 108*12c85518Srobert void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 109*12c85518Srobert bool isValidTuneCPUName(StringRef Name) const override; 110*12c85518Srobert void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override; 111e5dd7070Spatrick }; 112e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { 113e5dd7070Spatrick public: RISCV32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)114e5dd7070Spatrick RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 115e5dd7070Spatrick : RISCVTargetInfo(Triple, Opts) { 116e5dd7070Spatrick IntPtrType = SignedInt; 117e5dd7070Spatrick PtrDiffType = SignedInt; 118e5dd7070Spatrick SizeType = UnsignedInt; 119e5dd7070Spatrick resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128"); 120e5dd7070Spatrick } 121e5dd7070Spatrick setABI(const std::string & Name)122e5dd7070Spatrick bool setABI(const std::string &Name) override { 123e5dd7070Spatrick if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") { 124e5dd7070Spatrick ABI = Name; 125e5dd7070Spatrick return true; 126e5dd7070Spatrick } 127e5dd7070Spatrick return false; 128e5dd7070Spatrick } 129e5dd7070Spatrick setMaxAtomicWidth()130e5dd7070Spatrick void setMaxAtomicWidth() override { 131e5dd7070Spatrick MaxAtomicPromoteWidth = 128; 132e5dd7070Spatrick 133*12c85518Srobert if (ISAInfo->hasExtension("a")) 134e5dd7070Spatrick MaxAtomicInlineWidth = 32; 135e5dd7070Spatrick } 136e5dd7070Spatrick }; 137e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo { 138e5dd7070Spatrick public: RISCV64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)139e5dd7070Spatrick RISCV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 140e5dd7070Spatrick : RISCVTargetInfo(Triple, Opts) { 141e5dd7070Spatrick LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 142e5dd7070Spatrick IntMaxType = Int64Type = SignedLong; 143*12c85518Srobert resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"); 144e5dd7070Spatrick } 145e5dd7070Spatrick setABI(const std::string & Name)146e5dd7070Spatrick bool setABI(const std::string &Name) override { 147e5dd7070Spatrick if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") { 148e5dd7070Spatrick ABI = Name; 149e5dd7070Spatrick return true; 150e5dd7070Spatrick } 151e5dd7070Spatrick return false; 152e5dd7070Spatrick } 153e5dd7070Spatrick setMaxAtomicWidth()154e5dd7070Spatrick void setMaxAtomicWidth() override { 155e5dd7070Spatrick MaxAtomicPromoteWidth = 128; 156e5dd7070Spatrick 157*12c85518Srobert if (ISAInfo->hasExtension("a")) 158e5dd7070Spatrick MaxAtomicInlineWidth = 64; 159e5dd7070Spatrick } 160e5dd7070Spatrick }; 161e5dd7070Spatrick } // namespace targets 162e5dd7070Spatrick } // namespace clang 163e5dd7070Spatrick 164e5dd7070Spatrick #endif // LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H 165