clang 20.0.0git
RISCV.cpp
Go to the documentation of this file.
1//===--- RISCV.cpp - Implement RISC-V target feature support --------------===//
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 implements RISC-V TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCV.h"
17#include "llvm/ADT/StringSwitch.h"
18#include "llvm/Support/raw_ostream.h"
19#include "llvm/TargetParser/RISCVTargetParser.h"
20#include <optional>
21
22using namespace clang;
23using namespace clang::targets;
24
26 // clang-format off
27 static const char *const GCCRegNames[] = {
28 // Integer registers
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",
33
34 // Floating point registers
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",
39
40 // Vector registers
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",
45
46 // CSRs
47 "fflags", "frm", "vtype", "vl", "vxsat", "vxrm"
48 };
49 // clang-format on
51}
52
54 static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
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"}};
71 return llvm::ArrayRef(GCCRegAliases);
72}
73
75 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
76 switch (*Name) {
77 default:
78 return false;
79 case 'I':
80 // A 12-bit signed immediate.
81 Info.setRequiresImmediate(-2048, 2047);
82 return true;
83 case 'J':
84 // Integer zero.
86 return true;
87 case 'K':
88 // A 5-bit unsigned immediate for CSR access instructions.
89 Info.setRequiresImmediate(0, 31);
90 return true;
91 case 'f':
92 // A floating-point register.
93 Info.setAllowsRegister();
94 return true;
95 case 'A':
96 // An address that is held in a general-purpose register.
97 Info.setAllowsMemory();
98 return true;
99 case 's':
100 case 'S': // A symbol or label reference with a constant offset
101 Info.setAllowsRegister();
102 return true;
103 case 'v':
104 // A vector register.
105 if (Name[1] == 'r' || Name[1] == 'm') {
106 Info.setAllowsRegister();
107 Name += 1;
108 return true;
109 }
110 return false;
111 }
112}
113
114std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
115 std::string R;
116 switch (*Constraint) {
117 case 'v':
118 R = std::string("^") + std::string(Constraint, 2);
119 Constraint += 1;
120 break;
121 default:
122 R = TargetInfo::convertConstraint(Constraint);
123 break;
124 }
125 return R;
126}
127
128static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion) {
129 return MajorVersion * 1000000 + MinorVersion * 1000;
130}
131
133 MacroBuilder &Builder) const {
134 Builder.defineMacro("__riscv");
135 bool Is64Bit = getTriple().isRISCV64();
136 Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32");
137 StringRef CodeModel = getTargetOpts().CodeModel;
138 unsigned FLen = ISAInfo->getFLen();
139 unsigned MinVLen = ISAInfo->getMinVLen();
140 unsigned MaxELen = ISAInfo->getMaxELen();
141 unsigned MaxELenFp = ISAInfo->getMaxELenFp();
142 if (CodeModel == "default")
143 CodeModel = "small";
144
145 if (CodeModel == "small")
146 Builder.defineMacro("__riscv_cmodel_medlow");
147 else if (CodeModel == "medium")
148 Builder.defineMacro("__riscv_cmodel_medany");
149
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");
155 else
156 Builder.defineMacro("__riscv_float_abi_soft");
157
158 if (ABIName == "ilp32e" || ABIName == "lp64e")
159 Builder.defineMacro("__riscv_abi_rve");
160
161 Builder.defineMacro("__riscv_arch_test");
162
163 for (auto &Extension : ISAInfo->getExtensions()) {
164 auto ExtName = Extension.first;
165 auto ExtInfo = Extension.second;
166
167 Builder.defineMacro(Twine("__riscv_", ExtName),
168 Twine(getVersionValue(ExtInfo.Major, ExtInfo.Minor)));
169 }
170
171 if (ISAInfo->hasExtension("zmmul"))
172 Builder.defineMacro("__riscv_mul");
173
174 if (ISAInfo->hasExtension("m")) {
175 Builder.defineMacro("__riscv_div");
176 Builder.defineMacro("__riscv_muldiv");
177 }
178
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");
184 if (Is64Bit)
185 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
186 }
187
188 if (FLen) {
189 Builder.defineMacro("__riscv_flen", Twine(FLen));
190 Builder.defineMacro("__riscv_fdiv");
191 Builder.defineMacro("__riscv_fsqrt");
192 }
193
194 if (MinVLen) {
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));
198 }
199
200 if (ISAInfo->hasExtension("c"))
201 Builder.defineMacro("__riscv_compressed");
202
203 if (ISAInfo->hasExtension("zve32x")) {
204 Builder.defineMacro("__riscv_vector");
205 // Currently we support the v0.12 RISC-V V intrinsics.
206 Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 12)));
207 }
208
209 auto VScale = getVScaleRange(Opts);
210 if (VScale && VScale->first && VScale->first == VScale->second)
211 Builder.defineMacro("__riscv_v_fixed_vlen",
212 Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));
213
214 if (FastScalarUnalignedAccess)
215 Builder.defineMacro("__riscv_misaligned_fast");
216 else
217 Builder.defineMacro("__riscv_misaligned_avoid");
218
219 if (ISAInfo->hasExtension("e")) {
220 if (Is64Bit)
221 Builder.defineMacro("__riscv_64e");
222 else
223 Builder.defineMacro("__riscv_32e");
224 }
225}
226
227static constexpr Builtin::Info BuiltinInfo[] = {
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"
238};
239
243}
244
246 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
247 const std::vector<std::string> &FeaturesVec) const {
248
249 unsigned XLen = 32;
250
251 if (getTriple().isRISCV64()) {
252 Features["64bit"] = true;
253 XLen = 64;
254 } else {
255 Features["32bit"] = true;
256 }
257
258 // If a target attribute specified a full arch string, override all the ISA
259 // extension target features.
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());
263
264 // Add back any non ISA extension features, e.g. +relax.
265 auto IsNonISAExtFeature = [](StringRef Feature) {
266 assert(Feature.size() > 1 && (Feature[0] == '+' || Feature[0] == '-'));
267 StringRef Ext = Feature.substr(1); // drop the +/-
268 return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext);
269 };
270 llvm::copy_if(llvm::make_range(FeaturesVec.begin(), I),
271 std::back_inserter(OverrideFeatures), IsNonISAExtFeature);
272
273 return TargetInfo::initFeatureMap(Features, Diags, CPU, OverrideFeatures);
274 }
275
276 // Otherwise, parse the features and add any implied extensions.
277 std::vector<std::string> AllFeatures = FeaturesVec;
278 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
279 if (!ParseResult) {
280 std::string Buffer;
281 llvm::raw_string_ostream OutputErrMsg(Buffer);
282 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
283 OutputErrMsg << ErrMsg.getMessage();
284 });
285 Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
286 return false;
287 }
288
289 // Append all features, not just new ones, so we override any negatives.
290 llvm::append_range(AllFeatures, (*ParseResult)->toFeatures());
291 return TargetInfo::initFeatureMap(Features, Diags, CPU, AllFeatures);
292}
293
294std::optional<std::pair<unsigned, unsigned>>
296 // RISCV::RVVBitsPerBlock is 64.
297 unsigned VScaleMin = ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock;
298
299 if (LangOpts.VScaleMin || LangOpts.VScaleMax) {
300 // Treat Zvl*b as a lower bound on vscale.
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);
306 }
307
308 if (VScaleMin > 0) {
309 unsigned VScaleMax = ISAInfo->getMaxVLen() / llvm::RISCV::RVVBitsPerBlock;
310 return std::make_pair(VScaleMin, VScaleMax);
311 }
312
313 return std::nullopt;
314}
315
316/// Return true if has this feature, need to sync with handleTargetFeatures.
317bool RISCVTargetInfo::hasFeature(StringRef Feature) const {
318 bool Is64Bit = getTriple().isRISCV64();
319 auto Result = llvm::StringSwitch<std::optional<bool>>(Feature)
320 .Case("riscv", true)
321 .Case("riscv32", !Is64Bit)
322 .Case("riscv64", Is64Bit)
323 .Case("32bit", !Is64Bit)
324 .Case("64bit", Is64Bit)
325 .Case("experimental", HasExperimental)
326 .Default(std::nullopt);
327 if (Result)
328 return *Result;
329
330 return ISAInfo->hasExtension(Feature);
331}
332
333/// Perform initialization based on the user configured set of features.
334bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
335 DiagnosticsEngine &Diags) {
336 unsigned XLen = getTriple().isArch64Bit() ? 64 : 32;
337 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
338 if (!ParseResult) {
339 std::string Buffer;
340 llvm::raw_string_ostream OutputErrMsg(Buffer);
341 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
342 OutputErrMsg << ErrMsg.getMessage();
343 });
344 Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
345 return false;
346 } else {
347 ISAInfo = std::move(*ParseResult);
348 }
349
350 if (ABI.empty())
351 ABI = ISAInfo->computeDefaultABI().str();
352
353 if (ISAInfo->hasExtension("zfh") || ISAInfo->hasExtension("zhinx"))
354 HasLegalHalfType = true;
355
356 FastScalarUnalignedAccess =
357 llvm::is_contained(Features, "+unaligned-scalar-mem");
358
359 if (llvm::is_contained(Features, "+experimental"))
360 HasExperimental = true;
361
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";
365 return false;
366 }
367 return true;
368}
369
370bool RISCVTargetInfo::isValidCPUName(StringRef Name) const {
371 bool Is64Bit = getTriple().isArch64Bit();
372 return llvm::RISCV::parseCPU(Name, Is64Bit);
373}
374
376 SmallVectorImpl<StringRef> &Values) const {
377 bool Is64Bit = getTriple().isArch64Bit();
378 llvm::RISCV::fillValidCPUArchList(Values, Is64Bit);
379}
380
381bool RISCVTargetInfo::isValidTuneCPUName(StringRef Name) const {
382 bool Is64Bit = getTriple().isArch64Bit();
383 return llvm::RISCV::parseTuneCPU(Name, Is64Bit);
384}
385
387 SmallVectorImpl<StringRef> &Values) const {
388 bool Is64Bit = getTriple().isArch64Bit();
389 llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
390}
391
392static void handleFullArchString(StringRef FullArchStr,
393 std::vector<std::string> &Features) {
394 Features.push_back("__RISCV_TargetAttrNeedOverride");
395 auto RII = llvm::RISCVISAInfo::parseArchString(
396 FullArchStr, /* EnableExperimentalExtension */ true);
397 if (llvm::errorToBool(RII.takeError())) {
398 // Forward the invalid FullArchStr.
399 Features.push_back("+" + FullArchStr.str());
400 } else {
401 // Append a full list of features, including any negative extensions so that
402 // we override the CPU's features.
403 std::vector<std::string> FeatStrings =
404 (*RII)->toFeatures(/* AddAllExtensions */ true);
405 Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end());
406 }
407}
408
411 if (Features == "default")
412 return Ret;
413 SmallVector<StringRef, 1> AttrFeatures;
414 Features.split(AttrFeatures, ";");
415 bool FoundArch = false;
416
417 for (auto &Feature : AttrFeatures) {
418 Feature = Feature.trim();
419 StringRef AttrString = Feature.split("=").second.trim();
420
421 if (Feature.starts_with("arch=")) {
422 // Override last features
423 Ret.Features.clear();
424 if (FoundArch)
425 Ret.Duplicate = "arch=";
426 FoundArch = true;
427
428 if (AttrString.starts_with("+")) {
429 // EXTENSION like arch=+v,+zbb
431 AttrString.split(Exts, ",");
432 for (auto Ext : Exts) {
433 if (Ext.empty())
434 continue;
435
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);
441 else
442 Ret.Features.push_back(Ext.str());
443 }
444 } else {
445 // full-arch-string like arch=rv64gcv
446 handleFullArchString(AttrString, Ret.Features);
447 }
448 } else if (Feature.starts_with("cpu=")) {
449 if (!Ret.CPU.empty())
450 Ret.Duplicate = "cpu=";
451
452 Ret.CPU = AttrString;
453
454 if (!FoundArch) {
455 // Update Features with CPU's features
456 StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU);
457 if (MarchFromCPU != "") {
458 Ret.Features.clear();
459 handleFullArchString(MarchFromCPU, Ret.Features);
460 }
461 }
462 } else if (Feature.starts_with("tune=")) {
463 if (!Ret.Tune.empty())
464 Ret.Duplicate = "tune=";
465
466 Ret.Tune = AttrString;
467 }
468 }
469 return Ret;
470}
471
474 switch (CC) {
475 default:
476 return CCCR_Warning;
477 case CC_C:
479 return CCCR_OK;
480 }
481}
482
483bool RISCVTargetInfo::validateCpuSupports(StringRef Feature) const {
484 // Only allow extensions we have a known bit position for in the
485 // __riscv_feature_bits structure.
486 return -1 != llvm::RISCVISAInfo::getRISCVFeaturesBitsInfo(Feature).second;
487}
Defines the Diagnostic-related interfaces.
static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion)
Definition: RISCV.cpp:128
static void handleFullArchString(StringRef FullArchStr, std::vector< std::string > &Features)
Definition: RISCV.cpp:392
static constexpr Builtin::Info BuiltinInfo[]
Definition: Builtins.cpp:32
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.
Definition: Diagnostic.h:192
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1547
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:476
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition: TargetInfo.h:312
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1256
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 ...
Definition: TargetInfo.cpp:532
virtual std::string convertConstraint(const char *&Constraint) const
Definition: TargetInfo.h:1233
std::string convertConstraint(const char *&Constraint) const override
Definition: RISCV.cpp:114
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition: RISCV.cpp:132
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition: RISCV.cpp:240
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override
Definition: RISCV.cpp:74
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 ...
Definition: RISCV.cpp:245
std::unique_ptr< llvm::RISCVISAInfo > ISAInfo
Definition: RISCV.h:30
void fillValidTuneCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values for tuning CPU.
Definition: RISCV.cpp:386
bool isValidTuneCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name for tuning.
Definition: RISCV.cpp:381
std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts) const override
Returns target-specific min and max values VScale_Range.
Definition: RISCV.cpp:295
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition: RISCV.cpp:473
ArrayRef< const char * > getGCCRegNames() const override
Definition: RISCV.cpp:25
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: RISCV.cpp:53
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition: RISCV.cpp:375
bool validateCpuSupports(StringRef Feature) const override
Definition: RISCV.cpp:483
StringRef getABI() const override
Get the ABI currently in use.
Definition: RISCV.h:61
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features.
Definition: RISCV.cpp:334
ParsedTargetAttr parseTargetAttr(StringRef Str) const override
Definition: RISCV.cpp:409
bool hasFeature(StringRef Feature) const override
Return true if has this feature, need to sync with handleTargetFeatures.
Definition: RISCV.cpp:317
bool isValidCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name.
Definition: RISCV.cpp:370
static const char *const GCCRegNames[]
Definition: X86.cpp:44
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.
Definition: Specifiers.h:278
@ CC_C
Definition: Specifiers.h:279
@ CC_RISCVVectorCall
Definition: Specifiers.h:302
Contains information gathered from parsing the contents of TargetAttr.
Definition: TargetInfo.h:57
void setRequiresImmediate(int Min, int Max)
Definition: TargetInfo.h:1153