InstrInfoEmitter.cpp revision 296417
1296417Sdim//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. --*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This tablegen backend is responsible for emitting a description of the target 11193323Sed// instruction set for the code generator. 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15239462Sdim#include "CodeGenDAGPatterns.h" 16239462Sdim#include "CodeGenSchedule.h" 17193323Sed#include "CodeGenTarget.h" 18249423Sdim#include "SequenceToOffsetTable.h" 19243830Sdim#include "TableGenBackends.h" 20239462Sdim#include "llvm/ADT/StringExtras.h" 21243830Sdim#include "llvm/TableGen/Error.h" 22226633Sdim#include "llvm/TableGen/Record.h" 23239462Sdim#include "llvm/TableGen/TableGenBackend.h" 24193323Sed#include <algorithm> 25234353Sdim#include <cstdio> 26239462Sdim#include <map> 27239462Sdim#include <vector> 28296417Sdim 29193323Sedusing namespace llvm; 30193323Sed 31239462Sdimnamespace { 32239462Sdimclass InstrInfoEmitter { 33239462Sdim RecordKeeper &Records; 34239462Sdim CodeGenDAGPatterns CDP; 35239462Sdim const CodeGenSchedModels &SchedModels; 36239462Sdim 37239462Sdimpublic: 38239462Sdim InstrInfoEmitter(RecordKeeper &R): 39239462Sdim Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {} 40239462Sdim 41239462Sdim // run - Output the instruction set description. 42239462Sdim void run(raw_ostream &OS); 43239462Sdim 44239462Sdimprivate: 45239462Sdim void emitEnums(raw_ostream &OS); 46239462Sdim 47239462Sdim typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy; 48261991Sdim 49261991Sdim /// The keys of this map are maps which have OpName enum values as their keys 50261991Sdim /// and instruction operand indices as their values. The values of this map 51261991Sdim /// are lists of instruction names. 52261991Sdim typedef std::map<std::map<unsigned, unsigned>, 53261991Sdim std::vector<std::string> > OpNameMapTy; 54261991Sdim typedef std::map<std::string, unsigned>::iterator StrUintMapIter; 55239462Sdim void emitRecord(const CodeGenInstruction &Inst, unsigned Num, 56239462Sdim Record *InstrInfo, 57239462Sdim std::map<std::vector<Record*>, unsigned> &EL, 58239462Sdim const OperandInfoMapTy &OpInfo, 59239462Sdim raw_ostream &OS); 60261991Sdim void emitOperandTypesEnum(raw_ostream &OS, const CodeGenTarget &Target); 61261991Sdim void initOperandMapData( 62276479Sdim const std::vector<const CodeGenInstruction *> &NumberedInstructions, 63276479Sdim const std::string &Namespace, 64276479Sdim std::map<std::string, unsigned> &Operands, 65276479Sdim OpNameMapTy &OperandMap); 66261991Sdim void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target, 67261991Sdim const std::vector<const CodeGenInstruction*> &NumberedInstructions); 68239462Sdim 69239462Sdim // Operand information. 70239462Sdim void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); 71239462Sdim std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); 72239462Sdim}; 73296417Sdim} // end anonymous namespace 74239462Sdim 75193323Sedstatic void PrintDefList(const std::vector<Record*> &Uses, 76195340Sed unsigned Num, raw_ostream &OS) { 77296417Sdim OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; 78193323Sed for (unsigned i = 0, e = Uses.size(); i != e; ++i) 79193323Sed OS << getQualifiedName(Uses[i]) << ", "; 80193323Sed OS << "0 };\n"; 81193323Sed} 82193323Sed 83193323Sed//===----------------------------------------------------------------------===// 84193323Sed// Operand Info Emission. 85193323Sed//===----------------------------------------------------------------------===// 86193323Sed 87193323Sedstd::vector<std::string> 88193323SedInstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { 89193323Sed std::vector<std::string> Result; 90224145Sdim 91276479Sdim for (auto &Op : Inst.Operands) { 92193323Sed // Handle aggregate operands and normal operands the same way by expanding 93193323Sed // either case into a list of operands for this op. 94218893Sdim std::vector<CGIOperandList::OperandInfo> OperandList; 95193323Sed 96193323Sed // This might be a multiple operand thing. Targets like X86 have 97193323Sed // registers in their multi-operand operands. It may also be an anonymous 98193323Sed // operand, which has a single operand, but no declared class for the 99193323Sed // operand. 100276479Sdim DagInit *MIOI = Op.MIOperandInfo; 101224145Sdim 102193323Sed if (!MIOI || MIOI->getNumArgs() == 0) { 103193323Sed // Single, anonymous, operand. 104276479Sdim OperandList.push_back(Op); 105193323Sed } else { 106276479Sdim for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) { 107276479Sdim OperandList.push_back(Op); 108193323Sed 109243830Sdim Record *OpR = cast<DefInit>(MIOI->getArg(j))->getDef(); 110193323Sed OperandList.back().Rec = OpR; 111193323Sed } 112193323Sed } 113193323Sed 114193323Sed for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { 115193323Sed Record *OpR = OperandList[j].Rec; 116193323Sed std::string Res; 117224145Sdim 118224145Sdim if (OpR->isSubClassOf("RegisterOperand")) 119224145Sdim OpR = OpR->getValueAsDef("RegClass"); 120193323Sed if (OpR->isSubClassOf("RegisterClass")) 121193323Sed Res += getQualifiedName(OpR) + "RegClassID, "; 122198090Srdivacky else if (OpR->isSubClassOf("PointerLikeRegClass")) 123198090Srdivacky Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; 124193323Sed else 125210299Sed // -1 means the operand does not have a fixed register class. 126210299Sed Res += "-1, "; 127224145Sdim 128193323Sed // Fill in applicable flags. 129193323Sed Res += "0"; 130224145Sdim 131193323Sed // Ptr value whose register class is resolved via callback. 132198090Srdivacky if (OpR->isSubClassOf("PointerLikeRegClass")) 133224145Sdim Res += "|(1<<MCOI::LookupPtrRegClass)"; 134193323Sed 135193323Sed // Predicate operands. Check to see if the original unexpanded operand 136261991Sdim // was of type PredicateOp. 137276479Sdim if (Op.Rec->isSubClassOf("PredicateOp")) 138224145Sdim Res += "|(1<<MCOI::Predicate)"; 139224145Sdim 140193323Sed // Optional def operands. Check to see if the original unexpanded operand 141193323Sed // was of type OptionalDefOperand. 142276479Sdim if (Op.Rec->isSubClassOf("OptionalDefOperand")) 143224145Sdim Res += "|(1<<MCOI::OptionalDef)"; 144193323Sed 145234353Sdim // Fill in operand type. 146280031Sdim Res += ", "; 147276479Sdim assert(!Op.OperandType.empty() && "Invalid operand type."); 148276479Sdim Res += Op.OperandType; 149234353Sdim 150193323Sed // Fill in constraint info. 151203954Srdivacky Res += ", "; 152224145Sdim 153218893Sdim const CGIOperandList::ConstraintInfo &Constraint = 154276479Sdim Op.Constraints[j]; 155203954Srdivacky if (Constraint.isNone()) 156203954Srdivacky Res += "0"; 157203954Srdivacky else if (Constraint.isEarlyClobber()) 158224145Sdim Res += "(1 << MCOI::EARLY_CLOBBER)"; 159203954Srdivacky else { 160203954Srdivacky assert(Constraint.isTied()); 161203954Srdivacky Res += "((" + utostr(Constraint.getTiedOperand()) + 162224145Sdim " << 16) | (1 << MCOI::TIED_TO))"; 163203954Srdivacky } 164224145Sdim 165193323Sed Result.push_back(Res); 166193323Sed } 167193323Sed } 168193323Sed 169193323Sed return Result; 170193323Sed} 171193323Sed 172224145Sdimvoid InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, 173193323Sed OperandInfoMapTy &OperandInfoIDs) { 174193323Sed // ID #0 is for no operand info. 175193323Sed unsigned OperandListNum = 0; 176193323Sed OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; 177224145Sdim 178193323Sed OS << "\n"; 179193323Sed const CodeGenTarget &Target = CDP.getTargetInfo(); 180276479Sdim for (const CodeGenInstruction *Inst : Target.instructions()) { 181276479Sdim std::vector<std::string> OperandInfo = GetOperandInfo(*Inst); 182193323Sed unsigned &N = OperandInfoIDs[OperandInfo]; 183193323Sed if (N != 0) continue; 184224145Sdim 185193323Sed N = ++OperandListNum; 186224145Sdim OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; 187276479Sdim for (const std::string &Info : OperandInfo) 188276479Sdim OS << "{ " << Info << " }, "; 189193323Sed OS << "};\n"; 190193323Sed } 191193323Sed} 192193323Sed 193261991Sdim/// Initialize data structures for generating operand name mappings. 194261991Sdim/// 195261991Sdim/// \param Operands [out] A map used to generate the OpName enum with operand 196261991Sdim/// names as its keys and operand enum values as its values. 197261991Sdim/// \param OperandMap [out] A map for representing the operand name mappings for 198261991Sdim/// each instructions. This is used to generate the OperandMap table as 199261991Sdim/// well as the getNamedOperandIdx() function. 200261991Sdimvoid InstrInfoEmitter::initOperandMapData( 201276479Sdim const std::vector<const CodeGenInstruction *> &NumberedInstructions, 202261991Sdim const std::string &Namespace, 203261991Sdim std::map<std::string, unsigned> &Operands, 204261991Sdim OpNameMapTy &OperandMap) { 205261991Sdim 206261991Sdim unsigned NumOperands = 0; 207276479Sdim for (const CodeGenInstruction *Inst : NumberedInstructions) { 208276479Sdim if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable")) 209261991Sdim continue; 210261991Sdim std::map<unsigned, unsigned> OpList; 211276479Sdim for (const auto &Info : Inst->Operands) { 212261991Sdim StrUintMapIter I = Operands.find(Info.Name); 213261991Sdim 214261991Sdim if (I == Operands.end()) { 215261991Sdim I = Operands.insert(Operands.begin(), 216261991Sdim std::pair<std::string, unsigned>(Info.Name, NumOperands++)); 217261991Sdim } 218261991Sdim OpList[I->second] = Info.MIOperandNo; 219261991Sdim } 220261991Sdim OperandMap[OpList].push_back(Namespace + "::" + Inst->TheDef->getName()); 221261991Sdim } 222261991Sdim} 223261991Sdim 224261991Sdim/// Generate a table and function for looking up the indices of operands by 225261991Sdim/// name. 226261991Sdim/// 227261991Sdim/// This code generates: 228261991Sdim/// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry 229261991Sdim/// for each operand name. 230261991Sdim/// - A 2-dimensional table called OperandMap for mapping OpName enum values to 231261991Sdim/// operand indices. 232261991Sdim/// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) 233261991Sdim/// for looking up the operand index for an instruction, given a value from 234261991Sdim/// OpName enum 235261991Sdimvoid InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS, 236261991Sdim const CodeGenTarget &Target, 237261991Sdim const std::vector<const CodeGenInstruction*> &NumberedInstructions) { 238261991Sdim 239261991Sdim const std::string &Namespace = Target.getInstNamespace(); 240261991Sdim std::string OpNameNS = "OpName"; 241261991Sdim // Map of operand names to their enumeration value. This will be used to 242261991Sdim // generate the OpName enum. 243261991Sdim std::map<std::string, unsigned> Operands; 244261991Sdim OpNameMapTy OperandMap; 245261991Sdim 246261991Sdim initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap); 247261991Sdim 248261991Sdim OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n"; 249261991Sdim OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n"; 250288943Sdim OS << "namespace llvm {\n"; 251261991Sdim OS << "namespace " << Namespace << " {\n"; 252261991Sdim OS << "namespace " << OpNameNS << " { \n"; 253261991Sdim OS << "enum {\n"; 254276479Sdim for (const auto &Op : Operands) 255276479Sdim OS << " " << Op.first << " = " << Op.second << ",\n"; 256261991Sdim 257261991Sdim OS << "OPERAND_LAST"; 258261991Sdim OS << "\n};\n"; 259296417Sdim OS << "} // end namespace OpName\n"; 260296417Sdim OS << "} // end namespace " << Namespace << "\n"; 261296417Sdim OS << "} // end namespace llvm\n"; 262261991Sdim OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n"; 263261991Sdim 264261991Sdim OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n"; 265261991Sdim OS << "#undef GET_INSTRINFO_NAMED_OPS\n"; 266288943Sdim OS << "namespace llvm {\n"; 267261991Sdim OS << "namespace " << Namespace << " {\n"; 268280031Sdim OS << "LLVM_READONLY\n"; 269261991Sdim OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n"; 270261991Sdim if (!Operands.empty()) { 271261991Sdim OS << " static const int16_t OperandMap [][" << Operands.size() 272261991Sdim << "] = {\n"; 273276479Sdim for (const auto &Entry : OperandMap) { 274276479Sdim const std::map<unsigned, unsigned> &OpList = Entry.first; 275261991Sdim OS << "{"; 276261991Sdim 277261991Sdim // Emit a row of the OperandMap table 278276479Sdim for (unsigned i = 0, e = Operands.size(); i != e; ++i) 279276479Sdim OS << (OpList.count(i) == 0 ? -1 : (int)OpList.find(i)->second) << ", "; 280261991Sdim 281261991Sdim OS << "},\n"; 282261991Sdim } 283261991Sdim OS << "};\n"; 284261991Sdim 285261991Sdim OS << " switch(Opcode) {\n"; 286261991Sdim unsigned TableIndex = 0; 287276479Sdim for (const auto &Entry : OperandMap) { 288276479Sdim for (const std::string &Name : Entry.second) 289276479Sdim OS << " case " << Name << ":\n"; 290261991Sdim 291261991Sdim OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n"; 292261991Sdim } 293261991Sdim OS << " default: return -1;\n"; 294261991Sdim OS << " }\n"; 295261991Sdim } else { 296261991Sdim // There are no operands, so no need to emit anything 297261991Sdim OS << " return -1;\n"; 298261991Sdim } 299261991Sdim OS << "}\n"; 300296417Sdim OS << "} // end namespace " << Namespace << "\n"; 301296417Sdim OS << "} // end namespace llvm\n"; 302261991Sdim OS << "#endif //GET_INSTRINFO_NAMED_OPS\n"; 303261991Sdim 304261991Sdim} 305261991Sdim 306261991Sdim/// Generate an enum for all the operand types for this target, under the 307261991Sdim/// llvm::TargetNamespace::OpTypes namespace. 308261991Sdim/// Operand types are all definitions derived of the Operand Target.td class. 309261991Sdimvoid InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS, 310261991Sdim const CodeGenTarget &Target) { 311261991Sdim 312261991Sdim const std::string &Namespace = Target.getInstNamespace(); 313261991Sdim std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand"); 314261991Sdim 315261991Sdim OS << "\n#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 316261991Sdim OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 317288943Sdim OS << "namespace llvm {\n"; 318261991Sdim OS << "namespace " << Namespace << " {\n"; 319261991Sdim OS << "namespace OpTypes { \n"; 320261991Sdim OS << "enum OperandType {\n"; 321261991Sdim 322276479Sdim unsigned EnumVal = 0; 323276479Sdim for (const Record *Op : Operands) { 324276479Sdim if (!Op->isAnonymous()) 325276479Sdim OS << " " << Op->getName() << " = " << EnumVal << ",\n"; 326276479Sdim ++EnumVal; 327261991Sdim } 328261991Sdim 329261991Sdim OS << " OPERAND_TYPE_LIST_END" << "\n};\n"; 330296417Sdim OS << "} // end namespace OpTypes\n"; 331296417Sdim OS << "} // end namespace " << Namespace << "\n"; 332296417Sdim OS << "} // end namespace llvm\n"; 333261991Sdim OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 334261991Sdim} 335261991Sdim 336193323Sed//===----------------------------------------------------------------------===// 337193323Sed// Main Output. 338193323Sed//===----------------------------------------------------------------------===// 339193323Sed 340193323Sed// run - Emit the main instruction description records for the target... 341195340Sedvoid InstrInfoEmitter::run(raw_ostream &OS) { 342239462Sdim emitSourceFileHeader("Target Instruction Enum Values", OS); 343224145Sdim emitEnums(OS); 344224145Sdim 345239462Sdim emitSourceFileHeader("Target Instruction Descriptors", OS); 346193323Sed 347224145Sdim OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n"; 348224145Sdim OS << "#undef GET_INSTRINFO_MC_DESC\n"; 349224145Sdim 350193323Sed OS << "namespace llvm {\n\n"; 351193323Sed 352193323Sed CodeGenTarget &Target = CDP.getTargetInfo(); 353193323Sed const std::string &TargetName = Target.getName(); 354193323Sed Record *InstrInfo = Target.getInstructionSet(); 355193323Sed 356193323Sed // Keep track of all of the def lists we have emitted already. 357193323Sed std::map<std::vector<Record*>, unsigned> EmittedLists; 358193323Sed unsigned ListNumber = 0; 359224145Sdim 360193323Sed // Emit all of the instruction's implicit uses and defs. 361276479Sdim for (const CodeGenInstruction *II : Target.instructions()) { 362276479Sdim Record *Inst = II->TheDef; 363193323Sed std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 364193323Sed if (!Uses.empty()) { 365193323Sed unsigned &IL = EmittedLists[Uses]; 366193323Sed if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); 367193323Sed } 368193323Sed std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 369193323Sed if (!Defs.empty()) { 370193323Sed unsigned &IL = EmittedLists[Defs]; 371193323Sed if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); 372193323Sed } 373193323Sed } 374193323Sed 375193323Sed OperandInfoMapTy OperandInfoIDs; 376224145Sdim 377193323Sed // Emit all of the operand info records. 378193323Sed EmitOperandInfo(OS, OperandInfoIDs); 379224145Sdim 380224145Sdim // Emit all of the MCInstrDesc records in their ENUM ordering. 381193323Sed // 382234353Sdim OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; 383205407Srdivacky const std::vector<const CodeGenInstruction*> &NumberedInstructions = 384205407Srdivacky Target.getInstructionsByEnumValue(); 385193323Sed 386234353Sdim SequenceToOffsetTable<std::string> InstrNames; 387276479Sdim unsigned Num = 0; 388276479Sdim for (const CodeGenInstruction *Inst : NumberedInstructions) { 389276479Sdim // Keep a list of the instruction names. 390276479Sdim InstrNames.add(Inst->TheDef->getName()); 391276479Sdim // Emit the record into the table. 392276479Sdim emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS); 393234353Sdim } 394276479Sdim OS << "};\n\n"; 395234353Sdim 396276479Sdim // Emit the array of instruction names. 397234353Sdim InstrNames.layout(); 398234353Sdim OS << "extern const char " << TargetName << "InstrNameData[] = {\n"; 399234353Sdim InstrNames.emit(OS, printChar); 400234353Sdim OS << "};\n\n"; 401234353Sdim 402234353Sdim OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; 403276479Sdim Num = 0; 404276479Sdim for (const CodeGenInstruction *Inst : NumberedInstructions) { 405276479Sdim // Newline every eight entries. 406276479Sdim if (Num % 8 == 0) 407234353Sdim OS << "\n "; 408276479Sdim OS << InstrNames.get(Inst->TheDef->getName()) << "U, "; 409276479Sdim ++Num; 410234353Sdim } 411234353Sdim 412234353Sdim OS << "\n};\n\n"; 413234353Sdim 414224145Sdim // MCInstrInfo initialization routine. 415224145Sdim OS << "static inline void Init" << TargetName 416224145Sdim << "MCInstrInfo(MCInstrInfo *II) {\n"; 417224145Sdim OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " 418234353Sdim << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 419224145Sdim << NumberedInstructions.size() << ");\n}\n\n"; 420224145Sdim 421296417Sdim OS << "} // end llvm namespace \n"; 422224145Sdim 423224145Sdim OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; 424224145Sdim 425224145Sdim // Create a TargetInstrInfo subclass to hide the MC layer initialization. 426224145Sdim OS << "\n#ifdef GET_INSTRINFO_HEADER\n"; 427224145Sdim OS << "#undef GET_INSTRINFO_HEADER\n"; 428224145Sdim 429224145Sdim std::string ClassName = TargetName + "GenInstrInfo"; 430224145Sdim OS << "namespace llvm {\n"; 431249423Sdim OS << "struct " << ClassName << " : public TargetInstrInfo {\n" 432288943Sdim << " explicit " << ClassName 433296417Sdim << "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1);\n" 434296417Sdim << " ~" << ClassName << "() override {}\n" 435224145Sdim << "};\n"; 436296417Sdim OS << "} // end llvm namespace \n"; 437224145Sdim 438224145Sdim OS << "#endif // GET_INSTRINFO_HEADER\n\n"; 439224145Sdim 440261991Sdim OS << "\n#ifdef GET_INSTRINFO_CTOR_DTOR\n"; 441261991Sdim OS << "#undef GET_INSTRINFO_CTOR_DTOR\n"; 442224145Sdim 443224145Sdim OS << "namespace llvm {\n"; 444234353Sdim OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; 445234353Sdim OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; 446234353Sdim OS << "extern const char " << TargetName << "InstrNameData[];\n"; 447288943Sdim OS << ClassName << "::" << ClassName 448296417Sdim << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode)\n" 449296417Sdim << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode) {\n" 450288943Sdim << " InitMCInstrInfo(" << TargetName << "Insts, " << TargetName 451288943Sdim << "InstrNameIndices, " << TargetName << "InstrNameData, " 452296417Sdim << NumberedInstructions.size() << ");\n}\n"; 453296417Sdim OS << "} // end llvm namespace \n"; 454224145Sdim 455261991Sdim OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n"; 456261991Sdim 457261991Sdim emitOperandNameMappings(OS, Target, NumberedInstructions); 458261991Sdim 459261991Sdim emitOperandTypesEnum(OS, Target); 460193323Sed} 461193323Sed 462193323Sedvoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 463193323Sed Record *InstrInfo, 464193323Sed std::map<std::vector<Record*>, unsigned> &EmittedLists, 465193323Sed const OperandInfoMapTy &OpInfo, 466195340Sed raw_ostream &OS) { 467193323Sed int MinOperands = 0; 468243830Sdim if (!Inst.Operands.empty()) 469193323Sed // Each logical operand can be multiple MI operands. 470218893Sdim MinOperands = Inst.Operands.back().MIOperandNo + 471218893Sdim Inst.Operands.back().MINumOperands; 472193323Sed 473193323Sed OS << " { "; 474193323Sed OS << Num << ",\t" << MinOperands << ",\t" 475224145Sdim << Inst.Operands.NumDefs << ",\t" 476288943Sdim << Inst.TheDef->getValueAsInt("Size") << ",\t" 477288943Sdim << SchedModels.getSchedClassIdx(Inst) << ",\t0"; 478193323Sed 479288943Sdim // Emit all of the target independent flags... 480288943Sdim if (Inst.isPseudo) OS << "|(1ULL<<MCID::Pseudo)"; 481288943Sdim if (Inst.isReturn) OS << "|(1ULL<<MCID::Return)"; 482288943Sdim if (Inst.isBranch) OS << "|(1ULL<<MCID::Branch)"; 483288943Sdim if (Inst.isIndirectBranch) OS << "|(1ULL<<MCID::IndirectBranch)"; 484288943Sdim if (Inst.isCompare) OS << "|(1ULL<<MCID::Compare)"; 485288943Sdim if (Inst.isMoveImm) OS << "|(1ULL<<MCID::MoveImm)"; 486288943Sdim if (Inst.isBitcast) OS << "|(1ULL<<MCID::Bitcast)"; 487288943Sdim if (Inst.isSelect) OS << "|(1ULL<<MCID::Select)"; 488288943Sdim if (Inst.isBarrier) OS << "|(1ULL<<MCID::Barrier)"; 489288943Sdim if (Inst.hasDelaySlot) OS << "|(1ULL<<MCID::DelaySlot)"; 490288943Sdim if (Inst.isCall) OS << "|(1ULL<<MCID::Call)"; 491288943Sdim if (Inst.canFoldAsLoad) OS << "|(1ULL<<MCID::FoldableAsLoad)"; 492288943Sdim if (Inst.mayLoad) OS << "|(1ULL<<MCID::MayLoad)"; 493288943Sdim if (Inst.mayStore) OS << "|(1ULL<<MCID::MayStore)"; 494288943Sdim if (Inst.isPredicable) OS << "|(1ULL<<MCID::Predicable)"; 495288943Sdim if (Inst.isConvertibleToThreeAddress) OS << "|(1ULL<<MCID::ConvertibleTo3Addr)"; 496288943Sdim if (Inst.isCommutable) OS << "|(1ULL<<MCID::Commutable)"; 497288943Sdim if (Inst.isTerminator) OS << "|(1ULL<<MCID::Terminator)"; 498288943Sdim if (Inst.isReMaterializable) OS << "|(1ULL<<MCID::Rematerializable)"; 499288943Sdim if (Inst.isNotDuplicable) OS << "|(1ULL<<MCID::NotDuplicable)"; 500288943Sdim if (Inst.Operands.hasOptionalDef) OS << "|(1ULL<<MCID::HasOptionalDef)"; 501288943Sdim if (Inst.usesCustomInserter) OS << "|(1ULL<<MCID::UsesCustomInserter)"; 502288943Sdim if (Inst.hasPostISelHook) OS << "|(1ULL<<MCID::HasPostISelHook)"; 503288943Sdim if (Inst.Operands.isVariadic)OS << "|(1ULL<<MCID::Variadic)"; 504288943Sdim if (Inst.hasSideEffects) OS << "|(1ULL<<MCID::UnmodeledSideEffects)"; 505288943Sdim if (Inst.isAsCheapAsAMove) OS << "|(1ULL<<MCID::CheapAsAMove)"; 506288943Sdim if (Inst.hasExtraSrcRegAllocReq) OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)"; 507288943Sdim if (Inst.hasExtraDefRegAllocReq) OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)"; 508288943Sdim if (Inst.isRegSequence) OS << "|(1ULL<<MCID::RegSequence)"; 509288943Sdim if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)"; 510288943Sdim if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)"; 511288943Sdim if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)"; 512193323Sed 513193323Sed // Emit all of the target-specific flags... 514206274Srdivacky BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); 515243830Sdim if (!TSF) 516243830Sdim PrintFatalError("no TSFlags?"); 517206274Srdivacky uint64_t Value = 0; 518206274Srdivacky for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { 519243830Sdim if (BitInit *Bit = dyn_cast<BitInit>(TSF->getBit(i))) 520206274Srdivacky Value |= uint64_t(Bit->getValue()) << i; 521206274Srdivacky else 522243830Sdim PrintFatalError("Invalid TSFlags bit in " + Inst.TheDef->getName()); 523206274Srdivacky } 524206274Srdivacky OS << ", 0x"; 525206274Srdivacky OS.write_hex(Value); 526210299Sed OS << "ULL, "; 527193323Sed 528193323Sed // Emit the implicit uses and defs lists... 529193323Sed std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 530193323Sed if (UseList.empty()) 531276479Sdim OS << "nullptr, "; 532193323Sed else 533193323Sed OS << "ImplicitList" << EmittedLists[UseList] << ", "; 534193323Sed 535193323Sed std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 536193323Sed if (DefList.empty()) 537276479Sdim OS << "nullptr, "; 538193323Sed else 539193323Sed OS << "ImplicitList" << EmittedLists[DefList] << ", "; 540193323Sed 541193323Sed // Emit the operand info. 542193323Sed std::vector<std::string> OperandInfo = GetOperandInfo(Inst); 543193323Sed if (OperandInfo.empty()) 544276479Sdim OS << "nullptr"; 545193323Sed else 546193323Sed OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 547206274Srdivacky 548261991Sdim CodeGenTarget &Target = CDP.getTargetInfo(); 549261991Sdim if (Inst.HasComplexDeprecationPredicate) 550261991Sdim // Emit a function pointer to the complex predicate method. 551288943Sdim OS << ", -1 " 552261991Sdim << ",&get" << Inst.DeprecatedReason << "DeprecationInfo"; 553261991Sdim else if (!Inst.DeprecatedReason.empty()) 554261991Sdim // Emit the Subtarget feature. 555288943Sdim OS << ", " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason 556288943Sdim << " ,nullptr"; 557261991Sdim else 558261991Sdim // Instruction isn't deprecated. 559288943Sdim OS << ", -1 ,nullptr"; 560261991Sdim 561193323Sed OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 562193323Sed} 563224145Sdim 564224145Sdim// emitEnums - Print out enum values for all of the instructions. 565224145Sdimvoid InstrInfoEmitter::emitEnums(raw_ostream &OS) { 566224145Sdim 567224145Sdim OS << "\n#ifdef GET_INSTRINFO_ENUM\n"; 568224145Sdim OS << "#undef GET_INSTRINFO_ENUM\n"; 569224145Sdim 570224145Sdim OS << "namespace llvm {\n\n"; 571224145Sdim 572224145Sdim CodeGenTarget Target(Records); 573224145Sdim 574224145Sdim // We must emit the PHI opcode first... 575224145Sdim std::string Namespace = Target.getInstNamespace(); 576234353Sdim 577288943Sdim if (Namespace.empty()) 578288943Sdim PrintFatalError("No instructions defined!"); 579224145Sdim 580224145Sdim const std::vector<const CodeGenInstruction*> &NumberedInstructions = 581224145Sdim Target.getInstructionsByEnumValue(); 582224145Sdim 583224145Sdim OS << "namespace " << Namespace << " {\n"; 584224145Sdim OS << " enum {\n"; 585276479Sdim unsigned Num = 0; 586276479Sdim for (const CodeGenInstruction *Inst : NumberedInstructions) 587276479Sdim OS << " " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n"; 588224145Sdim OS << " INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n"; 589280031Sdim OS << " };\n\n"; 590261991Sdim OS << "namespace Sched {\n"; 591261991Sdim OS << " enum {\n"; 592276479Sdim Num = 0; 593276479Sdim for (const auto &Class : SchedModels.explicit_classes()) 594276479Sdim OS << " " << Class.Name << "\t= " << Num++ << ",\n"; 595261991Sdim OS << " SCHED_LIST_END = " << SchedModels.numInstrSchedClasses() << "\n"; 596280031Sdim OS << " };\n"; 597296417Sdim OS << "} // end Sched namespace\n"; 598296417Sdim OS << "} // end " << Namespace << " namespace\n"; 599296417Sdim OS << "} // end llvm namespace \n"; 600224145Sdim 601224145Sdim OS << "#endif // GET_INSTRINFO_ENUM\n\n"; 602224145Sdim} 603239462Sdim 604239462Sdimnamespace llvm { 605239462Sdim 606239462Sdimvoid EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { 607239462Sdim InstrInfoEmitter(RK).run(OS); 608243830Sdim EmitMapTable(RK, OS); 609239462Sdim} 610239462Sdim 611296417Sdim} // end llvm namespace 612