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