- << " const SmallVectorImpl<MCParsedAsmOperand*"
- << "> &Operands) {\n";
- CvtOS << " Inst.setOpcode(Opcode);\n";
- CvtOS << " switch (Kind) {\n";
- CvtOS << " default:\n";
-
- // Start the enum, which we will generate inline.
-
- OS << "// Unified function for converting operands to MCInst instances.\n\n";
- OS << "enum ConversionKind {\n";
-
- // TargetOperandClass - This is the target's operand class, like X86Operand.
- std::string TargetOperandClass = Target.getName() + "Operand";
+ << " const SmallVectorImpl<MCParsedAsmOperand*"
+ << "> &Operands) {\n"
+ << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
+ << " const uint8_t *Converter = ConversionTable[Kind];\n"
+ << " Inst.setOpcode(Opcode);\n"
+ << " for (const uint8_t *p = Converter; *p; p+= 2) {\n"
+ << " switch (*p) {\n"
+ << " default: llvm_unreachable(\"invalid conversion entry!\");\n"
+ << " case CVT_Reg:\n"
+ << " static_cast<" << TargetOperandClass
+ << "*>(Operands[*(p + 1)])->addRegOperands(Inst, 1);\n"
+ << " break;\n"
+ << " case CVT_Tied:\n"
+ << " Inst.addOperand(Inst.getOperand(*(p + 1)));\n"
+ << " break;\n";
+
+ std::string OperandFnBody;
+ raw_string_ostream OpOS(OperandFnBody);
+ // Start the operand number lookup function.
+ OpOS << "unsigned " << Target.getName() << ClassName << "::\n"
+ << "getMCInstOperandNumImpl(unsigned Kind, MCInst &Inst,\n"
+ << " const SmallVectorImpl<MCParsedAsmOperand*> "
+ << "&Operands,\n unsigned OperandNum, unsigned "
+ << "&NumMCOperands) {\n"
+ << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
+ << " NumMCOperands = 0;\n"
+ << " unsigned MCOperandNum = 0;\n"
+ << " const uint8_t *Converter = ConversionTable[Kind];\n"
+ << " for (const uint8_t *p = Converter; *p; p+= 2) {\n"
+ << " if (*(p + 1) > OperandNum) continue;\n"
+ << " switch (*p) {\n"
+ << " default: llvm_unreachable(\"invalid conversion entry!\");\n"
+ << " case CVT_Reg:\n"
+ << " if (*(p + 1) == OperandNum) {\n"
+ << " NumMCOperands = 1;\n"
+ << " break;\n"
+ << " }\n"
+ << " ++MCOperandNum;\n"
+ << " break;\n"
+ << " case CVT_Tied:\n"
+ << " // FIXME: Tied operand calculation not supported.\n"
+ << " assert (0 && \"getMCInstOperandNumImpl() doesn't support tied operands, yet!\");\n"
+ << " break;\n";
+
+ // Pre-populate the operand conversion kinds with the standard always
+ // available entries.
+ OperandConversionKinds.insert("CVT_Done");
+ OperandConversionKinds.insert("CVT_Reg");
+ OperandConversionKinds.insert("CVT_Tied");
+ enum { CVT_Done, CVT_Reg, CVT_Tied };