1 //===- InstrDocsEmitter.cpp - Opcode Documentation Generator --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // InstrDocsEmitter generates restructured text documentation for the opcodes 11 // that can be used by MachineInstr. For each opcode, the documentation lists: 12 // * Opcode name 13 // * Assembly string 14 // * Flags (e.g. mayLoad, isBranch, ...) 15 // * Operands, including type and name 16 // * Operand constraints 17 // * Implicit register uses & defs 18 // * Predicates 19 // 20 //===----------------------------------------------------------------------===// 21 22 #include "CodeGenDAGPatterns.h" 23 #include "CodeGenInstruction.h" 24 #include "CodeGenTarget.h" 25 #include "TableGenBackends.h" 26 #include "llvm/TableGen/Record.h" 27 #include <string> 28 #include <vector> 29 30 using namespace llvm; 31 32 namespace llvm { 33 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"; 37 } 38 39 void writeHeader(StringRef Str, raw_ostream &OS, char Kind = '-') { 40 OS << Str << "\n" << std::string(Str.size(), Kind) << "\n"; 41 } 42 43 std::string escapeForRST(StringRef Str) { 44 std::string Result; 45 Result.reserve(Str.size() + 4); 46 for (char C : Str) { 47 switch (C) { 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; 53 default: Result += C; 54 } 55 } 56 return Result; 57 } 58 59 void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS) { 60 CodeGenDAGPatterns CDP(RK); 61 CodeGenTarget &Target = CDP.getTargetInfo(); 62 unsigned VariantCount = Target.getAsmParserVariantCount(); 63 64 // Page title. 65 std::string Title = Target.getName(); 66 Title += " Instructions"; 67 writeTitle(Title, OS); 68 OS << "\n"; 69 70 for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) { 71 Record *Inst = II->TheDef; 72 73 // Don't print the target-independent instructions. 74 if (II->Namespace == "TargetOpcode") 75 continue; 76 77 // Heading (instruction name). 78 writeHeader(escapeForRST(Inst->getName()), OS, '='); 79 OS << "\n"; 80 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(" ")) 93 << "``\n\n"; 94 } 95 } 96 97 // Boolean flags. 98 std::vector<const char *> FlagStrings; 99 #define xstr(s) str(s) 100 #define str(s) #s 101 #define FLAG(f) if (II->f) { FlagStrings.push_back(str(f)); } 102 FLAG(isReturn) 103 FLAG(isBranch) 104 FLAG(isIndirectBranch) 105 FLAG(isCompare) 106 FLAG(isMoveImm) 107 FLAG(isBitcast) 108 FLAG(isSelect) 109 FLAG(isBarrier) 110 FLAG(isCall) 111 FLAG(isAdd) 112 FLAG(isTrap) 113 FLAG(canFoldAsLoad) 114 FLAG(mayLoad) 115 //FLAG(mayLoad_Unset) // Deliberately omitted. 116 FLAG(mayStore) 117 //FLAG(mayStore_Unset) // Deliberately omitted. 118 FLAG(isPredicable) 119 FLAG(isConvertibleToThreeAddress) 120 FLAG(isCommutable) 121 FLAG(isTerminator) 122 FLAG(isReMaterializable) 123 FLAG(hasDelaySlot) 124 FLAG(usesCustomInserter) 125 FLAG(hasPostISelHook) 126 FLAG(hasCtrlDep) 127 FLAG(isNotDuplicable) 128 FLAG(hasSideEffects) 129 //FLAG(hasSideEffects_Unset) // Deliberately omitted. 130 FLAG(isAsCheapAsAMove) 131 FLAG(hasExtraSrcRegAllocReq) 132 FLAG(hasExtraDefRegAllocReq) 133 FLAG(isCodeGenOnly) 134 FLAG(isPseudo) 135 FLAG(isRegSequence) 136 FLAG(isExtractSubreg) 137 FLAG(isInsertSubreg) 138 FLAG(isConvergent) 139 FLAG(hasNoSchedulingInfo) 140 if (!FlagStrings.empty()) { 141 OS << "Flags: "; 142 bool IsFirst = true; 143 for (auto FlagString : FlagStrings) { 144 if (!IsFirst) 145 OS << ", "; 146 OS << "``" << FlagString << "``"; 147 IsFirst = false; 148 } 149 OS << "\n\n"; 150 } 151 152 // Operands. 153 for (unsigned i = 0; i < II->Operands.size(); ++i) { 154 bool IsDef = i < II->Operands.NumDefs; 155 auto Op = II->Operands[i]; 156 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 161 // contains. 162 for (unsigned SubOpIdx = 0; SubOpIdx < Op.MINumOperands; ++SubOpIdx) { 163 Record *SubRec = 164 cast<DefInit>(Op.MIOperandInfo->getArg(SubOpIdx))->getDef(); 165 StringRef SubOpName = Op.MIOperandInfo->getArgNameStr(SubOpIdx); 166 StringRef SubOpTypeName = SubRec->getName(); 167 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; 173 else 174 OS << SubOpName; 175 OS << "``\n\n"; 176 } 177 } else { 178 // The operand corresponds to only one MachineInstruction operand. 179 OS << "* " << (IsDef ? "DEF" : "USE") << " ``" << Op.Rec->getName() 180 << ":$" << Op.Name << "``\n\n"; 181 } 182 } 183 184 // Constraints. 185 StringRef Constraints = Inst->getValueAsString("Constraints"); 186 if (!Constraints.empty()) { 187 OS << "Constraints: ``" << Constraints << "``\n\n"; 188 } 189 190 // Implicit definitions. 191 if (!II->ImplicitDefs.empty()) { 192 OS << "Implicit defs: "; 193 bool IsFirst = true; 194 for (Record *Def : II->ImplicitDefs) { 195 if (!IsFirst) 196 OS << ", "; 197 OS << "``" << Def->getName() << "``"; 198 IsFirst = false; 199 } 200 OS << "\n\n"; 201 } 202 203 // Implicit uses. 204 if (!II->ImplicitUses.empty()) { 205 OS << "Implicit uses: "; 206 bool IsFirst = true; 207 for (Record *Use : II->ImplicitUses) { 208 if (!IsFirst) 209 OS << ", "; 210 OS << "``" << Use->getName() << "``"; 211 IsFirst = false; 212 } 213 OS << "\n\n"; 214 } 215 216 // Predicates. 217 std::vector<Record *> Predicates = 218 II->TheDef->getValueAsListOfDefs("Predicates"); 219 if (!Predicates.empty()) { 220 OS << "Predicates: "; 221 bool IsFirst = true; 222 for (Record *P : Predicates) { 223 if (!IsFirst) 224 OS << ", "; 225 OS << "``" << P->getName() << "``"; 226 IsFirst = false; 227 } 228 OS << "\n\n"; 229 } 230 } 231 } 232 233 } // end llvm namespace 234