MC/X86/AsmMatcher: Use the new instruction cleanup routine to implement a
authorDaniel Dunbar <daniel@zuster.org>
Thu, 18 Mar 2010 20:06:02 +0000 (20:06 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 18 Mar 2010 20:06:02 +0000 (20:06 +0000)
temporary workaround for matching inc/dec on x86_64 to the correct instruction.
 - This hack will eventually be replaced with a robust mechanism for handling
   matching instructions based on the available target features.

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

lib/Target/X86/AsmParser/X86AsmParser.cpp
lib/Target/X86/X86.td
test/MC/AsmParser/X86/x86_64-incl_decl.s [new file with mode: 0644]

index dde86fbbe4403a347b0d08f6cd3829c40609ed3a..bfadd4e9fc47012f23890993cf626d01568f81e1 100644 (file)
@@ -29,6 +29,9 @@ struct X86Operand;
 class X86ATTAsmParser : public TargetAsmParser {
   MCAsmParser &Parser;
 
+protected:
+  unsigned Is64Bit : 1;
+
 private:
   MCAsmParser &getParser() const { return Parser; }
 
@@ -45,6 +48,8 @@ private:
 
   bool ParseDirectiveWord(unsigned Size, SMLoc L);
 
+  void InstructionCleanup(MCInst &Inst);
+
   /// @name Auto-generated Match Functions
   /// {  
 
@@ -62,7 +67,23 @@ public:
 
   virtual bool ParseDirective(AsmToken DirectiveID);
 };
-  
+class X86_32ATTAsmParser : public X86ATTAsmParser {
+public:
+  X86_32ATTAsmParser(const Target &T, MCAsmParser &_Parser)
+    : X86ATTAsmParser(T, _Parser) {
+    Is64Bit = false;
+  }
+};
+
+class X86_64ATTAsmParser : public X86ATTAsmParser {
+public:
+  X86_64ATTAsmParser(const Target &T, MCAsmParser &_Parser)
+    : X86ATTAsmParser(T, _Parser) {
+    Is64Bit = true;
+  }
+};
+
 } // end anonymous namespace
 
 /// @name Auto-generated Match Functions
@@ -586,12 +607,30 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
   return false;
 }
 
+// FIXME: Custom X86 cleanup function to implement a temporary hack to handle
+// matching INCL/DECL correctly for x86_64. This needs to be replaced by a
+// proper mechanism for supporting (ambiguous) feature dependent instructions.
+void X86ATTAsmParser::InstructionCleanup(MCInst &Inst) {
+  if (!Is64Bit) return;
+
+  switch (Inst.getOpcode()) {
+  case X86::DEC16r: Inst.setOpcode(X86::DEC64_16r); break;
+  case X86::DEC16m: Inst.setOpcode(X86::DEC64_16m); break;
+  case X86::DEC32r: Inst.setOpcode(X86::DEC64_32r); break;
+  case X86::DEC32m: Inst.setOpcode(X86::DEC64_32m); break;
+  case X86::INC16r: Inst.setOpcode(X86::INC64_16r); break;
+  case X86::INC16m: Inst.setOpcode(X86::INC64_16m); break;
+  case X86::INC32r: Inst.setOpcode(X86::INC64_32r); break;
+  case X86::INC32m: Inst.setOpcode(X86::INC64_32m); break;
+  }
+}
+
 extern "C" void LLVMInitializeX86AsmLexer();
 
 // Force static initialization.
 extern "C" void LLVMInitializeX86AsmParser() {
-  RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
-  RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
+  RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target);
+  RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target);
   LLVMInitializeX86AsmLexer();
 }
 
index 6a4bdb58603b71f0de1490cf76bce0a21a073887..2be51e1a13669493423c31920fa7c6662d2807ed 100644 (file)
@@ -191,6 +191,7 @@ include "X86CallingConv.td"
 // Currently the X86 assembly parser only supports ATT syntax.
 def ATTAsmParser : AsmParser {
   string AsmParserClassName  = "ATTAsmParser";
+  string AsmParserInstCleanup  = "InstructionCleanup";
   int Variant = 0;
 
   // Discard comments in assembly strings.
diff --git a/test/MC/AsmParser/X86/x86_64-incl_decl.s b/test/MC/AsmParser/X86/x86_64-incl_decl.s
new file mode 100644 (file)
index 0000000..51315f8
--- /dev/null
@@ -0,0 +1,26 @@
+// RUN: llvm-mc -triple i386-unknown-unknown --show-encoding %s | FileCheck --check-prefix=CHECK-X86_32 %s
+// RUN: llvm-mc -triple x86_64-unknown-unknown --show-encoding %s | FileCheck --check-prefix=CHECK-X86_64 %s
+
+# CHECK-X86_32:        incb    %al # encoding: [0xfe,0xc0]
+# CHECK-X86_64:        incb    %al # encoding: [0xfe,0xc0]
+       incb %al
+
+# CHECK-X86_32:        incw    %ax # encoding: [0x66,0x40]
+# CHECK-X86_64:        incw    %ax # encoding: [0x66,0xff,0xc0]
+       incw %ax
+
+# CHECK-X86_32:        incl    %eax # encoding: [0x40]
+# CHECK-X86_64:        incl    %eax # encoding: [0xff,0xc0]
+       incl %eax
+
+# CHECK-X86_32:        decb    %al # encoding: [0xfe,0xc8]
+# CHECK-X86_64:        decb    %al # encoding: [0xfe,0xc8]
+       decb %al
+
+# CHECK-X86_32:        decw    %ax # encoding: [0x66,0x48]
+# CHECK-X86_64:        decw    %ax # encoding: [0x66,0xff,0xc8]
+       decw %ax
+
+# CHECK-X86_32:        decl    %eax # encoding: [0x48]
+# CHECK-X86_64:        decl    %eax # encoding: [0xff,0xc8]
+       decl %eax