| //===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This tablegen backend is responsible for emitting a description of the target | 
 | // instruction set for the code generator. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "InstrInfoEmitter.h" | 
 | #include "CodeGenTarget.h" | 
 | #include "llvm/TableGen/Record.h" | 
 | #include "llvm/ADT/StringExtras.h" | 
 | #include <algorithm> | 
 | using namespace llvm; | 
 |  | 
 | static void PrintDefList(const std::vector<Record*> &Uses, | 
 |                          unsigned Num, raw_ostream &OS) { | 
 |   OS << "static const unsigned ImplicitList" << Num << "[] = { "; | 
 |   for (unsigned i = 0, e = Uses.size(); i != e; ++i) | 
 |     OS << getQualifiedName(Uses[i]) << ", "; | 
 |   OS << "0 };\n"; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Instruction Itinerary Information. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | void InstrInfoEmitter::GatherItinClasses() { | 
 |   std::vector<Record*> DefList = | 
 |   Records.getAllDerivedDefinitions("InstrItinClass"); | 
 |   std::sort(DefList.begin(), DefList.end(), LessRecord()); | 
 |  | 
 |   for (unsigned i = 0, N = DefList.size(); i < N; i++) | 
 |     ItinClassMap[DefList[i]->getName()] = i; | 
 | } | 
 |  | 
 | unsigned InstrInfoEmitter::getItinClassNumber(const Record *InstRec) { | 
 |   return ItinClassMap[InstRec->getValueAsDef("Itinerary")->getName()]; | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Operand Info Emission. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | std::vector<std::string> | 
 | InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { | 
 |   std::vector<std::string> Result; | 
 |  | 
 |   for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) { | 
 |     // Handle aggregate operands and normal operands the same way by expanding | 
 |     // either case into a list of operands for this op. | 
 |     std::vector<CGIOperandList::OperandInfo> OperandList; | 
 |  | 
 |     // This might be a multiple operand thing.  Targets like X86 have | 
 |     // registers in their multi-operand operands.  It may also be an anonymous | 
 |     // operand, which has a single operand, but no declared class for the | 
 |     // operand. | 
 |     DagInit *MIOI = Inst.Operands[i].MIOperandInfo; | 
 |  | 
 |     if (!MIOI || MIOI->getNumArgs() == 0) { | 
 |       // Single, anonymous, operand. | 
 |       OperandList.push_back(Inst.Operands[i]); | 
 |     } else { | 
 |       for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) { | 
 |         OperandList.push_back(Inst.Operands[i]); | 
 |  | 
 |         Record *OpR = dynamic_cast<DefInit*>(MIOI->getArg(j))->getDef(); | 
 |         OperandList.back().Rec = OpR; | 
 |       } | 
 |     } | 
 |  | 
 |     for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { | 
 |       Record *OpR = OperandList[j].Rec; | 
 |       std::string Res; | 
 |  | 
 |       if (OpR->isSubClassOf("RegisterOperand")) | 
 |         OpR = OpR->getValueAsDef("RegClass"); | 
 |       if (OpR->isSubClassOf("RegisterClass")) | 
 |         Res += getQualifiedName(OpR) + "RegClassID, "; | 
 |       else if (OpR->isSubClassOf("PointerLikeRegClass")) | 
 |         Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; | 
 |       else | 
 |         // -1 means the operand does not have a fixed register class. | 
 |         Res += "-1, "; | 
 |  | 
 |       // Fill in applicable flags. | 
 |       Res += "0"; | 
 |  | 
 |       // Ptr value whose register class is resolved via callback. | 
 |       if (OpR->isSubClassOf("PointerLikeRegClass")) | 
 |         Res += "|(1<<MCOI::LookupPtrRegClass)"; | 
 |  | 
 |       // Predicate operands.  Check to see if the original unexpanded operand | 
 |       // was of type PredicateOperand. | 
 |       if (Inst.Operands[i].Rec->isSubClassOf("PredicateOperand")) | 
 |         Res += "|(1<<MCOI::Predicate)"; | 
 |  | 
 |       // Optional def operands.  Check to see if the original unexpanded operand | 
 |       // was of type OptionalDefOperand. | 
 |       if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand")) | 
 |         Res += "|(1<<MCOI::OptionalDef)"; | 
 |  | 
 |       // Fill in constraint info. | 
 |       Res += ", "; | 
 |  | 
 |       const CGIOperandList::ConstraintInfo &Constraint = | 
 |         Inst.Operands[i].Constraints[j]; | 
 |       if (Constraint.isNone()) | 
 |         Res += "0"; | 
 |       else if (Constraint.isEarlyClobber()) | 
 |         Res += "(1 << MCOI::EARLY_CLOBBER)"; | 
 |       else { | 
 |         assert(Constraint.isTied()); | 
 |         Res += "((" + utostr(Constraint.getTiedOperand()) + | 
 |                     " << 16) | (1 << MCOI::TIED_TO))"; | 
 |       } | 
 |  | 
 |       // Fill in operand type. | 
 |       Res += ", MCOI::"; | 
 |       assert(!Inst.Operands[i].OperandType.empty() && "Invalid operand type."); | 
 |       Res += Inst.Operands[i].OperandType; | 
 |  | 
 |       Result.push_back(Res); | 
 |     } | 
 |   } | 
 |  | 
 |   return Result; | 
 | } | 
 |  | 
 | void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, | 
 |                                        OperandInfoMapTy &OperandInfoIDs) { | 
 |   // ID #0 is for no operand info. | 
 |   unsigned OperandListNum = 0; | 
 |   OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; | 
 |  | 
 |   OS << "\n"; | 
 |   const CodeGenTarget &Target = CDP.getTargetInfo(); | 
 |   for (CodeGenTarget::inst_iterator II = Target.inst_begin(), | 
 |        E = Target.inst_end(); II != E; ++II) { | 
 |     std::vector<std::string> OperandInfo = GetOperandInfo(**II); | 
 |     unsigned &N = OperandInfoIDs[OperandInfo]; | 
 |     if (N != 0) continue; | 
 |  | 
 |     N = ++OperandListNum; | 
 |     OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; | 
 |     for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) | 
 |       OS << "{ " << OperandInfo[i] << " }, "; | 
 |     OS << "};\n"; | 
 |   } | 
 | } | 
 |  | 
 | //===----------------------------------------------------------------------===// | 
 | // Main Output. | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | // run - Emit the main instruction description records for the target... | 
 | void InstrInfoEmitter::run(raw_ostream &OS) { | 
 |   emitEnums(OS); | 
 |  | 
 |   GatherItinClasses(); | 
 |  | 
 |   EmitSourceFileHeader("Target Instruction Descriptors", OS); | 
 |  | 
 |   OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n"; | 
 |   OS << "#undef GET_INSTRINFO_MC_DESC\n"; | 
 |  | 
 |   OS << "namespace llvm {\n\n"; | 
 |  | 
 |   CodeGenTarget &Target = CDP.getTargetInfo(); | 
 |   const std::string &TargetName = Target.getName(); | 
 |   Record *InstrInfo = Target.getInstructionSet(); | 
 |  | 
 |   // Keep track of all of the def lists we have emitted already. | 
 |   std::map<std::vector<Record*>, unsigned> EmittedLists; | 
 |   unsigned ListNumber = 0; | 
 |  | 
 |   // Emit all of the instruction's implicit uses and defs. | 
 |   for (CodeGenTarget::inst_iterator II = Target.inst_begin(), | 
 |          E = Target.inst_end(); II != E; ++II) { | 
 |     Record *Inst = (*II)->TheDef; | 
 |     std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); | 
 |     if (!Uses.empty()) { | 
 |       unsigned &IL = EmittedLists[Uses]; | 
 |       if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); | 
 |     } | 
 |     std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); | 
 |     if (!Defs.empty()) { | 
 |       unsigned &IL = EmittedLists[Defs]; | 
 |       if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); | 
 |     } | 
 |   } | 
 |  | 
 |   OperandInfoMapTy OperandInfoIDs; | 
 |  | 
 |   // Emit all of the operand info records. | 
 |   EmitOperandInfo(OS, OperandInfoIDs); | 
 |  | 
 |   // Emit all of the MCInstrDesc records in their ENUM ordering. | 
 |   // | 
 |   OS << "\nMCInstrDesc " << TargetName << "Insts[] = {\n"; | 
 |   const std::vector<const CodeGenInstruction*> &NumberedInstructions = | 
 |     Target.getInstructionsByEnumValue(); | 
 |  | 
 |   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) | 
 |     emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists, | 
 |                OperandInfoIDs, OS); | 
 |   OS << "};\n\n"; | 
 |  | 
 |   // MCInstrInfo initialization routine. | 
 |   OS << "static inline void Init" << TargetName | 
 |      << "MCInstrInfo(MCInstrInfo *II) {\n"; | 
 |   OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, " | 
 |      << NumberedInstructions.size() << ");\n}\n\n"; | 
 |  | 
 |   OS << "} // End llvm namespace \n"; | 
 |  | 
 |   OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; | 
 |  | 
 |   // Create a TargetInstrInfo subclass to hide the MC layer initialization. | 
 |   OS << "\n#ifdef GET_INSTRINFO_HEADER\n"; | 
 |   OS << "#undef GET_INSTRINFO_HEADER\n"; | 
 |  | 
 |   std::string ClassName = TargetName + "GenInstrInfo"; | 
 |   OS << "namespace llvm {\n"; | 
 |   OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n" | 
 |      << "  explicit " << ClassName << "(int SO = -1, int DO = -1);\n" | 
 |      << "};\n"; | 
 |   OS << "} // End llvm namespace \n"; | 
 |  | 
 |   OS << "#endif // GET_INSTRINFO_HEADER\n\n"; | 
 |  | 
 |   OS << "\n#ifdef GET_INSTRINFO_CTOR\n"; | 
 |   OS << "#undef GET_INSTRINFO_CTOR\n"; | 
 |  | 
 |   OS << "namespace llvm {\n"; | 
 |   OS << "extern MCInstrDesc " << TargetName << "Insts[];\n"; | 
 |   OS << ClassName << "::" << ClassName << "(int SO, int DO)\n" | 
 |      << "  : TargetInstrInfoImpl(SO, DO) {\n" | 
 |      << "  InitMCInstrInfo(" << TargetName << "Insts, " | 
 |      << NumberedInstructions.size() << ");\n}\n"; | 
 |   OS << "} // End llvm namespace \n"; | 
 |  | 
 |   OS << "#endif // GET_INSTRINFO_CTOR\n\n"; | 
 | } | 
 |  | 
 | void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, | 
 |                                   Record *InstrInfo, | 
 |                          std::map<std::vector<Record*>, unsigned> &EmittedLists, | 
 |                                   const OperandInfoMapTy &OpInfo, | 
 |                                   raw_ostream &OS) { | 
 |   int MinOperands = 0; | 
 |   if (!Inst.Operands.size() == 0) | 
 |     // Each logical operand can be multiple MI operands. | 
 |     MinOperands = Inst.Operands.back().MIOperandNo + | 
 |                   Inst.Operands.back().MINumOperands; | 
 |  | 
 |   OS << "  { "; | 
 |   OS << Num << ",\t" << MinOperands << ",\t" | 
 |      << Inst.Operands.NumDefs << ",\t" | 
 |      << getItinClassNumber(Inst.TheDef) << ",\t" | 
 |      << Inst.TheDef->getValueAsInt("Size") << ",\t\"" | 
 |      << Inst.TheDef->getName() << "\", 0"; | 
 |  | 
 |   // Emit all of the target indepedent flags... | 
 |   if (Inst.isPseudo)           OS << "|(1<<MCID::Pseudo)"; | 
 |   if (Inst.isReturn)           OS << "|(1<<MCID::Return)"; | 
 |   if (Inst.isBranch)           OS << "|(1<<MCID::Branch)"; | 
 |   if (Inst.isIndirectBranch)   OS << "|(1<<MCID::IndirectBranch)"; | 
 |   if (Inst.isCompare)          OS << "|(1<<MCID::Compare)"; | 
 |   if (Inst.isMoveImm)          OS << "|(1<<MCID::MoveImm)"; | 
 |   if (Inst.isBitcast)          OS << "|(1<<MCID::Bitcast)"; | 
 |   if (Inst.isBarrier)          OS << "|(1<<MCID::Barrier)"; | 
 |   if (Inst.hasDelaySlot)       OS << "|(1<<MCID::DelaySlot)"; | 
 |   if (Inst.isCall)             OS << "|(1<<MCID::Call)"; | 
 |   if (Inst.canFoldAsLoad)      OS << "|(1<<MCID::FoldableAsLoad)"; | 
 |   if (Inst.mayLoad)            OS << "|(1<<MCID::MayLoad)"; | 
 |   if (Inst.mayStore)           OS << "|(1<<MCID::MayStore)"; | 
 |   if (Inst.isPredicable)       OS << "|(1<<MCID::Predicable)"; | 
 |   if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)"; | 
 |   if (Inst.isCommutable)       OS << "|(1<<MCID::Commutable)"; | 
 |   if (Inst.isTerminator)       OS << "|(1<<MCID::Terminator)"; | 
 |   if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)"; | 
 |   if (Inst.isNotDuplicable)    OS << "|(1<<MCID::NotDuplicable)"; | 
 |   if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)"; | 
 |   if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)"; | 
 |   if (Inst.hasPostISelHook)    OS << "|(1<<MCID::HasPostISelHook)"; | 
 |   if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)"; | 
 |   if (Inst.hasSideEffects)     OS << "|(1<<MCID::UnmodeledSideEffects)"; | 
 |   if (Inst.isAsCheapAsAMove)   OS << "|(1<<MCID::CheapAsAMove)"; | 
 |   if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)"; | 
 |   if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)"; | 
 |  | 
 |   // Emit all of the target-specific flags... | 
 |   BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); | 
 |   if (!TSF) throw "no TSFlags?"; | 
 |   uint64_t Value = 0; | 
 |   for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { | 
 |     if (BitInit *Bit = dynamic_cast<BitInit*>(TSF->getBit(i))) | 
 |       Value |= uint64_t(Bit->getValue()) << i; | 
 |     else | 
 |       throw "Invalid TSFlags bit in " + Inst.TheDef->getName(); | 
 |   } | 
 |   OS << ", 0x"; | 
 |   OS.write_hex(Value); | 
 |   OS << "ULL, "; | 
 |  | 
 |   // Emit the implicit uses and defs lists... | 
 |   std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); | 
 |   if (UseList.empty()) | 
 |     OS << "NULL, "; | 
 |   else | 
 |     OS << "ImplicitList" << EmittedLists[UseList] << ", "; | 
 |  | 
 |   std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); | 
 |   if (DefList.empty()) | 
 |     OS << "NULL, "; | 
 |   else | 
 |     OS << "ImplicitList" << EmittedLists[DefList] << ", "; | 
 |  | 
 |   // Emit the operand info. | 
 |   std::vector<std::string> OperandInfo = GetOperandInfo(Inst); | 
 |   if (OperandInfo.empty()) | 
 |     OS << "0"; | 
 |   else | 
 |     OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; | 
 |  | 
 |   OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; | 
 | } | 
 |  | 
 | // emitEnums - Print out enum values for all of the instructions. | 
 | void InstrInfoEmitter::emitEnums(raw_ostream &OS) { | 
 |   EmitSourceFileHeader("Target Instruction Enum Values", OS); | 
 |  | 
 |   OS << "\n#ifdef GET_INSTRINFO_ENUM\n"; | 
 |   OS << "#undef GET_INSTRINFO_ENUM\n"; | 
 |  | 
 |   OS << "namespace llvm {\n\n"; | 
 |  | 
 |   CodeGenTarget Target(Records); | 
 |  | 
 |   // We must emit the PHI opcode first... | 
 |   std::string Namespace = Target.getInstNamespace(); | 
 |    | 
 |   if (Namespace.empty()) { | 
 |     fprintf(stderr, "No instructions defined!\n"); | 
 |     exit(1); | 
 |   } | 
 |  | 
 |   const std::vector<const CodeGenInstruction*> &NumberedInstructions = | 
 |     Target.getInstructionsByEnumValue(); | 
 |  | 
 |   OS << "namespace " << Namespace << " {\n"; | 
 |   OS << "  enum {\n"; | 
 |   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { | 
 |     OS << "    " << NumberedInstructions[i]->TheDef->getName() | 
 |        << "\t= " << i << ",\n"; | 
 |   } | 
 |   OS << "    INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n"; | 
 |   OS << "  };\n}\n"; | 
 |   OS << "} // End llvm namespace \n"; | 
 |  | 
 |   OS << "#endif // GET_INSTRINFO_ENUM\n\n"; | 
 | } |