1 //===- InstrDocsEmitter.cpp - Opcode Documentation Generator --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // InstrDocsEmitter generates restructured text documentation for the opcodes
11 // that can be used by MachineInstr. For each opcode, the documentation lists:
14 // * Flags (e.g. mayLoad, isBranch, ...)
15 // * Operands, including type and name
16 // * Operand constraints
17 // * Implicit register uses & defs
20 //===----------------------------------------------------------------------===//
22 #include "CodeGenDAGPatterns.h"
23 #include "CodeGenInstruction.h"
24 #include "CodeGenTarget.h"
25 #include "TableGenBackends.h"
26 #include "llvm/TableGen/Record.h"
34 void writeTitle(StringRef Str, raw_ostream &OS, char Kind = '-') {
35 OS << std::string(Str.size(), Kind) << "\n" << Str << "\n"
36 << std::string(Str.size(), Kind) << "\n";
39 void writeHeader(StringRef Str, raw_ostream &OS, char Kind = '-') {
40 OS << Str << "\n" << std::string(Str.size(), Kind) << "\n";
43 std::string escapeForRST(StringRef Str) {
45 Result.reserve(Str.size() + 4);
48 // We want special characters to be shown as their C escape codes.
49 case '\n': Result += "\\n"; break;
50 case '\t': Result += "\\t"; break;
51 // Underscore at the end of a line has a special meaning in rst.
52 case '_': Result += "\\_"; break;
59 void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS) {
60 CodeGenDAGPatterns CDP(RK);
61 CodeGenTarget &Target = CDP.getTargetInfo();
62 unsigned VariantCount = Target.getAsmParserVariantCount();
65 std::string Title = Target.getName();
66 Title += " Instructions";
67 writeTitle(Title, OS);
70 for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) {
71 Record *Inst = II->TheDef;
73 // Don't print the target-independent instructions.
74 if (II->Namespace == "TargetOpcode")
77 // Heading (instruction name).
78 writeHeader(escapeForRST(Inst->getName()), OS, '=');
81 // Assembly string(s).
82 if (!II->AsmString.empty()) {
83 for (unsigned VarNum = 0; VarNum < VariantCount; ++VarNum) {
84 Record *AsmVariant = Target.getAsmParserVariant(VarNum);
85 OS << "Assembly string";
86 if (VariantCount != 1)
87 OS << " (" << AsmVariant->getValueAsString("Name") << ")";
88 std::string AsmString =
89 CodeGenInstruction::FlattenAsmStringVariants(II->AsmString, VarNum);
90 // We trim spaces at each end of the asm string because rst needs the
91 // formatting backticks to be next to a non-whitespace character.
92 OS << ": ``" << escapeForRST(StringRef(AsmString).trim(" "))
98 std::vector<const char *> FlagStrings;
99 #define xstr(s) str(s)
101 #define FLAG(f) if (II->f) { FlagStrings.push_back(str(f)); }
104 FLAG(isIndirectBranch)
115 //FLAG(mayLoad_Unset) // Deliberately omitted.
117 //FLAG(mayStore_Unset) // Deliberately omitted.
119 FLAG(isConvertibleToThreeAddress)
122 FLAG(isReMaterializable)
124 FLAG(usesCustomInserter)
125 FLAG(hasPostISelHook)
127 FLAG(isNotDuplicable)
129 //FLAG(hasSideEffects_Unset) // Deliberately omitted.
130 FLAG(isAsCheapAsAMove)
131 FLAG(hasExtraSrcRegAllocReq)
132 FLAG(hasExtraDefRegAllocReq)
136 FLAG(isExtractSubreg)
139 FLAG(hasNoSchedulingInfo)
140 if (!FlagStrings.empty()) {
143 for (auto FlagString : FlagStrings) {
146 OS << "``" << FlagString << "``";
153 for (unsigned i = 0; i < II->Operands.size(); ++i) {
154 bool IsDef = i < II->Operands.NumDefs;
155 auto Op = II->Operands[i];
157 if (Op.MINumOperands > 1) {
158 // This operand corresponds to multiple operands on the
159 // MachineInstruction, so print all of them, showing the types and
160 // names of both the compound operand and the basic operands it
162 for (unsigned SubOpIdx = 0; SubOpIdx < Op.MINumOperands; ++SubOpIdx) {
164 cast<DefInit>(Op.MIOperandInfo->getArg(SubOpIdx))->getDef();
165 StringRef SubOpName = Op.MIOperandInfo->getArgNameStr(SubOpIdx);
166 StringRef SubOpTypeName = SubRec->getName();
168 OS << "* " << (IsDef ? "DEF" : "USE") << " ``" << Op.Rec->getName()
169 << "/" << SubOpTypeName << ":$" << Op.Name << ".";
170 // Not all sub-operands are named, make up a name for these.
171 if (SubOpName.empty())
172 OS << "anon" << SubOpIdx;
178 // The operand corresponds to only one MachineInstruction operand.
179 OS << "* " << (IsDef ? "DEF" : "USE") << " ``" << Op.Rec->getName()
180 << ":$" << Op.Name << "``\n\n";
185 StringRef Constraints = Inst->getValueAsString("Constraints");
186 if (!Constraints.empty()) {
187 OS << "Constraints: ``" << Constraints << "``\n\n";
190 // Implicit definitions.
191 if (!II->ImplicitDefs.empty()) {
192 OS << "Implicit defs: ";
194 for (Record *Def : II->ImplicitDefs) {
197 OS << "``" << Def->getName() << "``";
204 if (!II->ImplicitUses.empty()) {
205 OS << "Implicit uses: ";
207 for (Record *Use : II->ImplicitUses) {
210 OS << "``" << Use->getName() << "``";
217 std::vector<Record *> Predicates =
218 II->TheDef->getValueAsListOfDefs("Predicates");
219 if (!Predicates.empty()) {
220 OS << "Predicates: ";
222 for (Record *P : Predicates) {
225 OS << "``" << P->getName() << "``";
233 } // end llvm namespace