1 //===- InstrDocsEmitter.cpp - Opcode Documentation Generator --------------===//
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 // InstrDocsEmitter generates restructured text documentation for the opcodes
10 // that can be used by MachineInstr. For each opcode, the documentation lists:
13 // * Flags (e.g. mayLoad, isBranch, ...)
14 // * Operands, including type and name
15 // * Operand constraints
16 // * Implicit register uses & defs
19 //===----------------------------------------------------------------------===//
21 #include "CodeGenDAGPatterns.h"
22 #include "CodeGenInstruction.h"
23 #include "CodeGenTarget.h"
24 #include "TableGenBackends.h"
25 #include "llvm/TableGen/Record.h"
33 void writeTitle(StringRef Str
, raw_ostream
&OS
, char Kind
= '-') {
34 OS
<< std::string(Str
.size(), Kind
) << "\n" << Str
<< "\n"
35 << std::string(Str
.size(), Kind
) << "\n";
38 void writeHeader(StringRef Str
, raw_ostream
&OS
, char Kind
= '-') {
39 OS
<< Str
<< "\n" << std::string(Str
.size(), Kind
) << "\n";
42 std::string
escapeForRST(StringRef Str
) {
44 Result
.reserve(Str
.size() + 4);
47 // We want special characters to be shown as their C escape codes.
48 case '\n': Result
+= "\\n"; break;
49 case '\t': Result
+= "\\t"; break;
50 // Underscore at the end of a line has a special meaning in rst.
51 case '_': Result
+= "\\_"; break;
58 void EmitInstrDocs(RecordKeeper
&RK
, raw_ostream
&OS
) {
59 CodeGenDAGPatterns
CDP(RK
);
60 CodeGenTarget
&Target
= CDP
.getTargetInfo();
61 unsigned VariantCount
= Target
.getAsmParserVariantCount();
64 std::string Title
= Target
.getName();
65 Title
+= " Instructions";
66 writeTitle(Title
, OS
);
69 for (const CodeGenInstruction
*II
: Target
.getInstructionsByEnumValue()) {
70 Record
*Inst
= II
->TheDef
;
72 // Don't print the target-independent instructions.
73 if (II
->Namespace
== "TargetOpcode")
76 // Heading (instruction name).
77 writeHeader(escapeForRST(Inst
->getName()), OS
, '=');
80 // Assembly string(s).
81 if (!II
->AsmString
.empty()) {
82 for (unsigned VarNum
= 0; VarNum
< VariantCount
; ++VarNum
) {
83 Record
*AsmVariant
= Target
.getAsmParserVariant(VarNum
);
84 OS
<< "Assembly string";
85 if (VariantCount
!= 1)
86 OS
<< " (" << AsmVariant
->getValueAsString("Name") << ")";
87 std::string AsmString
=
88 CodeGenInstruction::FlattenAsmStringVariants(II
->AsmString
, VarNum
);
89 // We trim spaces at each end of the asm string because rst needs the
90 // formatting backticks to be next to a non-whitespace character.
91 OS
<< ": ``" << escapeForRST(StringRef(AsmString
).trim(" "))
97 std::vector
<const char *> FlagStrings
;
98 #define xstr(s) str(s)
100 #define FLAG(f) if (II->f) { FlagStrings.push_back(str(f)); }
102 FLAG(isEHScopeReturn
)
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 FLAG(variadicOpsAreDefs
)
141 if (!FlagStrings
.empty()) {
144 for (auto FlagString
: FlagStrings
) {
147 OS
<< "``" << FlagString
<< "``";
154 for (unsigned i
= 0; i
< II
->Operands
.size(); ++i
) {
155 bool IsDef
= i
< II
->Operands
.NumDefs
;
156 auto Op
= II
->Operands
[i
];
158 if (Op
.MINumOperands
> 1) {
159 // This operand corresponds to multiple operands on the
160 // MachineInstruction, so print all of them, showing the types and
161 // names of both the compound operand and the basic operands it
163 for (unsigned SubOpIdx
= 0; SubOpIdx
< Op
.MINumOperands
; ++SubOpIdx
) {
165 cast
<DefInit
>(Op
.MIOperandInfo
->getArg(SubOpIdx
))->getDef();
166 StringRef SubOpName
= Op
.MIOperandInfo
->getArgNameStr(SubOpIdx
);
167 StringRef SubOpTypeName
= SubRec
->getName();
169 OS
<< "* " << (IsDef
? "DEF" : "USE") << " ``" << Op
.Rec
->getName()
170 << "/" << SubOpTypeName
<< ":$" << Op
.Name
<< ".";
171 // Not all sub-operands are named, make up a name for these.
172 if (SubOpName
.empty())
173 OS
<< "anon" << SubOpIdx
;
179 // The operand corresponds to only one MachineInstruction operand.
180 OS
<< "* " << (IsDef
? "DEF" : "USE") << " ``" << Op
.Rec
->getName()
181 << ":$" << Op
.Name
<< "``\n\n";
186 StringRef Constraints
= Inst
->getValueAsString("Constraints");
187 if (!Constraints
.empty()) {
188 OS
<< "Constraints: ``" << Constraints
<< "``\n\n";
191 // Implicit definitions.
192 if (!II
->ImplicitDefs
.empty()) {
193 OS
<< "Implicit defs: ";
195 for (Record
*Def
: II
->ImplicitDefs
) {
198 OS
<< "``" << Def
->getName() << "``";
205 if (!II
->ImplicitUses
.empty()) {
206 OS
<< "Implicit uses: ";
208 for (Record
*Use
: II
->ImplicitUses
) {
211 OS
<< "``" << Use
->getName() << "``";
218 std::vector
<Record
*> Predicates
=
219 II
->TheDef
->getValueAsListOfDefs("Predicates");
220 if (!Predicates
.empty()) {
221 OS
<< "Predicates: ";
223 for (Record
*P
: Predicates
) {
226 OS
<< "``" << P
->getName() << "``";
234 } // end namespace llvm