From 62316fa00a342bdb618e4c020c8e8606f541db92 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Thu, 30 Aug 2012 17:59:25 +0000 Subject: [ms-inline asm] Add a new function, GetMCInstOperandNum, to the AsmMatcherEmitter. This function maps inline assembly operands to MCInst operands. For example, '__asm mov j, eax' is represented by the follow MCInst: > The first 5 MCInst operands are a result of j matching as a memory operand consisting of a BaseReg (Reg:0), MemScale (Imm:1), MemIndexReg(Reg:0), Expr (Expr:(j), and a MemSegReg (Reg:0). The 6th MCInst operand represents the eax register (Reg:43). This translation is necessary to determine the Input and Output Exprs. If a single asm operand maps to multiple MCInst operands, the index of the first MCInst operand is returned. Ideally, it would return the operand we really care out (i.e., the Expr:(j) in this case), but I haven't found an easy way of doing this yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162920 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 44 +++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 9e8e9462cc..25e9fbb4ec 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -1697,6 +1697,26 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, << " Inst.addOperand(Inst.getOperand(*(p + 1)));\n" << " break;\n"; + std::string OperandFnBody; + raw_string_ostream OpOS(OperandFnBody); + // Start the operand number lookup function. + OpOS << "bool " << Target.getName() << ClassName << "::\n" + << "GetMCInstOperandNum(unsigned Kind, MCInst &Inst,\n" + << " const SmallVectorImpl &Operands," + << "\n unsigned OperandNum, unsigned &MCOperandNum) {\n" + << " if (Kind >= CVT_NUM_SIGNATURES) return false;\n" + << " MCOperandNum = 0;\n" + << " uint8_t *Converter = ConversionTable[Kind];\n" + << " for (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" + << " ++MCOperandNum;\n" + << " break;\n" + << " case CVT_Tied:\n" + << " //Inst.getOperand(*(p + 1)));\n" + << " break;\n"; // Pre-populate the operand conversion kinds with the standard always // available entries. @@ -1734,6 +1754,7 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, << " return " << AsmMatchConverter << "(Inst, Opcode, Operands);\n"; + // FIXME: Handle the operand number lookup for custom match functions. continue; } @@ -1787,9 +1808,13 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, << Op.Class->RenderMethod << "(Inst, " << OpInfo.MINumOperands << ");\n" << " break;\n"; + + // Add a handler for the operand number lookup. + OpOS << " case " << Name << ":\n" + << " MCOperandNum += " << OpInfo.MINumOperands << ";\n" + << " break;\n"; break; } - case MatchableInfo::ResOperand::TiedOperand: { // If this operand is tied to a previous one, just copy the MCInst // operand from the earlier one.We can only tie single MCOperand values. @@ -1799,6 +1824,7 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, Signature += "__Tie" + utostr(TiedOp); ConversionRow.push_back(CVT_Tied); ConversionRow.push_back(TiedOp); + // FIXME: Handle the operand number lookup for tied operands. break; } case MatchableInfo::ResOperand::ImmOperand: { @@ -1821,6 +1847,9 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, << " Inst.addOperand(MCOperand::CreateImm(" << Val << "));\n" << " break;\n"; + OpOS << " case " << Name << ":\n" + << " ++MCOperandNum;\n" + << " break;\n"; break; } case MatchableInfo::ResOperand::RegOperand: { @@ -1846,6 +1875,10 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, CvtOS << " case " << Name << ":\n" << " Inst.addOperand(MCOperand::CreateReg(" << Reg << "));\n" << " break;\n"; + + OpOS << " case " << Name << ":\n" + << " ++MCOperandNum;\n" + << " break;\n"; } } } @@ -1868,6 +1901,9 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, // Finish up the converter driver function. CvtOS << " }\n }\n return true;\n}\n\n"; + // Finish up the operand number lookup function. + OpOS << " }\n }\n return true;\n}\n\n"; + OS << "namespace {\n"; // Output the operand conversion kind enum. @@ -1908,6 +1944,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName, // Spit out the conversion driver function. OS << CvtOS.str(); + // Spit out the operand number lookup function. + OS << OpOS.str(); } /// emitMatchClassEnumeration - Emit the enumeration for match class kinds. @@ -2542,6 +2580,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << "unsigned Opcode,\n" << " const SmallVectorImpl " << "&Operands);\n"; + OS << " bool GetMCInstOperandNum(unsigned Kind, MCInst &Inst,\n" + << " const SmallVectorImpl " + << "&Operands,\n unsigned OperandNum, unsigned " + << "&MCOperandNum);\n"; OS << " bool MnemonicIsValid(StringRef Mnemonic);\n"; OS << " unsigned MatchInstructionImpl(\n"; OS << " const SmallVectorImpl &Operands,\n"; -- cgit v1.2.3