[llvm-commits] [llvm] r103012 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp lib/Target/X86/X86.td test/MC/AsmParser/X86/x86_64-suffix-matching.s

Daniel Dunbar daniel at zuster.org
Tue May 4 09:12:42 PDT 2010


Author: ddunbar
Date: Tue May  4 11:12:42 2010
New Revision: 103012

URL: http://llvm.org/viewvc/llvm-project?rev=103012&view=rev
Log:
MC/X86: Add "support" for matching ATT style mnemonic prefixes.
 - The idea is that when a match fails, we just try to match each of +'b', +'w',
   +'l'. If exactly one matches, we assume this is a mnemonic prefix and accept
   it. If all match, we assume it is width generic, and take the 'l' form.

 - This would be a horrible hack, if it weren't so simple. Therefore it is an
   elegant solution! Chris gets the credit for this particular elegant
   solution. :)

 - Next step to making this more robust is to have the X86 matcher generate the
   mnemonic prefix information. Ideally we would also compute up-front exactly
   which mnemonic to attempt to match, but this may require more custom code in
   the matcher than is really worth it.

Added:
    llvm/trunk/test/MC/AsmParser/X86/x86_64-suffix-matching.s
Modified:
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/lib/Target/X86/X86.td

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=103012&r1=103011&r2=103012&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Tue May  4 11:12:42 2010
@@ -51,11 +51,14 @@
   void InstructionCleanup(MCInst &Inst);
 
   /// @name Auto-generated Match Functions
-  /// {  
+  /// {
 
   bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                         MCInst &Inst);
 
+  bool MatchInstructionImpl(
+    const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst &Inst);
+
   /// }
 
 public:
@@ -132,7 +135,7 @@
 
   X86Operand(KindTy K, SMLoc Start, SMLoc End)
     : Kind(K), StartLoc(Start), EndLoc(End) {}
-  
+
   /// getStartLoc - Get the location of the first token of this operand.
   SMLoc getStartLoc() const { return StartLoc; }
   /// getEndLoc - Get the location of the last token of this operand.
@@ -142,6 +145,11 @@
     assert(Kind == Token && "Invalid access!");
     return StringRef(Tok.Data, Tok.Length);
   }
+  void setTokenValue(StringRef Value) {
+    assert(Kind == Token && "Invalid access!");
+    Tok.Data = Value.data();
+    Tok.Length = Value.size();
+  }
 
   unsigned getReg() const {
     assert(Kind == Register && "Invalid access!");
@@ -632,6 +640,59 @@
   }
 }
 
+bool
+X86ATTAsmParser::MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
+                                    &Operands,
+                                  MCInst &Inst) {
+  // First, try a direct match.
+  if (!MatchInstructionImpl(Operands, Inst))
+    return false;
+
+  // Ignore anything which is obviously not a suffix match.
+  if (Operands.size() == 0)
+    return true;
+  X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
+  if (!Op->isToken() || Op->getToken().size() > 15)
+    return true;
+
+  // FIXME: Ideally, we would only attempt suffix matches for things which are
+  // valid prefixes, and we could just infer the right unambiguous
+  // type. However, that requires substantially more matcher support than the
+  // following hack.
+
+  // Change the operand to point to a temporary token.
+  char Tmp[16];
+  StringRef Base = Op->getToken();
+  memcpy(Tmp, Base.data(), Base.size());
+  Op->setTokenValue(StringRef(Tmp, Base.size() + 1));
+
+  // Check for the various suffix matches.
+  Tmp[Base.size()] = 'b';
+  bool MatchB = MatchInstructionImpl(Operands, Inst);
+  Tmp[Base.size()] = 'w';
+  bool MatchW = MatchInstructionImpl(Operands, Inst);
+  Tmp[Base.size()] = 'l';
+  bool MatchL = MatchInstructionImpl(Operands, Inst);
+
+  // Restore the old token.
+  Op->setTokenValue(Base);
+
+  // 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 == 2)
+    return false;
+
+  // Similarly, if all three matched then we assume this is a generic operation
+  // involving memory, and take the 'l' form (to match 'gas').
+  if (MatchB + MatchW + MatchL == 0)
+    return false;
+
+  // Otherwise, the match failed.
+  return true;
+}
+
+
 extern "C" void LLVMInitializeX86AsmLexer();
 
 // Force static initialization.

Modified: llvm/trunk/lib/Target/X86/X86.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=103012&r1=103011&r2=103012&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86.td (original)
+++ llvm/trunk/lib/Target/X86/X86.td Tue May  4 11:12:42 2010
@@ -179,8 +179,9 @@
 
 // Currently the X86 assembly parser only supports ATT syntax.
 def ATTAsmParser : AsmParser {
-  string AsmParserClassName  = "ATTAsmParser";
-  string AsmParserInstCleanup  = "InstructionCleanup";
+  string AsmParserClassName = "ATTAsmParser";
+  string AsmParserInstCleanup = "InstructionCleanup";
+  string MatchInstructionName = "MatchInstructionImpl";
   int Variant = 0;
 
   // Discard comments in assembly strings.

Added: llvm/trunk/test/MC/AsmParser/X86/x86_64-suffix-matching.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_64-suffix-matching.s?rev=103012&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/X86/x86_64-suffix-matching.s (added)
+++ llvm/trunk/test/MC/AsmParser/X86/x86_64-suffix-matching.s Tue May  4 11:12:42 2010
@@ -0,0 +1,8 @@
+// RUN: llvm-mc -triple x86_64 -o - %s | FileCheck %s
+
+// CHECK: addl $0, %eax
+        add $0, %eax
+// CHECK: addb $255, %al
+        add $0xFF, %al
+// CHECK: addl $0, (%rax)
+        add $0, 0(%rax)





More information about the llvm-commits mailing list