LLVM  16.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/SetVector.h"
13 #include "llvm/ADT/StringExtras.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Support/Errc.h"
16 #include "llvm/Support/Error.h"
18 
19 #include <array>
20 #include <optional>
21 #include <string>
22 #include <vector>
23 
24 using namespace llvm;
25 
26 namespace {
27 /// Represents the major and version number components of a RISC-V extension
28 struct RISCVExtensionVersion {
29  unsigned Major;
30  unsigned Minor;
31 };
32 
33 struct RISCVSupportedExtension {
34  const char *Name;
35  /// Supported version.
36  RISCVExtensionVersion Version;
37 };
38 
39 } // end anonymous namespace
40 
41 static constexpr StringLiteral AllStdExts = "mafdqlcbkjtpvn";
42 
43 static const RISCVSupportedExtension SupportedExtensions[] = {
44  {"i", RISCVExtensionVersion{2, 0}},
45  {"e", RISCVExtensionVersion{1, 9}},
46  {"m", RISCVExtensionVersion{2, 0}},
47  {"a", RISCVExtensionVersion{2, 0}},
48  {"f", RISCVExtensionVersion{2, 0}},
49  {"d", RISCVExtensionVersion{2, 0}},
50  {"c", RISCVExtensionVersion{2, 0}},
51 
52  {"zihintpause", RISCVExtensionVersion{2, 0}},
53 
54  {"zfhmin", RISCVExtensionVersion{1, 0}},
55  {"zfh", RISCVExtensionVersion{1, 0}},
56 
57  {"zfinx", RISCVExtensionVersion{1, 0}},
58  {"zdinx", RISCVExtensionVersion{1, 0}},
59  {"zhinxmin", RISCVExtensionVersion{1, 0}},
60  {"zhinx", RISCVExtensionVersion{1, 0}},
61 
62  {"zba", RISCVExtensionVersion{1, 0}},
63  {"zbb", RISCVExtensionVersion{1, 0}},
64  {"zbc", RISCVExtensionVersion{1, 0}},
65  {"zbs", RISCVExtensionVersion{1, 0}},
66 
67  {"zbkb", RISCVExtensionVersion{1, 0}},
68  {"zbkc", RISCVExtensionVersion{1, 0}},
69  {"zbkx", RISCVExtensionVersion{1, 0}},
70  {"zknd", RISCVExtensionVersion{1, 0}},
71  {"zkne", RISCVExtensionVersion{1, 0}},
72  {"zknh", RISCVExtensionVersion{1, 0}},
73  {"zksed", RISCVExtensionVersion{1, 0}},
74  {"zksh", RISCVExtensionVersion{1, 0}},
75  {"zkr", RISCVExtensionVersion{1, 0}},
76  {"zkn", RISCVExtensionVersion{1, 0}},
77  {"zks", RISCVExtensionVersion{1, 0}},
78  {"zkt", RISCVExtensionVersion{1, 0}},
79  {"zk", RISCVExtensionVersion{1, 0}},
80 
81  {"zmmul", RISCVExtensionVersion{1, 0}},
82 
83  {"v", RISCVExtensionVersion{1, 0}},
84  {"zvl32b", RISCVExtensionVersion{1, 0}},
85  {"zvl64b", RISCVExtensionVersion{1, 0}},
86  {"zvl128b", RISCVExtensionVersion{1, 0}},
87  {"zvl256b", RISCVExtensionVersion{1, 0}},
88  {"zvl512b", RISCVExtensionVersion{1, 0}},
89  {"zvl1024b", RISCVExtensionVersion{1, 0}},
90  {"zvl2048b", RISCVExtensionVersion{1, 0}},
91  {"zvl4096b", RISCVExtensionVersion{1, 0}},
92  {"zvl8192b", RISCVExtensionVersion{1, 0}},
93  {"zvl16384b", RISCVExtensionVersion{1, 0}},
94  {"zvl32768b", RISCVExtensionVersion{1, 0}},
95  {"zvl65536b", RISCVExtensionVersion{1, 0}},
96  {"zve32x", RISCVExtensionVersion{1, 0}},
97  {"zve32f", RISCVExtensionVersion{1, 0}},
98  {"zve64x", RISCVExtensionVersion{1, 0}},
99  {"zve64f", RISCVExtensionVersion{1, 0}},
100  {"zve64d", RISCVExtensionVersion{1, 0}},
101 
102  {"zicbom", RISCVExtensionVersion{1, 0}},
103  {"zicboz", RISCVExtensionVersion{1, 0}},
104  {"zicbop", RISCVExtensionVersion{1, 0}},
105 
106  {"svnapot", RISCVExtensionVersion{1, 0}},
107  {"svinval", RISCVExtensionVersion{1, 0}},
108  {"xventanacondops", RISCVExtensionVersion{1, 0}},
109 };
110 
111 static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
112  {"zihintntl", RISCVExtensionVersion{0, 2}},
113 
114  {"zca", RISCVExtensionVersion{0, 70}},
115  {"zcd", RISCVExtensionVersion{0, 70}},
116  {"zcf", RISCVExtensionVersion{0, 70}},
117  {"zvfh", RISCVExtensionVersion{0, 1}},
118  {"zawrs", RISCVExtensionVersion{1, 0}},
119  {"ztso", RISCVExtensionVersion{0, 1}},
120 };
121 
123  return Ext.consume_front("experimental-");
124 }
125 
126 // This function finds the first character that doesn't belong to a version
127 // (e.g. zba1p0 is extension 'zba' of version '1p0'). So the function will
128 // consume [0-9]*p[0-9]* starting from the backward. An extension name will not
129 // end with a digit or the letter 'p', so this function will parse correctly.
130 // NOTE: This function is NOT able to take empty strings or strings that only
131 // have version numbers and no extension name. It assumes the extension name
132 // will be at least more than one character.
134  assert(!Ext.empty() &&
135  "Already guarded by if-statement in ::parseArchString");
136 
137  int Pos = Ext.size() - 1;
138  while (Pos > 0 && isDigit(Ext[Pos]))
139  Pos--;
140  if (Pos > 0 && Ext[Pos] == 'p' && isDigit(Ext[Pos - 1])) {
141  Pos--;
142  while (Pos > 0 && isDigit(Ext[Pos]))
143  Pos--;
144  }
145  return Pos;
146 }
147 
148 namespace {
149 struct FindByName {
150  FindByName(StringRef Ext) : Ext(Ext){};
151  StringRef Ext;
152  bool operator()(const RISCVSupportedExtension &ExtInfo) {
153  return ExtInfo.Name == Ext;
154  }
155 };
156 } // namespace
157 
158 static std::optional<RISCVExtensionVersion>
160  // Find default version of an extension.
161  // TODO: We might set default version based on profile or ISA spec.
162  for (auto &ExtInfo : {makeArrayRef(SupportedExtensions),
164  auto ExtensionInfoIterator = llvm::find_if(ExtInfo, FindByName(ExtName));
165 
166  if (ExtensionInfoIterator == ExtInfo.end()) {
167  continue;
168  }
169  return ExtensionInfoIterator->Version;
170  }
171  return None;
172 }
173 
174 void RISCVISAInfo::addExtension(StringRef ExtName, unsigned MajorVersion,
175  unsigned MinorVersion) {
177  Ext.ExtName = ExtName.str();
178  Ext.MajorVersion = MajorVersion;
179  Ext.MinorVersion = MinorVersion;
180  Exts[ExtName.str()] = Ext;
181 }
182 
184  if (Ext.startswith("sx"))
185  return "non-standard supervisor-level extension";
186  if (Ext.startswith("s"))
187  return "standard supervisor-level extension";
188  if (Ext.startswith("x"))
189  return "non-standard user-level extension";
190  if (Ext.startswith("z"))
191  return "standard user-level extension";
192  return StringRef();
193 }
194 
196  if (Ext.startswith("sx"))
197  return "sx";
198  if (Ext.startswith("s"))
199  return "s";
200  if (Ext.startswith("x"))
201  return "x";
202  if (Ext.startswith("z"))
203  return "z";
204  return StringRef();
205 }
206 
207 static std::optional<RISCVExtensionVersion>
209  auto ExtIterator =
211  if (ExtIterator == std::end(SupportedExperimentalExtensions))
212  return None;
213 
214  return ExtIterator->Version;
215 }
216 
218  bool IsExperimental = stripExperimentalPrefix(Ext);
219 
220  if (IsExperimental)
221  return llvm::any_of(SupportedExperimentalExtensions, FindByName(Ext));
222  else
223  return llvm::any_of(SupportedExtensions, FindByName(Ext));
224 }
225 
227  return llvm::any_of(SupportedExtensions, FindByName(Ext)) ||
229 }
230 
232  unsigned MinorVersion) {
233  auto FindByNameAndVersion = [=](const RISCVSupportedExtension &ExtInfo) {
234  return ExtInfo.Name == Ext && (MajorVersion == ExtInfo.Version.Major) &&
235  (MinorVersion == ExtInfo.Version.Minor);
236  };
237  return llvm::any_of(SupportedExtensions, FindByNameAndVersion) ||
238  llvm::any_of(SupportedExperimentalExtensions, FindByNameAndVersion);
239 }
240 
243 
245  return false;
246 
247  return Exts.count(Ext.str()) != 0;
248 }
249 
250 // Get the rank for single-letter extension, lower value meaning higher
251 // priority.
252 static int singleLetterExtensionRank(char Ext) {
253  switch (Ext) {
254  case 'i':
255  return -2;
256  case 'e':
257  return -1;
258  default:
259  break;
260  }
261 
262  size_t Pos = AllStdExts.find(Ext);
263  int Rank;
264  if (Pos == StringRef::npos)
265  // If we got an unknown extension letter, then give it an alphabetical
266  // order, but after all known standard extensions.
267  Rank = AllStdExts.size() + (Ext - 'a');
268  else
269  Rank = Pos;
270 
271  return Rank;
272 }
273 
274 // Get the rank for multi-letter extension, lower value meaning higher
275 // priority/order in canonical order.
276 static int multiLetterExtensionRank(const std::string &ExtName) {
277  assert(ExtName.length() >= 2);
278  int HighOrder;
279  int LowOrder = 0;
280  // The order between multi-char extensions: s -> h -> z -> x.
281  char ExtClass = ExtName[0];
282  switch (ExtClass) {
283  case 's':
284  HighOrder = 0;
285  break;
286  case 'h':
287  HighOrder = 1;
288  break;
289  case 'z':
290  HighOrder = 2;
291  // `z` extension must be sorted by canonical order of second letter.
292  // e.g. zmx has higher rank than zax.
293  LowOrder = singleLetterExtensionRank(ExtName[1]);
294  break;
295  case 'x':
296  HighOrder = 3;
297  break;
298  default:
299  llvm_unreachable("Unknown prefix for multi-char extension");
300  return -1;
301  }
302 
303  return (HighOrder << 8) + LowOrder;
304 }
305 
306 // Compare function for extension.
307 // Only compare the extension name, ignore version comparison.
308 bool RISCVISAInfo::compareExtension(const std::string &LHS,
309  const std::string &RHS) {
310  size_t LHSLen = LHS.length();
311  size_t RHSLen = RHS.length();
312  if (LHSLen == 1 && RHSLen != 1)
313  return true;
314 
315  if (LHSLen != 1 && RHSLen == 1)
316  return false;
317 
318  if (LHSLen == 1 && RHSLen == 1)
319  return singleLetterExtensionRank(LHS[0]) <
321 
322  // Both are multi-char ext here.
323  int LHSRank = multiLetterExtensionRank(LHS);
324  int RHSRank = multiLetterExtensionRank(RHS);
325  if (LHSRank != RHSRank)
326  return LHSRank < RHSRank;
327 
328  // If the rank is same, it must be sorted by lexicographic order.
329  return LHS < RHS;
330 }
331 
333  std::vector<StringRef> &Features,
334  std::function<StringRef(const Twine &)> StrAlloc) const {
335  for (auto const &Ext : Exts) {
336  StringRef ExtName = Ext.first;
337 
338  if (ExtName == "i")
339  continue;
340 
341  if (isExperimentalExtension(ExtName)) {
342  Features.push_back(StrAlloc("+experimental-" + ExtName));
343  } else {
344  Features.push_back(StrAlloc("+" + ExtName));
345  }
346  }
347 }
348 
349 // Extensions may have a version number, and may be separated by
350 // an underscore '_' e.g.: rv32i2_m2.
351 // Version number is divided into major and minor version numbers,
352 // separated by a 'p'. If the minor version is 0 then 'p0' can be
353 // omitted from the version string. E.g., rv32i2p0, rv32i2, rv32i2p1.
355  unsigned &Minor, unsigned &ConsumeLength,
356  bool EnableExperimentalExtension,
357  bool ExperimentalExtensionVersionCheck) {
358  StringRef MajorStr, MinorStr;
359  Major = 0;
360  Minor = 0;
361  ConsumeLength = 0;
362  MajorStr = In.take_while(isDigit);
363  In = In.substr(MajorStr.size());
364 
365  if (!MajorStr.empty() && In.consume_front("p")) {
366  MinorStr = In.take_while(isDigit);
367  In = In.substr(MajorStr.size() + MinorStr.size() - 1);
368 
369  // Expected 'p' to be followed by minor version number.
370  if (MinorStr.empty()) {
371  return createStringError(
373  "minor version number missing after 'p' for extension '" + Ext + "'");
374  }
375  }
376 
377  if (!MajorStr.empty() && MajorStr.getAsInteger(10, Major))
378  return createStringError(
380  "Failed to parse major version number for extension '" + Ext + "'");
381 
382  if (!MinorStr.empty() && MinorStr.getAsInteger(10, Minor))
383  return createStringError(
385  "Failed to parse minor version number for extension '" + Ext + "'");
386 
387  ConsumeLength = MajorStr.size();
388 
389  if (!MinorStr.empty())
390  ConsumeLength += MinorStr.size() + 1 /*'p'*/;
391 
392  // Expected multi-character extension with version number to have no
393  // subsequent characters (i.e. must either end string or be followed by
394  // an underscore).
395  if (Ext.size() > 1 && In.size()) {
396  std::string Error =
397  "multi-character extensions must be separated by underscores";
399  }
400 
401  // If experimental extension, require use of current version number number
402  if (auto ExperimentalExtension = isExperimentalExtension(Ext)) {
403  if (!EnableExperimentalExtension) {
404  std::string Error = "requires '-menable-experimental-extensions' for "
405  "experimental extension '" +
406  Ext.str() + "'";
408  }
409 
410  if (ExperimentalExtensionVersionCheck &&
411  (MajorStr.empty() && MinorStr.empty())) {
412  std::string Error =
413  "experimental extension requires explicit version number `" +
414  Ext.str() + "`";
416  }
417 
418  auto SupportedVers = *ExperimentalExtension;
419  if (ExperimentalExtensionVersionCheck &&
420  (Major != SupportedVers.Major || Minor != SupportedVers.Minor)) {
421  std::string Error = "unsupported version number " + MajorStr.str();
422  if (!MinorStr.empty())
423  Error += "." + MinorStr.str();
424  Error += " for experimental extension '" + Ext.str() +
425  "' (this compiler supports " + utostr(SupportedVers.Major) +
426  "." + utostr(SupportedVers.Minor) + ")";
428  }
429  return Error::success();
430  }
431 
432  // Exception rule for `g`, we don't have clear version scheme for that on
433  // ISA spec.
434  if (Ext == "g")
435  return Error::success();
436 
437  if (MajorStr.empty() && MinorStr.empty()) {
438  if (auto DefaultVersion = findDefaultVersion(Ext)) {
439  Major = DefaultVersion->Major;
440  Minor = DefaultVersion->Minor;
441  }
442  // No matter found or not, return success, assume other place will
443  // verify.
444  return Error::success();
445  }
446 
447  if (RISCVISAInfo::isSupportedExtension(Ext, Major, Minor))
448  return Error::success();
449 
450  std::string Error = "unsupported version number " + std::string(MajorStr);
451  if (!MinorStr.empty())
452  Error += "." + MinorStr.str();
453  Error += " for extension '" + Ext.str() + "'";
455 }
456 
459  const std::vector<std::string> &Features) {
460  assert(XLen == 32 || XLen == 64);
461  std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
462 
463  for (auto &Feature : Features) {
464  StringRef ExtName = Feature;
465  bool Experimental = false;
466  assert(ExtName.size() > 1 && (ExtName[0] == '+' || ExtName[0] == '-'));
467  bool Add = ExtName[0] == '+';
468  ExtName = ExtName.drop_front(1); // Drop '+' or '-'
469  Experimental = stripExperimentalPrefix(ExtName);
470  auto ExtensionInfos = Experimental
473  auto ExtensionInfoIterator =
474  llvm::find_if(ExtensionInfos, FindByName(ExtName));
475 
476  // Not all features is related to ISA extension, like `relax` or
477  // `save-restore`, skip those feature.
478  if (ExtensionInfoIterator == ExtensionInfos.end())
479  continue;
480 
481  if (Add)
482  ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version.Major,
483  ExtensionInfoIterator->Version.Minor);
484  else
485  ISAInfo->Exts.erase(ExtName.str());
486  }
487 
488  return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
489 }
490 
492 RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
493  bool ExperimentalExtensionVersionCheck) {
494  // RISC-V ISA strings must be lowercase.
495  if (llvm::any_of(Arch, isupper)) {
497  "string must be lowercase");
498  }
499 
500  bool HasRV64 = Arch.startswith("rv64");
501  // ISA string must begin with rv32 or rv64.
502  if (!(Arch.startswith("rv32") || HasRV64) || (Arch.size() < 5)) {
504  "string must begin with rv32{i,e,g} or rv64{i,g}");
505  }
506 
507  unsigned XLen = HasRV64 ? 64 : 32;
508  std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
509 
510  // The canonical order specified in ISA manual.
511  // Ref: Table 22.1 in RISC-V User-Level ISA V2.2
512  StringRef StdExts = AllStdExts;
513  char Baseline = Arch[4];
514 
515  // First letter should be 'e', 'i' or 'g'.
516  switch (Baseline) {
517  default:
519  "first letter should be 'e', 'i' or 'g'");
520  case 'e': {
521  // Extension 'e' is not allowed in rv64.
522  if (HasRV64)
523  return createStringError(
525  "standard user-level extension 'e' requires 'rv32'");
526  break;
527  }
528  case 'i':
529  break;
530  case 'g':
531  // g = imafd
532  StdExts = StdExts.drop_front(4);
533  break;
534  }
535 
536  // Skip rvxxx
537  StringRef Exts = Arch.substr(5);
538 
539  // Remove multi-letter standard extensions, non-standard extensions and
540  // supervisor-level extensions. They have 'z', 'x', 's', 'sx' prefixes.
541  // Parse them at the end.
542  // Find the very first occurrence of 's', 'x' or 'z'.
543  StringRef OtherExts;
544  size_t Pos = Exts.find_first_of("zsx");
545  if (Pos != StringRef::npos) {
546  OtherExts = Exts.substr(Pos);
547  Exts = Exts.substr(0, Pos);
548  }
549 
550  unsigned Major, Minor, ConsumeLength;
551  if (auto E = getExtensionVersion(std::string(1, Baseline), Exts, Major, Minor,
552  ConsumeLength, EnableExperimentalExtension,
553  ExperimentalExtensionVersionCheck))
554  return std::move(E);
555 
556  if (Baseline == 'g') {
557  // No matter which version is given to `g`, we always set imafd to default
558  // version since the we don't have clear version scheme for that on
559  // ISA spec.
560  for (const auto *Ext : {"i", "m", "a", "f", "d"})
561  if (auto Version = findDefaultVersion(Ext))
562  ISAInfo->addExtension(Ext, Version->Major, Version->Minor);
563  else
564  llvm_unreachable("Default extension version not found?");
565  } else
566  // Baseline is `i` or `e`
567  ISAInfo->addExtension(std::string(1, Baseline), Major, Minor);
568 
569  // Consume the base ISA version number and any '_' between rvxxx and the
570  // first extension
571  Exts = Exts.drop_front(ConsumeLength);
572  Exts.consume_front("_");
573 
574  // TODO: Use version number when setting target features
575 
576  auto StdExtsItr = StdExts.begin();
577  auto StdExtsEnd = StdExts.end();
578  for (auto I = Exts.begin(), E = Exts.end(); I != E;) {
579  char C = *I;
580 
581  // Check ISA extensions are specified in the canonical order.
582  while (StdExtsItr != StdExtsEnd && *StdExtsItr != C)
583  ++StdExtsItr;
584 
585  if (StdExtsItr == StdExtsEnd) {
586  // Either c contains a valid extension but it was not given in
587  // canonical order or it is an invalid extension.
588  if (StdExts.contains(C)) {
589  return createStringError(
591  "standard user-level extension not given in canonical order '%c'",
592  C);
593  }
594 
596  "invalid standard user-level extension '%c'", C);
597  }
598 
599  // Move to next char to prevent repeated letter.
600  ++StdExtsItr;
601 
602  std::string Next;
603  unsigned Major, Minor, ConsumeLength;
604  if (std::next(I) != E)
605  Next = std::string(std::next(I), E);
606  if (auto E = getExtensionVersion(std::string(1, C), Next, Major, Minor,
607  ConsumeLength, EnableExperimentalExtension,
608  ExperimentalExtensionVersionCheck))
609  return std::move(E);
610 
611  // The order is OK, then push it into features.
612  // TODO: Use version number when setting target features
613  // Currently LLVM supports only "mafdcv".
614  StringRef SupportedStandardExtension = "mafdcv";
615  if (!SupportedStandardExtension.contains(C))
617  "unsupported standard user-level extension '%c'",
618  C);
619  ISAInfo->addExtension(std::string(1, C), Major, Minor);
620 
621  // Consume full extension name and version, including any optional '_'
622  // between this extension and the next
623  ++I;
624  I += ConsumeLength;
625  if (*I == '_')
626  ++I;
627  }
628 
629  // Handle other types of extensions other than the standard
630  // general purpose and standard user-level extensions.
631  // Parse the ISA string containing non-standard user-level
632  // extensions, standard supervisor-level extensions and
633  // non-standard supervisor-level extensions.
634  // These extensions start with 'z', 'x', 's', 'sx' prefixes, follow a
635  // canonical order, might have a version number (major, minor)
636  // and are separated by a single underscore '_'.
637  // Set the hardware features for the extensions that are supported.
638 
639  // Multi-letter extensions are seperated by a single underscore
640  // as described in RISC-V User-Level ISA V2.2.
642  OtherExts.split(Split, '_');
643 
645  std::array<StringRef, 4> Prefix{"z", "x", "s", "sx"};
646  auto I = Prefix.begin();
647  auto E = Prefix.end();
648  if (Split.size() > 1 || Split[0] != "") {
649  for (StringRef Ext : Split) {
650  if (Ext.empty())
652  "extension name missing after separator '_'");
653 
656  auto Pos = findFirstNonVersionCharacter(Ext) + 1;
657  StringRef Name(Ext.substr(0, Pos));
658  StringRef Vers(Ext.substr(Pos));
659 
660  if (Type.empty())
662  "invalid extension prefix '" + Ext + "'");
663 
664  // Check ISA extensions are specified in the canonical order.
665  while (I != E && *I != Type)
666  ++I;
667 
668  if (I == E)
670  "%s not given in canonical order '%s'",
671  Desc.str().c_str(), Ext.str().c_str());
672 
673  if (Name.size() == Type.size()) {
675  "%s name missing after '%s'",
676  Desc.str().c_str(), Type.str().c_str());
677  }
678 
679  unsigned Major, Minor, ConsumeLength;
680  if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength,
681  EnableExperimentalExtension,
682  ExperimentalExtensionVersionCheck))
683  return std::move(E);
684 
685  // Check if duplicated extension.
686  if (llvm::is_contained(AllExts, Name))
687  return createStringError(errc::invalid_argument, "duplicated %s '%s'",
688  Desc.str().c_str(), Name.str().c_str());
689 
690  ISAInfo->addExtension(Name, Major, Minor);
691  // Extension format is correct, keep parsing the extensions.
692  // TODO: Save Type, Name, Major, Minor to avoid parsing them later.
693  AllExts.push_back(Name);
694  }
695  }
696 
697  for (auto Ext : AllExts) {
698  if (!isSupportedExtension(Ext)) {
700  return createStringError(errc::invalid_argument, "unsupported %s '%s'",
701  Desc.str().c_str(), Ext.str().c_str());
702  }
703  }
704 
705  return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
706 }
707 
708 Error RISCVISAInfo::checkDependency() {
709  bool IsRv32 = XLen == 32;
710  bool HasE = Exts.count("e") != 0;
711  bool HasD = Exts.count("d") != 0;
712  bool HasF = Exts.count("f") != 0;
713  bool HasZfinx = Exts.count("zfinx") != 0;
714  bool HasZdinx = Exts.count("zdinx") != 0;
715  bool HasVector = Exts.count("zve32x") != 0;
716  bool HasZve32f = Exts.count("zve32f") != 0;
717  bool HasZve64d = Exts.count("zve64d") != 0;
718  bool HasZvl = MinVLen != 0;
719 
720  if (HasE && !IsRv32)
721  return createStringError(
723  "standard user-level extension 'e' requires 'rv32'");
724 
725  // It's illegal to specify the 'd' (double-precision floating point)
726  // extension without also specifying the 'f' (single precision
727  // floating-point) extension.
728  // TODO: This has been removed in later specs, which specify that D implies F
729  if (HasD && !HasF)
731  "d requires f extension to also be specified");
732 
733  if (HasZve32f && !HasF && !HasZfinx)
734  return createStringError(
736  "zve32f requires f or zfinx extension to also be specified");
737 
738  if (HasZve64d && !HasD && !HasZdinx)
739  return createStringError(
741  "zve64d requires d or zdinx extension to also be specified");
742 
743  if (Exts.count("zvfh") && !Exts.count("zfh") && !Exts.count("zfhmin") &&
744  !Exts.count("zhinx") && !Exts.count("zhinxmin"))
745  return createStringError(
747  "zvfh requires zfh, zfhmin, zhinx or zhinxmin extension to also be "
748  "specified");
749 
750  if (HasZvl && !HasVector)
751  return createStringError(
753  "zvl*b requires v or zve* extension to also be specified");
754 
755  // Additional dependency checks.
756  // TODO: The 'q' extension requires rv64.
757  // TODO: It is illegal to specify 'e' extensions with 'f' and 'd'.
758 
759  return Error::success();
760 }
761 
762 static const char *ImpliedExtsV[] = {"zvl128b", "zve64d", "f", "d"};
763 static const char *ImpliedExtsZfhmin[] = {"f"};
764 static const char *ImpliedExtsZfh[] = {"f"};
765 static const char *ImpliedExtsZdinx[] = {"zfinx"};
766 static const char *ImpliedExtsZhinxmin[] = {"zfinx"};
767 static const char *ImpliedExtsZhinx[] = {"zfinx"};
768 static const char *ImpliedExtsZve64d[] = {"zve64f"};
769 static const char *ImpliedExtsZve64f[] = {"zve64x", "zve32f"};
770 static const char *ImpliedExtsZve64x[] = {"zve32x", "zvl64b"};
771 static const char *ImpliedExtsZve32f[] = {"zve32x"};
772 static const char *ImpliedExtsZve32x[] = {"zvl32b"};
773 static const char *ImpliedExtsZvl65536b[] = {"zvl32768b"};
774 static const char *ImpliedExtsZvl32768b[] = {"zvl16384b"};
775 static const char *ImpliedExtsZvl16384b[] = {"zvl8192b"};
776 static const char *ImpliedExtsZvl8192b[] = {"zvl4096b"};
777 static const char *ImpliedExtsZvl4096b[] = {"zvl2048b"};
778 static const char *ImpliedExtsZvl2048b[] = {"zvl1024b"};
779 static const char *ImpliedExtsZvl1024b[] = {"zvl512b"};
780 static const char *ImpliedExtsZvl512b[] = {"zvl256b"};
781 static const char *ImpliedExtsZvl256b[] = {"zvl128b"};
782 static const char *ImpliedExtsZvl128b[] = {"zvl64b"};
783 static const char *ImpliedExtsZvl64b[] = {"zvl32b"};
784 static const char *ImpliedExtsZk[] = {"zkn", "zkt", "zkr"};
785 static const char *ImpliedExtsZkn[] = {"zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"};
786 static const char *ImpliedExtsZks[] = {"zbkb", "zbkc", "zbkx", "zksed", "zksh"};
787 static const char *ImpliedExtsZvfh[] = {"zve32f"};
788 
792 
793  bool operator<(const ImpliedExtsEntry &Other) const {
794  return Name < Other.Name;
795  }
796 
797  bool operator<(StringRef Other) const { return Name < Other; }
798 };
799 
800 // Note: The table needs to be sorted by name.
801 static constexpr ImpliedExtsEntry ImpliedExts[] = {
802  {{"v"}, {ImpliedExtsV}},
803  {{"zdinx"}, {ImpliedExtsZdinx}},
804  {{"zfh"}, {ImpliedExtsZfh}},
805  {{"zfhmin"}, {ImpliedExtsZfhmin}},
806  {{"zhinx"}, {ImpliedExtsZhinx}},
807  {{"zhinxmin"}, {ImpliedExtsZhinxmin}},
808  {{"zk"}, {ImpliedExtsZk}},
809  {{"zkn"}, {ImpliedExtsZkn}},
810  {{"zks"}, {ImpliedExtsZks}},
811  {{"zve32f"}, {ImpliedExtsZve32f}},
812  {{"zve32x"}, {ImpliedExtsZve32x}},
813  {{"zve64d"}, {ImpliedExtsZve64d}},
814  {{"zve64f"}, {ImpliedExtsZve64f}},
815  {{"zve64x"}, {ImpliedExtsZve64x}},
816  {{"zvfh"}, {ImpliedExtsZvfh}},
817  {{"zvl1024b"}, {ImpliedExtsZvl1024b}},
818  {{"zvl128b"}, {ImpliedExtsZvl128b}},
819  {{"zvl16384b"}, {ImpliedExtsZvl16384b}},
820  {{"zvl2048b"}, {ImpliedExtsZvl2048b}},
821  {{"zvl256b"}, {ImpliedExtsZvl256b}},
822  {{"zvl32768b"}, {ImpliedExtsZvl32768b}},
823  {{"zvl4096b"}, {ImpliedExtsZvl4096b}},
824  {{"zvl512b"}, {ImpliedExtsZvl512b}},
825  {{"zvl64b"}, {ImpliedExtsZvl64b}},
826  {{"zvl65536b"}, {ImpliedExtsZvl65536b}},
827  {{"zvl8192b"}, {ImpliedExtsZvl8192b}},
828 };
829 
830 void RISCVISAInfo::updateImplication() {
831  bool HasE = Exts.count("e") != 0;
832  bool HasI = Exts.count("i") != 0;
833 
834  // If not in e extension and i extension does not exist, i extension is
835  // implied
836  if (!HasE && !HasI) {
837  auto Version = findDefaultVersion("i");
838  addExtension("i", Version->Major, Version->Minor);
839  }
840 
841  assert(llvm::is_sorted(ImpliedExts) && "Table not sorted by Name");
842 
843  // This loop may execute over 1 iteration since implication can be layered
844  // Exits loop if no more implication is applied
846  for (auto const &Ext : Exts)
847  WorkList.insert(Ext.first);
848 
849  while (!WorkList.empty()) {
850  StringRef ExtName = WorkList.pop_back_val();
851  auto I = llvm::lower_bound(ImpliedExts, ExtName);
852  if (I != std::end(ImpliedExts) && I->Name == ExtName) {
853  for (const char *ImpliedExt : I->Exts) {
854  if (WorkList.count(ImpliedExt))
855  continue;
856  if (Exts.count(ImpliedExt))
857  continue;
858  auto Version = findDefaultVersion(ImpliedExt);
859  addExtension(ImpliedExt, Version->Major, Version->Minor);
860  WorkList.insert(ImpliedExt);
861  }
862  }
863  }
864 }
865 
869 };
870 
871 static constexpr CombinedExtsEntry CombineIntoExts[] = {
872  {{"zk"}, {ImpliedExtsZk}},
873  {{"zkn"}, {ImpliedExtsZkn}},
874  {{"zks"}, {ImpliedExtsZks}},
875 };
876 
877 void RISCVISAInfo::updateCombination() {
878  bool IsNewCombine = false;
879  do {
880  IsNewCombine = false;
881  for (CombinedExtsEntry CombineIntoExt : CombineIntoExts) {
882  auto CombineExt = CombineIntoExt.CombineExt;
883  auto RequiredExts = CombineIntoExt.RequiredExts;
884  if (hasExtension(CombineExt))
885  continue;
886  bool IsAllRequiredFeatureExist = true;
887  for (const char *Ext : RequiredExts)
888  IsAllRequiredFeatureExist &= hasExtension(Ext);
889  if (IsAllRequiredFeatureExist) {
890  auto Version = findDefaultVersion(CombineExt);
891  addExtension(CombineExt, Version->Major, Version->Minor);
892  IsNewCombine = true;
893  }
894  }
895  } while (IsNewCombine);
896 }
897 
898 void RISCVISAInfo::updateFLen() {
899  FLen = 0;
900  // TODO: Handle q extension.
901  if (Exts.count("d"))
902  FLen = 64;
903  else if (Exts.count("f"))
904  FLen = 32;
905 }
906 
907 void RISCVISAInfo::updateMinVLen() {
908  for (auto const &Ext : Exts) {
909  StringRef ExtName = Ext.first;
910  bool IsZvlExt = ExtName.consume_front("zvl") && ExtName.consume_back("b");
911  if (IsZvlExt) {
912  unsigned ZvlLen;
913  if (!ExtName.getAsInteger(10, ZvlLen))
914  MinVLen = std::max(MinVLen, ZvlLen);
915  }
916  }
917 }
918 
919 void RISCVISAInfo::updateMaxELen() {
920  // handles EEW restriction by sub-extension zve
921  for (auto const &Ext : Exts) {
922  StringRef ExtName = Ext.first;
923  bool IsZveExt = ExtName.consume_front("zve");
924  if (IsZveExt) {
925  if (ExtName.back() == 'f')
926  MaxELenFp = std::max(MaxELenFp, 32u);
927  if (ExtName.back() == 'd')
928  MaxELenFp = std::max(MaxELenFp, 64u);
929  ExtName = ExtName.drop_back();
930  unsigned ZveELen;
931  ExtName.getAsInteger(10, ZveELen);
932  MaxELen = std::max(MaxELen, ZveELen);
933  }
934  }
935 }
936 
937 std::string RISCVISAInfo::toString() const {
938  std::string Buffer;
939  raw_string_ostream Arch(Buffer);
940 
941  Arch << "rv" << XLen;
942 
943  ListSeparator LS("_");
944  for (auto const &Ext : Exts) {
945  StringRef ExtName = Ext.first;
946  auto ExtInfo = Ext.second;
947  Arch << LS << ExtName;
948  Arch << ExtInfo.MajorVersion << "p" << ExtInfo.MinorVersion;
949  }
950 
951  return Arch.str();
952 }
953 
954 std::vector<std::string> RISCVISAInfo::toFeatureVector() const {
955  std::vector<std::string> FeatureVector;
956  for (auto const &Ext : Exts) {
957  std::string ExtName = Ext.first;
958  if (ExtName == "i") // i is not recognized in clang -cc1
959  continue;
960  std::string Feature = isExperimentalExtension(ExtName)
961  ? "+experimental-" + ExtName
962  : "+" + ExtName;
963  FeatureVector.push_back(Feature);
964  }
965  return FeatureVector;
966 }
967 
969 RISCVISAInfo::postProcessAndChecking(std::unique_ptr<RISCVISAInfo> &&ISAInfo) {
970  ISAInfo->updateImplication();
971  ISAInfo->updateCombination();
972  ISAInfo->updateFLen();
973  ISAInfo->updateMinVLen();
974  ISAInfo->updateMaxELen();
975 
976  if (Error Result = ISAInfo->checkDependency())
977  return std::move(Result);
978  return std::move(ISAInfo);
979 }
980 
982  if (XLen == 32) {
983  if (hasExtension("d"))
984  return "ilp32d";
985  if (hasExtension("e"))
986  return "ilp32e";
987  return "ilp32";
988  } else if (XLen == 64) {
989  if (hasExtension("d"))
990  return "lp64d";
991  return "lp64";
992  }
993  llvm_unreachable("Invalid XLEN");
994 }
llvm::RISCVISAInfo::hasExtension
bool hasExtension(StringRef Ext) const
Definition: RISCVISAInfo.cpp:241
llvm::errc::invalid_argument
@ invalid_argument
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::RISCVISAInfo::compareExtension
static bool compareExtension(const std::string &LHS, const std::string &RHS)
Definition: RISCVISAInfo.cpp:308
ImpliedExtsEntry::Name
StringLiteral Name
Definition: RISCVISAInfo.cpp:790
ImpliedExtsV
static const char * ImpliedExtsV[]
Definition: RISCVISAInfo.cpp:762
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:161
ImpliedExtsZvl1024b
static const char * ImpliedExtsZvl1024b[]
Definition: RISCVISAInfo.cpp:779
llvm::lower_bound
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1922
StringRef.h
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:629
ImpliedExtsZfh
static const char * ImpliedExtsZfh[]
Definition: RISCVISAInfo.cpp:764
llvm::RISCVISAInfo::computeDefaultABI
StringRef computeDefaultABI() const
Definition: RISCVISAInfo.cpp:981
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:52
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
ImpliedExtsZhinxmin
static const char * ImpliedExtsZhinxmin[]
Definition: RISCVISAInfo.cpp:766
getExtensionTypeDesc
static StringRef getExtensionTypeDesc(StringRef Ext)
Definition: RISCVISAInfo.cpp:183
ImpliedExtsZvl128b
static const char * ImpliedExtsZvl128b[]
Definition: RISCVISAInfo.cpp:782
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
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:627
Errc.h
multiLetterExtensionRank
static int multiLetterExtensionRank(const std::string &ExtName)
Definition: RISCVISAInfo.cpp:276
llvm::StringRef::find_first_of
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:381
AllStdExts
static constexpr StringLiteral AllStdExts
Definition: RISCVISAInfo.cpp:41
findFirstNonVersionCharacter
static size_t findFirstNonVersionCharacter(StringRef Ext)
Definition: RISCVISAInfo.cpp:133
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
ImpliedExtsZvl8192b
static const char * ImpliedExtsZvl8192b[]
Definition: RISCVISAInfo.cpp:776
ImpliedExtsZve32f
static const char * ImpliedExtsZve32f[]
Definition: RISCVISAInfo.cpp:771
llvm::StringRef::substr
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:564
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::RISCVISAInfo::isSupportedExtension
static bool isSupportedExtension(StringRef Ext)
Definition: RISCVISAInfo.cpp:226
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
STLExtras.h
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
ImpliedExtsZvl512b
static const char * ImpliedExtsZvl512b[]
Definition: RISCVISAInfo.cpp:780
llvm::RISCVISAInfo::toFeatureVector
std::vector< std::string > toFeatureVector() const
Definition: RISCVISAInfo.cpp:954
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
ImpliedExtsZvl65536b
static const char * ImpliedExtsZvl65536b[]
Definition: RISCVISAInfo.cpp:773
llvm::StringLiteral
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:845
CombineIntoExts
static constexpr CombinedExtsEntry CombineIntoExts[]
Definition: RISCVISAInfo.cpp:871
llvm::StringRef::startswith
bool startswith(StringRef Prefix) const
Definition: StringRef.h:260
ImpliedExtsZvl2048b
static const char * ImpliedExtsZvl2048b[]
Definition: RISCVISAInfo.cpp:778
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
ImpliedExtsZvl64b
static const char * ImpliedExtsZvl64b[]
Definition: RISCVISAInfo.cpp:783
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::StringRef::getAsInteger
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:474
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:458
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1056
llvm::RISCVISAInfo::toString
std::string toString() const
Definition: RISCVISAInfo.cpp:937
ImpliedExtsEntry::Exts
ArrayRef< const char * > Exts
Definition: RISCVISAInfo.cpp:791
llvm::SetVector< T, SmallVector< T, N >, SmallDenseSet< T, N > >::empty
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:72
getExtensionVersion
static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major, unsigned &Minor, unsigned &ConsumeLength, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck)
Definition: RISCVISAInfo.cpp:354
ImpliedExtsZk
static const char * ImpliedExtsZk[]
Definition: RISCVISAInfo.cpp:784
CombinedExtsEntry::RequiredExts
ArrayRef< const char * > RequiredExts
Definition: RISCVISAInfo.cpp:868
getExtensionType
static StringRef getExtensionType(StringRef Ext)
Definition: RISCVISAInfo.cpp:195
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
ImpliedExtsZvl32768b
static const char * ImpliedExtsZvl32768b[]
Definition: RISCVISAInfo.cpp:774
llvm::MipsISD::Ext
@ Ext
Definition: MipsISelLowering.h:159
llvm::RISCVExtensionInfo
Definition: RISCVISAInfo.h:20
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:113
ImpliedExtsZvl16384b
static const char * ImpliedExtsZvl16384b[]
Definition: RISCVISAInfo.cpp:775
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
ImpliedExtsZkn
static const char * ImpliedExtsZkn[]
Definition: RISCVISAInfo.cpp:785
I
#define I(x, y, z)
Definition: MD5.cpp:58
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:1868
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:492
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ImpliedExtsZks
static const char * ImpliedExtsZks[]
Definition: RISCVISAInfo.cpp:786
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:82
llvm::SetVector< T, SmallVector< T, N >, SmallDenseSet< T, N > >::insert
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:141
isDigit
static bool isDigit(const char C)
Definition: RustDemangle.cpp:173
llvm::ArrayRef< const char * >
ImpliedExtsZve64f
static const char * ImpliedExtsZve64f[]
Definition: RISCVISAInfo.cpp:769
None.h
llvm::SetVector< T, SmallVector< T, N >, SmallDenseSet< T, N > >::pop_back_val
T pop_back_val()
Definition: SetVector.h:232
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:1741
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
CombinedExtsEntry::CombineExt
StringLiteral CombineExt
Definition: RISCVISAInfo.cpp:867
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
SupportedExtensions
static const RISCVSupportedExtension SupportedExtensions[]
Definition: RISCVISAInfo.cpp:43
ImpliedExtsZve64d
static const char * ImpliedExtsZve64d[]
Definition: RISCVISAInfo.cpp:768
ImpliedExtsZvl4096b
static const char * ImpliedExtsZvl4096b[]
Definition: RISCVISAInfo.cpp:777
stripExperimentalPrefix
static bool stripExperimentalPrefix(StringRef &Ext)
Definition: RISCVISAInfo.cpp:122
isExperimentalExtension
static std::optional< RISCVExtensionVersion > isExperimentalExtension(StringRef Ext)
Definition: RISCVISAInfo.cpp:208
ImpliedExtsEntry::operator<
bool operator<(StringRef Other) const
Definition: RISCVISAInfo.cpp:797
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:1761
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
llvm::RISCVISAInfo::RISCVISAInfo
RISCVISAInfo(const RISCVISAInfo &)=delete
ImpliedExtsZvl256b
static const char * ImpliedExtsZvl256b[]
Definition: RISCVISAInfo.cpp:781
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1238
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::None
constexpr std::nullopt_t None
Definition: None.h:27
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::AArch64CC::LS
@ LS
Definition: AArch64BaseInfo.h:264
llvm::SetVector< T, SmallVector< T, N >, SmallDenseSet< T, N > >::count
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
Definition: SetVector.h:215
llvm::is_sorted
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition: STLExtras.h:1883
singleLetterExtensionRank
static int singleLetterExtensionRank(char Ext)
Definition: RISCVISAInfo.cpp:252
ImpliedExtsEntry
Definition: RISCVISAInfo.cpp:789
llvm::RISCVISAInfo::isSupportedExtensionFeature
static bool isSupportedExtensionFeature(StringRef Ext)
Definition: RISCVISAInfo.cpp:217
ImpliedExtsZve32x
static const char * ImpliedExtsZve32x[]
Definition: RISCVISAInfo.cpp:772
ImpliedExtsEntry::operator<
bool operator<(const ImpliedExtsEntry &Other) const
Definition: RISCVISAInfo.cpp:793
llvm::StringRef::contains
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:428
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:475
ImpliedExtsZve64x
static const char * ImpliedExtsZve64x[]
Definition: RISCVISAInfo.cpp:770
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:332
llvm::StringRef::consume_back
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
Definition: StringRef.h:647
ImpliedExtsZdinx
static const char * ImpliedExtsZdinx[]
Definition: RISCVISAInfo.cpp:765
llvm::StringRef::back
char back() const
back - Get the last character in the string.
Definition: StringRef.h:146
ImpliedExtsZhinx
static const char * ImpliedExtsZhinx[]
Definition: RISCVISAInfo.cpp:767
llvm::SmallSetVector
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:307
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:221
ImpliedExtsZvfh
static const char * ImpliedExtsZvfh[]
Definition: RISCVISAInfo.cpp:787
llvm::StringRef::find
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:294
ImpliedExtsZfhmin
static const char * ImpliedExtsZfhmin[]
Definition: RISCVISAInfo.cpp:763
raw_ostream.h
SupportedExperimentalExtensions
static const RISCVSupportedExtension SupportedExperimentalExtensions[]
Definition: RISCVISAInfo.cpp:111
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:111
CombinedExtsEntry
Definition: RISCVISAInfo.cpp:866
llvm::raw_string_ostream::str
std::string & str()
Returns the string's reference.
Definition: raw_ostream.h:647
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:692
llvm::StringRef::drop_front
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:601
llvm::StringRef::drop_back
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
Definition: StringRef.h:608
SetVector.h
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1251
ImpliedExts
static constexpr ImpliedExtsEntry ImpliedExts[]
Definition: RISCVISAInfo.cpp:801
findDefaultVersion
static std::optional< RISCVExtensionVersion > findDefaultVersion(StringRef ExtName)
Definition: RISCVISAInfo.cpp:159