/// Generate an enum for all the operand types for this target, under the /// llvm::TargetNamespace::OpTypes namespace. /// Operand types are all definitions derived of the Operand Target.td class. void InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS, const CodeGenTarget &Target) { const std::string &Namespace = Target.getInstNamespace(); std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand"); OS << "\n#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; OS << "namespace llvm {"; OS << "namespace " << Namespace << " {\n"; OS << "namespace OpTypes { \n"; OS << "enum OperandType {\n"; for (unsigned oi = 0, oe = Operands.size(); oi != oe; ++oi) { if (!Operands[oi]->isAnonymous()) OS << " " << Operands[oi]->getName() << " = " << oi << ",\n"; } OS << " OPERAND_TYPE_LIST_END" << "\n};\n"; OS << "} // End namespace OpTypes\n"; OS << "} // End namespace " << Namespace << "\n"; OS << "} // End namespace llvm\n"; OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; }
/// Generate a table and function for looking up the indices of operands by /// name. /// /// This code generates: /// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry /// for each operand name. /// - A 2-dimensional table called OperandMap for mapping OpName enum values to /// operand indices. /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) /// for looking up the operand index for an instruction, given a value from /// OpName enum void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target, const std::vector<const CodeGenInstruction*> &NumberedInstructions) { const std::string &Namespace = Target.getInstNamespace(); std::string OpNameNS = "OpName"; // Map of operand names to their enumeration value. This will be used to // generate the OpName enum. std::map<std::string, unsigned> Operands; OpNameMapTy OperandMap; initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap); OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n"; OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n"; OS << "namespace llvm {\n"; OS << "namespace " << Namespace << " {\n"; OS << "namespace " << OpNameNS << " { \n"; OS << "enum {\n"; for (const auto &Op : Operands) OS << " " << Op.first << " = " << Op.second << ",\n"; OS << "OPERAND_LAST"; OS << "\n};\n"; OS << "} // end namespace OpName\n"; OS << "} // end namespace " << Namespace << "\n"; OS << "} // end namespace llvm\n"; OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n"; OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n"; OS << "#undef GET_INSTRINFO_NAMED_OPS\n"; OS << "namespace llvm {\n"; OS << "namespace " << Namespace << " {\n"; OS << "LLVM_READONLY\n"; OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n"; if (!Operands.empty()) { OS << " static const int16_t OperandMap [][" << Operands.size() << "] = {\n"; for (const auto &Entry : OperandMap) { const std::map<unsigned, unsigned> &OpList = Entry.first; OS << "{"; // Emit a row of the OperandMap table for (unsigned i = 0, e = Operands.size(); i != e; ++i) OS << (OpList.count(i) == 0 ? -1 : (int)OpList.find(i)->second) << ", "; OS << "},\n"; } OS << "};\n"; OS << " switch(Opcode) {\n"; unsigned TableIndex = 0; for (const auto &Entry : OperandMap) { for (const std::string &Name : Entry.second) OS << " case " << Name << ":\n"; OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n"; } OS << " default: return -1;\n"; OS << " }\n"; } else { // There are no operands, so no need to emit anything OS << " return -1;\n"; } OS << "}\n"; OS << "} // end namespace " << Namespace << "\n"; OS << "} // end namespace llvm\n"; OS << "#endif //GET_INSTRINFO_NAMED_OPS\n"; }
/// Generate a table and function for looking up the indices of operands by /// name. /// /// This code generates: /// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry /// for each operand name. /// - A 2-dimensional table called OperandMap for mapping OpName enum values to /// operand indices. /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) /// for looking up the operand index for an instruction, given a value from /// OpName enum void InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target, const std::vector<const CodeGenInstruction*> &NumberedInstructions) { const std::string &Namespace = Target.getInstNamespace(); std::string OpNameNS = "OpName"; // Map of operand names to their enumeration value. This will be used to // generate the OpName enum. std::map<std::string, unsigned> Operands; OpNameMapTy OperandMap; initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap); OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n"; OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n"; OS << "namespace llvm {"; OS << "namespace " << Namespace << " {\n"; OS << "namespace " << OpNameNS << " { \n"; OS << "enum {\n"; for (StrUintMapIter i = Operands.begin(), e = Operands.end(); i != e; ++i) OS << " " << i->first << " = " << i->second << ",\n"; OS << "OPERAND_LAST"; OS << "\n};\n"; OS << "} // End namespace OpName\n"; OS << "} // End namespace " << Namespace << "\n"; OS << "} // End namespace llvm\n"; OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n"; OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n"; OS << "#undef GET_INSTRINFO_NAMED_OPS\n"; OS << "namespace llvm {"; OS << "namespace " << Namespace << " {\n"; OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n"; OS << " static const int16_t OperandMap []["<< Operands.size() << "] = {\n"; for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end(); i != e; ++i) { const std::map<unsigned, unsigned> &OpList = i->first; OS << "{"; // Emit a row of the OperandMap table for (unsigned ii = 0, ie = Operands.size(); ii != ie; ++ii) OS << (OpList.count(ii) == 0 ? -1 : (int)OpList.find(ii)->second) << ", "; OS << "},\n"; } OS << "};\n"; OS << " switch(Opcode) {\n"; unsigned TableIndex = 0; for (OpNameMapTy::iterator i = OperandMap.begin(), e = OperandMap.end(); i != e; ++i) { std::vector<std::string> &OpcodeList = i->second; for (unsigned ii = 0, ie = OpcodeList.size(); ii != ie; ++ii) OS << " case " << OpcodeList[ii] << ":\n"; OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n"; } OS << " default: return -1;\n"; OS << " }\n"; OS << "}\n"; OS << "} // End namespace " << Namespace << "\n"; OS << "} // End namespace llvm\n"; OS << "#endif //GET_INSTRINFO_NAMED_OPS\n"; }