InstrInfoEmitter.cpp revision 234353
192654Sjeff//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===// 292654Sjeff// 392654Sjeff// The LLVM Compiler Infrastructure 492654Sjeff// 592654Sjeff// This file is distributed under the University of Illinois Open Source 692654Sjeff// License. See LICENSE.TXT for details. 792654Sjeff// 892654Sjeff//===----------------------------------------------------------------------===// 992654Sjeff// 1092654Sjeff// This tablegen backend is responsible for emitting a description of the target 1192654Sjeff// instruction set for the code generator. 1292654Sjeff// 1392654Sjeff//===----------------------------------------------------------------------===// 1492654Sjeff 1592654Sjeff#include "InstrInfoEmitter.h" 1692654Sjeff#include "CodeGenTarget.h" 1792654Sjeff#include "SequenceToOffsetTable.h" 1892654Sjeff#include "llvm/TableGen/Record.h" 1992654Sjeff#include "llvm/ADT/StringExtras.h" 2092654Sjeff#include <algorithm> 2192654Sjeff#include <cstdio> 2292654Sjeffusing namespace llvm; 2392654Sjeff 2492654Sjeffstatic void PrintDefList(const std::vector<Record*> &Uses, 2592654Sjeff unsigned Num, raw_ostream &OS) { 2692654Sjeff OS << "static const uint16_t ImplicitList" << Num << "[] = { "; 2792654Sjeff for (unsigned i = 0, e = Uses.size(); i != e; ++i) 2892654Sjeff OS << getQualifiedName(Uses[i]) << ", "; 2992654Sjeff OS << "0 };\n"; 3092654Sjeff} 3192654Sjeff 3292654Sjeff//===----------------------------------------------------------------------===// 3392654Sjeff// Instruction Itinerary Information. 3492654Sjeff//===----------------------------------------------------------------------===// 3592654Sjeff 3692654Sjeffvoid InstrInfoEmitter::GatherItinClasses() { 3792654Sjeff std::vector<Record*> DefList = 3892654Sjeff Records.getAllDerivedDefinitions("InstrItinClass"); 3992654Sjeff std::sort(DefList.begin(), DefList.end(), LessRecord()); 4092654Sjeff 4192654Sjeff for (unsigned i = 0, N = DefList.size(); i < N; i++) 4292654Sjeff ItinClassMap[DefList[i]->getName()] = i; 4392654Sjeff} 4492654Sjeff 4592654Sjeffunsigned InstrInfoEmitter::getItinClassNumber(const Record *InstRec) { 4692654Sjeff return ItinClassMap[InstRec->getValueAsDef("Itinerary")->getName()]; 4792654Sjeff} 4892654Sjeff 4992654Sjeff//===----------------------------------------------------------------------===// 5092654Sjeff// Operand Info Emission. 5192654Sjeff//===----------------------------------------------------------------------===// 5292654Sjeff 5392654Sjeffstd::vector<std::string> 5492654SjeffInstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { 5592654Sjeff std::vector<std::string> Result; 5692654Sjeff 5792654Sjeff for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) { 5892654Sjeff // Handle aggregate operands and normal operands the same way by expanding 5992654Sjeff // either case into a list of operands for this op. 6092654Sjeff std::vector<CGIOperandList::OperandInfo> OperandList; 6192654Sjeff 6292654Sjeff // This might be a multiple operand thing. Targets like X86 have 6392654Sjeff // registers in their multi-operand operands. It may also be an anonymous 6492654Sjeff // operand, which has a single operand, but no declared class for the 6592654Sjeff // operand. 6692654Sjeff DagInit *MIOI = Inst.Operands[i].MIOperandInfo; 6792654Sjeff 6892654Sjeff if (!MIOI || MIOI->getNumArgs() == 0) { 6992654Sjeff // Single, anonymous, operand. 7092654Sjeff OperandList.push_back(Inst.Operands[i]); 7192654Sjeff } else { 7292654Sjeff for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) { 7392654Sjeff OperandList.push_back(Inst.Operands[i]); 7492654Sjeff 7592654Sjeff Record *OpR = dynamic_cast<DefInit*>(MIOI->getArg(j))->getDef(); 7692654Sjeff OperandList.back().Rec = OpR; 7792654Sjeff } 7892654Sjeff } 7992654Sjeff 8092654Sjeff for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { 8192654Sjeff Record *OpR = OperandList[j].Rec; 8292654Sjeff std::string Res; 8392654Sjeff 8492654Sjeff if (OpR->isSubClassOf("RegisterOperand")) 8592654Sjeff OpR = OpR->getValueAsDef("RegClass"); 8692654Sjeff if (OpR->isSubClassOf("RegisterClass")) 8792654Sjeff Res += getQualifiedName(OpR) + "RegClassID, "; 8892654Sjeff else if (OpR->isSubClassOf("PointerLikeRegClass")) 8992654Sjeff Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; 9092654Sjeff else 9192654Sjeff // -1 means the operand does not have a fixed register class. 9292654Sjeff Res += "-1, "; 9392654Sjeff 9492654Sjeff // Fill in applicable flags. 9592654Sjeff Res += "0"; 9692654Sjeff 9792654Sjeff // Ptr value whose register class is resolved via callback. 9892654Sjeff if (OpR->isSubClassOf("PointerLikeRegClass")) 9992654Sjeff Res += "|(1<<MCOI::LookupPtrRegClass)"; 10092654Sjeff 10192654Sjeff // Predicate operands. Check to see if the original unexpanded operand 10292654Sjeff // was of type PredicateOperand. 10392654Sjeff if (Inst.Operands[i].Rec->isSubClassOf("PredicateOperand")) 10492654Sjeff Res += "|(1<<MCOI::Predicate)"; 10592654Sjeff 10692654Sjeff // Optional def operands. Check to see if the original unexpanded operand 10792654Sjeff // was of type OptionalDefOperand. 10892654Sjeff if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand")) 10992654Sjeff Res += "|(1<<MCOI::OptionalDef)"; 11092654Sjeff 11192654Sjeff // Fill in operand type. 11292654Sjeff Res += ", MCOI::"; 11392654Sjeff assert(!Inst.Operands[i].OperandType.empty() && "Invalid operand type."); 11492654Sjeff Res += Inst.Operands[i].OperandType; 11592654Sjeff 11692654Sjeff // Fill in constraint info. 11792654Sjeff Res += ", "; 11892654Sjeff 11992654Sjeff const CGIOperandList::ConstraintInfo &Constraint = 12092654Sjeff Inst.Operands[i].Constraints[j]; 12192654Sjeff if (Constraint.isNone()) 12292654Sjeff Res += "0"; 12392654Sjeff else if (Constraint.isEarlyClobber()) 12492654Sjeff Res += "(1 << MCOI::EARLY_CLOBBER)"; 12592654Sjeff else { 12692654Sjeff assert(Constraint.isTied()); 12792654Sjeff Res += "((" + utostr(Constraint.getTiedOperand()) + 12892654Sjeff " << 16) | (1 << MCOI::TIED_TO))"; 12992654Sjeff } 13092654Sjeff 13192654Sjeff Result.push_back(Res); 13292654Sjeff } 13392654Sjeff } 13492654Sjeff 13592654Sjeff return Result; 13692654Sjeff} 13792654Sjeff 13892654Sjeffvoid InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, 13992654Sjeff OperandInfoMapTy &OperandInfoIDs) { 14092654Sjeff // ID #0 is for no operand info. 14192654Sjeff unsigned OperandListNum = 0; 14292654Sjeff OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; 14392654Sjeff 14492654Sjeff OS << "\n"; 14592654Sjeff const CodeGenTarget &Target = CDP.getTargetInfo(); 14692654Sjeff for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 14792654Sjeff E = Target.inst_end(); II != E; ++II) { 14892654Sjeff std::vector<std::string> OperandInfo = GetOperandInfo(**II); 14992654Sjeff unsigned &N = OperandInfoIDs[OperandInfo]; 15092654Sjeff if (N != 0) continue; 15192654Sjeff 15292654Sjeff N = ++OperandListNum; 15392654Sjeff OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; 15492654Sjeff for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) 15592654Sjeff OS << "{ " << OperandInfo[i] << " }, "; 15692654Sjeff OS << "};\n"; 15792654Sjeff } 15892654Sjeff} 15992654Sjeff 16092654Sjeff//===----------------------------------------------------------------------===// 16192654Sjeff// Main Output. 16292654Sjeff//===----------------------------------------------------------------------===// 16392654Sjeff 16492654Sjeff// run - Emit the main instruction description records for the target... 16592654Sjeffvoid InstrInfoEmitter::run(raw_ostream &OS) { 16692654Sjeff emitEnums(OS); 16792654Sjeff 16892654Sjeff GatherItinClasses(); 16992654Sjeff 17092654Sjeff EmitSourceFileHeader("Target Instruction Descriptors", OS); 17192654Sjeff 17292654Sjeff OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n"; 17392654Sjeff OS << "#undef GET_INSTRINFO_MC_DESC\n"; 17492654Sjeff 17592654Sjeff OS << "namespace llvm {\n\n"; 17692654Sjeff 17792654Sjeff CodeGenTarget &Target = CDP.getTargetInfo(); 17892654Sjeff const std::string &TargetName = Target.getName(); 17992654Sjeff Record *InstrInfo = Target.getInstructionSet(); 18092654Sjeff 18192654Sjeff // Keep track of all of the def lists we have emitted already. 18292654Sjeff std::map<std::vector<Record*>, unsigned> EmittedLists; 18392654Sjeff unsigned ListNumber = 0; 18492654Sjeff 18592654Sjeff // Emit all of the instruction's implicit uses and defs. 18692654Sjeff for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 18792654Sjeff E = Target.inst_end(); II != E; ++II) { 18892654Sjeff Record *Inst = (*II)->TheDef; 18992654Sjeff std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 19092654Sjeff if (!Uses.empty()) { 19192654Sjeff unsigned &IL = EmittedLists[Uses]; 19292654Sjeff if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); 19392654Sjeff } 19492654Sjeff std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 19592654Sjeff if (!Defs.empty()) { 19692654Sjeff unsigned &IL = EmittedLists[Defs]; 19792654Sjeff if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); 19892654Sjeff } 19992654Sjeff } 20092654Sjeff 20192654Sjeff OperandInfoMapTy OperandInfoIDs; 20292654Sjeff 20392654Sjeff // Emit all of the operand info records. 20492654Sjeff EmitOperandInfo(OS, OperandInfoIDs); 20592654Sjeff 20692654Sjeff // Emit all of the MCInstrDesc records in their ENUM ordering. 20792654Sjeff // 20892654Sjeff OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; 20992654Sjeff const std::vector<const CodeGenInstruction*> &NumberedInstructions = 21092654Sjeff Target.getInstructionsByEnumValue(); 21192654Sjeff 21292654Sjeff for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) 21392654Sjeff emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists, 21492654Sjeff OperandInfoIDs, OS); 21592654Sjeff OS << "};\n\n"; 21692654Sjeff 21792654Sjeff // Build an array of instruction names 21892654Sjeff SequenceToOffsetTable<std::string> InstrNames; 21992654Sjeff for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 22092654Sjeff const CodeGenInstruction *Instr = NumberedInstructions[i]; 22192654Sjeff InstrNames.add(Instr->TheDef->getName()); 22292654Sjeff } 22392654Sjeff 22492654Sjeff InstrNames.layout(); 22592654Sjeff OS << "extern const char " << TargetName << "InstrNameData[] = {\n"; 22692654Sjeff InstrNames.emit(OS, printChar); 22792654Sjeff OS << "};\n\n"; 22892654Sjeff 22992654Sjeff OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; 23092654Sjeff for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 23192654Sjeff if (i % 8 == 0) 23292654Sjeff OS << "\n "; 23392654Sjeff const CodeGenInstruction *Instr = NumberedInstructions[i]; 23492654Sjeff OS << InstrNames.get(Instr->TheDef->getName()) << "U, "; 23592654Sjeff } 23692654Sjeff 23792654Sjeff OS << "\n};\n\n"; 23892654Sjeff 23992654Sjeff // MCInstrInfo initialization routine. 24092654Sjeff OS << "static inline void Init" << TargetName 24192654Sjeff << "MCInstrInfo(MCInstrInfo *II) {\n"; 24292654Sjeff OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " 24392654Sjeff << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 24492654Sjeff << NumberedInstructions.size() << ");\n}\n\n"; 24592654Sjeff 24692654Sjeff OS << "} // End llvm namespace \n"; 24792654Sjeff 24892654Sjeff OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; 24992654Sjeff 25092654Sjeff // Create a TargetInstrInfo subclass to hide the MC layer initialization. 25192654Sjeff OS << "\n#ifdef GET_INSTRINFO_HEADER\n"; 25292654Sjeff OS << "#undef GET_INSTRINFO_HEADER\n"; 25392654Sjeff 25492654Sjeff std::string ClassName = TargetName + "GenInstrInfo"; 25592654Sjeff OS << "namespace llvm {\n"; 25692654Sjeff OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n" 25792654Sjeff << " explicit " << ClassName << "(int SO = -1, int DO = -1);\n" 25892654Sjeff << "};\n"; 25992654Sjeff OS << "} // End llvm namespace \n"; 26092654Sjeff 26192654Sjeff OS << "#endif // GET_INSTRINFO_HEADER\n\n"; 26292654Sjeff 26392654Sjeff OS << "\n#ifdef GET_INSTRINFO_CTOR\n"; 26492654Sjeff OS << "#undef GET_INSTRINFO_CTOR\n"; 26592654Sjeff 26692654Sjeff OS << "namespace llvm {\n"; 26792654Sjeff OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; 26892654Sjeff OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; 26992654Sjeff OS << "extern const char " << TargetName << "InstrNameData[];\n"; 27092654Sjeff OS << ClassName << "::" << ClassName << "(int SO, int DO)\n" 27192654Sjeff << " : TargetInstrInfoImpl(SO, DO) {\n" 27292654Sjeff << " InitMCInstrInfo(" << TargetName << "Insts, " 27392654Sjeff << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 27492654Sjeff << NumberedInstructions.size() << ");\n}\n"; 27592654Sjeff OS << "} // End llvm namespace \n"; 27692654Sjeff 27792654Sjeff OS << "#endif // GET_INSTRINFO_CTOR\n\n"; 27892654Sjeff} 27992654Sjeff 28092654Sjeffvoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 28192654Sjeff Record *InstrInfo, 28292654Sjeff std::map<std::vector<Record*>, unsigned> &EmittedLists, 28392654Sjeff const OperandInfoMapTy &OpInfo, 28492654Sjeff raw_ostream &OS) { 28592654Sjeff int MinOperands = 0; 28692654Sjeff if (!Inst.Operands.size() == 0) 28792654Sjeff // Each logical operand can be multiple MI operands. 28892654Sjeff MinOperands = Inst.Operands.back().MIOperandNo + 28992654Sjeff Inst.Operands.back().MINumOperands; 29092654Sjeff 29192654Sjeff OS << " { "; 29292654Sjeff OS << Num << ",\t" << MinOperands << ",\t" 29392654Sjeff << Inst.Operands.NumDefs << ",\t" 29492654Sjeff << getItinClassNumber(Inst.TheDef) << ",\t" 29592654Sjeff << Inst.TheDef->getValueAsInt("Size") << ",\t0"; 29692654Sjeff 29792654Sjeff // Emit all of the target indepedent flags... 29892654Sjeff if (Inst.isPseudo) OS << "|(1<<MCID::Pseudo)"; 29992654Sjeff if (Inst.isReturn) OS << "|(1<<MCID::Return)"; 30092654Sjeff if (Inst.isBranch) OS << "|(1<<MCID::Branch)"; 30192654Sjeff if (Inst.isIndirectBranch) OS << "|(1<<MCID::IndirectBranch)"; 30292654Sjeff if (Inst.isCompare) OS << "|(1<<MCID::Compare)"; 30392654Sjeff if (Inst.isMoveImm) OS << "|(1<<MCID::MoveImm)"; 30492654Sjeff if (Inst.isBitcast) OS << "|(1<<MCID::Bitcast)"; 30592654Sjeff if (Inst.isBarrier) OS << "|(1<<MCID::Barrier)"; 30692654Sjeff if (Inst.hasDelaySlot) OS << "|(1<<MCID::DelaySlot)"; 30792654Sjeff if (Inst.isCall) OS << "|(1<<MCID::Call)"; 30892654Sjeff if (Inst.canFoldAsLoad) OS << "|(1<<MCID::FoldableAsLoad)"; 30992654Sjeff if (Inst.mayLoad) OS << "|(1<<MCID::MayLoad)"; 31092654Sjeff if (Inst.mayStore) OS << "|(1<<MCID::MayStore)"; 31192654Sjeff if (Inst.isPredicable) OS << "|(1<<MCID::Predicable)"; 31292654Sjeff if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)"; 31392654Sjeff if (Inst.isCommutable) OS << "|(1<<MCID::Commutable)"; 31492654Sjeff if (Inst.isTerminator) OS << "|(1<<MCID::Terminator)"; 31592654Sjeff if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)"; 31692654Sjeff if (Inst.isNotDuplicable) OS << "|(1<<MCID::NotDuplicable)"; 31792654Sjeff if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)"; 31892654Sjeff if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)"; 31992654Sjeff if (Inst.hasPostISelHook) OS << "|(1<<MCID::HasPostISelHook)"; 32092654Sjeff if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)"; 32192654Sjeff if (Inst.hasSideEffects) OS << "|(1<<MCID::UnmodeledSideEffects)"; 32292654Sjeff if (Inst.isAsCheapAsAMove) OS << "|(1<<MCID::CheapAsAMove)"; 32392654Sjeff if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)"; 32492654Sjeff if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)"; 32592654Sjeff 32692654Sjeff // Emit all of the target-specific flags... 32792654Sjeff BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); 32892654Sjeff if (!TSF) throw "no TSFlags?"; 32992654Sjeff uint64_t Value = 0; 33092654Sjeff for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { 33192654Sjeff if (BitInit *Bit = dynamic_cast<BitInit*>(TSF->getBit(i))) 33292654Sjeff Value |= uint64_t(Bit->getValue()) << i; 33392654Sjeff else 33492654Sjeff throw "Invalid TSFlags bit in " + Inst.TheDef->getName(); 33592654Sjeff } 33692654Sjeff OS << ", 0x"; 33792654Sjeff OS.write_hex(Value); 33892654Sjeff OS << "ULL, "; 33992654Sjeff 34092654Sjeff // Emit the implicit uses and defs lists... 34192654Sjeff std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 34292654Sjeff if (UseList.empty()) 34392654Sjeff OS << "NULL, "; 34492654Sjeff else 34592654Sjeff OS << "ImplicitList" << EmittedLists[UseList] << ", "; 34692654Sjeff 34792654Sjeff std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 34892654Sjeff if (DefList.empty()) 34992654Sjeff OS << "NULL, "; 35092654Sjeff else 35192654Sjeff OS << "ImplicitList" << EmittedLists[DefList] << ", "; 35292654Sjeff 35392654Sjeff // Emit the operand info. 35492654Sjeff std::vector<std::string> OperandInfo = GetOperandInfo(Inst); 35592654Sjeff if (OperandInfo.empty()) 35692654Sjeff OS << "0"; 35792654Sjeff else 35892654Sjeff OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 35992654Sjeff 36092654Sjeff OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 36192654Sjeff} 36292758Sjeff 36392758Sjeff// emitEnums - Print out enum values for all of the instructions. 36492758Sjeffvoid InstrInfoEmitter::emitEnums(raw_ostream &OS) { 36592758Sjeff EmitSourceFileHeader("Target Instruction Enum Values", OS); 36692758Sjeff 36792758Sjeff OS << "\n#ifdef GET_INSTRINFO_ENUM\n"; 36892758Sjeff OS << "#undef GET_INSTRINFO_ENUM\n"; 36992758Sjeff 37092758Sjeff OS << "namespace llvm {\n\n"; 37192758Sjeff 37292654Sjeff CodeGenTarget Target(Records); 37392654Sjeff 37492654Sjeff // We must emit the PHI opcode first... 37592654Sjeff std::string Namespace = Target.getInstNamespace(); 37692654Sjeff 37792654Sjeff if (Namespace.empty()) { 37892654Sjeff fprintf(stderr, "No instructions defined!\n"); 37992654Sjeff exit(1); 38092654Sjeff } 38192654Sjeff 38292654Sjeff const std::vector<const CodeGenInstruction*> &NumberedInstructions = 38392654Sjeff Target.getInstructionsByEnumValue(); 38492654Sjeff 38592654Sjeff OS << "namespace " << Namespace << " {\n"; 38692654Sjeff OS << " enum {\n"; 38792654Sjeff for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 38892654Sjeff OS << " " << NumberedInstructions[i]->TheDef->getName() 38992654Sjeff << "\t= " << i << ",\n"; 39092654Sjeff } 39192654Sjeff OS << " INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n"; 39292654Sjeff OS << " };\n}\n"; 39392654Sjeff OS << "} // End llvm namespace \n"; 39492654Sjeff 39592654Sjeff OS << "#endif // GET_INSTRINFO_ENUM\n\n"; 39692654Sjeff} 39792654Sjeff