[ms-inline asm] Add support for ImmDisp [ Symbol ] memory operands.
authorChad Rosier <mcrosier@apple.com>
Mon, 8 Apr 2013 17:43:47 +0000 (17:43 +0000)
committerChad Rosier <mcrosier@apple.com>
Mon, 8 Apr 2013 17:43:47 +0000 (17:43 +0000)
rdar://13521249

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

include/llvm/MC/MCTargetAsmParser.h
lib/MC/MCParser/AsmParser.cpp
lib/Target/X86/AsmParser/X86AsmParser.cpp

index 4c5b17612569e19daea5eeb6fe69b298100bbe8d..2cdb983285e4689ca035bf13ca80f931369fb991 100644 (file)
@@ -22,7 +22,7 @@ class MCInst;
 template <typename T> class SmallVectorImpl;
 
 enum AsmRewriteKind {
-  AOK_Align,          // Rewrite align as .align.
+  AOK_Align = 0,      // Rewrite align as .align.
   AOK_DotOperator,    // Rewrite a dot operator expression as an immediate.
                       // E.g., [eax].foo.bar -> [eax].8
   AOK_Emit,           // Rewrite _emit as .byte.
@@ -34,6 +34,18 @@ enum AsmRewriteKind {
   AOK_Skip            // Skip emission (e.g., offset/type operators).
 };
 
+const char AsmRewritePrecedence [] = {
+  0, // AOK_Align
+  0, // AOK_DotOperator
+  0, // AOK_Emit
+  2, // AOK_Imm
+  2, // AOK_ImmPrefix
+  1, // AOK_Input
+  1, // AOK_Output
+  3, // AOK_SizeDirective
+  0  // AOK_Skip
+};
+
 struct AsmRewrite {
   AsmRewriteKind Kind;
   SMLoc Loc;
index 804734cea9396614897a6baa404f267c15ba8945..275e748c70bd5d4be283c733c9fed1660213b921 100644 (file)
@@ -4046,19 +4046,17 @@ static int RewritesSort(const void *A, const void *B) {
   if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
     return 1;
 
-  // It's possible to have a SizeDirective rewrite and an Input/Output rewrite
-  // to the same location.  Make sure the SizeDirective rewrite is performed
-  // first.  This also ensure the sort algorithm is stable.
-  if (AsmRewriteA->Kind == AOK_SizeDirective) {
-    assert ((AsmRewriteB->Kind == AOK_Input || AsmRewriteB->Kind == AOK_Output) &&
-            "Expected an Input/Output rewrite!");
+  // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
+  // rewrite to the same location.  Make sure the SizeDirective rewrite is
+  // performed first, then the Imm/ImmPrefix and finally the Input/Output.  This
+  // ensures the sort algorithm is stable.
+  if (AsmRewritePrecedence [AsmRewriteA->Kind] >
+      AsmRewritePrecedence [AsmRewriteB->Kind])
     return -1;
-  }
-  if (AsmRewriteB->Kind == AOK_SizeDirective) {
-    assert ((AsmRewriteA->Kind == AOK_Input || AsmRewriteA->Kind == AOK_Output) &&
-            "Expected an Input/Output rewrite!");
+
+  if (AsmRewritePrecedence [AsmRewriteA->Kind] <
+      AsmRewritePrecedence [AsmRewriteB->Kind])
     return 1;
-  }
   llvm_unreachable ("Unstable rewrite sort.");
 }
 
index e9fc0d7ed1f3adf2568727fae27abf95d7c2e8a2..4f4fad9b9f9b4bad4fc40c2423ebee4d5d855ef8 100644 (file)
@@ -61,8 +61,8 @@ private:
   X86Operand *ParseIntelOperator(SMLoc StartLoc, unsigned OpKind);
   X86Operand *ParseIntelMemOperand(unsigned SegReg, uint64_t ImmDisp,
                                    SMLoc StartLoc);
-  X86Operand *ParseIntelBracExpression(unsigned SegReg, uint64_t ImmDisp,
-                                       unsigned Size);
+  X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc SizeDirLoc,
+                                       uint64_t ImmDisp, unsigned Size);
   X86Operand *ParseIntelVarWithQualifier(const MCExpr *&Disp,
                                          SMLoc &IdentStart);
   X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
@@ -1100,6 +1100,7 @@ X86Operand *X86AsmParser::CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start,
 }
 
 X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
+                                                   SMLoc SizeDirLoc,
                                                    uint64_t ImmDisp,
                                                    unsigned Size) {
   const AsmToken &Tok = Parser.getTok();
@@ -1126,18 +1127,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
       if (getLexer().isNot(AsmToken::RBrac))
         return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
 
-      // FIXME: We don't handle 'ImmDisp' '[' 'Symbol' ']'.
-      if (ImmDisp)
-        return ErrorOperand(Start, "Unsupported immediate displacement!");
-
       // Adjust the EndLoc due to the ']'.
       End = SMLoc::getFromPointer(Parser.getTok().getEndLoc().getPointer()-1);
       Parser.Lex();
       if (!isParsingInlineAsm())
         return X86Operand::CreateMem(Disp, Start, End, Size);
-
-      // We want the size directive before the '['.
-      SMLoc SizeDirLoc = SMLoc::getFromPointer(Start.getPointer()-1);
       return CreateMemForInlineAsm(Disp, Start, End, SizeDirLoc, Size);
     }
   }
@@ -1302,11 +1296,11 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
     Parser.Lex(); // Eat the integer.
     if (getLexer().isNot(AsmToken::LBrac))
       return ErrorOperand(Start, "Expected '[' token!");
-    return ParseIntelBracExpression(SegReg, ImmDisp, Size);
+    return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
   }
 
   if (getLexer().is(AsmToken::LBrac))
-    return ParseIntelBracExpression(SegReg, ImmDisp, Size);
+    return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
 
   if (!ParseRegister(SegReg, Start, End)) {
     // Handel SegReg : [ ... ]
@@ -1315,7 +1309,7 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
     Parser.Lex(); // Eat :
     if (getLexer().isNot(AsmToken::LBrac))
       return ErrorOperand(Start, "Expected '[' token!");
-    return ParseIntelBracExpression(SegReg, ImmDisp, Size);
+    return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
   }
 
   const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());