1193323Sed//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===// 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 16239462Sdim#include "CodeGenDAGPatterns.h" 17239462Sdim#include "CodeGenSchedule.h" 18193323Sed#include "CodeGenTarget.h" 19249423Sdim#include "SequenceToOffsetTable.h" 20243830Sdim#include "TableGenBackends.h" 21239462Sdim#include "llvm/ADT/StringExtras.h" 22243830Sdim#include "llvm/TableGen/Error.h" 23226633Sdim#include "llvm/TableGen/Record.h" 24239462Sdim#include "llvm/TableGen/TableGenBackend.h" 25193323Sed#include <algorithm> 26234353Sdim#include <cstdio> 27239462Sdim#include <map> 28239462Sdim#include <vector> 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; 48263508Sdim 49263508Sdim /// The keys of this map are maps which have OpName enum values as their keys 50263508Sdim /// and instruction operand indices as their values. The values of this map 51263508Sdim /// are lists of instruction names. 52263508Sdim typedef std::map<std::map<unsigned, unsigned>, 53263508Sdim std::vector<std::string> > OpNameMapTy; 54263508Sdim 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); 60263508Sdim void emitOperandTypesEnum(raw_ostream &OS, const CodeGenTarget &Target); 61263508Sdim void initOperandMapData( 62263508Sdim const std::vector<const CodeGenInstruction *> NumberedInstructions, 63263508Sdim const std::string &Namespace, 64263508Sdim std::map<std::string, unsigned> &Operands, 65263508Sdim OpNameMapTy &OperandMap); 66263508Sdim void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target, 67263508Sdim 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}; 73239462Sdim} // End anonymous namespace 74239462Sdim 75193323Sedstatic void PrintDefList(const std::vector<Record*> &Uses, 76195340Sed unsigned Num, raw_ostream &OS) { 77234353Sdim OS << "static const uint16_t 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 91218893Sdim for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) { 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. 100218893Sdim DagInit *MIOI = Inst.Operands[i].MIOperandInfo; 101224145Sdim 102193323Sed if (!MIOI || MIOI->getNumArgs() == 0) { 103193323Sed // Single, anonymous, operand. 104218893Sdim OperandList.push_back(Inst.Operands[i]); 105193323Sed } else { 106218893Sdim for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) { 107218893Sdim OperandList.push_back(Inst.Operands[i]); 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 136263508Sdim // was of type PredicateOp. 137263508Sdim if (Inst.Operands[i].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. 142218893Sdim if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand")) 143224145Sdim Res += "|(1<<MCOI::OptionalDef)"; 144193323Sed 145234353Sdim // Fill in operand type. 146234353Sdim Res += ", MCOI::"; 147234353Sdim assert(!Inst.Operands[i].OperandType.empty() && "Invalid operand type."); 148234353Sdim Res += Inst.Operands[i].OperandType; 149234353Sdim 150193323Sed // Fill in constraint info. 151203954Srdivacky Res += ", "; 152224145Sdim 153218893Sdim const CGIOperandList::ConstraintInfo &Constraint = 154218893Sdim Inst.Operands[i].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(); 180193323Sed for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 181193323Sed E = Target.inst_end(); II != E; ++II) { 182205407Srdivacky std::vector<std::string> OperandInfo = GetOperandInfo(**II); 183193323Sed unsigned &N = OperandInfoIDs[OperandInfo]; 184193323Sed if (N != 0) continue; 185224145Sdim 186193323Sed N = ++OperandListNum; 187224145Sdim OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; 188193323Sed for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) 189193323Sed OS << "{ " << OperandInfo[i] << " }, "; 190193323Sed OS << "};\n"; 191193323Sed } 192193323Sed} 193193323Sed 194263508Sdim 195263508Sdim/// Initialize data structures for generating operand name mappings. 196263508Sdim/// 197263508Sdim/// \param Operands [out] A map used to generate the OpName enum with operand 198263508Sdim/// names as its keys and operand enum values as its values. 199263508Sdim/// \param OperandMap [out] A map for representing the operand name mappings for 200263508Sdim/// each instructions. This is used to generate the OperandMap table as 201263508Sdim/// well as the getNamedOperandIdx() function. 202263508Sdimvoid InstrInfoEmitter::initOperandMapData( 203263508Sdim const std::vector<const CodeGenInstruction *> NumberedInstructions, 204263508Sdim const std::string &Namespace, 205263508Sdim std::map<std::string, unsigned> &Operands, 206263508Sdim OpNameMapTy &OperandMap) { 207263508Sdim 208263508Sdim unsigned NumOperands = 0; 209263508Sdim for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 210263508Sdim const CodeGenInstruction *Inst = NumberedInstructions[i]; 211263508Sdim if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable")) { 212263508Sdim continue; 213263508Sdim } 214263508Sdim std::map<unsigned, unsigned> OpList; 215263508Sdim for (unsigned j = 0, je = Inst->Operands.size(); j != je; ++j) { 216263508Sdim const CGIOperandList::OperandInfo &Info = Inst->Operands[j]; 217263508Sdim StrUintMapIter I = Operands.find(Info.Name); 218263508Sdim 219263508Sdim if (I == Operands.end()) { 220263508Sdim I = Operands.insert(Operands.begin(), 221263508Sdim std::pair<std::string, unsigned>(Info.Name, NumOperands++)); 222263508Sdim } 223263508Sdim OpList[I->second] = Info.MIOperandNo; 224263508Sdim } 225263508Sdim OperandMap[OpList].push_back(Namespace + "::" + Inst->TheDef->getName()); 226263508Sdim } 227263508Sdim} 228263508Sdim 229263508Sdim/// Generate a table and function for looking up the indices of operands by 230263508Sdim/// name. 231263508Sdim/// 232263508Sdim/// This code generates: 233263508Sdim/// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry 234263508Sdim/// for each operand name. 235263508Sdim/// - A 2-dimensional table called OperandMap for mapping OpName enum values to 236263508Sdim/// operand indices. 237263508Sdim/// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) 238263508Sdim/// for looking up the operand index for an instruction, given a value from 239263508Sdim/// OpName enum 240263508Sdimvoid InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS, 241263508Sdim const CodeGenTarget &Target, 242263508Sdim const std::vector<const CodeGenInstruction*> &NumberedInstructions) { 243263508Sdim 244263508Sdim const std::string &Namespace = Target.getInstNamespace(); 245263508Sdim std::string OpNameNS = "OpName"; 246263508Sdim // Map of operand names to their enumeration value. This will be used to 247263508Sdim // generate the OpName enum. 248263508Sdim std::map<std::string, unsigned> Operands; 249263508Sdim OpNameMapTy OperandMap; 250263508Sdim 251263508Sdim initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap); 252263508Sdim 253263508Sdim OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n"; 254263508Sdim OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n"; 255263508Sdim OS << "namespace llvm {"; 256263508Sdim OS << "namespace " << Namespace << " {\n"; 257263508Sdim OS << "namespace " << OpNameNS << " { \n"; 258263508Sdim OS << "enum {\n"; 259263508Sdim for (StrUintMapIter i = Operands.begin(), e = Operands.end(); i != e; ++i) 260263508Sdim OS << " " << i->first << " = " << i->second << ",\n"; 261263508Sdim 262263508Sdim OS << "OPERAND_LAST"; 263263508Sdim OS << "\n};\n"; 264263508Sdim OS << "} // End namespace OpName\n"; 265263508Sdim OS << "} // End namespace " << Namespace << "\n"; 266263508Sdim OS << "} // End namespace llvm\n"; 267263508Sdim OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n"; 268263508Sdim 269263508Sdim OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n"; 270263508Sdim OS << "#undef GET_INSTRINFO_NAMED_OPS\n"; 271263508Sdim OS << "namespace llvm {"; 272263508Sdim OS << "namespace " << Namespace << " {\n"; 273263508Sdim OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n"; 274263508Sdim if (!Operands.empty()) { 275263508Sdim OS << " static const int16_t OperandMap [][" << Operands.size() 276263508Sdim << "] = {\n"; 277263508Sdim for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end(); 278263508Sdim i != e; ++i) { 279263508Sdim const std::map<unsigned, unsigned> &OpList = i->first; 280263508Sdim OS << "{"; 281263508Sdim 282263508Sdim // Emit a row of the OperandMap table 283263508Sdim for (unsigned ii = 0, ie = Operands.size(); ii != ie; ++ii) 284263508Sdim OS << (OpList.count(ii) == 0 ? -1 : (int)OpList.find(ii)->second) 285263508Sdim << ", "; 286263508Sdim 287263508Sdim OS << "},\n"; 288263508Sdim } 289263508Sdim OS << "};\n"; 290263508Sdim 291263508Sdim OS << " switch(Opcode) {\n"; 292263508Sdim unsigned TableIndex = 0; 293263508Sdim for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end(); 294263508Sdim i != e; ++i) { 295263508Sdim std::vector<std::string> &OpcodeList = i->second; 296263508Sdim 297263508Sdim for (unsigned ii = 0, ie = OpcodeList.size(); ii != ie; ++ii) 298263508Sdim OS << " case " << OpcodeList[ii] << ":\n"; 299263508Sdim 300263508Sdim OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n"; 301263508Sdim } 302263508Sdim OS << " default: return -1;\n"; 303263508Sdim OS << " }\n"; 304263508Sdim } else { 305263508Sdim // There are no operands, so no need to emit anything 306263508Sdim OS << " return -1;\n"; 307263508Sdim } 308263508Sdim OS << "}\n"; 309263508Sdim OS << "} // End namespace " << Namespace << "\n"; 310263508Sdim OS << "} // End namespace llvm\n"; 311263508Sdim OS << "#endif //GET_INSTRINFO_NAMED_OPS\n"; 312263508Sdim 313263508Sdim} 314263508Sdim 315263508Sdim/// Generate an enum for all the operand types for this target, under the 316263508Sdim/// llvm::TargetNamespace::OpTypes namespace. 317263508Sdim/// Operand types are all definitions derived of the Operand Target.td class. 318263508Sdimvoid InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS, 319263508Sdim const CodeGenTarget &Target) { 320263508Sdim 321263508Sdim const std::string &Namespace = Target.getInstNamespace(); 322263508Sdim std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand"); 323263508Sdim 324263508Sdim OS << "\n#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 325263508Sdim OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 326263508Sdim OS << "namespace llvm {"; 327263508Sdim OS << "namespace " << Namespace << " {\n"; 328263508Sdim OS << "namespace OpTypes { \n"; 329263508Sdim OS << "enum OperandType {\n"; 330263508Sdim 331263508Sdim for (unsigned oi = 0, oe = Operands.size(); oi != oe; ++oi) { 332263508Sdim if (!Operands[oi]->isAnonymous()) 333263508Sdim OS << " " << Operands[oi]->getName() << " = " << oi << ",\n"; 334263508Sdim } 335263508Sdim 336263508Sdim OS << " OPERAND_TYPE_LIST_END" << "\n};\n"; 337263508Sdim OS << "} // End namespace OpTypes\n"; 338263508Sdim OS << "} // End namespace " << Namespace << "\n"; 339263508Sdim OS << "} // End namespace llvm\n"; 340263508Sdim OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 341263508Sdim} 342263508Sdim 343193323Sed//===----------------------------------------------------------------------===// 344193323Sed// Main Output. 345193323Sed//===----------------------------------------------------------------------===// 346193323Sed 347193323Sed// run - Emit the main instruction description records for the target... 348195340Sedvoid InstrInfoEmitter::run(raw_ostream &OS) { 349239462Sdim emitSourceFileHeader("Target Instruction Enum Values", OS); 350224145Sdim emitEnums(OS); 351224145Sdim 352239462Sdim emitSourceFileHeader("Target Instruction Descriptors", OS); 353193323Sed 354224145Sdim OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n"; 355224145Sdim OS << "#undef GET_INSTRINFO_MC_DESC\n"; 356224145Sdim 357193323Sed OS << "namespace llvm {\n\n"; 358193323Sed 359193323Sed CodeGenTarget &Target = CDP.getTargetInfo(); 360193323Sed const std::string &TargetName = Target.getName(); 361193323Sed Record *InstrInfo = Target.getInstructionSet(); 362193323Sed 363193323Sed // Keep track of all of the def lists we have emitted already. 364193323Sed std::map<std::vector<Record*>, unsigned> EmittedLists; 365193323Sed unsigned ListNumber = 0; 366224145Sdim 367193323Sed // Emit all of the instruction's implicit uses and defs. 368193323Sed for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 369193323Sed E = Target.inst_end(); II != E; ++II) { 370205407Srdivacky Record *Inst = (*II)->TheDef; 371193323Sed std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 372193323Sed if (!Uses.empty()) { 373193323Sed unsigned &IL = EmittedLists[Uses]; 374193323Sed if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); 375193323Sed } 376193323Sed std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 377193323Sed if (!Defs.empty()) { 378193323Sed unsigned &IL = EmittedLists[Defs]; 379193323Sed if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); 380193323Sed } 381193323Sed } 382193323Sed 383193323Sed OperandInfoMapTy OperandInfoIDs; 384224145Sdim 385193323Sed // Emit all of the operand info records. 386193323Sed EmitOperandInfo(OS, OperandInfoIDs); 387224145Sdim 388224145Sdim // Emit all of the MCInstrDesc records in their ENUM ordering. 389193323Sed // 390234353Sdim OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; 391205407Srdivacky const std::vector<const CodeGenInstruction*> &NumberedInstructions = 392205407Srdivacky Target.getInstructionsByEnumValue(); 393193323Sed 394193323Sed for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) 395193323Sed emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists, 396224145Sdim OperandInfoIDs, OS); 397224145Sdim OS << "};\n\n"; 398224145Sdim 399234353Sdim // Build an array of instruction names 400234353Sdim SequenceToOffsetTable<std::string> InstrNames; 401234353Sdim for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 402234353Sdim const CodeGenInstruction *Instr = NumberedInstructions[i]; 403234353Sdim InstrNames.add(Instr->TheDef->getName()); 404234353Sdim } 405234353Sdim 406234353Sdim InstrNames.layout(); 407234353Sdim OS << "extern const char " << TargetName << "InstrNameData[] = {\n"; 408234353Sdim InstrNames.emit(OS, printChar); 409234353Sdim OS << "};\n\n"; 410234353Sdim 411234353Sdim OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; 412234353Sdim for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 413234353Sdim if (i % 8 == 0) 414234353Sdim OS << "\n "; 415234353Sdim const CodeGenInstruction *Instr = NumberedInstructions[i]; 416234353Sdim OS << InstrNames.get(Instr->TheDef->getName()) << "U, "; 417234353Sdim } 418234353Sdim 419234353Sdim OS << "\n};\n\n"; 420234353Sdim 421224145Sdim // MCInstrInfo initialization routine. 422224145Sdim OS << "static inline void Init" << TargetName 423224145Sdim << "MCInstrInfo(MCInstrInfo *II) {\n"; 424224145Sdim OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " 425234353Sdim << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 426224145Sdim << NumberedInstructions.size() << ");\n}\n\n"; 427224145Sdim 428193323Sed OS << "} // End llvm namespace \n"; 429224145Sdim 430224145Sdim OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; 431224145Sdim 432224145Sdim // Create a TargetInstrInfo subclass to hide the MC layer initialization. 433224145Sdim OS << "\n#ifdef GET_INSTRINFO_HEADER\n"; 434224145Sdim OS << "#undef GET_INSTRINFO_HEADER\n"; 435224145Sdim 436224145Sdim std::string ClassName = TargetName + "GenInstrInfo"; 437224145Sdim OS << "namespace llvm {\n"; 438249423Sdim OS << "struct " << ClassName << " : public TargetInstrInfo {\n" 439224145Sdim << " explicit " << ClassName << "(int SO = -1, int DO = -1);\n" 440263508Sdim << " virtual ~" << ClassName << "();\n" 441224145Sdim << "};\n"; 442224145Sdim OS << "} // End llvm namespace \n"; 443224145Sdim 444224145Sdim OS << "#endif // GET_INSTRINFO_HEADER\n\n"; 445224145Sdim 446263508Sdim OS << "\n#ifdef GET_INSTRINFO_CTOR_DTOR\n"; 447263508Sdim OS << "#undef GET_INSTRINFO_CTOR_DTOR\n"; 448224145Sdim 449224145Sdim OS << "namespace llvm {\n"; 450234353Sdim OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; 451234353Sdim OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; 452234353Sdim OS << "extern const char " << TargetName << "InstrNameData[];\n"; 453224145Sdim OS << ClassName << "::" << ClassName << "(int SO, int DO)\n" 454249423Sdim << " : TargetInstrInfo(SO, DO) {\n" 455224145Sdim << " InitMCInstrInfo(" << TargetName << "Insts, " 456234353Sdim << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 457263508Sdim << NumberedInstructions.size() << ");\n}\n" 458263508Sdim << ClassName << "::~" << ClassName << "() {}\n"; 459224145Sdim OS << "} // End llvm namespace \n"; 460224145Sdim 461263508Sdim OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n"; 462263508Sdim 463263508Sdim emitOperandNameMappings(OS, Target, NumberedInstructions); 464263508Sdim 465263508Sdim emitOperandTypesEnum(OS, Target); 466193323Sed} 467193323Sed 468193323Sedvoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 469193323Sed Record *InstrInfo, 470193323Sed std::map<std::vector<Record*>, unsigned> &EmittedLists, 471193323Sed const OperandInfoMapTy &OpInfo, 472195340Sed raw_ostream &OS) { 473193323Sed int MinOperands = 0; 474243830Sdim if (!Inst.Operands.empty()) 475193323Sed // Each logical operand can be multiple MI operands. 476218893Sdim MinOperands = Inst.Operands.back().MIOperandNo + 477218893Sdim Inst.Operands.back().MINumOperands; 478193323Sed 479193323Sed OS << " { "; 480193323Sed OS << Num << ",\t" << MinOperands << ",\t" 481224145Sdim << Inst.Operands.NumDefs << ",\t" 482243830Sdim << SchedModels.getSchedClassIdx(Inst) << ",\t" 483234353Sdim << Inst.TheDef->getValueAsInt("Size") << ",\t0"; 484193323Sed 485193323Sed // Emit all of the target indepedent flags... 486226633Sdim if (Inst.isPseudo) OS << "|(1<<MCID::Pseudo)"; 487224145Sdim if (Inst.isReturn) OS << "|(1<<MCID::Return)"; 488224145Sdim if (Inst.isBranch) OS << "|(1<<MCID::Branch)"; 489224145Sdim if (Inst.isIndirectBranch) OS << "|(1<<MCID::IndirectBranch)"; 490224145Sdim if (Inst.isCompare) OS << "|(1<<MCID::Compare)"; 491224145Sdim if (Inst.isMoveImm) OS << "|(1<<MCID::MoveImm)"; 492224145Sdim if (Inst.isBitcast) OS << "|(1<<MCID::Bitcast)"; 493239462Sdim if (Inst.isSelect) OS << "|(1<<MCID::Select)"; 494224145Sdim if (Inst.isBarrier) OS << "|(1<<MCID::Barrier)"; 495224145Sdim if (Inst.hasDelaySlot) OS << "|(1<<MCID::DelaySlot)"; 496224145Sdim if (Inst.isCall) OS << "|(1<<MCID::Call)"; 497224145Sdim if (Inst.canFoldAsLoad) OS << "|(1<<MCID::FoldableAsLoad)"; 498224145Sdim if (Inst.mayLoad) OS << "|(1<<MCID::MayLoad)"; 499224145Sdim if (Inst.mayStore) OS << "|(1<<MCID::MayStore)"; 500224145Sdim if (Inst.isPredicable) OS << "|(1<<MCID::Predicable)"; 501224145Sdim if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)"; 502224145Sdim if (Inst.isCommutable) OS << "|(1<<MCID::Commutable)"; 503224145Sdim if (Inst.isTerminator) OS << "|(1<<MCID::Terminator)"; 504224145Sdim if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)"; 505224145Sdim if (Inst.isNotDuplicable) OS << "|(1<<MCID::NotDuplicable)"; 506224145Sdim if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)"; 507224145Sdim if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)"; 508226633Sdim if (Inst.hasPostISelHook) OS << "|(1<<MCID::HasPostISelHook)"; 509224145Sdim if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)"; 510224145Sdim if (Inst.hasSideEffects) OS << "|(1<<MCID::UnmodeledSideEffects)"; 511224145Sdim if (Inst.isAsCheapAsAMove) OS << "|(1<<MCID::CheapAsAMove)"; 512224145Sdim if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)"; 513224145Sdim if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)"; 514193323Sed 515193323Sed // Emit all of the target-specific flags... 516206274Srdivacky BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); 517243830Sdim if (!TSF) 518243830Sdim PrintFatalError("no TSFlags?"); 519206274Srdivacky uint64_t Value = 0; 520206274Srdivacky for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { 521243830Sdim if (BitInit *Bit = dyn_cast<BitInit>(TSF->getBit(i))) 522206274Srdivacky Value |= uint64_t(Bit->getValue()) << i; 523206274Srdivacky else 524243830Sdim PrintFatalError("Invalid TSFlags bit in " + Inst.TheDef->getName()); 525206274Srdivacky } 526206274Srdivacky OS << ", 0x"; 527206274Srdivacky OS.write_hex(Value); 528210299Sed OS << "ULL, "; 529193323Sed 530193323Sed // Emit the implicit uses and defs lists... 531193323Sed std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 532193323Sed if (UseList.empty()) 533193323Sed OS << "NULL, "; 534193323Sed else 535193323Sed OS << "ImplicitList" << EmittedLists[UseList] << ", "; 536193323Sed 537193323Sed std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 538193323Sed if (DefList.empty()) 539193323Sed OS << "NULL, "; 540193323Sed else 541193323Sed OS << "ImplicitList" << EmittedLists[DefList] << ", "; 542193323Sed 543193323Sed // Emit the operand info. 544193323Sed std::vector<std::string> OperandInfo = GetOperandInfo(Inst); 545193323Sed if (OperandInfo.empty()) 546193323Sed OS << "0"; 547193323Sed else 548193323Sed OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 549206274Srdivacky 550263508Sdim CodeGenTarget &Target = CDP.getTargetInfo(); 551263508Sdim if (Inst.HasComplexDeprecationPredicate) 552263508Sdim // Emit a function pointer to the complex predicate method. 553263508Sdim OS << ",0" 554263508Sdim << ",&get" << Inst.DeprecatedReason << "DeprecationInfo"; 555263508Sdim else if (!Inst.DeprecatedReason.empty()) 556263508Sdim // Emit the Subtarget feature. 557263508Sdim OS << "," << Target.getInstNamespace() << "::" << Inst.DeprecatedReason 558263508Sdim << ",0"; 559263508Sdim else 560263508Sdim // Instruction isn't deprecated. 561263508Sdim OS << ",0,0"; 562263508Sdim 563193323Sed OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 564193323Sed} 565224145Sdim 566224145Sdim// emitEnums - Print out enum values for all of the instructions. 567224145Sdimvoid InstrInfoEmitter::emitEnums(raw_ostream &OS) { 568224145Sdim 569224145Sdim OS << "\n#ifdef GET_INSTRINFO_ENUM\n"; 570224145Sdim OS << "#undef GET_INSTRINFO_ENUM\n"; 571224145Sdim 572224145Sdim OS << "namespace llvm {\n\n"; 573224145Sdim 574224145Sdim CodeGenTarget Target(Records); 575224145Sdim 576224145Sdim // We must emit the PHI opcode first... 577224145Sdim std::string Namespace = Target.getInstNamespace(); 578234353Sdim 579224145Sdim if (Namespace.empty()) { 580224145Sdim fprintf(stderr, "No instructions defined!\n"); 581224145Sdim exit(1); 582224145Sdim } 583224145Sdim 584224145Sdim const std::vector<const CodeGenInstruction*> &NumberedInstructions = 585224145Sdim Target.getInstructionsByEnumValue(); 586224145Sdim 587224145Sdim OS << "namespace " << Namespace << " {\n"; 588224145Sdim OS << " enum {\n"; 589224145Sdim for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 590224145Sdim OS << " " << NumberedInstructions[i]->TheDef->getName() 591224145Sdim << "\t= " << i << ",\n"; 592224145Sdim } 593224145Sdim OS << " INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n"; 594263508Sdim OS << " };\n"; 595263508Sdim OS << "namespace Sched {\n"; 596263508Sdim OS << " enum {\n"; 597263508Sdim for (unsigned i = 0, e = SchedModels.numInstrSchedClasses(); i != e; ++i) { 598263508Sdim OS << " " << SchedModels.getSchedClass(i).Name 599263508Sdim << "\t= " << i << ",\n"; 600263508Sdim } 601263508Sdim OS << " SCHED_LIST_END = " << SchedModels.numInstrSchedClasses() << "\n"; 602263508Sdim OS << " };\n}\n}\n"; 603224145Sdim OS << "} // End llvm namespace \n"; 604224145Sdim 605224145Sdim OS << "#endif // GET_INSTRINFO_ENUM\n\n"; 606224145Sdim} 607239462Sdim 608239462Sdimnamespace llvm { 609239462Sdim 610239462Sdimvoid EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { 611239462Sdim InstrInfoEmitter(RK).run(OS); 612243830Sdim EmitMapTable(RK, OS); 613239462Sdim} 614239462Sdim 615239462Sdim} // End llvm namespace 616