[llvm-commits] [llvm] r94869 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp lib/Target/X86/X86InstrInfo.td test/MC/AsmParser/X86/x86_instructions.s test/MC/AsmParser/labels.s

Daniel Dunbar daniel at zuster.org
Fri Jan 29 17:02:48 PST 2010


Author: ddunbar
Date: Fri Jan 29 19:02:48 2010
New Revision: 94869

URL: http://llvm.org/viewvc/llvm-project?rev=94869&view=rev
Log:
MC/X86 AsmParser: Handle absolute memory operands correctly. We were doing
something totally broken and parsing them as immediates, but the .td file also
had the wrong match class so things sortof worked. Except, that is, that we
would parse
  movl $0, %eax
as
  movl 0, %eax
Feel free to guess how well that worked.

Modified:
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/test/MC/AsmParser/X86/x86_instructions.s
    llvm/trunk/test/MC/AsmParser/labels.s

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=94869&r1=94868&r2=94869&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Fri Jan 29 19:02:48 2010
@@ -172,6 +172,11 @@
   
   bool isMem() const { return Kind == Memory; }
 
+  bool isAbsMem() const {
+    return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
+      !getMemIndexReg() && !getMemScale();
+  }
+
   bool isNoSegMem() const {
     return Kind == Memory && !getMemSegReg();
   }
@@ -196,7 +201,6 @@
 
   void addMemOperands(MCInst &Inst, unsigned N) const {
     assert((N == 5) && "Invalid number of operands!");
-
     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
     Inst.addOperand(MCOperand::CreateImm(getMemScale()));
     Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
@@ -204,9 +208,13 @@
     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
   }
 
+  void addAbsMemOperands(MCInst &Inst, unsigned N) const {
+    assert((N == 1) && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
+  }
+
   void addNoSegMemOperands(MCInst &Inst, unsigned N) const {
     assert((N == 4) && "Invalid number of operands!");
-
     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
     Inst.addOperand(MCOperand::CreateImm(getMemScale()));
     Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
@@ -232,10 +240,24 @@
     return Res;
   }
 
+  /// Create an absolute memory operand.
+  static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc,
+                               SMLoc EndLoc) {
+    X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
+    Res->Mem.SegReg   = 0;
+    Res->Mem.Disp     = Disp;
+    Res->Mem.BaseReg  = 0;
+    Res->Mem.IndexReg = 0;
+    Res->Mem.Scale    = 0;
+    return Res;
+  }
+
+  /// Create a generalized memory operand.
   static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
                                unsigned BaseReg, unsigned IndexReg,
                                unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
-    // We should never just have a displacement, that would be an immediate.
+    // We should never just have a displacement, that should be parsed as an
+    // absolute memory operand.
     assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
 
     // The scale should always be one of {1,2,4,8}.
@@ -322,7 +344,7 @@
     if (getLexer().isNot(AsmToken::LParen)) {
       // Unless we have a segment register, treat this as an immediate.
       if (SegReg == 0)
-        return X86Operand::CreateImm(Disp, MemStart, ExprEnd);
+        return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
       return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
     }
     
@@ -349,7 +371,7 @@
       if (getLexer().isNot(AsmToken::LParen)) {
         // Unless we have a segment register, treat this as an immediate.
         if (SegReg == 0)
-          return X86Operand::CreateImm(Disp, LParenLoc, ExprEnd);
+          return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
         return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
       }
       

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=94869&r1=94868&r2=94869&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Fri Jan 29 19:02:48 2010
@@ -192,6 +192,10 @@
   let Name = "Mem";
   let SuperClass = ?;
 }
+def X86AbsMemAsmOperand : AsmOperandClass {
+  let Name = "AbsMem";
+  let SuperClass = X86MemAsmOperand;
+}
 def X86NoSegMemAsmOperand : AsmOperandClass {
   let Name = "NoSegMem";
   let SuperClass = X86MemAsmOperand;
@@ -233,7 +237,8 @@
   let ParserMatchClass = X86NoSegMemAsmOperand;
 }
 
-let PrintMethod = "print_pcrel_imm" in {
+let ParserMatchClass = X86AbsMemAsmOperand,
+    PrintMethod = "print_pcrel_imm" in {
 def i32imm_pcrel : Operand<i32>;
 
 def offset8 : Operand<i64>;

Modified: llvm/trunk/test/MC/AsmParser/X86/x86_instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/X86/x86_instructions.s?rev=94869&r1=94868&r2=94869&view=diff

==============================================================================
--- llvm/trunk/test/MC/AsmParser/X86/x86_instructions.s (original)
+++ llvm/trunk/test/MC/AsmParser/X86/x86_instructions.s Fri Jan 29 19:02:48 2010
@@ -16,6 +16,12 @@
         movl %eax, 10(%ebp, %ebx, 4)
 // CHECK: movl %eax, 10(,%ebx,4)
         movl %eax, 10(, %ebx, 4)
+
+// CHECK: movl 0, %eax        
+        movl 0, %eax
+// CHECK: movl $0, %eax        
+        movl $0, %eax
+        
 // CHECK: ret
         ret
         

Modified: llvm/trunk/test/MC/AsmParser/labels.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/labels.s?rev=94869&r1=94868&r2=94869&view=diff

==============================================================================
--- llvm/trunk/test/MC/AsmParser/labels.s (original)
+++ llvm/trunk/test/MC/AsmParser/labels.s Fri Jan 29 19:02:48 2010
@@ -21,7 +21,7 @@
 // CHECK: b$c = 10
 "b$c" = 10
 // CHECK: addl $10, %eax
-        addl "b$c", %eax
+        addl $"b$c", %eax
 
 // CHECK: "a 0" = 11
         .set "a 0", 11





More information about the llvm-commits mailing list