InstrInfoEmitter.cpp revision 243830
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" 19243830Sdim#include "TableGenBackends.h" 20234353Sdim#include "SequenceToOffsetTable.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; 48239462Sdim void emitRecord(const CodeGenInstruction &Inst, unsigned Num, 49239462Sdim Record *InstrInfo, 50239462Sdim std::map<std::vector<Record*>, unsigned> &EL, 51239462Sdim const OperandInfoMapTy &OpInfo, 52239462Sdim raw_ostream &OS); 53239462Sdim 54239462Sdim // Operand information. 55239462Sdim void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); 56239462Sdim std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); 57239462Sdim}; 58239462Sdim} // End anonymous namespace 59239462Sdim 60193323Sedstatic void PrintDefList(const std::vector<Record*> &Uses, 61195340Sed unsigned Num, raw_ostream &OS) { 62234353Sdim OS << "static const uint16_t ImplicitList" << Num << "[] = { "; 63193323Sed for (unsigned i = 0, e = Uses.size(); i != e; ++i) 64193323Sed OS << getQualifiedName(Uses[i]) << ", "; 65193323Sed OS << "0 };\n"; 66193323Sed} 67193323Sed 68193323Sed//===----------------------------------------------------------------------===// 69193323Sed// Operand Info Emission. 70193323Sed//===----------------------------------------------------------------------===// 71193323Sed 72193323Sedstd::vector<std::string> 73193323SedInstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { 74193323Sed std::vector<std::string> Result; 75224145Sdim 76218893Sdim for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) { 77193323Sed // Handle aggregate operands and normal operands the same way by expanding 78193323Sed // either case into a list of operands for this op. 79218893Sdim std::vector<CGIOperandList::OperandInfo> OperandList; 80193323Sed 81193323Sed // This might be a multiple operand thing. Targets like X86 have 82193323Sed // registers in their multi-operand operands. It may also be an anonymous 83193323Sed // operand, which has a single operand, but no declared class for the 84193323Sed // operand. 85218893Sdim DagInit *MIOI = Inst.Operands[i].MIOperandInfo; 86224145Sdim 87193323Sed if (!MIOI || MIOI->getNumArgs() == 0) { 88193323Sed // Single, anonymous, operand. 89218893Sdim OperandList.push_back(Inst.Operands[i]); 90193323Sed } else { 91218893Sdim for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) { 92218893Sdim OperandList.push_back(Inst.Operands[i]); 93193323Sed 94243830Sdim Record *OpR = cast<DefInit>(MIOI->getArg(j))->getDef(); 95193323Sed OperandList.back().Rec = OpR; 96193323Sed } 97193323Sed } 98193323Sed 99193323Sed for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { 100193323Sed Record *OpR = OperandList[j].Rec; 101193323Sed std::string Res; 102224145Sdim 103224145Sdim if (OpR->isSubClassOf("RegisterOperand")) 104224145Sdim OpR = OpR->getValueAsDef("RegClass"); 105193323Sed if (OpR->isSubClassOf("RegisterClass")) 106193323Sed Res += getQualifiedName(OpR) + "RegClassID, "; 107198090Srdivacky else if (OpR->isSubClassOf("PointerLikeRegClass")) 108198090Srdivacky Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; 109193323Sed else 110210299Sed // -1 means the operand does not have a fixed register class. 111210299Sed Res += "-1, "; 112224145Sdim 113193323Sed // Fill in applicable flags. 114193323Sed Res += "0"; 115224145Sdim 116193323Sed // Ptr value whose register class is resolved via callback. 117198090Srdivacky if (OpR->isSubClassOf("PointerLikeRegClass")) 118224145Sdim Res += "|(1<<MCOI::LookupPtrRegClass)"; 119193323Sed 120193323Sed // Predicate operands. Check to see if the original unexpanded operand 121193323Sed // was of type PredicateOperand. 122218893Sdim if (Inst.Operands[i].Rec->isSubClassOf("PredicateOperand")) 123224145Sdim Res += "|(1<<MCOI::Predicate)"; 124224145Sdim 125193323Sed // Optional def operands. Check to see if the original unexpanded operand 126193323Sed // was of type OptionalDefOperand. 127218893Sdim if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand")) 128224145Sdim Res += "|(1<<MCOI::OptionalDef)"; 129193323Sed 130234353Sdim // Fill in operand type. 131234353Sdim Res += ", MCOI::"; 132234353Sdim assert(!Inst.Operands[i].OperandType.empty() && "Invalid operand type."); 133234353Sdim Res += Inst.Operands[i].OperandType; 134234353Sdim 135193323Sed // Fill in constraint info. 136203954Srdivacky Res += ", "; 137224145Sdim 138218893Sdim const CGIOperandList::ConstraintInfo &Constraint = 139218893Sdim Inst.Operands[i].Constraints[j]; 140203954Srdivacky if (Constraint.isNone()) 141203954Srdivacky Res += "0"; 142203954Srdivacky else if (Constraint.isEarlyClobber()) 143224145Sdim Res += "(1 << MCOI::EARLY_CLOBBER)"; 144203954Srdivacky else { 145203954Srdivacky assert(Constraint.isTied()); 146203954Srdivacky Res += "((" + utostr(Constraint.getTiedOperand()) + 147224145Sdim " << 16) | (1 << MCOI::TIED_TO))"; 148203954Srdivacky } 149224145Sdim 150193323Sed Result.push_back(Res); 151193323Sed } 152193323Sed } 153193323Sed 154193323Sed return Result; 155193323Sed} 156193323Sed 157224145Sdimvoid InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, 158193323Sed OperandInfoMapTy &OperandInfoIDs) { 159193323Sed // ID #0 is for no operand info. 160193323Sed unsigned OperandListNum = 0; 161193323Sed OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; 162224145Sdim 163193323Sed OS << "\n"; 164193323Sed const CodeGenTarget &Target = CDP.getTargetInfo(); 165193323Sed for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 166193323Sed E = Target.inst_end(); II != E; ++II) { 167205407Srdivacky std::vector<std::string> OperandInfo = GetOperandInfo(**II); 168193323Sed unsigned &N = OperandInfoIDs[OperandInfo]; 169193323Sed if (N != 0) continue; 170224145Sdim 171193323Sed N = ++OperandListNum; 172224145Sdim OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; 173193323Sed for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) 174193323Sed OS << "{ " << OperandInfo[i] << " }, "; 175193323Sed OS << "};\n"; 176193323Sed } 177193323Sed} 178193323Sed 179193323Sed//===----------------------------------------------------------------------===// 180193323Sed// Main Output. 181193323Sed//===----------------------------------------------------------------------===// 182193323Sed 183193323Sed// run - Emit the main instruction description records for the target... 184195340Sedvoid InstrInfoEmitter::run(raw_ostream &OS) { 185239462Sdim emitSourceFileHeader("Target Instruction Enum Values", OS); 186224145Sdim emitEnums(OS); 187224145Sdim 188239462Sdim emitSourceFileHeader("Target Instruction Descriptors", OS); 189193323Sed 190224145Sdim OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n"; 191224145Sdim OS << "#undef GET_INSTRINFO_MC_DESC\n"; 192224145Sdim 193193323Sed OS << "namespace llvm {\n\n"; 194193323Sed 195193323Sed CodeGenTarget &Target = CDP.getTargetInfo(); 196193323Sed const std::string &TargetName = Target.getName(); 197193323Sed Record *InstrInfo = Target.getInstructionSet(); 198193323Sed 199193323Sed // Keep track of all of the def lists we have emitted already. 200193323Sed std::map<std::vector<Record*>, unsigned> EmittedLists; 201193323Sed unsigned ListNumber = 0; 202224145Sdim 203193323Sed // Emit all of the instruction's implicit uses and defs. 204193323Sed for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 205193323Sed E = Target.inst_end(); II != E; ++II) { 206205407Srdivacky Record *Inst = (*II)->TheDef; 207193323Sed std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 208193323Sed if (!Uses.empty()) { 209193323Sed unsigned &IL = EmittedLists[Uses]; 210193323Sed if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); 211193323Sed } 212193323Sed std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 213193323Sed if (!Defs.empty()) { 214193323Sed unsigned &IL = EmittedLists[Defs]; 215193323Sed if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); 216193323Sed } 217193323Sed } 218193323Sed 219193323Sed OperandInfoMapTy OperandInfoIDs; 220224145Sdim 221193323Sed // Emit all of the operand info records. 222193323Sed EmitOperandInfo(OS, OperandInfoIDs); 223224145Sdim 224224145Sdim // Emit all of the MCInstrDesc records in their ENUM ordering. 225193323Sed // 226234353Sdim OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; 227205407Srdivacky const std::vector<const CodeGenInstruction*> &NumberedInstructions = 228205407Srdivacky Target.getInstructionsByEnumValue(); 229193323Sed 230193323Sed for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) 231193323Sed emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists, 232224145Sdim OperandInfoIDs, OS); 233224145Sdim OS << "};\n\n"; 234224145Sdim 235234353Sdim // Build an array of instruction names 236234353Sdim SequenceToOffsetTable<std::string> InstrNames; 237234353Sdim for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 238234353Sdim const CodeGenInstruction *Instr = NumberedInstructions[i]; 239234353Sdim InstrNames.add(Instr->TheDef->getName()); 240234353Sdim } 241234353Sdim 242234353Sdim InstrNames.layout(); 243234353Sdim OS << "extern const char " << TargetName << "InstrNameData[] = {\n"; 244234353Sdim InstrNames.emit(OS, printChar); 245234353Sdim OS << "};\n\n"; 246234353Sdim 247234353Sdim OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; 248234353Sdim for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 249234353Sdim if (i % 8 == 0) 250234353Sdim OS << "\n "; 251234353Sdim const CodeGenInstruction *Instr = NumberedInstructions[i]; 252234353Sdim OS << InstrNames.get(Instr->TheDef->getName()) << "U, "; 253234353Sdim } 254234353Sdim 255234353Sdim OS << "\n};\n\n"; 256234353Sdim 257224145Sdim // MCInstrInfo initialization routine. 258224145Sdim OS << "static inline void Init" << TargetName 259224145Sdim << "MCInstrInfo(MCInstrInfo *II) {\n"; 260224145Sdim OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " 261234353Sdim << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 262224145Sdim << NumberedInstructions.size() << ");\n}\n\n"; 263224145Sdim 264193323Sed OS << "} // End llvm namespace \n"; 265224145Sdim 266224145Sdim OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; 267224145Sdim 268224145Sdim // Create a TargetInstrInfo subclass to hide the MC layer initialization. 269224145Sdim OS << "\n#ifdef GET_INSTRINFO_HEADER\n"; 270224145Sdim OS << "#undef GET_INSTRINFO_HEADER\n"; 271224145Sdim 272224145Sdim std::string ClassName = TargetName + "GenInstrInfo"; 273224145Sdim OS << "namespace llvm {\n"; 274224145Sdim OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n" 275224145Sdim << " explicit " << ClassName << "(int SO = -1, int DO = -1);\n" 276224145Sdim << "};\n"; 277224145Sdim OS << "} // End llvm namespace \n"; 278224145Sdim 279224145Sdim OS << "#endif // GET_INSTRINFO_HEADER\n\n"; 280224145Sdim 281224145Sdim OS << "\n#ifdef GET_INSTRINFO_CTOR\n"; 282224145Sdim OS << "#undef GET_INSTRINFO_CTOR\n"; 283224145Sdim 284224145Sdim OS << "namespace llvm {\n"; 285234353Sdim OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; 286234353Sdim OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; 287234353Sdim OS << "extern const char " << TargetName << "InstrNameData[];\n"; 288224145Sdim OS << ClassName << "::" << ClassName << "(int SO, int DO)\n" 289224145Sdim << " : TargetInstrInfoImpl(SO, DO) {\n" 290224145Sdim << " InitMCInstrInfo(" << TargetName << "Insts, " 291234353Sdim << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 292224145Sdim << NumberedInstructions.size() << ");\n}\n"; 293224145Sdim OS << "} // End llvm namespace \n"; 294224145Sdim 295224145Sdim OS << "#endif // GET_INSTRINFO_CTOR\n\n"; 296193323Sed} 297193323Sed 298193323Sedvoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 299193323Sed Record *InstrInfo, 300193323Sed std::map<std::vector<Record*>, unsigned> &EmittedLists, 301193323Sed const OperandInfoMapTy &OpInfo, 302195340Sed raw_ostream &OS) { 303193323Sed int MinOperands = 0; 304243830Sdim if (!Inst.Operands.empty()) 305193323Sed // Each logical operand can be multiple MI operands. 306218893Sdim MinOperands = Inst.Operands.back().MIOperandNo + 307218893Sdim Inst.Operands.back().MINumOperands; 308193323Sed 309193323Sed OS << " { "; 310193323Sed OS << Num << ",\t" << MinOperands << ",\t" 311224145Sdim << Inst.Operands.NumDefs << ",\t" 312243830Sdim << SchedModels.getSchedClassIdx(Inst) << ",\t" 313234353Sdim << Inst.TheDef->getValueAsInt("Size") << ",\t0"; 314193323Sed 315193323Sed // Emit all of the target indepedent flags... 316226633Sdim if (Inst.isPseudo) OS << "|(1<<MCID::Pseudo)"; 317224145Sdim if (Inst.isReturn) OS << "|(1<<MCID::Return)"; 318224145Sdim if (Inst.isBranch) OS << "|(1<<MCID::Branch)"; 319224145Sdim if (Inst.isIndirectBranch) OS << "|(1<<MCID::IndirectBranch)"; 320224145Sdim if (Inst.isCompare) OS << "|(1<<MCID::Compare)"; 321224145Sdim if (Inst.isMoveImm) OS << "|(1<<MCID::MoveImm)"; 322224145Sdim if (Inst.isBitcast) OS << "|(1<<MCID::Bitcast)"; 323239462Sdim if (Inst.isSelect) OS << "|(1<<MCID::Select)"; 324224145Sdim if (Inst.isBarrier) OS << "|(1<<MCID::Barrier)"; 325224145Sdim if (Inst.hasDelaySlot) OS << "|(1<<MCID::DelaySlot)"; 326224145Sdim if (Inst.isCall) OS << "|(1<<MCID::Call)"; 327224145Sdim if (Inst.canFoldAsLoad) OS << "|(1<<MCID::FoldableAsLoad)"; 328224145Sdim if (Inst.mayLoad) OS << "|(1<<MCID::MayLoad)"; 329224145Sdim if (Inst.mayStore) OS << "|(1<<MCID::MayStore)"; 330224145Sdim if (Inst.isPredicable) OS << "|(1<<MCID::Predicable)"; 331224145Sdim if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)"; 332224145Sdim if (Inst.isCommutable) OS << "|(1<<MCID::Commutable)"; 333224145Sdim if (Inst.isTerminator) OS << "|(1<<MCID::Terminator)"; 334224145Sdim if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)"; 335224145Sdim if (Inst.isNotDuplicable) OS << "|(1<<MCID::NotDuplicable)"; 336224145Sdim if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)"; 337224145Sdim if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)"; 338226633Sdim if (Inst.hasPostISelHook) OS << "|(1<<MCID::HasPostISelHook)"; 339224145Sdim if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)"; 340224145Sdim if (Inst.hasSideEffects) OS << "|(1<<MCID::UnmodeledSideEffects)"; 341224145Sdim if (Inst.isAsCheapAsAMove) OS << "|(1<<MCID::CheapAsAMove)"; 342224145Sdim if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)"; 343224145Sdim if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)"; 344193323Sed 345193323Sed // Emit all of the target-specific flags... 346206274Srdivacky BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); 347243830Sdim if (!TSF) 348243830Sdim PrintFatalError("no TSFlags?"); 349206274Srdivacky uint64_t Value = 0; 350206274Srdivacky for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { 351243830Sdim if (BitInit *Bit = dyn_cast<BitInit>(TSF->getBit(i))) 352206274Srdivacky Value |= uint64_t(Bit->getValue()) << i; 353206274Srdivacky else 354243830Sdim PrintFatalError("Invalid TSFlags bit in " + Inst.TheDef->getName()); 355206274Srdivacky } 356206274Srdivacky OS << ", 0x"; 357206274Srdivacky OS.write_hex(Value); 358210299Sed OS << "ULL, "; 359193323Sed 360193323Sed // Emit the implicit uses and defs lists... 361193323Sed std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 362193323Sed if (UseList.empty()) 363193323Sed OS << "NULL, "; 364193323Sed else 365193323Sed OS << "ImplicitList" << EmittedLists[UseList] << ", "; 366193323Sed 367193323Sed std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 368193323Sed if (DefList.empty()) 369193323Sed OS << "NULL, "; 370193323Sed else 371193323Sed OS << "ImplicitList" << EmittedLists[DefList] << ", "; 372193323Sed 373193323Sed // Emit the operand info. 374193323Sed std::vector<std::string> OperandInfo = GetOperandInfo(Inst); 375193323Sed if (OperandInfo.empty()) 376193323Sed OS << "0"; 377193323Sed else 378193323Sed OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 379206274Srdivacky 380193323Sed OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 381193323Sed} 382224145Sdim 383224145Sdim// emitEnums - Print out enum values for all of the instructions. 384224145Sdimvoid InstrInfoEmitter::emitEnums(raw_ostream &OS) { 385224145Sdim 386224145Sdim OS << "\n#ifdef GET_INSTRINFO_ENUM\n"; 387224145Sdim OS << "#undef GET_INSTRINFO_ENUM\n"; 388224145Sdim 389224145Sdim OS << "namespace llvm {\n\n"; 390224145Sdim 391224145Sdim CodeGenTarget Target(Records); 392224145Sdim 393224145Sdim // We must emit the PHI opcode first... 394224145Sdim std::string Namespace = Target.getInstNamespace(); 395234353Sdim 396224145Sdim if (Namespace.empty()) { 397224145Sdim fprintf(stderr, "No instructions defined!\n"); 398224145Sdim exit(1); 399224145Sdim } 400224145Sdim 401224145Sdim const std::vector<const CodeGenInstruction*> &NumberedInstructions = 402224145Sdim Target.getInstructionsByEnumValue(); 403224145Sdim 404224145Sdim OS << "namespace " << Namespace << " {\n"; 405224145Sdim OS << " enum {\n"; 406224145Sdim for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 407224145Sdim OS << " " << NumberedInstructions[i]->TheDef->getName() 408224145Sdim << "\t= " << i << ",\n"; 409224145Sdim } 410224145Sdim OS << " INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n"; 411224145Sdim OS << " };\n}\n"; 412224145Sdim OS << "} // End llvm namespace \n"; 413224145Sdim 414224145Sdim OS << "#endif // GET_INSTRINFO_ENUM\n\n"; 415224145Sdim} 416239462Sdim 417239462Sdimnamespace llvm { 418239462Sdim 419239462Sdimvoid EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { 420239462Sdim InstrInfoEmitter(RK).run(OS); 421243830Sdim EmitMapTable(RK, OS); 422239462Sdim} 423239462Sdim 424239462Sdim} // End llvm namespace 425