LLVM  14.0.0git
RISCVISAInfo.cpp
Go to the documentation of this file.
1 //===-- RISCVISAInfo.cpp - RISCV Arch String Parser --------------===//
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 
10 #include "llvm/ADT/None.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/Support/Errc.h"
15 #include "llvm/Support/Error.h"
17 
18 #include <array>
19 #include <string>
20 #include <vector>
21 
22 using namespace llvm;
23 
24 namespace {
25 /// Represents the major and version number components of a RISC-V extension
26 struct RISCVExtensionVersion {
27  unsigned Major;
28  unsigned Minor;
29 };
30 
31 struct RISCVSupportedExtension {
32  const char *Name;
33  /// Supported version.
34  RISCVExtensionVersion Version;
35 };
36 
37 } // end anonymous namespace
38 
39 static constexpr StringLiteral AllStdExts = "mafdqlcbjtpvn";
40 
41 static const RISCVSupportedExtension SupportedExtensions[] = {
42  {"i", RISCVExtensionVersion{2, 0}},
43  {"e", RISCVExtensionVersion{1, 9}},
44  {"m", RISCVExtensionVersion{2, 0}},
45  {"a", RISCVExtensionVersion{2, 0}},
46  {"f", RISCVExtensionVersion{2, 0}},
47  {"d", RISCVExtensionVersion{2, 0}},
48  {"c", RISCVExtensionVersion{2, 0}},
49 };
50 
51 static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
52  {"v", RISCVExtensionVersion{0, 10}},
53  {"zba", RISCVExtensionVersion{1, 0}},
54  {"zbb", RISCVExtensionVersion{1, 0}},
55  {"zbc", RISCVExtensionVersion{1, 0}},
56  {"zbe", RISCVExtensionVersion{0, 93}},
57  {"zbf", RISCVExtensionVersion{0, 93}},
58  {"zbm", RISCVExtensionVersion{0, 93}},
59  {"zbp", RISCVExtensionVersion{0, 93}},
60  {"zbr", RISCVExtensionVersion{0, 93}},
61  {"zbs", RISCVExtensionVersion{1, 0}},
62  {"zbt", RISCVExtensionVersion{0, 93}},
63 
64  {"zvamo", RISCVExtensionVersion{0, 10}},
65  {"zvlsseg", RISCVExtensionVersion{0, 10}},
66 
67  {"zfhmin", RISCVExtensionVersion{0, 1}},
68  {"zfh", RISCVExtensionVersion{0, 1}},
69 };
70 
72  return Ext.consume_front("experimental-");
73 }
74 
75 struct FindByName {
77  StringRef Ext;
78  bool operator()(const RISCVSupportedExtension &ExtInfo) {
79  return ExtInfo.Name == Ext;
80  }
81 };
82 
84  // Find default version of an extension.
85  // TODO: We might set default version based on profile or ISA spec.
86  for (auto &ExtInfo : {makeArrayRef(SupportedExtensions),
88  auto ExtensionInfoIterator = llvm::find_if(ExtInfo, FindByName(ExtName));
89 
90  if (ExtensionInfoIterator == ExtInfo.end()) {
91  continue;
92  }
93  return ExtensionInfoIterator->Version;
94  }
95  return None;
96 }
97 
98 void RISCVISAInfo::addExtension(StringRef ExtName, unsigned MajorVersion,
99  unsigned MinorVersion) {
101  Ext.ExtName = ExtName.str();
102  Ext.MajorVersion = MajorVersion;
103  Ext.MinorVersion = MinorVersion;
104  Exts[ExtName.str()] = Ext;
105 }
106 
108  if (Ext.startswith("sx"))
109  return "non-standard supervisor-level extension";
110  if (Ext.startswith("s"))
111  return "standard supervisor-level extension";
112  if (Ext.startswith("x"))
113  return "non-standard user-level extension";
114  if (Ext.startswith("z"))
115  return "standard user-level extension";
116  return StringRef();
117 }
118 
120  if (Ext.startswith("sx"))
121  return "sx";
122  if (Ext.startswith("s"))
123  return "s";
124  if (Ext.startswith("x"))
125  return "x";
126  if (Ext.startswith("z"))
127  return "z";
128  return StringRef();
129 }
130 
132  auto ExtIterator =
134  if (ExtIterator == std::end(SupportedExperimentalExtensions))
135  return None;
136 
137  return ExtIterator->Version;
138 }
139 
141  bool IsExperimental = stripExperimentalPrefix(Ext);
142 
143  if (IsExperimental)
145  else
147 }
148 
152 }
153 
155  unsigned MinorVersion) {
156  auto FindByNameAndVersion = [=](const RISCVSupportedExtension &ExtInfo) {
157  return ExtInfo.Name == Ext && (MajorVersion == ExtInfo.Version.Major) &&
158  (MinorVersion == ExtInfo.Version.Minor);
159  };
160  return llvm::any_of(SupportedExtensions, FindByNameAndVersion) ||
161  llvm::any_of(SupportedExperimentalExtensions, FindByNameAndVersion);
162 }
163 
166 
168  return false;
169 
170  return Exts.count(Ext.str()) != 0;
171 }
172 
173 // Get the rank for single-letter extension, lower value meaning higher
174 // priority.
175 static int singleLetterExtensionRank(char Ext) {
176  switch (Ext) {
177  case 'i':
178  return -2;
179  case 'e':
180  return -1;
181  default:
182  break;
183  }
184 
185  size_t Pos = AllStdExts.find(Ext);
186  int Rank;
187  if (Pos == StringRef::npos)
188  // If we got an unknown extension letter, then give it an alphabetical
189  // order, but after all known standard extensions.
190  Rank = AllStdExts.size() + (Ext - 'a');
191  else
192  Rank = Pos;
193 
194  return Rank;
195 }
196 
197 // Get the rank for multi-letter extension, lower value meaning higher
198 // priority/order in canonical order.
199 static int multiLetterExtensionRank(const std::string &ExtName) {
200  assert(ExtName.length() >= 2);
201  int HighOrder;
202  int LowOrder = 0;
203  // The order between multi-char extensions: s -> h -> z -> x.
204  char ExtClass = ExtName[0];
205  switch (ExtClass) {
206  case 's':
207  HighOrder = 0;
208  break;
209  case 'h':
210  HighOrder = 1;
211  break;
212  case 'z':
213  HighOrder = 2;
214  // `z` extension must be sorted by canonical order of second letter.
215  // e.g. zmx has higher rank than zax.
216  LowOrder = singleLetterExtensionRank(ExtName[1]);
217  break;
218  case 'x':
219  HighOrder = 3;
220  break;
221  default:
222  llvm_unreachable("Unknown prefix for multi-char extension");
223  return -1;
224  }
225 
226  return (HighOrder << 8) + LowOrder;
227 }
228 
229 // Compare function for extension.
230 // Only compare the extension name, ignore version comparison.
231 bool RISCVISAInfo::compareExtension(const std::string &LHS,
232  const std::string &RHS) {
233  size_t LHSLen = LHS.length();
234  size_t RHSLen = RHS.length();
235  if (LHSLen == 1 && RHSLen != 1)
236  return true;
237 
238  if (LHSLen != 1 && RHSLen == 1)
239  return false;
240 
241  if (LHSLen == 1 && RHSLen == 1)
242  return singleLetterExtensionRank(LHS[0]) <
244 
245  // Both are multi-char ext here.
246  int LHSRank = multiLetterExtensionRank(LHS);
247  int RHSRank = multiLetterExtensionRank(RHS);
248  if (LHSRank != RHSRank)
249  return LHSRank < RHSRank;
250 
251  // If the rank is same, it must be sorted by lexicographic order.
252  return LHS < RHS;
253 }
254 
256  std::vector<StringRef> &Features,
257  std::function<StringRef(const Twine &)> StrAlloc) const {
258  for (auto &Ext : Exts) {
259  StringRef ExtName = Ext.first;
260 
261  if (ExtName == "i")
262  continue;
263 
264  if (ExtName == "zvlsseg") {
265  Features.push_back("+experimental-v");
266  Features.push_back("+experimental-zvlsseg");
267  } else if (ExtName == "zvamo") {
268  Features.push_back("+experimental-v");
269  Features.push_back("+experimental-zvlsseg");
270  Features.push_back("+experimental-zvamo");
271  } else if (isExperimentalExtension(ExtName)) {
272  Features.push_back(StrAlloc("+experimental-" + ExtName));
273  } else {
274  Features.push_back(StrAlloc("+" + ExtName));
275  }
276  }
277 }
278 
279 // Extensions may have a version number, and may be separated by
280 // an underscore '_' e.g.: rv32i2_m2.
281 // Version number is divided into major and minor version numbers,
282 // separated by a 'p'. If the minor version is 0 then 'p0' can be
283 // omitted from the version string. E.g., rv32i2p0, rv32i2, rv32i2p1.
285  unsigned &Minor, unsigned &ConsumeLength,
286  bool EnableExperimentalExtension,
287  bool ExperimentalExtensionVersionCheck) {
288  StringRef MajorStr, MinorStr;
289  Major = 0;
290  Minor = 0;
291  ConsumeLength = 0;
292  MajorStr = In.take_while(isDigit);
293  In = In.substr(MajorStr.size());
294 
295  if (!MajorStr.empty() && In.consume_front("p")) {
296  MinorStr = In.take_while(isDigit);
297  In = In.substr(MajorStr.size() + 1);
298 
299  // Expected 'p' to be followed by minor version number.
300  if (MinorStr.empty()) {
301  return createStringError(
303  "minor version number missing after 'p' for extension '" + Ext + "'");
304  }
305  }
306 
307  if (!MajorStr.empty() && MajorStr.getAsInteger(10, Major))
308  return createStringError(
310  "Failed to parse major version number for extension '" + Ext + "'");
311 
312  if (!MinorStr.empty() && MinorStr.getAsInteger(10, Minor))
313  return createStringError(
315  "Failed to parse minor version number for extension '" + Ext + "'");
316 
317  ConsumeLength = MajorStr.size();
318 
319  if (!MinorStr.empty())
320  ConsumeLength += MinorStr.size() + 1 /*'p'*/;
321 
322  // Expected multi-character extension with version number to have no
323  // subsequent characters (i.e. must either end string or be followed by
324  // an underscore).
325  if (Ext.size() > 1 && In.size()) {
326  std::string Error =
327  "multi-character extensions must be separated by underscores";
329  }
330 
331  // If experimental extension, require use of current version number number
332  if (auto ExperimentalExtension = isExperimentalExtension(Ext)) {
333  if (!EnableExperimentalExtension) {
334  std::string Error = "requires '-menable-experimental-extensions' for "
335  "experimental extension '" +
336  Ext.str() + "'";
338  }
339 
340  if (ExperimentalExtensionVersionCheck &&
341  (MajorStr.empty() && MinorStr.empty())) {
342  std::string Error =
343  "experimental extension requires explicit version number `" +
344  Ext.str() + "`";
346  }
347 
348  auto SupportedVers = *ExperimentalExtension;
349  if (ExperimentalExtensionVersionCheck &&
350  (Major != SupportedVers.Major || Minor != SupportedVers.Minor)) {
351  std::string Error = "unsupported version number " + MajorStr.str();
352  if (!MinorStr.empty())
353  Error += "." + MinorStr.str();
354  Error += " for experimental extension '" + Ext.str() +
355  "'(this compiler supports " + utostr(SupportedVers.Major) + "." +
356  utostr(SupportedVers.Minor) + ")";
358  }
359  return Error::success();
360  }
361 
362  // Exception rule for `g`, we don't have clear version scheme for that on
363  // ISA spec.
364  if (Ext == "g")
365  return Error::success();
366 
367  if (MajorStr.empty() && MinorStr.empty()) {
368  if (auto DefaultVersion = findDefaultVersion(Ext)) {
369  Major = DefaultVersion->Major;
370  Minor = DefaultVersion->Minor;
371  }
372  // No matter found or not, return success, assume other place will
373  // verify.
374  return Error::success();
375  }
376 
377  if (RISCVISAInfo::isSupportedExtension(Ext, Major, Minor))
378  return Error::success();
379 
380  std::string Error = "unsupported version number " + std::string(MajorStr);
381  if (!MinorStr.empty())
382  Error += "." + MinorStr.str();
383  Error += " for extension '" + Ext.str() + "'";
385 }
386 
389  const std::vector<std::string> &Features) {
390  assert(XLen == 32 || XLen == 64);
391  std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
392 
393  bool HasE = false;
394  for (auto &Feature : Features) {
395  StringRef ExtName = Feature;
396  bool Experimental = false;
397  assert(ExtName.size() > 1 && (ExtName[0] == '+' || ExtName[0] == '-'));
398  bool Add = ExtName[0] == '+';
399  ExtName = ExtName.drop_front(1); // Drop '+' or '-'
400  Experimental = stripExperimentalPrefix(ExtName);
401  auto ExtensionInfos = Experimental
404  auto ExtensionInfoIterator =
405  llvm::find_if(ExtensionInfos, FindByName(ExtName));
406 
407  // Not all features is related to ISA extension, like `relax` or
408  // `save-restore`, skip those feature.
409  if (ExtensionInfoIterator == ExtensionInfos.end())
410  continue;
411 
412  if (Add) {
413  if (ExtName == "e") {
414  if (XLen != 32)
415  return createStringError(
417  "standard user-level extension 'e' requires 'rv32'");
418  HasE = true;
419  }
420 
421  ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version.Major,
422  ExtensionInfoIterator->Version.Minor);
423  } else
424  ISAInfo->Exts.erase(ExtName.str());
425  }
426  if (!HasE) {
427  if (auto Version = findDefaultVersion("i"))
428  ISAInfo->addExtension("i", Version->Major, Version->Minor);
429  else
430  llvm_unreachable("Default extension version for 'i' not found?");
431  }
432 
433  ISAInfo->updateFLen();
434 
435  return std::move(ISAInfo);
436 }
437 
439 RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
440  bool ExperimentalExtensionVersionCheck) {
441  // RISC-V ISA strings must be lowercase.
442  if (llvm::any_of(Arch, isupper)) {
444  "string must be lowercase");
445  }
446 
447  bool HasRV64 = Arch.startswith("rv64");
448  // ISA string must begin with rv32 or rv64.
449  if (!(Arch.startswith("rv32") || HasRV64) || (Arch.size() < 5)) {
451  "string must begin with rv32{i,e,g} or rv64{i,g}");
452  }
453 
454  unsigned XLen = HasRV64 ? 64 : 32;
455  std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
456 
457  // The canonical order specified in ISA manual.
458  // Ref: Table 22.1 in RISC-V User-Level ISA V2.2
459  StringRef StdExts = AllStdExts;
460  bool HasF = false, HasD = false;
461  char Baseline = Arch[4];
462 
463  // First letter should be 'e', 'i' or 'g'.
464  switch (Baseline) {
465  default:
467  "first letter should be 'e', 'i' or 'g'");
468  case 'e': {
469  // Extension 'e' is not allowed in rv64.
470  if (HasRV64)
471  return createStringError(
473  "standard user-level extension 'e' requires 'rv32'");
474  break;
475  }
476  case 'i':
477  break;
478  case 'g':
479  // g = imafd
480  StdExts = StdExts.drop_front(4);
481  HasF = true;
482  HasD = true;
483  break;
484  }
485 
486  // Skip rvxxx
487  StringRef Exts = Arch.substr(5);
488 
489  // Remove multi-letter standard extensions, non-standard extensions and
490  // supervisor-level extensions. They have 'z', 'x', 's', 'sx' prefixes.
491  // Parse them at the end.
492  // Find the very first occurrence of 's', 'x' or 'z'.
493  StringRef OtherExts;
494  size_t Pos = Exts.find_first_of("zsx");
495  if (Pos != StringRef::npos) {
496  OtherExts = Exts.substr(Pos);
497  Exts = Exts.substr(0, Pos);
498  }
499 
500  unsigned Major, Minor, ConsumeLength;
501  if (auto E = getExtensionVersion(std::string(1, Baseline), Exts, Major, Minor,
502  ConsumeLength, EnableExperimentalExtension,
503  ExperimentalExtensionVersionCheck))
504  return std::move(E);
505 
506  if (Baseline == 'g') {
507  // No matter which version is given to `g`, we always set imafd to default
508  // version since the we don't have clear version scheme for that on
509  // ISA spec.
510  for (auto Ext : {"i", "m", "a", "f", "d"})
511  if (auto Version = findDefaultVersion(Ext))
512  ISAInfo->addExtension(Ext, Version->Major, Version->Minor);
513  else
514  llvm_unreachable("Default extension version not found?");
515  } else
516  // Baseline is `i` or `e`
517  ISAInfo->addExtension(std::string(1, Baseline), Major, Minor);
518 
519  // Consume the base ISA version number and any '_' between rvxxx and the
520  // first extension
521  Exts = Exts.drop_front(ConsumeLength);
522  Exts.consume_front("_");
523 
524  // TODO: Use version number when setting target features
525 
526  auto StdExtsItr = StdExts.begin();
527  auto StdExtsEnd = StdExts.end();
528  for (auto I = Exts.begin(), E = Exts.end(); I != E;) {
529  char C = *I;
530 
531  // Check ISA extensions are specified in the canonical order.
532  while (StdExtsItr != StdExtsEnd && *StdExtsItr != C)
533  ++StdExtsItr;
534 
535  if (StdExtsItr == StdExtsEnd) {
536  // Either c contains a valid extension but it was not given in
537  // canonical order or it is an invalid extension.
538  if (StdExts.contains(C)) {
539  return createStringError(
541  "standard user-level extension not given in canonical order '%c'",
542  C);
543  }
544 
546  "invalid standard user-level extension '%c'", C);
547  }
548 
549  // Move to next char to prevent repeated letter.
550  ++StdExtsItr;
551 
552  std::string Next;
553  unsigned Major, Minor, ConsumeLength;
554  if (std::next(I) != E)
555  Next = std::string(std::next(I), E);
556  if (auto E = getExtensionVersion(std::string(1, C), Next, Major, Minor,
557  ConsumeLength, EnableExperimentalExtension,
558  ExperimentalExtensionVersionCheck))
559  return std::move(E);
560 
561  // The order is OK, then push it into features.
562  // TODO: Use version number when setting target features
563  switch (C) {
564  default:
565  // Currently LLVM supports only "mafdcbv".
567  "unsupported standard user-level extension '%c'",
568  C);
569  case 'm':
570  ISAInfo->addExtension("m", Major, Minor);
571  break;
572  case 'a':
573  ISAInfo->addExtension("a", Major, Minor);
574  break;
575  case 'f':
576  ISAInfo->addExtension("f", Major, Minor);
577  HasF = true;
578  break;
579  case 'd':
580  ISAInfo->addExtension("d", Major, Minor);
581  HasD = true;
582  break;
583  case 'c':
584  ISAInfo->addExtension("c", Major, Minor);
585  break;
586  case 'v':
587  ISAInfo->addExtension("v", Major, Minor);
588  ISAInfo->addExtension("zvlsseg", Major, Minor);
589  break;
590  }
591  // Consume full extension name and version, including any optional '_'
592  // between this extension and the next
593  ++I;
594  I += ConsumeLength;
595  if (*I == '_')
596  ++I;
597  }
598  // Dependency check.
599  // It's illegal to specify the 'd' (double-precision floating point)
600  // extension without also specifying the 'f' (single precision
601  // floating-point) extension.
602  // TODO: This has been removed in later specs, which specify that D implies F
603  if (HasD && !HasF)
605  "d requires f extension to also be specified");
606 
607  // Additional dependency checks.
608  // TODO: The 'q' extension requires rv64.
609  // TODO: It is illegal to specify 'e' extensions with 'f' and 'd'.
610 
611  if (OtherExts.empty())
612  return std::move(ISAInfo);
613 
614  // Handle other types of extensions other than the standard
615  // general purpose and standard user-level extensions.
616  // Parse the ISA string containing non-standard user-level
617  // extensions, standard supervisor-level extensions and
618  // non-standard supervisor-level extensions.
619  // These extensions start with 'z', 'x', 's', 'sx' prefixes, follow a
620  // canonical order, might have a version number (major, minor)
621  // and are separated by a single underscore '_'.
622  // Set the hardware features for the extensions that are supported.
623 
624  // Multi-letter extensions are seperated by a single underscore
625  // as described in RISC-V User-Level ISA V2.2.
627  OtherExts.split(Split, '_');
628 
630  std::array<StringRef, 4> Prefix{"z", "x", "s", "sx"};
631  auto I = Prefix.begin();
632  auto E = Prefix.end();
633 
634  for (StringRef Ext : Split) {
635  if (Ext.empty())
637  "extension name missing after separator '_'");
638 
641  auto Pos = Ext.find_if(isDigit);
642  StringRef Name(Ext.substr(0, Pos));
643  StringRef Vers(Ext.substr(Pos));
644 
645  if (Type.empty())
647  "invalid extension prefix '" + Ext + "'");
648 
649  // Check ISA extensions are specified in the canonical order.
650  while (I != E && *I != Type)
651  ++I;
652 
653  if (I == E)
655  "%s not given in canonical order '%s'",
656  Desc.str().c_str(), Ext.str().c_str());
657 
658  if (Name.size() == Type.size()) {
660  "%s name missing after '%s'", Desc.str().c_str(),
661  Type.str().c_str());
662  }
663 
664  unsigned Major, Minor, ConsumeLength;
665  if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength,
666  EnableExperimentalExtension,
667  ExperimentalExtensionVersionCheck))
668  return std::move(E);
669 
670  // Check if duplicated extension.
671  if (llvm::is_contained(AllExts, Name))
672  return createStringError(errc::invalid_argument, "duplicated %s '%s'",
673  Desc.str().c_str(), Name.str().c_str());
674 
675  ISAInfo->addExtension(Name, Major, Minor);
676  // Extension format is correct, keep parsing the extensions.
677  // TODO: Save Type, Name, Major, Minor to avoid parsing them later.
678  AllExts.push_back(Name);
679  }
680 
681  for (auto Ext : AllExts) {
682  if (!isSupportedExtension(Ext)) {
684  return createStringError(errc::invalid_argument, "unsupported %s '%s'",
685  Desc.str().c_str(), Ext.str().c_str());
686  }
687  }
688 
689  ISAInfo->updateFLen();
690 
691  return std::move(ISAInfo);
692 }
693 
694 void RISCVISAInfo::updateFLen() {
695  FLen = 0;
696  // TODO: Handle q extension.
697  if (Exts.count("d"))
698  FLen = 64;
699  else if (Exts.count("f"))
700  FLen = 32;
701 }
702 
703 std::string RISCVISAInfo::toString() const {
704  std::string Buffer;
705  raw_string_ostream Arch(Buffer);
706 
707  Arch << "rv" << XLen;
708 
709  ListSeparator LS("_");
710  for (auto &Ext : Exts) {
711  StringRef ExtName = Ext.first;
712  auto ExtInfo = Ext.second;
713  Arch << LS << ExtName;
714  Arch << ExtInfo.MajorVersion << "p" << ExtInfo.MinorVersion;
715  }
716 
717  return Arch.str();
718 }
llvm::RISCVISAInfo::hasExtension
bool hasExtension(StringRef Ext) const
Definition: RISCVISAInfo.cpp:164
llvm::errc::invalid_argument
@ invalid_argument
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:285
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::RISCVISAInfo::compareExtension
static bool compareExtension(const std::string &LHS, const std::string &RHS)
Definition: RISCVISAInfo.cpp:231
llvm::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:152
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:164
StringRef.h
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:625
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:59
llvm::StringRef::find
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:314
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
getExtensionTypeDesc
static StringRef getExtensionTypeDesc(StringRef Ext)
Definition: RISCVISAInfo.cpp:107
FindByName::operator()
bool operator()(const RISCVSupportedExtension &ExtInfo)
Definition: RISCVISAInfo.cpp:78
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
Error.h
llvm::StringRef::consume_front
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:681
FindByName
Definition: RISCVISAInfo.cpp:75
Errc.h
multiLetterExtensionRank
static int multiLetterExtensionRank(const std::string &ExtName)
Definition: RISCVISAInfo.cpp:199
AllStdExts
static constexpr StringLiteral AllStdExts
Definition: RISCVISAInfo.cpp:39
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
llvm::Optional
Definition: APInt.h:33
llvm::RISCVISAInfo::isSupportedExtension
static bool isSupportedExtension(StringRef Ext)
Definition: RISCVISAInfo.cpp:149
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
STLExtras.h
llvm::StringRef::substr
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:610
llvm::StringLiteral
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:890
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::StringRef::split
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:748
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::RISCVISAInfo::parseFeatures
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatures(unsigned XLen, const std::vector< std::string > &Features)
Parse RISCV ISA info from feature vector.
Definition: RISCVISAInfo.cpp:388
llvm::StringRef::contains
LLVM_NODISCARD bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:461
llvm::RISCVISAInfo::toString
std::string toString() const
Definition: RISCVISAInfo.cpp:703
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:244
llvm::StringRef::getAsInteger
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:509
llvm::None
const NoneType None
Definition: None.h:23
getExtensionVersion
static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major, unsigned &Minor, unsigned &ConsumeLength, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck)
Definition: RISCVISAInfo.cpp:284
findDefaultVersion
static Optional< RISCVExtensionVersion > findDefaultVersion(StringRef ExtName)
Definition: RISCVISAInfo.cpp:83
getExtensionType
static StringRef getExtensionType(StringRef Ext)
Definition: RISCVISAInfo.cpp:119
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::MipsISD::Ext
@ Ext
Definition: MipsISelLowering.h:156
llvm::RISCVExtensionInfo
Definition: RISCVISAInfo.h:22
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:129
RISCVISAInfo.h
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
I
#define I(x, y, z)
Definition: MD5.cpp:59
StringExtras.h
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1646
llvm::RISCVISAInfo::parseArchString
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISCV ISA info from arch string.
Definition: RISCVISAInfo.cpp:439
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
isDigit
static bool isDigit(const char C)
Definition: RustDemangle.cpp:206
None.h
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1588
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
SupportedExtensions
static const RISCVSupportedExtension SupportedExtensions[]
Definition: RISCVISAInfo.cpp:41
stripExperimentalPrefix
static bool stripExperimentalPrefix(StringRef &Ext)
Definition: RISCVISAInfo.cpp:71
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1608
llvm::RISCVISAInfo::RISCVISAInfo
RISCVISAInfo(const RISCVISAInfo &)=delete
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1241
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::StringRef::drop_front
LLVM_NODISCARD StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:652
isExperimentalExtension
static Optional< RISCVExtensionVersion > isExperimentalExtension(StringRef Ext)
Definition: RISCVISAInfo.cpp:131
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::AArch64CC::LS
@ LS
Definition: AArch64BaseInfo.h:264
singleLetterExtensionRank
static int singleLetterExtensionRank(char Ext)
Definition: RISCVISAInfo.cpp:175
llvm::RISCVISAInfo::isSupportedExtensionFeature
static bool isSupportedExtensionFeature(StringRef Ext)
Definition: RISCVISAInfo.cpp:140
FindByName::FindByName
FindByName(StringRef Ext)
Definition: RISCVISAInfo.cpp:76
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:474
Version
uint64_t Version
Definition: RawMemProfReader.cpp:24
llvm::RISCVISAInfo::toFeatures
void toFeatures(std::vector< StringRef > &Features, std::function< StringRef(const Twine &)> StrAlloc) const
Convert RISCV ISA info to a feature vector.
Definition: RISCVISAInfo.cpp:255
llvm::StringRef::find_first_of
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Definition: StringRef.h:409
raw_ostream.h
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:156
SupportedExperimentalExtensions
static const RISCVSupportedExtension SupportedExperimentalExtensions[]
Definition: RISCVISAInfo.cpp:51
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:127
llvm::raw_string_ostream::str
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
Definition: raw_ostream.h:643