17#include "llvm/ADT/StringSwitch.h"
18#include "llvm/Support/raw_ostream.h"
19#include "llvm/TargetParser/RISCVTargetParser.h"
28 "x0",
"x1",
"x2",
"x3",
"x4",
"x5",
"x6",
"x7",
29 "x8",
"x9",
"x10",
"x11",
"x12",
"x13",
"x14",
"x15",
30 "x16",
"x17",
"x18",
"x19",
"x20",
"x21",
"x22",
"x23",
31 "x24",
"x25",
"x26",
"x27",
"x28",
"x29",
"x30",
"x31",
34 "f0",
"f1",
"f2",
"f3",
"f4",
"f5",
"f6",
"f7",
35 "f8",
"f9",
"f10",
"f11",
"f12",
"f13",
"f14",
"f15",
36 "f16",
"f17",
"f18",
"f19",
"f20",
"f21",
"f22",
"f23",
37 "f24",
"f25",
"f26",
"f27",
"f28",
"f29",
"f30",
"f31",
40 "v0",
"v1",
"v2",
"v3",
"v4",
"v5",
"v6",
"v7",
41 "v8",
"v9",
"v10",
"v11",
"v12",
"v13",
"v14",
"v15",
42 "v16",
"v17",
"v18",
"v19",
"v20",
"v21",
"v22",
"v23",
43 "v24",
"v25",
"v26",
"v27",
"v28",
"v29",
"v30",
"v31"};
49 {{
"zero"},
"x0"}, {{
"ra"},
"x1"}, {{
"sp"},
"x2"}, {{
"gp"},
"x3"},
50 {{
"tp"},
"x4"}, {{
"t0"},
"x5"}, {{
"t1"},
"x6"}, {{
"t2"},
"x7"},
51 {{
"s0"},
"x8"}, {{
"s1"},
"x9"}, {{
"a0"},
"x10"}, {{
"a1"},
"x11"},
52 {{
"a2"},
"x12"}, {{
"a3"},
"x13"}, {{
"a4"},
"x14"}, {{
"a5"},
"x15"},
53 {{
"a6"},
"x16"}, {{
"a7"},
"x17"}, {{
"s2"},
"x18"}, {{
"s3"},
"x19"},
54 {{
"s4"},
"x20"}, {{
"s5"},
"x21"}, {{
"s6"},
"x22"}, {{
"s7"},
"x23"},
55 {{
"s8"},
"x24"}, {{
"s9"},
"x25"}, {{
"s10"},
"x26"}, {{
"s11"},
"x27"},
56 {{
"t3"},
"x28"}, {{
"t4"},
"x29"}, {{
"t5"},
"x30"}, {{
"t6"},
"x31"},
57 {{
"ft0"},
"f0"}, {{
"ft1"},
"f1"}, {{
"ft2"},
"f2"}, {{
"ft3"},
"f3"},
58 {{
"ft4"},
"f4"}, {{
"ft5"},
"f5"}, {{
"ft6"},
"f6"}, {{
"ft7"},
"f7"},
59 {{
"fs0"},
"f8"}, {{
"fs1"},
"f9"}, {{
"fa0"},
"f10"}, {{
"fa1"},
"f11"},
60 {{
"fa2"},
"f12"}, {{
"fa3"},
"f13"}, {{
"fa4"},
"f14"}, {{
"fa5"},
"f15"},
61 {{
"fa6"},
"f16"}, {{
"fa7"},
"f17"}, {{
"fs2"},
"f18"}, {{
"fs3"},
"f19"},
62 {{
"fs4"},
"f20"}, {{
"fs5"},
"f21"}, {{
"fs6"},
"f22"}, {{
"fs7"},
"f23"},
63 {{
"fs8"},
"f24"}, {{
"fs9"},
"f25"}, {{
"fs10"},
"f26"}, {{
"fs11"},
"f27"},
64 {{
"ft8"},
"f28"}, {{
"ft9"},
"f29"}, {{
"ft10"},
"f30"}, {{
"ft11"},
"f31"}};
98 if (Name[1] ==
'r' || Name[1] ==
'm') {
109 switch (*Constraint) {
111 R = std::string(
"^") + std::string(Constraint, 2);
122 return MajorVersion * 1000000 + MinorVersion * 1000;
127 Builder.defineMacro(
"__riscv");
128 bool Is64Bit =
getTriple().getArch() == llvm::Triple::riscv64;
129 Builder.defineMacro(
"__riscv_xlen", Is64Bit ?
"64" :
"32");
131 unsigned FLen =
ISAInfo->getFLen();
132 unsigned MinVLen =
ISAInfo->getMinVLen();
133 unsigned MaxELen =
ISAInfo->getMaxELen();
134 unsigned MaxELenFp =
ISAInfo->getMaxELenFp();
135 if (CodeModel ==
"default")
138 if (CodeModel ==
"small")
139 Builder.defineMacro(
"__riscv_cmodel_medlow");
140 else if (CodeModel ==
"medium")
141 Builder.defineMacro(
"__riscv_cmodel_medany");
143 StringRef ABIName =
getABI();
144 if (ABIName ==
"ilp32f" || ABIName ==
"lp64f")
145 Builder.defineMacro(
"__riscv_float_abi_single");
146 else if (ABIName ==
"ilp32d" || ABIName ==
"lp64d")
147 Builder.defineMacro(
"__riscv_float_abi_double");
149 Builder.defineMacro(
"__riscv_float_abi_soft");
151 if (ABIName ==
"ilp32e")
152 Builder.defineMacro(
"__riscv_abi_rve");
154 Builder.defineMacro(
"__riscv_arch_test");
156 for (
auto &Extension :
ISAInfo->getExtensions()) {
157 auto ExtName = Extension.first;
158 auto ExtInfo = Extension.second;
161 Twine(
"__riscv_", ExtName),
166 Builder.defineMacro(
"__riscv_mul");
168 if (
ISAInfo->hasExtension(
"m")) {
169 Builder.defineMacro(
"__riscv_div");
170 Builder.defineMacro(
"__riscv_muldiv");
173 if (
ISAInfo->hasExtension(
"a")) {
174 Builder.defineMacro(
"__riscv_atomic");
175 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
176 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
177 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
179 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
183 Builder.defineMacro(
"__riscv_flen", Twine(FLen));
184 Builder.defineMacro(
"__riscv_fdiv");
185 Builder.defineMacro(
"__riscv_fsqrt");
189 Builder.defineMacro(
"__riscv_v_min_vlen", Twine(MinVLen));
190 Builder.defineMacro(
"__riscv_v_elen", Twine(MaxELen));
191 Builder.defineMacro(
"__riscv_v_elen_fp", Twine(MaxELenFp));
194 if (
ISAInfo->hasExtension(
"c"))
195 Builder.defineMacro(
"__riscv_compressed");
197 if (
ISAInfo->hasExtension(
"zve32x")) {
198 Builder.defineMacro(
"__riscv_vector");
200 Builder.defineMacro(
"__riscv_v_intrinsic", Twine(
getVersionValue(0, 11)));
204 if (VScale && VScale->first && VScale->first == VScale->second)
205 Builder.defineMacro(
"__riscv_v_fixed_vlen",
206 Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));
210#define BUILTIN(ID, TYPE, ATTRS) \
211 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
212#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
213 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
214#include "clang/Basic/BuiltinsRISCVVector.def"
215#define BUILTIN(ID, TYPE, ATTRS) \
216 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
217#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
218 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
219#include "clang/Basic/BuiltinsRISCV.def"
229 const std::vector<std::string> &FeaturesVec)
const {
233 if (
getTriple().getArch() == llvm::Triple::riscv64) {
234 Features[
"64bit"] =
true;
237 Features[
"32bit"] =
true;
240 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
243 llvm::raw_string_ostream OutputErrMsg(Buffer);
244 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
245 OutputErrMsg << ErrMsg.getMessage();
247 Diags.
Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
252 std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector();
254 for (
const std::string &Feature : FeaturesVec)
255 if (!llvm::is_contained(ImpliedFeatures, Feature))
256 ImpliedFeatures.push_back(Feature);
261std::optional<std::pair<unsigned, unsigned>>
264 unsigned VScaleMin =
ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock;
266 if (LangOpts.VScaleMin || LangOpts.VScaleMax) {
268 VScaleMin = std::max(VScaleMin, LangOpts.VScaleMin);
269 unsigned VScaleMax = LangOpts.VScaleMax;
270 if (VScaleMax != 0 && VScaleMax < VScaleMin)
271 VScaleMax = VScaleMin;
272 return std::pair<unsigned, unsigned>(VScaleMin ? VScaleMin : 1, VScaleMax);
276 unsigned VScaleMax =
ISAInfo->getMaxVLen() / llvm::RISCV::RVVBitsPerBlock;
277 return std::make_pair(VScaleMin, VScaleMax);
285 bool Is64Bit =
getTriple().getArch() == llvm::Triple::riscv64;
286 auto Result = llvm::StringSwitch<std::optional<bool>>(Feature)
288 .Case(
"riscv32", !Is64Bit)
289 .Case(
"riscv64", Is64Bit)
290 .Case(
"32bit", !Is64Bit)
291 .Case(
"64bit", Is64Bit)
292 .Default(std::nullopt);
296 if (
ISAInfo->isSupportedExtensionFeature(Feature))
297 return ISAInfo->hasExtension(Feature);
305 unsigned XLen =
getTriple().isArch64Bit() ? 64 : 32;
306 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
309 llvm::raw_string_ostream OutputErrMsg(Buffer);
310 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
311 OutputErrMsg << ErrMsg.getMessage();
313 Diags.
Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
316 ISAInfo = std::move(*ParseResult);
322 if (
ISAInfo->hasExtension(
"zfh") ||
ISAInfo->hasExtension(
"zhinx"))
329 bool Is64Bit =
getTriple().isArch64Bit();
330 return llvm::RISCV::parseCPU(Name, Is64Bit);
335 bool Is64Bit =
getTriple().isArch64Bit();
336 llvm::RISCV::fillValidCPUArchList(Values, Is64Bit);
340 bool Is64Bit =
getTriple().isArch64Bit();
341 return llvm::RISCV::parseTuneCPU(Name, Is64Bit);
346 bool Is64Bit =
getTriple().isArch64Bit();
347 llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
Defines the Diagnostic-related interfaces.
static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion)
static constexpr Builtin::Info BuiltinInfo[]
Defines the clang::MacroBuilder utility class.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
virtual std::string convertConstraint(const char *&Constraint) const
std::string convertConstraint(const char *&Constraint) const override
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override
bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeaturesVec) const override
Initialize the map with the default set of target features for the CPU this should include all legal ...
std::unique_ptr< llvm::RISCVISAInfo > ISAInfo
void fillValidTuneCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values for tuning CPU.
bool isValidTuneCPUName(StringRef Name) const override
brief Determine whether this TargetInfo supports the given CPU name for
std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts) const override
Returns target-specific min and max values VScale_Range.
ArrayRef< const char * > getGCCRegNames() const override
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
StringRef getABI() const override
Get the ABI currently in use.
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features.
bool hasFeature(StringRef Feature) const override
Return true if has this feature, need to sync with handleTargetFeatures.
bool isValidCPUName(StringRef Name) const override
brief Determine whether this TargetInfo supports the given CPU name.
static const char *const GCCRegNames[]
@ Result
The result type of a method or function.
void setRequiresImmediate(int Min, int Max)