17#include "llvm/ADT/StringSwitch.h"
18#include "llvm/Support/raw_ostream.h"
19#include "llvm/TargetParser/RISCVTargetParser.h"
29 "x0",
"x1",
"x2",
"x3",
"x4",
"x5",
"x6",
"x7",
30 "x8",
"x9",
"x10",
"x11",
"x12",
"x13",
"x14",
"x15",
31 "x16",
"x17",
"x18",
"x19",
"x20",
"x21",
"x22",
"x23",
32 "x24",
"x25",
"x26",
"x27",
"x28",
"x29",
"x30",
"x31",
35 "f0",
"f1",
"f2",
"f3",
"f4",
"f5",
"f6",
"f7",
36 "f8",
"f9",
"f10",
"f11",
"f12",
"f13",
"f14",
"f15",
37 "f16",
"f17",
"f18",
"f19",
"f20",
"f21",
"f22",
"f23",
38 "f24",
"f25",
"f26",
"f27",
"f28",
"f29",
"f30",
"f31",
41 "v0",
"v1",
"v2",
"v3",
"v4",
"v5",
"v6",
"v7",
42 "v8",
"v9",
"v10",
"v11",
"v12",
"v13",
"v14",
"v15",
43 "v16",
"v17",
"v18",
"v19",
"v20",
"v21",
"v22",
"v23",
44 "v24",
"v25",
"v26",
"v27",
"v28",
"v29",
"v30",
"v31",
47 "fflags",
"frm",
"vtype",
"vl",
"vxsat",
"vxrm"
55 {{
"zero"},
"x0"}, {{
"ra"},
"x1"}, {{
"sp"},
"x2"}, {{
"gp"},
"x3"},
56 {{
"tp"},
"x4"}, {{
"t0"},
"x5"}, {{
"t1"},
"x6"}, {{
"t2"},
"x7"},
57 {{
"s0"},
"x8"}, {{
"s1"},
"x9"}, {{
"a0"},
"x10"}, {{
"a1"},
"x11"},
58 {{
"a2"},
"x12"}, {{
"a3"},
"x13"}, {{
"a4"},
"x14"}, {{
"a5"},
"x15"},
59 {{
"a6"},
"x16"}, {{
"a7"},
"x17"}, {{
"s2"},
"x18"}, {{
"s3"},
"x19"},
60 {{
"s4"},
"x20"}, {{
"s5"},
"x21"}, {{
"s6"},
"x22"}, {{
"s7"},
"x23"},
61 {{
"s8"},
"x24"}, {{
"s9"},
"x25"}, {{
"s10"},
"x26"}, {{
"s11"},
"x27"},
62 {{
"t3"},
"x28"}, {{
"t4"},
"x29"}, {{
"t5"},
"x30"}, {{
"t6"},
"x31"},
63 {{
"ft0"},
"f0"}, {{
"ft1"},
"f1"}, {{
"ft2"},
"f2"}, {{
"ft3"},
"f3"},
64 {{
"ft4"},
"f4"}, {{
"ft5"},
"f5"}, {{
"ft6"},
"f6"}, {{
"ft7"},
"f7"},
65 {{
"fs0"},
"f8"}, {{
"fs1"},
"f9"}, {{
"fa0"},
"f10"}, {{
"fa1"},
"f11"},
66 {{
"fa2"},
"f12"}, {{
"fa3"},
"f13"}, {{
"fa4"},
"f14"}, {{
"fa5"},
"f15"},
67 {{
"fa6"},
"f16"}, {{
"fa7"},
"f17"}, {{
"fs2"},
"f18"}, {{
"fs3"},
"f19"},
68 {{
"fs4"},
"f20"}, {{
"fs5"},
"f21"}, {{
"fs6"},
"f22"}, {{
"fs7"},
"f23"},
69 {{
"fs8"},
"f24"}, {{
"fs9"},
"f25"}, {{
"fs10"},
"f26"}, {{
"fs11"},
"f27"},
70 {{
"ft8"},
"f28"}, {{
"ft9"},
"f29"}, {{
"ft10"},
"f30"}, {{
"ft11"},
"f31"}};
105 if (Name[1] ==
'r' || Name[1] ==
'm') {
116 switch (*Constraint) {
118 R = std::string(
"^") + std::string(Constraint, 2);
129 return MajorVersion * 1000000 + MinorVersion * 1000;
134 Builder.defineMacro(
"__riscv");
136 Builder.defineMacro(
"__riscv_xlen", Is64Bit ?
"64" :
"32");
138 unsigned FLen =
ISAInfo->getFLen();
139 unsigned MinVLen =
ISAInfo->getMinVLen();
140 unsigned MaxELen =
ISAInfo->getMaxELen();
141 unsigned MaxELenFp =
ISAInfo->getMaxELenFp();
142 if (CodeModel ==
"default")
145 if (CodeModel ==
"small")
146 Builder.defineMacro(
"__riscv_cmodel_medlow");
147 else if (CodeModel ==
"medium")
148 Builder.defineMacro(
"__riscv_cmodel_medany");
150 StringRef ABIName =
getABI();
151 if (ABIName ==
"ilp32f" || ABIName ==
"lp64f")
152 Builder.defineMacro(
"__riscv_float_abi_single");
153 else if (ABIName ==
"ilp32d" || ABIName ==
"lp64d")
154 Builder.defineMacro(
"__riscv_float_abi_double");
156 Builder.defineMacro(
"__riscv_float_abi_soft");
158 if (ABIName ==
"ilp32e" || ABIName ==
"lp64e")
159 Builder.defineMacro(
"__riscv_abi_rve");
161 Builder.defineMacro(
"__riscv_arch_test");
163 for (
auto &Extension :
ISAInfo->getExtensions()) {
164 auto ExtName = Extension.first;
165 auto ExtInfo = Extension.second;
167 Builder.defineMacro(Twine(
"__riscv_", ExtName),
171 if (
ISAInfo->hasExtension(
"zmmul"))
172 Builder.defineMacro(
"__riscv_mul");
174 if (
ISAInfo->hasExtension(
"m")) {
175 Builder.defineMacro(
"__riscv_div");
176 Builder.defineMacro(
"__riscv_muldiv");
179 if (
ISAInfo->hasExtension(
"a")) {
180 Builder.defineMacro(
"__riscv_atomic");
181 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
182 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
183 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
185 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
189 Builder.defineMacro(
"__riscv_flen", Twine(FLen));
190 Builder.defineMacro(
"__riscv_fdiv");
191 Builder.defineMacro(
"__riscv_fsqrt");
195 Builder.defineMacro(
"__riscv_v_min_vlen", Twine(MinVLen));
196 Builder.defineMacro(
"__riscv_v_elen", Twine(MaxELen));
197 Builder.defineMacro(
"__riscv_v_elen_fp", Twine(MaxELenFp));
200 if (
ISAInfo->hasExtension(
"c"))
201 Builder.defineMacro(
"__riscv_compressed");
203 if (
ISAInfo->hasExtension(
"zve32x")) {
204 Builder.defineMacro(
"__riscv_vector");
206 Builder.defineMacro(
"__riscv_v_intrinsic", Twine(
getVersionValue(0, 12)));
210 if (VScale && VScale->first && VScale->first == VScale->second)
211 Builder.defineMacro(
"__riscv_v_fixed_vlen",
212 Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));
214 if (FastScalarUnalignedAccess)
215 Builder.defineMacro(
"__riscv_misaligned_fast");
217 Builder.defineMacro(
"__riscv_misaligned_avoid");
219 if (
ISAInfo->hasExtension(
"e")) {
221 Builder.defineMacro(
"__riscv_64e");
223 Builder.defineMacro(
"__riscv_32e");
228#define BUILTIN(ID, TYPE, ATTRS) \
229 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
230#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
231 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
232#include "clang/Basic/BuiltinsRISCVVector.def"
233#define BUILTIN(ID, TYPE, ATTRS) \
234 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
235#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
236 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
237#include "clang/Basic/BuiltinsRISCV.inc"
247 const std::vector<std::string> &FeaturesVec)
const {
252 Features[
"64bit"] =
true;
255 Features[
"32bit"] =
true;
260 const auto I = llvm::find(FeaturesVec,
"__RISCV_TargetAttrNeedOverride");
261 if (I != FeaturesVec.end()) {
262 std::vector<std::string> OverrideFeatures(std::next(I), FeaturesVec.end());
265 auto IsNonISAExtFeature = [](StringRef Feature) {
266 assert(Feature.size() > 1 && (Feature[0] ==
'+' || Feature[0] ==
'-'));
267 StringRef Ext = Feature.substr(1);
268 return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext);
270 llvm::copy_if(llvm::make_range(FeaturesVec.begin(), I),
271 std::back_inserter(OverrideFeatures), IsNonISAExtFeature);
277 std::vector<std::string> AllFeatures = FeaturesVec;
278 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
281 llvm::raw_string_ostream OutputErrMsg(Buffer);
282 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
283 OutputErrMsg << ErrMsg.getMessage();
285 Diags.
Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
290 llvm::append_range(AllFeatures, (*ParseResult)->toFeatures());
294std::optional<std::pair<unsigned, unsigned>>
297 unsigned VScaleMin =
ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock;
299 if (LangOpts.VScaleMin || LangOpts.VScaleMax) {
301 VScaleMin = std::max(VScaleMin, LangOpts.VScaleMin);
302 unsigned VScaleMax = LangOpts.VScaleMax;
303 if (VScaleMax != 0 && VScaleMax < VScaleMin)
304 VScaleMax = VScaleMin;
305 return std::pair<unsigned, unsigned>(VScaleMin ? VScaleMin : 1, VScaleMax);
309 unsigned VScaleMax =
ISAInfo->getMaxVLen() / llvm::RISCV::RVVBitsPerBlock;
310 return std::make_pair(VScaleMin, VScaleMax);
319 auto Result = llvm::StringSwitch<std::optional<bool>>(Feature)
321 .Case(
"riscv32", !Is64Bit)
322 .Case(
"riscv64", Is64Bit)
323 .Case(
"32bit", !Is64Bit)
324 .Case(
"64bit", Is64Bit)
325 .Case(
"experimental", HasExperimental)
326 .Default(std::nullopt);
330 return ISAInfo->hasExtension(Feature);
336 unsigned XLen =
getTriple().isArch64Bit() ? 64 : 32;
337 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
340 llvm::raw_string_ostream OutputErrMsg(Buffer);
341 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
342 OutputErrMsg << ErrMsg.getMessage();
344 Diags.
Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
347 ISAInfo = std::move(*ParseResult);
353 if (
ISAInfo->hasExtension(
"zfh") ||
ISAInfo->hasExtension(
"zhinx"))
356 FastScalarUnalignedAccess =
357 llvm::is_contained(Features,
"+unaligned-scalar-mem");
359 if (llvm::is_contained(Features,
"+experimental"))
360 HasExperimental =
true;
362 if (
ABI ==
"ilp32e" &&
ISAInfo->hasExtension(
"d")) {
363 Diags.
Report(diag::err_invalid_feature_combination)
364 <<
"ILP32E cannot be used with the D ISA extension";
371 bool Is64Bit =
getTriple().isArch64Bit();
372 return llvm::RISCV::parseCPU(Name, Is64Bit);
377 bool Is64Bit =
getTriple().isArch64Bit();
378 llvm::RISCV::fillValidCPUArchList(Values, Is64Bit);
382 bool Is64Bit =
getTriple().isArch64Bit();
383 return llvm::RISCV::parseTuneCPU(Name, Is64Bit);
388 bool Is64Bit =
getTriple().isArch64Bit();
389 llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
393 std::vector<std::string> &Features) {
394 Features.push_back(
"__RISCV_TargetAttrNeedOverride");
395 auto RII = llvm::RISCVISAInfo::parseArchString(
397 if (llvm::errorToBool(RII.takeError())) {
399 Features.push_back(
"+" + FullArchStr.str());
403 std::vector<std::string> FeatStrings =
404 (*RII)->toFeatures(
true);
405 Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end());
411 if (Features ==
"default")
414 Features.split(AttrFeatures,
";");
415 bool FoundArch =
false;
417 for (
auto &Feature : AttrFeatures) {
418 Feature = Feature.trim();
419 StringRef AttrString = Feature.split(
"=").second.trim();
421 if (Feature.starts_with(
"arch=")) {
423 Ret.Features.clear();
425 Ret.Duplicate =
"arch=";
428 if (AttrString.starts_with(
"+")) {
431 AttrString.split(Exts,
",");
432 for (
auto Ext : Exts) {
436 StringRef ExtName = Ext.substr(1);
437 std::string TargetFeature =
438 llvm::RISCVISAInfo::getTargetFeatureForExtension(ExtName);
439 if (!TargetFeature.empty())
440 Ret.Features.push_back(Ext.front() + TargetFeature);
442 Ret.Features.push_back(Ext.str());
448 }
else if (Feature.starts_with(
"cpu=")) {
449 if (!Ret.CPU.empty())
450 Ret.Duplicate =
"cpu=";
452 Ret.CPU = AttrString;
456 StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU);
457 if (MarchFromCPU !=
"") {
458 Ret.Features.clear();
462 }
else if (Feature.starts_with(
"tune=")) {
463 if (!Ret.Tune.empty())
464 Ret.Duplicate =
"tune=";
466 Ret.Tune = AttrString;
486 return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second;
Defines the Diagnostic-related interfaces.
static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion)
static void handleFullArchString(StringRef FullArchStr, std::vector< std::string > &Features)
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
Determine whether this TargetInfo supports the given CPU name for tuning.
std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts) const override
Returns target-specific min and max values VScale_Range.
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
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.
bool validateCpuSupports(StringRef Feature) const override
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.
ParsedTargetAttr parseTargetAttr(StringRef Str) const override
bool hasFeature(StringRef Feature) const override
Return true if has this feature, need to sync with handleTargetFeatures.
bool isValidCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name.
static const char *const GCCRegNames[]
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Contains information gathered from parsing the contents of TargetAttr.
void setRequiresImmediate(int Min, int Max)