clang  19.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"
14 #include "clang/Basic/Diagnostic.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/Support/raw_ostream.h"
19 #include "llvm/TargetParser/RISCVTargetParser.h"
20 #include <optional>
21 
22 using namespace clang;
23 using 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.
85  Info.setRequiresImmediate(0);
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 
114 std::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 
128 static 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("m") || 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 (FastUnalignedAccess)
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 
227 static 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 
294 std::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.
317 bool 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.
334 bool 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  FastUnalignedAccess = llvm::is_contained(Features, "+unaligned-scalar-mem") &&
357  llvm::is_contained(Features, "+unaligned-vector-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 
370 bool 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 
381 bool 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 
392 static 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:
478  case CC_RISCVVectorCall:
479  return CCCR_OK;
480  }
481 }
Defines the Diagnostic-related interfaces.
static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion)
Definition: RISCV.cpp:128
static constexpr Builtin::Info BuiltinInfo[]
Definition: RISCV.cpp:227
static void handleFullArchString(StringRef FullArchStr, std::vector< std::string > &Features)
Definition: RISCV.cpp:392
Defines the clang::MacroBuilder utility class.
Enumerates target-specific builtins in their own namespaces within namespace clang.
__DEVICE__ int max(int __a, int __b)
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:193
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1553
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
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:566
virtual std::string convertConstraint(const char *&Constraint) const
Definition: TargetInfo.h:1233
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition: TargetInfo.h:312
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
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
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
Definition: Interp.h:218
static const char *const GCCRegNames[]
Definition: X86.cpp:44
The JSON file list parser is used to communicate input to InstallAPI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:275
@ CC_C
Definition: Specifiers.h:276
@ CC_RISCVVectorCall
Definition: Specifiers.h:299
Contains information gathered from parsing the contents of TargetAttr.
Definition: TargetInfo.h:57
void setRequiresImmediate(int Min, int Max)
Definition: TargetInfo.h:1153