Example #1
0
/// 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";

}
Example #3
0
/// 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";

}