[llvm-commits] [llvm] r113166 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp utils/TableGen/AsmMatcherEmitter.cpp

Chris Lattner sabre at nondot.org
Mon Sep 6 13:08:02 PDT 2010


Author: lattner
Date: Mon Sep  6 15:08:02 2010
New Revision: 113166

URL: http://llvm.org/viewvc/llvm-project?rev=113166&view=rev
Log:
have tblgen detect when an instruction would have matched, but
failed because a subtarget feature was not enabled.  Use this to
remove a bunch of hacks from the X86AsmParser for rejecting things
like popfl in 64-bit mode.  Previously these hacks weren't needed,
but were important to get a message better than "invalid instruction"
when used in the wrong mode.

This also fixes bugs where pushal would not be rejected correctly in
32-bit mode (just pusha).

Modified:
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp

Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=113166&r1=113165&r2=113166&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Mon Sep  6 15:08:02 2010
@@ -615,28 +615,13 @@
 bool X86ATTAsmParser::
 ParseInstruction(StringRef Name, SMLoc NameLoc,
                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
-  // The various flavors of pushf and popf use Requires<In32BitMode> and
-  // Requires<In64BitMode>, but the assembler doesn't yet implement that.
-  // For now, just do a manual check to prevent silent misencoding.
-  if (Is64Bit) {
-    if (Name == "popfl")
-      return Error(NameLoc, "popfl cannot be encoded in 64-bit mode");
-    if (Name == "pushfl")
-      return Error(NameLoc, "pushfl cannot be encoded in 64-bit mode");
-    if (Name == "pusha")
-      return Error(NameLoc, "pusha cannot be encoded in 64-bit mode");
-  } else {
-    if (Name == "popfq")
-      return Error(NameLoc, "popfq cannot be encoded in 32-bit mode");
-    if (Name == "pushfq")
-      return Error(NameLoc, "pushfq cannot be encoded in 32-bit mode");
-  }
 
   // The "Jump if rCX Zero" form jcxz is not allowed in 64-bit mode and
   // the form jrcxz is not allowed in 32-bit mode.
   if (Is64Bit) {
-    if (Name == "jcxz")
-      return Error(NameLoc, "jcxz cannot be encoded in 64-bit mode");
+    // FIXME: We can do jcxz/jecxz, we just don't have the encoding right yet.
+    if (Name == "jcxz" || Name == "jecxz")
+      return Error(NameLoc, Name + " cannot be encoded in 64-bit mode");
   } else {
     if (Name == "jrcxz")
       return Error(NameLoc, "jrcxz cannot be encoded in 32-bit mode");
@@ -881,8 +866,15 @@
   assert(!Operands.empty() && "Unexpect empty operand list!");
 
   // First, try a direct match.
-  if (MatchInstructionImpl(Operands, Inst) == Match_Success)
+  switch (MatchInstructionImpl(Operands, Inst)) {
+  case Match_Success:
     return false;
+  case Match_MissingFeature:
+    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
+    return true;
+  default:
+    break;
+  }
 
   // FIXME: Ideally, we would only attempt suffix matches for things which are
   // valid prefixes, and we could just infer the right unambiguous
@@ -901,13 +893,13 @@
 
   // Check for the various suffix matches.
   Tmp[Base.size()] = 'b';
-  bool MatchB = MatchInstructionImpl(Operands, Inst) != Match_Success;
+  MatchResultTy MatchB = MatchInstructionImpl(Operands, Inst);
   Tmp[Base.size()] = 'w';
-  bool MatchW = MatchInstructionImpl(Operands, Inst) != Match_Success;
+  MatchResultTy MatchW = MatchInstructionImpl(Operands, Inst);
   Tmp[Base.size()] = 'l';
-  bool MatchL = MatchInstructionImpl(Operands, Inst) != Match_Success;
+  MatchResultTy MatchL = MatchInstructionImpl(Operands, Inst);
   Tmp[Base.size()] = 'q';
-  bool MatchQ = MatchInstructionImpl(Operands, Inst) != Match_Success;
+  MatchResultTy MatchQ = MatchInstructionImpl(Operands, Inst);
 
   // Restore the old token.
   Op->setTokenValue(Base);
@@ -915,23 +907,26 @@
   // If exactly one matched, then we treat that as a successful match (and the
   // instruction will already have been filled in correctly, since the failing
   // matches won't have modified it).
-  if (MatchB + MatchW + MatchL + MatchQ == 3)
+  unsigned NumSuccessfulMatches =
+    (MatchB == Match_Success) + (MatchW == Match_Success) +
+    (MatchL == Match_Success) + (MatchQ == Match_Success);
+  if (NumSuccessfulMatches == 1)
     return false;
 
-  // Otherwise, the match failed.
+  // Otherwise, the match failed, try to produce a decent error message.
 
   // If we had multiple suffix matches, then identify this as an ambiguous
   // match.
-  if (MatchB + MatchW + MatchL + MatchQ != 4) {
+  if (NumSuccessfulMatches > 1) {
     char MatchChars[4];
     unsigned NumMatches = 0;
-    if (!MatchB)
+    if (MatchB == Match_Success)
       MatchChars[NumMatches++] = 'b';
-    if (!MatchW)
+    if (MatchW == Match_Success)
       MatchChars[NumMatches++] = 'w';
-    if (!MatchL)
+    if (MatchL == Match_Success)
       MatchChars[NumMatches++] = 'l';
-    if (!MatchQ)
+    if (MatchQ == Match_Success)
       MatchChars[NumMatches++] = 'q';
 
     SmallString<126> Msg;
@@ -946,11 +941,26 @@
     }
     OS << ")";
     Error(IDLoc, OS.str());
-  } else {
-    // FIXME: We should give nicer diagnostics about the exact failure.
-    Error(IDLoc, "unrecognized instruction");
+    return true;
   }
-
+  
+  unsigned NumMatchFailures =
+    (MatchB == Match_Fail) + (MatchW == Match_Fail) +
+    (MatchL == Match_Fail) + (MatchQ == Match_Fail);
+  
+  
+  // If one instruction matched with a missing feature, report this as a
+  // missing feature.
+  if ((MatchB == Match_MissingFeature) + (MatchW == Match_MissingFeature) +
+      (MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1&&
+      NumMatchFailures == 3) {
+    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
+    return true;
+  }
+  
+  // If all of these were an outright failure, report it in a useless way.
+  // FIXME: We should give nicer diagnostics about the exact failure.
+  Error(IDLoc, "unrecognized instruction");
   return true;
 }
 

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=113166&r1=113165&r2=113166&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Mon Sep  6 15:08:02 2010
@@ -1549,7 +1549,7 @@
   OS << "  unsigned ComputeAvailableFeatures(const " <<
            Target.getName() << "Subtarget *Subtarget) const;\n";
   OS << "  enum MatchResultTy {\n";
-  OS << "    Match_Success, Match_Fail\n";
+  OS << "    Match_Success, Match_Fail, Match_MissingFeature\n";
   OS << "  };\n";
   OS << "  MatchResultTy MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
      << " &Operands, MCInst &Inst);\n\n";
@@ -1678,21 +1678,24 @@
 
   // Emit code to search the table.
   OS << "  // Search the table.\n";
+  OS << "  bool HadMatchOtherThanFeatures = false;\n";
   OS << "  for (const MatchEntry *it = MatchTable, "
      << "*ie = MatchTable + " << Info.Instructions.size()
      << "; it != ie; ++it) {\n";
 
-  // Emit check that the required features are available.
-  OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
-     << "!= it->RequiredFeatures)\n";
-  OS << "      continue;\n";
-  
   // Emit check that the subclasses match.
   for (unsigned i = 0; i != MaxNumOperands; ++i) {
     OS << "    if (!IsSubclass(Classes[" 
        << i << "], it->Classes[" << i << "]))\n";
     OS << "      continue;\n";
   }
+
+  // Emit check that the required features are available.
+  OS << "    if ((AvailableFeatures & it->RequiredFeatures) "
+     << "!= it->RequiredFeatures) {\n";
+  OS << "      HadMatchOtherThanFeatures = true;\n";
+  OS << "      continue;\n";
+  OS << "    }\n";
   
   OS << "\n";
   OS << "    ConvertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
@@ -1706,6 +1709,8 @@
   OS << "    return Match_Success;\n";
   OS << "  }\n\n";
 
+  OS << "  // Okay, we had no match.  Try to return a useful error code.\n";
+  OS << "  if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n";
   OS << "  return Match_Fail;\n";
   OS << "}\n\n";
   





More information about the llvm-commits mailing list