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 14 #include "TableGenBackends.h" 15 #include "llvm/Support/RISCVISAInfo.h" 16 #include "llvm/TableGen/Record.h" 17 18 using namespace llvm; 19 20 using ISAInfoTy = llvm::Expected<std::unique_ptr<RISCVISAInfo>>; 21 22 // We can generate march string from target features as what has been described 23 // in RISCV ISA specification (version 20191213) 'Chapter 27. ISA Extension 24 // Naming Conventions'. 25 // 26 // This is almost the same as RISCVFeatures::parseFeatureBits, except that we 27 // get feature name from feature records instead of feature bits. 28 static std::string getMArch(const Record &Rec) { 29 std::vector<std::string> FeatureVector; 30 int XLen = 32; 31 32 // Convert features to FeatureVector. 33 for (auto *Feature : Rec.getValueAsListOfDefs("Features")) { 34 StringRef FeatureName = Feature->getValueAsString("Name"); 35 if (llvm::RISCVISAInfo::isSupportedExtensionFeature(FeatureName)) 36 FeatureVector.push_back((Twine("+") + FeatureName).str()); 37 else if (FeatureName == "64bit") 38 XLen = 64; 39 } 40 41 ISAInfoTy ISAInfo = llvm::RISCVISAInfo::parseFeatures(XLen, FeatureVector); 42 if (!ISAInfo) 43 report_fatal_error("Invalid features"); 44 45 // RISCVISAInfo::toString will generate a march string with all the extensions 46 // we have added to it. 47 return (*ISAInfo)->toString(); 48 } 49 50 void llvm::EmitRISCVTargetDef(const RecordKeeper &RK, raw_ostream &OS) { 51 OS << "#ifndef PROC\n" 52 << "#define PROC(ENUM, NAME, DEFAULT_MARCH)\n" 53 << "#endif\n\n"; 54 55 OS << "PROC(INVALID, {\"invalid\"}, {\"\"})\n"; 56 // Iterate on all definition records. 57 for (const Record *Rec : RK.getAllDerivedDefinitions("RISCVProcessorModel")) { 58 std::string MArch = Rec->getValueAsString("DefaultMarch").str(); 59 60 // Compute MArch from features if we don't specify it. 61 if (MArch.empty()) 62 MArch = getMArch(*Rec); 63 64 OS << "PROC(" << Rec->getName() << ", " 65 << "{\"" << Rec->getValueAsString("Name") << "\"}, " 66 << "{\"" << MArch << "\"})\n"; 67 } 68 OS << "\n#undef PROC\n"; 69 OS << "\n"; 70 OS << "#ifndef TUNE_PROC\n" 71 << "#define TUNE_PROC(ENUM, NAME)\n" 72 << "#endif\n\n"; 73 OS << "TUNE_PROC(GENERIC, \"generic\")\n"; 74 75 for (const Record *Rec : 76 RK.getAllDerivedDefinitions("RISCVTuneProcessorModel")) { 77 OS << "TUNE_PROC(" << Rec->getName() << ", " 78 << "\"" << Rec->getValueAsString("Name") << "\")\n"; 79 } 80 81 OS << "\n#undef TUNE_PROC\n"; 82 } 83