[llvm-commits] [llvm] r172121 - in /llvm/trunk: include/llvm/MC/MCParser/MCAsmParser.h include/llvm/MC/MCParser/MCParsedAsmOperand.h lib/MC/MCParser/AsmParser.cpp lib/Target/X86/AsmParser/X86AsmParser.cpp test/CodeGen/X86/ms-inline-asm.ll

Chad Rosier mcrosier at apple.com
Thu Jan 10 14:10:27 PST 2013


Author: mcrosier
Date: Thu Jan 10 16:10:27 2013
New Revision: 172121

URL: http://llvm.org/viewvc/llvm-project?rev=172121&view=rev
Log:
[ms-inline asm] Add support for calling functions from inline assembly.
Part of rdar://12991541

Modified:
    llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h
    llvm/trunk/include/llvm/MC/MCParser/MCParsedAsmOperand.h
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
    llvm/trunk/test/CodeGen/X86/ms-inline-asm.ll

Modified: llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h?rev=172121&r1=172120&r2=172121&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h (original)
+++ llvm/trunk/include/llvm/MC/MCParser/MCAsmParser.h Thu Jan 10 16:10:27 2013
@@ -36,7 +36,7 @@
 public:
   virtual ~MCAsmParserSemaCallback(); 
   virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc,
-                                          unsigned &Size) = 0;
+                                          unsigned &Size, bool &IsVarDecl) = 0;
   virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
                                     unsigned &Offset) = 0;
 };

Modified: llvm/trunk/include/llvm/MC/MCParser/MCParsedAsmOperand.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCParser/MCParsedAsmOperand.h?rev=172121&r1=172120&r2=172121&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCParser/MCParsedAsmOperand.h (original)
+++ llvm/trunk/include/llvm/MC/MCParser/MCParsedAsmOperand.h Thu Jan 10 16:10:27 2013
@@ -70,6 +70,10 @@
   /// care of the rewrites.  Only valid when parsing MS-style inline assembly.
   virtual bool needAsmRewrite() const { return true; }
 
+  /// needAddressOf - Do we need to emit code to get the address of the
+  /// variable/label?   Only valid when parsing MS-style inline assembly.
+  virtual bool needAddressOf() const { return false; }
+
   /// isOffsetOf - Do we need to emit code to get the offset of the variable,
   /// rather then the value of the variable?   Only valid when parsing MS-style
   /// inline assembly.

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=172121&r1=172120&r2=172121&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Thu Jan 10 16:10:27 2013
@@ -3777,8 +3777,8 @@
                                  MCAsmParserSemaCallback &SI) {
   SmallVector<void *, 4> InputDecls;
   SmallVector<void *, 4> OutputDecls;
-  SmallVector<bool, 4> InputDeclsOffsetOf;
-  SmallVector<bool, 4> OutputDeclsOffsetOf;
+  SmallVector<bool, 4> InputDeclsAddressOf;
+  SmallVector<bool, 4> OutputDeclsAddressOf;
   SmallVector<std::string, 4> InputConstraints;
   SmallVector<std::string, 4> OutputConstraints;
   std::set<std::string> ClobberRegs;
@@ -3815,7 +3815,7 @@
         }
 
         // Register operand.
-        if (Operand->isReg() && !Operand->isOffsetOf()) {
+        if (Operand->isReg() && !Operand->needAddressOf()) {
           unsigned NumDefs = Desc.getNumDefs();
           // Clobber.
           if (NumDefs && Operand->getMCOperandNum() < NumDefs) {
@@ -3829,11 +3829,12 @@
 
         // Expr/Input or Output.
         unsigned Size;
+        bool IsVarDecl;
         void *OpDecl = SI.LookupInlineAsmIdentifier(Operand->getName(), AsmLoc,
-                                                    Size);
+                                                    Size, IsVarDecl);
         if (OpDecl) {
           bool isOutput = (i == 1) && Desc.mayStore();
-          if (!Operand->isOffsetOf() && Operand->needSizeDirective())
+          if (Operand->isMem() && Operand->needSizeDirective())
             AsmStrRewrites.push_back(AsmRewrite(AOK_SizeDirective,
                                                 Operand->getStartLoc(),
                                                 /*Len*/0,
@@ -3842,7 +3843,7 @@
             std::string Constraint = "=";
             ++InputIdx;
             OutputDecls.push_back(OpDecl);
-            OutputDeclsOffsetOf.push_back(Operand->isOffsetOf());
+            OutputDeclsAddressOf.push_back(Operand->needAddressOf());
             Constraint += Operand->getConstraint().str();
             OutputConstraints.push_back(Constraint);
             AsmStrRewrites.push_back(AsmRewrite(AOK_Output,
@@ -3850,7 +3851,7 @@
                                                 Operand->getNameLen()));
           } else {
             InputDecls.push_back(OpDecl);
-            InputDeclsOffsetOf.push_back(Operand->isOffsetOf());
+            InputDeclsAddressOf.push_back(Operand->needAddressOf());
             InputConstraints.push_back(Operand->getConstraint().str());
             AsmStrRewrites.push_back(AsmRewrite(AOK_Input,
                                                 Operand->getStartLoc(),
@@ -3876,14 +3877,14 @@
     OpDecls.resize(NumExprs);
     Constraints.resize(NumExprs);
     // FIXME: Constraints are hard coded to 'm', but we need an 'r'
-    // constraint for offsetof.  This needs to be cleaned up!
+    // constraint for addressof.  This needs to be cleaned up!
     for (unsigned i = 0; i < NumOutputs; ++i) {
-      OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsOffsetOf[i]);
-      Constraints[i] = OutputDeclsOffsetOf[i] ? "=r" : OutputConstraints[i];
+      OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
+      Constraints[i] = OutputDeclsAddressOf[i] ? "=r" : OutputConstraints[i];
     }
     for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
-      OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsOffsetOf[i]);
-      Constraints[j] = InputDeclsOffsetOf[i] ? "r" : InputConstraints[i];
+      OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
+      Constraints[j] = InputDeclsAddressOf[i] ? "r" : InputConstraints[i];
     }
   }
 

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=172121&r1=172120&r2=172121&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Thu Jan 10 16:10:27 2013
@@ -168,6 +168,7 @@
 
   SMLoc StartLoc, EndLoc;
   SMLoc OffsetOfLoc;
+  bool AddressOf;
 
   union {
     struct {
@@ -340,6 +341,10 @@
     return OffsetOfLoc.getPointer();
   }
 
+  bool needAddressOf() const {
+    return AddressOf;
+  }
+
   bool needSizeDirective() const {
     assert(Kind == Memory && "Invalid access!");
     return Mem.NeedSizeDir;
@@ -471,9 +476,11 @@
   }
 
   static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
+                               bool AddressOf = false,
                                SMLoc OffsetOfLoc = SMLoc()) {
     X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
     Res->Reg.RegNo = RegNo;
+    Res->AddressOf = AddressOf;
     Res->OffsetOfLoc = OffsetOfLoc;
     return Res;
   }
@@ -836,24 +843,39 @@
     return 0;
 
   bool NeedSizeDir = false;
-  if (!Size && isParsingInlineAsm()) {
+  bool IsVarDecl = false;
+  if (isParsingInlineAsm()) {
     if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Disp)) {
       const MCSymbol &Sym = SymRef->getSymbol();
       // FIXME: The SemaLookup will fail if the name is anything other then an
       // identifier.
       // FIXME: Pass a valid SMLoc.
-      SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, Size);
+      unsigned tSize;
+      SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, tSize,
+                                              IsVarDecl);
+      if (!Size)
+        Size = tSize;
       NeedSizeDir = Size > 0;
     }
   }
   if (!isParsingInlineAsm())
     return X86Operand::CreateMem(Disp, Start, End, Size);
-  else
+  else {
+    // If this is not a VarDecl then assume it is a FuncDecl or some other label
+    // reference.  We need an 'r' constraint here, so we need to create register
+    // operand to ensure proper matching.  Just pick a GPR based on the size of
+    // a pointer.
+    if (!IsVarDecl) {
+      unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
+      return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true);
+    }
+
     // When parsing inline assembly we set the base register to a non-zero value
     // as we don't know the actual value at this time.  This is necessary to
     // get the matching correct in some cases.
     return X86Operand::CreateMem(/*SegReg*/0, Disp, /*BaseReg*/1, /*IndexReg*/0,
                                  /*Scale*/1, Start, End, Size, NeedSizeDir);
+  }
 }
 
 /// Parse the '.' operator.
@@ -929,7 +951,8 @@
   // register operand to ensure proper matching.  Just pick a GPR based on
   // the size of a pointer.
   unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX;
-  return X86Operand::CreateReg(RegNo, Start, End, OffsetOfLoc);
+  return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
+                               OffsetOfLoc);
 }
 
 /// Parse the 'TYPE' operator.  The TYPE operator returns the size of a C or
@@ -952,7 +975,9 @@
     // FIXME: The SemaLookup will fail if the name is anything other then an
     // identifier.
     // FIXME: Pass a valid SMLoc.
-    if (!SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, Size))
+    bool IsVarDecl;
+    if (!SemaCallback->LookupInlineAsmIdentifier(Sym.getName(), NULL, Size,
+                                                 IsVarDecl))
       return ErrorOperand(Start, "Unable to lookup TYPE of expr!");
 
     Size /= 8; // Size is in terms of bits, but we want bytes in the context.

Modified: llvm/trunk/test/CodeGen/X86/ms-inline-asm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/ms-inline-asm.ll?rev=172121&r1=172120&r2=172121&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/ms-inline-asm.ll (original)
+++ llvm/trunk/test/CodeGen/X86/ms-inline-asm.ll Thu Jan 10 16:10:27 2013
@@ -61,3 +61,21 @@
 ; CHECK: .att_syntax
 ; CHECK: {{## InlineAsm End|#NO_APP}}
 }
+
+define void @t19_helper() nounwind {
+entry:
+  ret void
+}
+
+define void @t19() nounwind {
+entry:
+  call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(void ()* @t19_helper) nounwind
+  ret void
+; CHECK: t19
+; CHECK: movl $_t19_helper, %eax
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: call eax
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+}





More information about the llvm-commits mailing list