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