OSDN Git Service

MC/X86 AsmParser: Handle absolute memory operands correctly. We were doing
authorDaniel Dunbar <daniel@zuster.org>
Sat, 30 Jan 2010 01:02:48 +0000 (01:02 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sat, 30 Jan 2010 01:02:48 +0000 (01:02 +0000)
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.

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

lib/Target/X86/AsmParser/X86AsmParser.cpp
lib/Target/X86/X86InstrInfo.td
test/MC/AsmParser/X86/x86_instructions.s
test/MC/AsmParser/labels.s

index cc4498b..65e4981 100644 (file)
@@ -172,6 +172,11 @@ struct X86Operand : public MCParsedAsmOperand {
   
   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 @@ struct X86Operand : public MCParsedAsmOperand {
 
   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 @@ struct X86Operand : public MCParsedAsmOperand {
     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 @@ struct X86Operand : public MCParsedAsmOperand {
     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 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
     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 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() {
       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);
       }
       
index 5041263..b6f9e16 100644 (file)
@@ -192,6 +192,10 @@ def X86MemAsmOperand : AsmOperandClass {
   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 @@ def lea32mem : Operand<i32> {
   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>;
index ed806ee..314fc1a 100644 (file)
         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
         
index 456d61f..3bc7e63 100644 (file)
@@ -21,7 +21,7 @@ foo:
 // 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