Index: test/TableGen/get-operand-type.td =================================================================== --- test/TableGen/get-operand-type.td +++ test/TableGen/get-operand-type.td @@ -16,6 +16,8 @@ def OpA : Operand; def OpB : Operand; +def RegOp : RegisterOperand; + def InstA : Instruction { let Size = 1; let OutOperandList = (outs OpA:$a); @@ -34,7 +36,17 @@ let Namespace = "MyNamespace"; } +def InstC : Instruction { + let Size = 1; + let OutOperandList = (outs RegClass:$d); + let InOperandList = (ins RegOp:$x); + field bits<8> Inst; + field bits<8> SoftFail = 0; + let Namespace = "MyNamespace"; +} + // CHECK: #ifdef GET_INSTRINFO_OPERAND_TYPE // CHECK: OpTypes::OpA, OpTypes::OpB, OpTypes::i32imm, // CHECK-NEXT: OpTypes::i32imm, -1, -// CHECK: #endif //GET_INSTRINFO_OPERAND_TYPE +// CHECK-NEXT: OpTypes::RegClass, OpTypes::RegOp, +// CHECK: #endif // GET_INSTRINFO_OPERAND_TYPE Index: utils/TableGen/InstrInfoEmitter.cpp =================================================================== --- utils/TableGen/InstrInfoEmitter.cpp +++ utils/TableGen/InstrInfoEmitter.cpp @@ -332,6 +332,10 @@ StringRef Namespace = Target.getInstNamespace(); std::vector Operands = Records.getAllDerivedDefinitions("Operand"); + std::vector RegisterOperands = + Records.getAllDerivedDefinitions("RegisterOperand"); + std::vector RegisterClasses = + Records.getAllDerivedDefinitions("RegisterClass"); OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; @@ -340,11 +344,20 @@ OS << "namespace OpTypes {\n"; OS << "enum OperandType {\n"; + Record **RecordRangesToAdd[][2] = { + {Operands.data(), Operands.data() + Operands.size()}, + {RegisterOperands.data(), + RegisterOperands.data() + RegisterOperands.size()}, + {RegisterClasses.data(), RegisterClasses.data() + RegisterClasses.size()}, + }; unsigned EnumVal = 0; - for (const Record *Op : Operands) { - if (!Op->isAnonymous()) - OS << " " << Op->getName() << " = " << EnumVal << ",\n"; - ++EnumVal; + for (Record **(&RecordRange)[2] : RecordRangesToAdd) { + for (Record **OpIt = RecordRange[0]; OpIt != RecordRange[1]; ++OpIt) { + Record *Op = *OpIt; + if (!Op->isAnonymous()) + OS << " " << Op->getName() << " = " << EnumVal << ",\n"; + ++EnumVal; + } } OS << " OPERAND_TYPE_LIST_END" << "\n};\n"; @@ -358,7 +371,8 @@ OS << "namespace llvm {\n"; OS << "namespace " << Namespace << " {\n"; OS << "LLVM_READONLY\n"; - OS << "int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n"; + OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n"; + // TODO: Factor out instructions with same operands to compress the tables. if (!NumberedInstructions.empty()) { std::vector OperandOffsets; std::vector OperandRecords; @@ -399,7 +413,10 @@ OS << "/**/\n "; } Record *OpR = OperandRecords[I]; - if (OpR->isSubClassOf("Operand") && !OpR->isAnonymous()) + if ((OpR->isSubClassOf("Operand") || + OpR->isSubClassOf("RegisterOperand") || + OpR->isSubClassOf("RegisterClass")) && + !OpR->isAnonymous()) OS << "OpTypes::" << OpR->getName(); else OS << -1; @@ -414,7 +431,7 @@ OS << "}\n"; OS << "} // end namespace " << Namespace << "\n"; OS << "} // end namespace llvm\n"; - OS << "#endif //GET_INSTRINFO_OPERAND_TYPE\n\n"; + OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n"; } void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,