[ms-inline asm] Add support for the [] operator. Essentially, [expr1][expr2] is
authorChad Rosier <mcrosier@apple.com>
Mon, 29 Oct 2012 18:01:54 +0000 (18:01 +0000)
committerChad Rosier <mcrosier@apple.com>
Mon, 29 Oct 2012 18:01:54 +0000 (18:01 +0000)
equivalent to [expr1 + expr2].  See test cases for more examples.
rdar://12470392

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

lib/Target/X86/AsmParser/X86AsmParser.cpp
test/CodeGen/X86/ms-inline-asm.ll
test/MC/X86/x86-32-ms-inline-asm.s

index 4bd9db9837976474c6d59f5774a98af4598edadb..ce446e75737cd88fe956c74111b5b10e15d0ab59 100644 (file)
@@ -695,6 +695,7 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
       if (getLexer().isNot(AsmToken::RBrac))
         return ErrorOperand(Start, "Expected ']' token!");
       Parser.Lex();
       if (getLexer().isNot(AsmToken::RBrac))
         return ErrorOperand(Start, "Expected ']' token!");
       Parser.Lex();
+      End = Tok.getLoc();
       return X86Operand::CreateMem(Disp, Start, End, Size);
     }
   } else if (getLexer().is(AsmToken::Integer)) {
       return X86Operand::CreateMem(Disp, Start, End, Size);
     }
   } else if (getLexer().is(AsmToken::Integer)) {
@@ -704,6 +705,7 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
       if (getLexer().is(AsmToken::RBrac)) {
         // Handle '[' number ']'
         Parser.Lex();
       if (getLexer().is(AsmToken::RBrac)) {
         // Handle '[' number ']'
         Parser.Lex();
+        End = Tok.getLoc();
         const MCExpr *Disp = MCConstantExpr::Create(Val, getContext());
         if (SegReg)
           return X86Operand::CreateMem(SegReg, Disp, 0, 0, Scale,
         const MCExpr *Disp = MCConstantExpr::Create(Val, getContext());
         if (SegReg)
           return X86Operand::CreateMem(SegReg, Disp, 0, 0, Scale,
@@ -720,9 +722,20 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
         return ErrorOperand(Loc, "Unexpected token");
   }
 
         return ErrorOperand(Loc, "Unexpected token");
   }
 
-  if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus)) {
-    bool isPlus = getLexer().is(AsmToken::Plus);
+  // Parse ][ as a plus.
+  bool ExpectRBrac = true;
+  if (getLexer().is(AsmToken::RBrac)) {
+    ExpectRBrac = false;
     Parser.Lex();
     Parser.Lex();
+    End = Tok.getLoc();
+  }
+
+  if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus) ||
+      getLexer().is(AsmToken::LBrac)) {
+    ExpectRBrac = true;
+    bool isPlus = getLexer().is(AsmToken::Plus) ||
+      getLexer().is(AsmToken::LBrac);
+    Parser.Lex(); 
     SMLoc PlusLoc = Tok.getLoc();
     if (getLexer().is(AsmToken::Integer)) {
       int64_t Val = Tok.getIntVal();
     SMLoc PlusLoc = Tok.getLoc();
     if (getLexer().is(AsmToken::Integer)) {
       int64_t Val = Tok.getIntVal();
@@ -746,15 +759,29 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
       else if (getParser().ParseExpression(Disp, End)) return 0;
     }
   }
       else if (getParser().ParseExpression(Disp, End)) return 0;
     }
   }
+  
+  // Parse ][ as a plus.
+  if (getLexer().is(AsmToken::RBrac)) {
+    ExpectRBrac = false;
+    Parser.Lex();
+    End = Tok.getLoc();
+    if (getLexer().is(AsmToken::LBrac)) {
+      ExpectRBrac = true;
+      Parser.Lex();
+      if (getParser().ParseExpression(Disp, End))
+        return 0;
+    }
+  } else if (ExpectRBrac) {
+      if (getParser().ParseExpression(Disp, End))
+        return 0;
+  }
 
 
-  if (getLexer().isNot(AsmToken::RBrac))
-    if (getParser().ParseExpression(Disp, End)) return 0;
-
-  End = Tok.getLoc();
-  if (getLexer().isNot(AsmToken::RBrac))
-    return ErrorOperand(End, "expected ']' token!");
-  Parser.Lex();
-  End = Tok.getLoc();
+  if (ExpectRBrac) {
+    if (getLexer().isNot(AsmToken::RBrac))
+      return ErrorOperand(End, "expected ']' token!");
+    Parser.Lex();
+    End = Tok.getLoc();
+  }
 
   // Parse the dot operator (e.g., [ebx].foo.bar).
   if (Tok.getString().startswith(".")) {
 
   // Parse the dot operator (e.g., [ebx].foo.bar).
   if (Tok.getString().startswith(".")) {
index 24d28adda894969f437c4629d9937f1970c722d1..403da3f34eadd87b6c74d14d19675cc88eb2804d 100644 (file)
@@ -61,3 +61,110 @@ entry:
 ; CHECK: .att_syntax
 ; CHECK: {{## InlineAsm End|#NO_APP}}
 }
 ; CHECK: .att_syntax
 ; CHECK: {{## InlineAsm End|#NO_APP}}
 }
+
+define void @t21() nounwind {
+; CHECK: t21
+entry:
+  br label %foo
+
+foo:                                              ; preds = %entry
+  call void asm sideeffect inteldialect "mov eax, [4*eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [4*eax + 4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [4*eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [4*eax][4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi + eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi + eax]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi][eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi][eax]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi + 4*eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi + 4*eax]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi][4*eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi][4*eax]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi + eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi + eax + 4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi][eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi][eax + 4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi + eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi + eax][4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi][eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi][eax][4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi + 2*eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi + 2*eax + 4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi][2*eax + 4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi][2*eax + 4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi + 2*eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi + 2*eax][4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  call void asm sideeffect inteldialect "mov eax, [esi][2*eax][4]", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, [esi][2*eax][4]
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+
+  ret void
+}
index a5e80b2c9389f557535c8976165a95aa2726cb99..73d5878b41bc0127bbac2f48ea861a5e3761b825 100644 (file)
@@ -8,3 +8,53 @@ mov [ebx].4, ecx
 // CHECK: movl %ecx, 4(%ebx)
 // CHECK: encoding: [0x89,0x4b,0x04]
         
 // CHECK: movl %ecx, 4(%ebx)
 // CHECK: encoding: [0x89,0x4b,0x04]
         
+_t21:                                   ## @t21
+// CHECK: t21
+       mov eax, [4*eax + 4]
+// CHECK: movl 4(,%eax,4), %eax
+// CHECK: # encoding: [0x8b,0x04,0x85,0x04,0x00,0x00,0x00]
+    mov eax, [4*eax][4]
+// CHECK: movl 4(,%eax,4), %eax
+// CHECK: # encoding: [0x8b,0x04,0x85,0x04,0x00,0x00,0x00]
+        
+       mov eax, [esi + eax]
+// CHECK: movl (%esi,%eax), %eax
+// CHECK: # encoding: [0x8b,0x04,0x06]
+       mov eax, [esi][eax]
+// CHECK: movl (%esi,%eax), %eax
+// CHECK: # encoding: [0x8b,0x04,0x06]
+        
+       mov eax, [esi + 4*eax]
+// CHECK: movl (%esi,%eax,4), %eax
+// CHECK: # encoding: [0x8b,0x04,0x86]
+       mov eax, [esi][4*eax]
+// CHECK: movl (%esi,%eax,4), %eax
+// CHECK: # encoding: [0x8b,0x04,0x86]
+
+    mov eax, [esi + eax + 4]
+// CHECK: movl 4(%esi,%eax), %eax
+// CHECK: # encoding: [0x8b,0x44,0x06,0x04]
+       mov eax, [esi][eax + 4]
+// CHECK: movl 4(%esi,%eax), %eax
+// CHECK: # encoding: [0x8b,0x44,0x06,0x04]
+       mov eax, [esi + eax][4]
+// CHECK: movl 4(%esi,%eax), %eax
+// CHECK: # encoding: [0x8b,0x44,0x06,0x04]
+       mov eax, [esi][eax][4]
+// CHECK: movl 4(%esi,%eax), %eax
+// CHECK: # encoding: [0x8b,0x44,0x06,0x04]
+
+       mov eax, [esi + 2*eax + 4]
+// CHECK: movl 4(%esi,%eax,2), %eax
+// CHECK: # encoding: [0x8b,0x44,0x46,0x04]
+       mov eax, [esi][2*eax + 4]
+// CHECK: movl 4(%esi,%eax,2), %eax
+// CHECK: # encoding: [0x8b,0x44,0x46,0x04]
+       mov eax, [esi + 2*eax][4]
+// CHECK: movl 4(%esi,%eax,2), %eax
+// CHECK: # encoding: [0x8b,0x44,0x46,0x04]
+       mov eax, [esi][2*eax][4]
+// CHECK: movl 4(%esi,%eax,2), %eax
+// CHECK: # encoding: [0x8b,0x44,0x46,0x04]
+
+       ret