RISCVTargetDefEmitter.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //===- RISCVTargetDefEmitter.cpp - Generate lists of RISCV CPUs -----------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This tablegen backend emits the include file needed by the target
  10. // parser to parse the RISC-V CPUs.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "TableGenBackends.h"
  14. #include "llvm/Support/RISCVISAInfo.h"
  15. #include "llvm/TableGen/Record.h"
  16. using namespace llvm;
  17. using ISAInfoTy = llvm::Expected<std::unique_ptr<RISCVISAInfo>>;
  18. // We can generate march string from target features as what has been described
  19. // in RISCV ISA specification (version 20191213) 'Chapter 27. ISA Extension
  20. // Naming Conventions'.
  21. //
  22. // This is almost the same as RISCVFeatures::parseFeatureBits, except that we
  23. // get feature name from feature records instead of feature bits.
  24. static std::string getMArch(const Record &Rec) {
  25. std::vector<std::string> FeatureVector;
  26. int XLen = 32;
  27. // Convert features to FeatureVector.
  28. for (auto *Feature : Rec.getValueAsListOfDefs("Features")) {
  29. StringRef FeatureName = Feature->getValueAsString("Name");
  30. if (llvm::RISCVISAInfo::isSupportedExtensionFeature(FeatureName))
  31. FeatureVector.push_back((Twine("+") + FeatureName).str());
  32. else if (FeatureName == "64bit")
  33. XLen = 64;
  34. }
  35. ISAInfoTy ISAInfo = llvm::RISCVISAInfo::parseFeatures(XLen, FeatureVector);
  36. if (!ISAInfo)
  37. report_fatal_error("Invalid features");
  38. // RISCVISAInfo::toString will generate a march string with all the extensions
  39. // we have added to it.
  40. return (*ISAInfo)->toString();
  41. }
  42. void llvm::EmitRISCVTargetDef(const RecordKeeper &RK, raw_ostream &OS) {
  43. OS << "#ifndef PROC\n"
  44. << "#define PROC(ENUM, NAME, DEFAULT_MARCH)\n"
  45. << "#endif\n\n";
  46. OS << "PROC(INVALID, {\"invalid\"}, {\"\"})\n";
  47. // Iterate on all definition records.
  48. for (const Record *Rec : RK.getAllDerivedDefinitions("RISCVProcessorModel")) {
  49. std::string MArch = Rec->getValueAsString("DefaultMarch").str();
  50. // Compute MArch from features if we don't specify it.
  51. if (MArch.empty())
  52. MArch = getMArch(*Rec);
  53. OS << "PROC(" << Rec->getName() << ", "
  54. << "{\"" << Rec->getValueAsString("Name") << "\"}, "
  55. << "{\"" << MArch << "\"})\n";
  56. }
  57. OS << "\n#undef PROC\n";
  58. OS << "\n";
  59. OS << "#ifndef TUNE_PROC\n"
  60. << "#define TUNE_PROC(ENUM, NAME)\n"
  61. << "#endif\n\n";
  62. OS << "TUNE_PROC(GENERIC, \"generic\")\n";
  63. for (const Record *Rec :
  64. RK.getAllDerivedDefinitions("RISCVTuneProcessorModel")) {
  65. OS << "TUNE_PROC(" << Rec->getName() << ", "
  66. << "\"" << Rec->getValueAsString("Name") << "\")\n";
  67. }
  68. OS << "\n#undef TUNE_PROC\n";
  69. }