OSDN Git Service

[ms-inline asm] Add the convertToMapAndConstraints() function that is used to
authorChad Rosier <mcrosier@apple.com>
Mon, 1 Oct 2012 23:45:51 +0000 (23:45 +0000)
committerChad Rosier <mcrosier@apple.com>
Mon, 1 Oct 2012 23:45:51 +0000 (23:45 +0000)
map constraints and MCInst operands to inline asm operands.  This replaces the
getMCInstOperandNum() function.

The logic to determine the constraints are not in place, so we still default to
a register constraint (i.e., "r"). Also, we no longer build the MCInst but
rather return just the opcode to get the MCInstrDesc.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164979 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCTargetAsmParser.h
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/X86/AsmParser/X86AsmParser.cpp
utils/TableGen/AsmMatcherEmitter.cpp

index 2b5a672..16cf627 100644 (file)
@@ -89,11 +89,11 @@ public:
   /// On failure, the target parser is responsible for emitting a diagnostic
   /// explaining the match failure.
   virtual bool
-  MatchInstruction(SMLoc IDLoc, unsigned &Kind,
+  MatchInstruction(SMLoc IDLoc, 
                    SmallVectorImpl<MCParsedAsmOperand*> &Operands,
-                   SmallVectorImpl<MCInst> &MCInsts,
-                   unsigned &OrigErrorInfo,
-                   bool matchingInlineAsm = false) {
+                   MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
+        SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,
+                   unsigned &OrigErrorInfo, bool matchingInlineAsm = false) {
     OrigErrorInfo = ~0x0;
     return true;
   }
@@ -115,10 +115,9 @@ public:
     return Match_Success;
   }
 
-  virtual unsigned getMCInstOperandNum(unsigned Kind,
+  virtual void convertToMapAndConstraints(unsigned Kind,
                            const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
-                                       unsigned OperandNum,
-                                       unsigned &NumMCOperands) = 0;
+   SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints) = 0;
 };
 
 } // End llvm namespace
index aa5ba46..9e92649 100644 (file)
@@ -7480,8 +7480,10 @@ MatchAndEmitInstruction(SMLoc IDLoc,
   unsigned Kind;
   unsigned ErrorInfo;
   unsigned MatchResult;
-
-  MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo);
+  SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
+  MatchResult = MatchInstructionImpl(Operands, Kind, Inst,
+                                     MapAndConstraints, ErrorInfo,
+                                     /*matchingInlineAsm*/ false);
   switch (MatchResult) {
   default: break;
   case Match_Success:
index 9e22fd0..09eb4c8 100644 (file)
@@ -318,8 +318,9 @@ MatchAndEmitInstruction(SMLoc IDLoc,
   MCInst Inst;
   unsigned Kind;
   unsigned ErrorInfo;
-
-  switch (MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo)) {
+  SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
+  switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints,
+                               ErrorInfo, /*matchingInlineAsm*/ false)) {
   default: break;
   case Match_Success:
     Out.EmitInstruction(Inst);
index b1ada10..349abef 100644 (file)
@@ -261,9 +261,12 @@ MatchAndEmitInstruction(SMLoc IDLoc,
                         SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                         MCStreamer &Out) {
   MCInst Inst;
-  unsigned ErrorInfo;
   unsigned Kind;
-  unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo);
+  unsigned ErrorInfo;
+  SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
+  unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst,
+                                              MapAndConstraints, ErrorInfo,
+                                              /*matchingInlineAsm*/ false);
 
   switch (MatchResult) {
   default: break;
index 9263bdd..704d5f9 100644 (file)
@@ -66,12 +66,11 @@ private:
   bool MatchAndEmitInstruction(SMLoc IDLoc,
                                SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                                MCStreamer &Out);
-
-  bool MatchInstruction(SMLoc IDLoc,  unsigned &Kind,
+  bool MatchInstruction(SMLoc IDLoc,
                         SmallVectorImpl<MCParsedAsmOperand*> &Operands,
-                        SmallVectorImpl<MCInst> &MCInsts,
-                        unsigned &OrigErrorInfo,
-                        bool matchingInlineAsm = false);
+                        MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
+  SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,
+                       unsigned &OrigErrorInfo, bool matchingInlineAsm = false);
 
   /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
   /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode.
@@ -1521,22 +1520,20 @@ MatchAndEmitInstruction(SMLoc IDLoc,
                         SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                         MCStreamer &Out) {
   unsigned Kind;
+  unsigned Opcode;
   unsigned ErrorInfo;
-  SmallVector<MCInst, 2> Insts;
-
-  bool Error = MatchInstruction(IDLoc, Kind, Operands, Insts,
-                                ErrorInfo);
-  if (!Error)
-    for (unsigned i = 0, e = Insts.size(); i != e; ++i)
-      Out.EmitInstruction(Insts[i]);
+  SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
+  bool Error = MatchInstruction(IDLoc, Operands, Out, Kind, Opcode,
+                                MapAndConstraints, ErrorInfo);
   return Error;
 }
 
 bool X86AsmParser::
-MatchInstruction(SMLoc IDLoc, unsigned &Kind,
+MatchInstruction(SMLoc IDLoc,
                  SmallVectorImpl<MCParsedAsmOperand*> &Operands,
-                 SmallVectorImpl<MCInst> &MCInsts, unsigned &OrigErrorInfo,
-                 bool matchingInlineAsm) {
+                 MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
+  SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,
+                 unsigned &OrigErrorInfo, bool matchingInlineAsm) {
   assert(!Operands.empty() && "Unexpect empty operand list!");
   X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
   assert(Op->isToken() && "Leading operand should always be a mnemonic!");
@@ -1553,7 +1550,8 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
     MCInst Inst;
     Inst.setOpcode(X86::WAIT);
     Inst.setLoc(IDLoc);
-    MCInsts.push_back(Inst);
+    if (!matchingInlineAsm)
+      Out.EmitInstruction(Inst);
 
     const char *Repl =
       StringSwitch<const char*>(Op->getToken())
@@ -1575,18 +1573,22 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
   MCInst Inst;
 
   // First, try a direct match.
-  switch (MatchInstructionImpl(Operands, Kind, Inst, OrigErrorInfo,
+  switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints,
+                               OrigErrorInfo, matchingInlineAsm,
                                isParsingIntelSyntax())) {
   default: break;
   case Match_Success:
     // Some instructions need post-processing to, for example, tweak which
     // encoding is selected. Loop on it while changes happen so the
     // individual transformations can chain off each other.
-    while (processInstruction(Inst, Operands))
-      ;
+    if (!matchingInlineAsm)
+      while (processInstruction(Inst, Operands))
+        ;
 
     Inst.setLoc(IDLoc);
-    MCInsts.push_back(Inst);
+    if (!matchingInlineAsm)
+      Out.EmitInstruction(Inst);
+    Opcode = Inst.getOpcode();
     return false;
   case Match_MissingFeature:
     Error(IDLoc, "instruction requires a CPU feature not currently enabled",
@@ -1625,20 +1627,21 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
   unsigned Match1, Match2, Match3, Match4;
   unsigned tKind;
 
-  Match1 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
-                                isParsingIntelSyntax());
+  SmallVector<std::pair< unsigned, std::string >, 4> tMapAndConstraints[4];
+  Match1 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[0],
+                                ErrorInfoIgnore, isParsingIntelSyntax());
   if (Match1 == Match_Success) Kind = tKind;
   Tmp[Base.size()] = Suffixes[1];
-  Match2 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
-                                isParsingIntelSyntax());
+  Match2 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[1],
+                                ErrorInfoIgnore, isParsingIntelSyntax());
   if (Match2 == Match_Success) Kind = tKind;
   Tmp[Base.size()] = Suffixes[2];
-  Match3 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
-                                isParsingIntelSyntax());
+  Match3 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[2],
+                                ErrorInfoIgnore, isParsingIntelSyntax());
   if (Match3 == Match_Success) Kind = tKind;
   Tmp[Base.size()] = Suffixes[3];
-  Match4 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
-                                isParsingIntelSyntax());
+  Match4 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[3],
+                                ErrorInfoIgnore, isParsingIntelSyntax());
   if (Match4 == Match_Success) Kind = tKind;
 
   // Restore the old token.
@@ -1652,7 +1655,10 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
     (Match3 == Match_Success) + (Match4 == Match_Success);
   if (NumSuccessfulMatches == 1) {
     Inst.setLoc(IDLoc);
-    MCInsts.push_back(Inst);
+    if (!matchingInlineAsm)
+      Out.EmitInstruction(Inst);
+    Opcode = Inst.getOpcode();
+    // FIXME: Handle the map and constraints.
     return false;
   }
 
index 7b49723..7e04089 100644 (file)
@@ -1674,9 +1674,9 @@ static unsigned getConverterOperandID(const std::string &Name,
 }
 
 
-static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
-                                std::vector<MatchableInfo*> &Infos,
-                                raw_ostream &OS) {
+static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
+                             std::vector<MatchableInfo*> &Infos,
+                             raw_ostream &OS) {
   SetVector<std::string> OperandConversionKinds;
   SetVector<std::string> InstructionConversionKinds;
   std::vector<std::vector<uint8_t> > ConversionTable;
@@ -1713,29 +1713,22 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
   std::string OperandFnBody;
   raw_string_ostream OpOS(OperandFnBody);
   // Start the operand number lookup function.
-  OpOS << "unsigned " << Target.getName() << ClassName << "::\n"
-       << "getMCInstOperandNum(unsigned Kind,\n"
-       << "                    const SmallVectorImpl<MCParsedAsmOperand*> "
-       << "&Operands,\n                    unsigned OperandNum, unsigned "
-       << "&NumMCOperands) {\n"
+  OpOS << "void " << Target.getName() << ClassName << "::\n"
+       << "convertToMapAndConstraints(unsigned Kind,\n";
+  OpOS.indent(20);
+  OpOS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
+       << "SmallVectorImpl<std::pair< unsigned, std::string > >"
+       << " &MapAndConstraints) {\n"
        << "  assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
-       << "  NumMCOperands = 0;\n"
-       << "  unsigned MCOperandNum = 0;\n"
+       << "  unsigned NumMCOperands = 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"
+       << "      MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n"
+       << "      ++NumMCOperands;\n"
        << "      break;\n";
 
   // Pre-populate the operand conversion kinds with the standard always
@@ -1831,11 +1824,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
 
         // Add a handler for the operand number lookup.
         OpOS << "    case " << Name << ":\n"
-             << "      if (*(p + 1) == OperandNum) {\n"
-             << "        NumMCOperands = " << OpInfo.MINumOperands << ";\n"
-             << "        break;\n"
-             << "      }\n"
-             << "      MCOperandNum += " << OpInfo.MINumOperands << ";\n"
+             << "      MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n"
+             << "      NumMCOperands += " << OpInfo.MINumOperands << ";\n"
              << "      break;\n";
         break;
       }
@@ -1872,11 +1862,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
               << "      break;\n";
 
         OpOS << "    case " << Name << ":\n"
-             << "      if (*(p + 1) == OperandNum) {\n"
-             << "        NumMCOperands = 1;\n"
-             << "        break;\n"
-             << "      }\n"
-             << "      ++MCOperandNum;\n"
+             << "      MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"\"));\n"
+             << "      ++NumMCOperands;\n"
              << "      break;\n";
         break;
       }
@@ -1905,11 +1892,8 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
               << "      break;\n";
 
         OpOS << "    case " << Name << ":\n"
-             << "      if (*(p + 1) == OperandNum) {\n"
-             << "        NumMCOperands = 1;\n"
-             << "        break;\n"
-             << "      }\n"
-             << "      ++MCOperandNum;\n"
+             << "      MapAndConstraints.push_back(std::make_pair(NumMCOperands,\"r\"));\n"
+             << "      ++NumMCOperands;\n"
              << "      break;\n";
       }
       }
@@ -1934,7 +1918,7 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
   CvtOS << "    }\n  }\n}\n\n";
 
   // Finish up the operand number lookup function.
-  OpOS << "    }\n  }\n  return MCOperandNum;\n}\n\n";
+  OpOS << "    }\n  }\n}\n\n";
 
   OS << "namespace {\n";
 
@@ -2617,15 +2601,16 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
      << "unsigned Opcode,\n"
      << "                          const SmallVectorImpl<MCParsedAsmOperand*> "
      << "&Operands);\n";
-  OS << "  unsigned getMCInstOperandNum(unsigned Kind,\n"
-     << "                       const "
-     << "SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n                     "
-     << "      unsigned OperandNum, unsigned &NumMCOperands);\n";
+  OS << "  void convertToMapAndConstraints(unsigned Kind,\n";
+  OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
+     << "SmallVectorImpl<std::pair< unsigned, std::string > >"
+     << " &MapAndConstraints);\n";
   OS << "  bool mnemonicIsValid(StringRef Mnemonic);\n";
   OS << "  unsigned MatchInstructionImpl(\n"
      << "    const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
      << "    unsigned &Kind, MCInst &Inst, "
-     << "unsigned &ErrorInfo,\n    unsigned VariantID = 0);\n";
+     << "SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,\n"
+     << "unsigned &ErrorInfo,\n    bool matchingInlineAsm, unsigned VariantID = 0);\n";
 
   if (Info.OperandMatchInfo.size()) {
     OS << "\n  enum OperandMatchResultTy {\n";
@@ -2678,8 +2663,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   // Generate the function that remaps for mnemonic aliases.
   bool HasMnemonicAliases = emitMnemonicAliases(OS, Info);
 
-  // Generate the unified function to convert operands into an MCInst.
-  emitConvertToMCInst(Target, ClassName, Info.Matchables, OS);
+  // Generate the convertToMCInst function to convert operands into an MCInst.
+  // Also, generate the convertToMapAndConstraints function for MS-style inline
+  // assembly.  The latter doesn't actually generate a MCInst.
+  emitConvertFuncs(Target, ClassName, Info.Matchables, OS);
 
   // Emit the enumeration for classes which participate in matching.
   emitMatchClassEnumeration(Target, Info.Classes, OS);
@@ -2813,8 +2800,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
      << Target.getName() << ClassName << "::\n"
      << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
      << " &Operands,\n";
-  OS << "                     unsigned &Kind, MCInst &Inst, unsigned ";
-  OS << "&ErrorInfo,\n                     unsigned VariantID) {\n";
+  OS << "                     unsigned &Kind, MCInst &Inst,\n"
+     << "SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,\n"
+     << "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
 
   OS << "  // Eliminate obvious mismatches.\n";
   OS << "  if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
@@ -2908,6 +2896,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   OS << "      continue;\n";
   OS << "    }\n";
   OS << "\n";
+  OS << "    if (matchingInlineAsm) {\n";
+  OS << "      Kind = it->ConvertFn;\n";
+  OS << "      Inst.setOpcode(it->Opcode);\n";
+  OS << "      convertToMapAndConstraints(it->ConvertFn, Operands, MapAndConstraints);\n";
+  OS << "      return Match_Success;\n";
+  OS << "    }\n\n";
   OS << "    // We have selected a definite instruction, convert the parsed\n"
      << "    // operands into the appropriate MCInst.\n";
   OS << "    convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
@@ -2931,7 +2925,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
   if (!InsnCleanupFn.empty())
     OS << "    " << InsnCleanupFn << "(Inst);\n";
 
-  OS << "    Kind = it->ConvertFn;\n";
   OS << "    return Match_Success;\n";
   OS << "  }\n\n";