InstrInfoEmitter.cpp revision 6f36fa981a59461466e12e5056ba209d289b81b1
17842e56b97ce677b83bdab09cda48bc2d89ac75aJust//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===// 28413c108d21e8cf0e9059bbfffde8d13f2616340Behdad Esfahbod// 37842e56b97ce677b83bdab09cda48bc2d89ac75aJust// The LLVM Compiler Infrastructure 422dcb9e6f9a9d087e87cece6caca6aa5d92f4d91jvr// 5b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod// This file is distributed under the University of Illinois Open Source 622dcb9e6f9a9d087e87cece6caca6aa5d92f4d91jvr// License. See LICENSE.TXT for details. 77842e56b97ce677b83bdab09cda48bc2d89ac75aJust// 87842e56b97ce677b83bdab09cda48bc2d89ac75aJust//===----------------------------------------------------------------------===// 97842e56b97ce677b83bdab09cda48bc2d89ac75aJust// 107842e56b97ce677b83bdab09cda48bc2d89ac75aJust// This tablegen backend is responsible for emitting a description of the target 11859967e5218bed974d05ddec93996b9aea2782a5Just// instruction set for the code generator. 12859967e5218bed974d05ddec93996b9aea2782a5Just// 13859967e5218bed974d05ddec93996b9aea2782a5Just//===----------------------------------------------------------------------===// 14859967e5218bed974d05ddec93996b9aea2782a5Just 15859967e5218bed974d05ddec93996b9aea2782a5Just 16859967e5218bed974d05ddec93996b9aea2782a5Just#include "CodeGenDAGPatterns.h" 17859967e5218bed974d05ddec93996b9aea2782a5Just#include "CodeGenTarget.h" 18859967e5218bed974d05ddec93996b9aea2782a5Just#include "SequenceToOffsetTable.h" 19859967e5218bed974d05ddec93996b9aea2782a5Just#include "llvm/ADT/StringExtras.h" 20859967e5218bed974d05ddec93996b9aea2782a5Just#include "llvm/TableGen/Record.h" 217842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include "llvm/TableGen/TableGenBackend.h" 227842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include <algorithm> 237842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include <cstdio> 247842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include <map> 257842e56b97ce677b83bdab09cda48bc2d89ac75aJust#include <vector> 267842e56b97ce677b83bdab09cda48bc2d89ac75aJustusing namespace llvm; 277842e56b97ce677b83bdab09cda48bc2d89ac75aJust 287842e56b97ce677b83bdab09cda48bc2d89ac75aJustnamespace { 297842e56b97ce677b83bdab09cda48bc2d89ac75aJustclass InstrInfoEmitter { 307842e56b97ce677b83bdab09cda48bc2d89ac75aJust RecordKeeper &Records; 317842e56b97ce677b83bdab09cda48bc2d89ac75aJust CodeGenDAGPatterns CDP; 327842e56b97ce677b83bdab09cda48bc2d89ac75aJust std::map<std::string, unsigned> ItinClassMap; 337842e56b97ce677b83bdab09cda48bc2d89ac75aJust 347842e56b97ce677b83bdab09cda48bc2d89ac75aJustpublic: 357842e56b97ce677b83bdab09cda48bc2d89ac75aJust InstrInfoEmitter(RecordKeeper &R) : Records(R), CDP(R) { } 367842e56b97ce677b83bdab09cda48bc2d89ac75aJust 377842e56b97ce677b83bdab09cda48bc2d89ac75aJust // run - Output the instruction set description. 38859967e5218bed974d05ddec93996b9aea2782a5Just void run(raw_ostream &OS); 39859967e5218bed974d05ddec93996b9aea2782a5Just 40859967e5218bed974d05ddec93996b9aea2782a5Justprivate: 41859967e5218bed974d05ddec93996b9aea2782a5Just void emitEnums(raw_ostream &OS); 42859967e5218bed974d05ddec93996b9aea2782a5Just 43859967e5218bed974d05ddec93996b9aea2782a5Just typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy; 44859967e5218bed974d05ddec93996b9aea2782a5Just void emitRecord(const CodeGenInstruction &Inst, unsigned Num, 45859967e5218bed974d05ddec93996b9aea2782a5Just Record *InstrInfo, 46859967e5218bed974d05ddec93996b9aea2782a5Just std::map<std::vector<Record*>, unsigned> &EL, 47859967e5218bed974d05ddec93996b9aea2782a5Just const OperandInfoMapTy &OpInfo, 48859967e5218bed974d05ddec93996b9aea2782a5Just raw_ostream &OS); 49859967e5218bed974d05ddec93996b9aea2782a5Just 50859967e5218bed974d05ddec93996b9aea2782a5Just // Itinerary information. 51859967e5218bed974d05ddec93996b9aea2782a5Just void GatherItinClasses(); 52859967e5218bed974d05ddec93996b9aea2782a5Just unsigned getItinClassNumber(const Record *InstRec); 53859967e5218bed974d05ddec93996b9aea2782a5Just 54859967e5218bed974d05ddec93996b9aea2782a5Just // Operand information. 55859967e5218bed974d05ddec93996b9aea2782a5Just void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); 5604985bfdded4d445c67524b018965df1f4a4c313fcoiffie std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); 5704985bfdded4d445c67524b018965df1f4a4c313fcoiffie}; 5804985bfdded4d445c67524b018965df1f4a4c313fcoiffie} // End anonymous namespace 5904985bfdded4d445c67524b018965df1f4a4c313fcoiffie 60859967e5218bed974d05ddec93996b9aea2782a5Juststatic void PrintDefList(const std::vector<Record*> &Uses, 61859967e5218bed974d05ddec93996b9aea2782a5Just unsigned Num, raw_ostream &OS) { 62859967e5218bed974d05ddec93996b9aea2782a5Just OS << "static const uint16_t ImplicitList" << Num << "[] = { "; 63859967e5218bed974d05ddec93996b9aea2782a5Just for (unsigned i = 0, e = Uses.size(); i != e; ++i) 646146b084c29234a873c31e3bfaee5df2d015e63ajvr OS << getQualifiedName(Uses[i]) << ", "; 656146b084c29234a873c31e3bfaee5df2d015e63ajvr OS << "0 };\n"; 666146b084c29234a873c31e3bfaee5df2d015e63ajvr} 67859967e5218bed974d05ddec93996b9aea2782a5Just 68859967e5218bed974d05ddec93996b9aea2782a5Just//===----------------------------------------------------------------------===// 697842e56b97ce677b83bdab09cda48bc2d89ac75aJust// Instruction Itinerary Information. 707842e56b97ce677b83bdab09cda48bc2d89ac75aJust//===----------------------------------------------------------------------===// 717842e56b97ce677b83bdab09cda48bc2d89ac75aJust 7204985bfdded4d445c67524b018965df1f4a4c313fcoiffievoid InstrInfoEmitter::GatherItinClasses() { 7304985bfdded4d445c67524b018965df1f4a4c313fcoiffie std::vector<Record*> DefList = 747842e56b97ce677b83bdab09cda48bc2d89ac75aJust Records.getAllDerivedDefinitions("InstrItinClass"); 757842e56b97ce677b83bdab09cda48bc2d89ac75aJust std::sort(DefList.begin(), DefList.end(), LessRecord()); 767842e56b97ce677b83bdab09cda48bc2d89ac75aJust 77859967e5218bed974d05ddec93996b9aea2782a5Just for (unsigned i = 0, N = DefList.size(); i < N; i++) 78859967e5218bed974d05ddec93996b9aea2782a5Just ItinClassMap[DefList[i]->getName()] = i; 79859967e5218bed974d05ddec93996b9aea2782a5Just} 80859967e5218bed974d05ddec93996b9aea2782a5Just 81859967e5218bed974d05ddec93996b9aea2782a5Justunsigned InstrInfoEmitter::getItinClassNumber(const Record *InstRec) { 827842e56b97ce677b83bdab09cda48bc2d89ac75aJust return ItinClassMap[InstRec->getValueAsDef("Itinerary")->getName()]; 837842e56b97ce677b83bdab09cda48bc2d89ac75aJust} 84aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten 85aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten//===----------------------------------------------------------------------===// 86aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten// Operand Info Emission. 87aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten//===----------------------------------------------------------------------===// 88aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten 897842e56b97ce677b83bdab09cda48bc2d89ac75aJuststd::vector<std::string> 907842e56b97ce677b83bdab09cda48bc2d89ac75aJustInstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { 917842e56b97ce677b83bdab09cda48bc2d89ac75aJust std::vector<std::string> Result; 927842e56b97ce677b83bdab09cda48bc2d89ac75aJust 93aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) { 947842e56b97ce677b83bdab09cda48bc2d89ac75aJust // Handle aggregate operands and normal operands the same way by expanding 957842e56b97ce677b83bdab09cda48bc2d89ac75aJust // either case into a list of operands for this op. 96aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten std::vector<CGIOperandList::OperandInfo> OperandList; 977842e56b97ce677b83bdab09cda48bc2d89ac75aJust 987842e56b97ce677b83bdab09cda48bc2d89ac75aJust // This might be a multiple operand thing. Targets like X86 have 997842e56b97ce677b83bdab09cda48bc2d89ac75aJust // registers in their multi-operand operands. It may also be an anonymous 1007842e56b97ce677b83bdab09cda48bc2d89ac75aJust // operand, which has a single operand, but no declared class for the 1017842e56b97ce677b83bdab09cda48bc2d89ac75aJust // operand. 1027842e56b97ce677b83bdab09cda48bc2d89ac75aJust DagInit *MIOI = Inst.Operands[i].MIOperandInfo; 1037842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1047842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (!MIOI || MIOI->getNumArgs() == 0) { 105b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod // Single, anonymous, operand. 1067842e56b97ce677b83bdab09cda48bc2d89ac75aJust OperandList.push_back(Inst.Operands[i]); 107b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod } else { 1084acb76de2ef06f9dbf431a52abe0c6da7c5f2a8ajvr for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) { 109b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod OperandList.push_back(Inst.Operands[i]); 110aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten 111b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod Record *OpR = dynamic_cast<DefInit*>(MIOI->getArg(j))->getDef(); 112170fc9d40fb1abf5bf5582f603ba4e9a0a441a0cBehdad Esfahbod OperandList.back().Rec = OpR; 113170fc9d40fb1abf5bf5582f603ba4e9a0a441a0cBehdad Esfahbod } 1147842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 1157842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1167842e56b97ce677b83bdab09cda48bc2d89ac75aJust for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { 117b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod Record *OpR = OperandList[j].Rec; 118f1e8c3e8a0bd12858e1ab361973c286eb7cad30aBehdad Esfahbod std::string Res; 119b3c860477c42c4c0adc1197dcf47bb899db258c4Behdad Esfahbod 1207842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (OpR->isSubClassOf("RegisterOperand")) 1217842e56b97ce677b83bdab09cda48bc2d89ac75aJust OpR = OpR->getValueAsDef("RegClass"); 1227842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (OpR->isSubClassOf("RegisterClass")) 1237842e56b97ce677b83bdab09cda48bc2d89ac75aJust Res += getQualifiedName(OpR) + "RegClassID, "; 1247842e56b97ce677b83bdab09cda48bc2d89ac75aJust else if (OpR->isSubClassOf("PointerLikeRegClass")) 1257842e56b97ce677b83bdab09cda48bc2d89ac75aJust Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; 1267842e56b97ce677b83bdab09cda48bc2d89ac75aJust else 1277842e56b97ce677b83bdab09cda48bc2d89ac75aJust // -1 means the operand does not have a fixed register class. 1287842e56b97ce677b83bdab09cda48bc2d89ac75aJust Res += "-1, "; 1294acb76de2ef06f9dbf431a52abe0c6da7c5f2a8ajvr 1307842e56b97ce677b83bdab09cda48bc2d89ac75aJust // Fill in applicable flags. 131aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten Res += "0"; 132170fc9d40fb1abf5bf5582f603ba4e9a0a441a0cBehdad Esfahbod 133170fc9d40fb1abf5bf5582f603ba4e9a0a441a0cBehdad Esfahbod // Ptr value whose register class is resolved via callback. 134170fc9d40fb1abf5bf5582f603ba4e9a0a441a0cBehdad Esfahbod if (OpR->isSubClassOf("PointerLikeRegClass")) 135170fc9d40fb1abf5bf5582f603ba4e9a0a441a0cBehdad Esfahbod Res += "|(1<<MCOI::LookupPtrRegClass)"; 136aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten 137170fc9d40fb1abf5bf5582f603ba4e9a0a441a0cBehdad Esfahbod // Predicate operands. Check to see if the original unexpanded operand 138170fc9d40fb1abf5bf5582f603ba4e9a0a441a0cBehdad Esfahbod // was of type PredicateOperand. 1397842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (Inst.Operands[i].Rec->isSubClassOf("PredicateOperand")) 1407842e56b97ce677b83bdab09cda48bc2d89ac75aJust Res += "|(1<<MCOI::Predicate)"; 1417842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1427842e56b97ce677b83bdab09cda48bc2d89ac75aJust // Optional def operands. Check to see if the original unexpanded operand 1437842e56b97ce677b83bdab09cda48bc2d89ac75aJust // was of type OptionalDefOperand. 1447842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand")) 1457842e56b97ce677b83bdab09cda48bc2d89ac75aJust Res += "|(1<<MCOI::OptionalDef)"; 1467842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1477842e56b97ce677b83bdab09cda48bc2d89ac75aJust // Fill in operand type. 1484acb76de2ef06f9dbf431a52abe0c6da7c5f2a8ajvr Res += ", MCOI::"; 1497842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert(!Inst.Operands[i].OperandType.empty() && "Invalid operand type."); 150aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten Res += Inst.Operands[i].OperandType; 151aa37c0aa7d4e692cc85c70a9bb22be16433c2394Olivier Berten 1527842e56b97ce677b83bdab09cda48bc2d89ac75aJust // Fill in constraint info. 1537842e56b97ce677b83bdab09cda48bc2d89ac75aJust Res += ", "; 1547842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1557842e56b97ce677b83bdab09cda48bc2d89ac75aJust const CGIOperandList::ConstraintInfo &Constraint = 1567842e56b97ce677b83bdab09cda48bc2d89ac75aJust Inst.Operands[i].Constraints[j]; 1577842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (Constraint.isNone()) 1587842e56b97ce677b83bdab09cda48bc2d89ac75aJust Res += "0"; 1597842e56b97ce677b83bdab09cda48bc2d89ac75aJust else if (Constraint.isEarlyClobber()) 1607842e56b97ce677b83bdab09cda48bc2d89ac75aJust Res += "(1 << MCOI::EARLY_CLOBBER)"; 1617842e56b97ce677b83bdab09cda48bc2d89ac75aJust else { 1627842e56b97ce677b83bdab09cda48bc2d89ac75aJust assert(Constraint.isTied()); 1637842e56b97ce677b83bdab09cda48bc2d89ac75aJust Res += "((" + utostr(Constraint.getTiedOperand()) + 1647842e56b97ce677b83bdab09cda48bc2d89ac75aJust " << 16) | (1 << MCOI::TIED_TO))"; 1657842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 1667842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1677842e56b97ce677b83bdab09cda48bc2d89ac75aJust Result.push_back(Res); 1687842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 1697842e56b97ce677b83bdab09cda48bc2d89ac75aJust } 1707842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1717842e56b97ce677b83bdab09cda48bc2d89ac75aJust return Result; 1727842e56b97ce677b83bdab09cda48bc2d89ac75aJust} 1737842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1747842e56b97ce677b83bdab09cda48bc2d89ac75aJustvoid InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, 1757842e56b97ce677b83bdab09cda48bc2d89ac75aJust OperandInfoMapTy &OperandInfoIDs) { 1767842e56b97ce677b83bdab09cda48bc2d89ac75aJust // ID #0 is for no operand info. 1777842e56b97ce677b83bdab09cda48bc2d89ac75aJust unsigned OperandListNum = 0; 1787842e56b97ce677b83bdab09cda48bc2d89ac75aJust OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; 1797842e56b97ce677b83bdab09cda48bc2d89ac75aJust 18022dcb9e6f9a9d087e87cece6caca6aa5d92f4d91jvr OS << "\n"; 1817842e56b97ce677b83bdab09cda48bc2d89ac75aJust const CodeGenTarget &Target = CDP.getTargetInfo(); 1827842e56b97ce677b83bdab09cda48bc2d89ac75aJust for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 1837842e56b97ce677b83bdab09cda48bc2d89ac75aJust E = Target.inst_end(); II != E; ++II) { 1847842e56b97ce677b83bdab09cda48bc2d89ac75aJust std::vector<std::string> OperandInfo = GetOperandInfo(**II); 1857842e56b97ce677b83bdab09cda48bc2d89ac75aJust unsigned &N = OperandInfoIDs[OperandInfo]; 1867842e56b97ce677b83bdab09cda48bc2d89ac75aJust if (N != 0) continue; 1877842e56b97ce677b83bdab09cda48bc2d89ac75aJust 1887842e56b97ce677b83bdab09cda48bc2d89ac75aJust N = ++OperandListNum; 1897842e56b97ce677b83bdab09cda48bc2d89ac75aJust OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; 1907842e56b97ce677b83bdab09cda48bc2d89ac75aJust for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) 1917842e56b97ce677b83bdab09cda48bc2d89ac75aJust OS << "{ " << OperandInfo[i] << " }, "; 1927842e56b97ce677b83bdab09cda48bc2d89ac75aJust OS << "};\n"; 193 } 194} 195 196//===----------------------------------------------------------------------===// 197// Main Output. 198//===----------------------------------------------------------------------===// 199 200// run - Emit the main instruction description records for the target... 201void InstrInfoEmitter::run(raw_ostream &OS) { 202 emitSourceFileHeader("Target Instruction Enum Values", OS); 203 emitEnums(OS); 204 205 GatherItinClasses(); 206 207 emitSourceFileHeader("Target Instruction Descriptors", OS); 208 209 OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n"; 210 OS << "#undef GET_INSTRINFO_MC_DESC\n"; 211 212 OS << "namespace llvm {\n\n"; 213 214 CodeGenTarget &Target = CDP.getTargetInfo(); 215 const std::string &TargetName = Target.getName(); 216 Record *InstrInfo = Target.getInstructionSet(); 217 218 // Keep track of all of the def lists we have emitted already. 219 std::map<std::vector<Record*>, unsigned> EmittedLists; 220 unsigned ListNumber = 0; 221 222 // Emit all of the instruction's implicit uses and defs. 223 for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 224 E = Target.inst_end(); II != E; ++II) { 225 Record *Inst = (*II)->TheDef; 226 std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 227 if (!Uses.empty()) { 228 unsigned &IL = EmittedLists[Uses]; 229 if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); 230 } 231 std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 232 if (!Defs.empty()) { 233 unsigned &IL = EmittedLists[Defs]; 234 if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); 235 } 236 } 237 238 OperandInfoMapTy OperandInfoIDs; 239 240 // Emit all of the operand info records. 241 EmitOperandInfo(OS, OperandInfoIDs); 242 243 // Emit all of the MCInstrDesc records in their ENUM ordering. 244 // 245 OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; 246 const std::vector<const CodeGenInstruction*> &NumberedInstructions = 247 Target.getInstructionsByEnumValue(); 248 249 for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) 250 emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists, 251 OperandInfoIDs, OS); 252 OS << "};\n\n"; 253 254 // Build an array of instruction names 255 SequenceToOffsetTable<std::string> InstrNames; 256 for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 257 const CodeGenInstruction *Instr = NumberedInstructions[i]; 258 InstrNames.add(Instr->TheDef->getName()); 259 } 260 261 InstrNames.layout(); 262 OS << "extern const char " << TargetName << "InstrNameData[] = {\n"; 263 InstrNames.emit(OS, printChar); 264 OS << "};\n\n"; 265 266 OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; 267 for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 268 if (i % 8 == 0) 269 OS << "\n "; 270 const CodeGenInstruction *Instr = NumberedInstructions[i]; 271 OS << InstrNames.get(Instr->TheDef->getName()) << "U, "; 272 } 273 274 OS << "\n};\n\n"; 275 276 // MCInstrInfo initialization routine. 277 OS << "static inline void Init" << TargetName 278 << "MCInstrInfo(MCInstrInfo *II) {\n"; 279 OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " 280 << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 281 << NumberedInstructions.size() << ");\n}\n\n"; 282 283 OS << "} // End llvm namespace \n"; 284 285 OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; 286 287 // Create a TargetInstrInfo subclass to hide the MC layer initialization. 288 OS << "\n#ifdef GET_INSTRINFO_HEADER\n"; 289 OS << "#undef GET_INSTRINFO_HEADER\n"; 290 291 std::string ClassName = TargetName + "GenInstrInfo"; 292 OS << "namespace llvm {\n"; 293 OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n" 294 << " explicit " << ClassName << "(int SO = -1, int DO = -1);\n" 295 << "};\n"; 296 OS << "} // End llvm namespace \n"; 297 298 OS << "#endif // GET_INSTRINFO_HEADER\n\n"; 299 300 OS << "\n#ifdef GET_INSTRINFO_CTOR\n"; 301 OS << "#undef GET_INSTRINFO_CTOR\n"; 302 303 OS << "namespace llvm {\n"; 304 OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; 305 OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; 306 OS << "extern const char " << TargetName << "InstrNameData[];\n"; 307 OS << ClassName << "::" << ClassName << "(int SO, int DO)\n" 308 << " : TargetInstrInfoImpl(SO, DO) {\n" 309 << " InitMCInstrInfo(" << TargetName << "Insts, " 310 << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 311 << NumberedInstructions.size() << ");\n}\n"; 312 OS << "} // End llvm namespace \n"; 313 314 OS << "#endif // GET_INSTRINFO_CTOR\n\n"; 315} 316 317void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 318 Record *InstrInfo, 319 std::map<std::vector<Record*>, unsigned> &EmittedLists, 320 const OperandInfoMapTy &OpInfo, 321 raw_ostream &OS) { 322 int MinOperands = 0; 323 if (!Inst.Operands.size() == 0) 324 // Each logical operand can be multiple MI operands. 325 MinOperands = Inst.Operands.back().MIOperandNo + 326 Inst.Operands.back().MINumOperands; 327 328 OS << " { "; 329 OS << Num << ",\t" << MinOperands << ",\t" 330 << Inst.Operands.NumDefs << ",\t" 331 << getItinClassNumber(Inst.TheDef) << ",\t" 332 << Inst.TheDef->getValueAsInt("Size") << ",\t0"; 333 334 // Emit all of the target indepedent flags... 335 if (Inst.isPseudo) OS << "|(1<<MCID::Pseudo)"; 336 if (Inst.isReturn) OS << "|(1<<MCID::Return)"; 337 if (Inst.isBranch) OS << "|(1<<MCID::Branch)"; 338 if (Inst.isIndirectBranch) OS << "|(1<<MCID::IndirectBranch)"; 339 if (Inst.isCompare) OS << "|(1<<MCID::Compare)"; 340 if (Inst.isMoveImm) OS << "|(1<<MCID::MoveImm)"; 341 if (Inst.isBitcast) OS << "|(1<<MCID::Bitcast)"; 342 if (Inst.isBarrier) OS << "|(1<<MCID::Barrier)"; 343 if (Inst.hasDelaySlot) OS << "|(1<<MCID::DelaySlot)"; 344 if (Inst.isCall) OS << "|(1<<MCID::Call)"; 345 if (Inst.canFoldAsLoad) OS << "|(1<<MCID::FoldableAsLoad)"; 346 if (Inst.mayLoad) OS << "|(1<<MCID::MayLoad)"; 347 if (Inst.mayStore) OS << "|(1<<MCID::MayStore)"; 348 if (Inst.isPredicable) OS << "|(1<<MCID::Predicable)"; 349 if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)"; 350 if (Inst.isCommutable) OS << "|(1<<MCID::Commutable)"; 351 if (Inst.isTerminator) OS << "|(1<<MCID::Terminator)"; 352 if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)"; 353 if (Inst.isNotDuplicable) OS << "|(1<<MCID::NotDuplicable)"; 354 if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)"; 355 if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)"; 356 if (Inst.hasPostISelHook) OS << "|(1<<MCID::HasPostISelHook)"; 357 if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)"; 358 if (Inst.hasSideEffects) OS << "|(1<<MCID::UnmodeledSideEffects)"; 359 if (Inst.isAsCheapAsAMove) OS << "|(1<<MCID::CheapAsAMove)"; 360 if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)"; 361 if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)"; 362 363 // Emit all of the target-specific flags... 364 BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); 365 if (!TSF) throw "no TSFlags?"; 366 uint64_t Value = 0; 367 for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { 368 if (BitInit *Bit = dynamic_cast<BitInit*>(TSF->getBit(i))) 369 Value |= uint64_t(Bit->getValue()) << i; 370 else 371 throw "Invalid TSFlags bit in " + Inst.TheDef->getName(); 372 } 373 OS << ", 0x"; 374 OS.write_hex(Value); 375 OS << "ULL, "; 376 377 // Emit the implicit uses and defs lists... 378 std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 379 if (UseList.empty()) 380 OS << "NULL, "; 381 else 382 OS << "ImplicitList" << EmittedLists[UseList] << ", "; 383 384 std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 385 if (DefList.empty()) 386 OS << "NULL, "; 387 else 388 OS << "ImplicitList" << EmittedLists[DefList] << ", "; 389 390 // Emit the operand info. 391 std::vector<std::string> OperandInfo = GetOperandInfo(Inst); 392 if (OperandInfo.empty()) 393 OS << "0"; 394 else 395 OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 396 397 OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 398} 399 400// emitEnums - Print out enum values for all of the instructions. 401void InstrInfoEmitter::emitEnums(raw_ostream &OS) { 402 403 OS << "\n#ifdef GET_INSTRINFO_ENUM\n"; 404 OS << "#undef GET_INSTRINFO_ENUM\n"; 405 406 OS << "namespace llvm {\n\n"; 407 408 CodeGenTarget Target(Records); 409 410 // We must emit the PHI opcode first... 411 std::string Namespace = Target.getInstNamespace(); 412 413 if (Namespace.empty()) { 414 fprintf(stderr, "No instructions defined!\n"); 415 exit(1); 416 } 417 418 const std::vector<const CodeGenInstruction*> &NumberedInstructions = 419 Target.getInstructionsByEnumValue(); 420 421 OS << "namespace " << Namespace << " {\n"; 422 OS << " enum {\n"; 423 for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 424 OS << " " << NumberedInstructions[i]->TheDef->getName() 425 << "\t= " << i << ",\n"; 426 } 427 OS << " INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n"; 428 OS << " };\n}\n"; 429 OS << "} // End llvm namespace \n"; 430 431 OS << "#endif // GET_INSTRINFO_ENUM\n\n"; 432} 433 434namespace llvm { 435 436void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { 437 InstrInfoEmitter(RK).run(OS); 438} 439 440} // End llvm namespace 441