llvm-mc: A few more parsing / match tweaks.
authorDaniel Dunbar <daniel@zuster.org>
Fri, 31 Jul 2009 22:22:54 +0000 (22:22 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Fri, 31 Jul 2009 22:22:54 +0000 (22:22 +0000)
 - Operands which are just a label should be parsed as immediates, not memory
   operands (from the assembler perspective).

 - Match a few more flavors of immediates.

 - Distinguish match functions for memory operands which don't take a segment
   register.

 - We match the .s for "hello world" now!

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

lib/Target/X86/AsmParser/X86AsmParser.cpp
test/MC/AsmParser/hello.s [new file with mode: 0644]

index 1c55c3fc7b28a78889ea41766c718b281599ba6e..db52c118ea350a40763ffdfe2253655d09707325 100644 (file)
@@ -135,6 +135,9 @@ struct X86Operand {
   }
   static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg,
                               unsigned IndexReg, unsigned Scale) {
+    // We should never just have a displacement, that would be an immediate.
+    assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
+
     // The scale should always be one of {1,2,4,8}.
     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
            "Invalid scale!");
@@ -216,7 +219,11 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
     // After parsing the base expression we could either have a parenthesized
     // memory address or not.  If not, return now.  If so, eat the (.
     if (getLexer().isNot(AsmToken::LParen)) {
-      Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
+      // Unless we have a segment register, treat this as an immediate.
+      if (SegReg)
+        Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
+      else
+        Op = X86Operand::CreateImm(Disp);
       return false;
     }
     
@@ -238,7 +245,11 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
       // After parsing the base expression we could either have a parenthesized
       // memory address or not.  If not, return now.  If so, eat the (.
       if (getLexer().isNot(AsmToken::LParen)) {
-        Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
+        // Unless we have a segment register, treat this as an immediate.
+        if (SegReg)
+          Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
+        else
+          Op = X86Operand::CreateImm(Disp);
         return false;
       }
       
@@ -377,10 +388,10 @@ Match_X86_Op_IMM(const X86Operand &Op, MCOperand *MCOps, unsigned NumOps) {
   return false;
 }
 
-static bool Match_X86_Op_MEM(const X86Operand &Op,
+static bool Match_X86_Op_LMEM(const X86Operand &Op,
                              MCOperand *MCOps,
                              unsigned NumMCOps) {
-  assert(NumMCOps == 5 && "Invalid number of ops!");
+  assert(NumMCOps == 4 && "Invalid number of ops!");
 
   if (Op.Kind != X86Operand::Memory)
     return true;
@@ -389,6 +400,18 @@ static bool Match_X86_Op_MEM(const X86Operand &Op,
   MCOps[1].MakeImm(Op.getMemScale());
   MCOps[2].MakeReg(Op.getMemIndexReg());
   MCOps[3].MakeMCValue(Op.getMemDisp());
+
+  return false;  
+}
+
+static bool Match_X86_Op_MEM(const X86Operand &Op,
+                             MCOperand *MCOps,
+                             unsigned NumMCOps) {
+  assert(NumMCOps == 5 && "Invalid number of ops!");
+
+  if (Match_X86_Op_LMEM(Op, MCOps, 4))
+    return true;
+
   MCOps[4].MakeReg(Op.getMemSegReg());
 
   return false;  
@@ -413,15 +436,30 @@ REG(GR8)
     return Match_X86_Op_IMM(Op, MCOps, NumMCOps);       \
   }
 
+IMM(brtarget)
+IMM(brtarget8)
 IMM(i16i8imm)
 IMM(i16imm)
 IMM(i32i8imm)
 IMM(i32imm)
+IMM(i32imm_pcrel)
 IMM(i64i32imm)
+IMM(i64i32imm_pcrel)
 IMM(i64i8imm)
 IMM(i64imm)
 IMM(i8imm)
 
+#define LMEM(name) \
+  static bool Match_X86_Op_##name(const X86Operand &Op, \
+                                  MCOperand *MCOps,     \
+                                  unsigned NumMCOps) {  \
+    return Match_X86_Op_LMEM(Op, MCOps, NumMCOps);       \
+  }
+
+LMEM(lea32mem)
+LMEM(lea64_32mem)
+LMEM(lea64mem)
+
 #define MEM(name) \
   static bool Match_X86_Op_##name(const X86Operand &Op, \
                                   MCOperand *MCOps,     \
@@ -438,9 +476,6 @@ MEM(i16mem)
 MEM(i32mem)
 MEM(i64mem)
 MEM(i8mem)
-MEM(lea32mem)
-MEM(lea64_32mem)
-MEM(lea64mem)
 MEM(sdmem)
 MEM(ssmem)
 
@@ -458,10 +493,6 @@ DUMMY(GR8_NOREX)
 DUMMY(RST)
 DUMMY(VR128)
 DUMMY(VR64)
-DUMMY(brtarget)
-DUMMY(brtarget8)
-DUMMY(i32imm_pcrel)
-DUMMY(i64i32imm_pcrel)
 DUMMY(i8mem_NOREX)
 
 #include "X86GenAsmMatcher.inc"
diff --git a/test/MC/AsmParser/hello.s b/test/MC/AsmParser/hello.s
new file mode 100644 (file)
index 0000000..34b547e
--- /dev/null
@@ -0,0 +1,27 @@
+// RUN: llvm-mc %s -o -
+
+       .text
+       .align  4,0x90
+       .globl  _main
+_main:
+       pushl   %ebp
+       movl    %esp, %ebp
+       subl    $8, %esp
+       call    "L1$pb"
+"L1$pb":
+       popl    %eax
+       movl    $0, -4(%ebp)
+       movl    %esp, %ecx
+       leal    L_.str-"L1$pb"(%eax), %eax
+       movl    %eax, (%ecx)
+       call    _printf
+       movl    $0, -4(%ebp)
+       movl    -4(%ebp), %eax
+       addl    $8, %esp
+       popl    %ebp
+       ret
+       .subsections_via_symbols
+       .cstring
+L_.str:
+       .asciz  "hello world!\n"
+