1 //===- RISCVTargetDefEmitter.cpp - Generate lists of RISC-V CPUs ----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This tablegen backend emits the include file needed by the target
10 // parser to parse the RISC-V CPUs.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Support/RISCVISAInfo.h"
15 #include "llvm/TableGen/Record.h"
16 #include "llvm/TableGen/TableGenBackend.h"
20 using ISAInfoTy
= llvm::Expected
<std::unique_ptr
<RISCVISAInfo
>>;
22 // We can generate march string from target features as what has been described
23 // in RISC-V ISA specification (version 20191213) 'Chapter 27. ISA Extension
24 // Naming Conventions'.
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
;
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")
41 ISAInfoTy ISAInfo
= llvm::RISCVISAInfo::parseFeatures(XLen
, FeatureVector
);
43 report_fatal_error("Invalid features");
45 // RISCVISAInfo::toString will generate a march string with all the extensions
46 // we have added to it.
47 return (*ISAInfo
)->toString();
50 static void EmitRISCVTargetDef(RecordKeeper
&RK
, raw_ostream
&OS
) {
51 OS
<< "#ifndef PROC\n"
52 << "#define PROC(ENUM, NAME, DEFAULT_MARCH)\n"
55 // Iterate on all definition records.
56 for (const Record
*Rec
: RK
.getAllDerivedDefinitions("RISCVProcessorModel")) {
57 std::string MArch
= Rec
->getValueAsString("DefaultMarch").str();
59 // Compute MArch from features if we don't specify it.
61 MArch
= getMArch(*Rec
);
63 OS
<< "PROC(" << Rec
->getName() << ", "
64 << "{\"" << Rec
->getValueAsString("Name") << "\"}, "
65 << "{\"" << MArch
<< "\"})\n";
67 OS
<< "\n#undef PROC\n";
69 OS
<< "#ifndef TUNE_PROC\n"
70 << "#define TUNE_PROC(ENUM, NAME)\n"
72 OS
<< "TUNE_PROC(GENERIC, \"generic\")\n";
74 for (const Record
*Rec
:
75 RK
.getAllDerivedDefinitions("RISCVTuneProcessorModel")) {
76 OS
<< "TUNE_PROC(" << Rec
->getName() << ", "
77 << "\"" << Rec
->getValueAsString("Name") << "\")\n";
80 OS
<< "\n#undef TUNE_PROC\n";
83 static TableGen::Emitter::Opt
X("gen-riscv-target-def", EmitRISCVTargetDef
,
84 "Generate the list of CPU for RISCV");