[llvm-commits] [llvm] r51952 - in /llvm/trunk: lib/Target/CBackend/CBackend.cpp test/CodeGen/CBackend/2008-06-04-IndirectMem.ll

Chris Lattner sabre at nondot.org
Wed Jun 4 11:03:29 PDT 2008


Author: lattner
Date: Wed Jun  4 13:03:28 2008
New Revision: 51952

URL: http://llvm.org/viewvc/llvm-project?rev=51952&view=rev
Log:
Rewrite a bunch of the CBE's inline asm code, giving it the
ability to handle indirect input operands.  This fixes PR2407.

Added:
    llvm/trunk/test/CodeGen/CBackend/2008-06-04-IndirectMem.ll
Modified:
    llvm/trunk/lib/Target/CBackend/CBackend.cpp

Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=51952&r1=51951&r2=51952&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Wed Jun  4 13:03:28 2008
@@ -2956,10 +2956,6 @@
 void CWriter::visitInlineAsm(CallInst &CI) {
   InlineAsm* as = cast<InlineAsm>(CI.getOperand(0));
   std::vector<InlineAsm::ConstraintInfo> Constraints = as->ParseConstraints();
-  std::vector<std::pair<std::string, Value*> > Input;
-  std::vector<std::pair<std::string, std::pair<Value*, int> > > Output;
-  std::string Clobber;
-  unsigned ValueCount = 0;
   
   std::vector<std::pair<Value*, int> > ResultVals;
   if (CI.getType() == Type::VoidTy)
@@ -2971,61 +2967,103 @@
     ResultVals.push_back(std::make_pair(&CI, -1));
   }
   
+  // Fix up the asm string for gcc and emit it.
+  Out << "__asm__ volatile (\"" << gccifyAsm(as->getAsmString()) << "\"\n";
+  Out << "        :";
+
+  unsigned ValueCount = 0;
+  bool IsFirst = true;
+  
+  // Convert over all the output constraints.
   for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),
-         E = Constraints.end(); I != E; ++I) {
+       E = Constraints.end(); I != E; ++I) {
+    
+    if (I->Type != InlineAsm::isOutput) {
+      ++ValueCount;
+      continue;  // Ignore non-output constraints.
+    }
+    
     assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
     std::string C = InterpretASMConstraint(*I);
     if (C.empty()) continue;
     
-    switch (I->Type) {
-    default: assert(0 && "Unknown asm constraint");
-    case InlineAsm::isInput: {
-      assert(ValueCount >= ResultVals.size() && "Input can't refer to result");
-      Value *V = CI.getOperand(ValueCount-ResultVals.size()+1);
-      Input.push_back(std::make_pair(C, V));
-      break;
-    }
-    case InlineAsm::isOutput: {
-      std::pair<Value*, int> V;
-      if (ValueCount < ResultVals.size())
-        V = ResultVals[ValueCount];
-      else
-        V = std::make_pair(CI.getOperand(ValueCount-ResultVals.size()+1), -1);
-      Output.push_back(std::make_pair("="+((I->isEarlyClobber ? "&" : "")+C),
-                                      V));
-      break;
-    }
-    case InlineAsm::isClobber:
-      Clobber += ",\"" + C + "\"";
-      continue;  // Not an actual argument.
+    if (!IsFirst) {
+      Out << ", ";
+      IsFirst = false;
     }
-    ++ValueCount; // Consumes an argument.
+
+    // Unpack the dest.
+    Value *DestVal;
+    int DestValNo = -1;
+    
+    if (ValueCount < ResultVals.size()) {
+      DestVal = ResultVals[ValueCount].first;
+      DestValNo = ResultVals[ValueCount].second;
+    } else
+      DestVal = CI.getOperand(ValueCount-ResultVals.size()+1);
+
+    if (I->isEarlyClobber)
+      C = "&"+C;
+      
+    Out << "\"=" << C << "\"(" << GetValueName(DestVal);
+    if (DestValNo != -1)
+      Out << ".field" << DestValNo; // Multiple retvals.
+    Out << ")";
+    ++ValueCount;
   }
   
-  // Fix up the asm string for gcc.
-  std::string asmstr = gccifyAsm(as->getAsmString());
   
-  Out << "__asm__ volatile (\"" << asmstr << "\"\n";
-  Out << "        :";
-  for (unsigned i = 0, e = Output.size(); i != e; ++i) {
-    if (i)
+  // Convert over all the input constraints.
+  Out << "\n        :";
+  IsFirst = true;
+  ValueCount = 0;
+  for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),
+       E = Constraints.end(); I != E; ++I) {
+    if (I->Type != InlineAsm::isInput) {
+      ++ValueCount;
+      continue;  // Ignore non-input constraints.
+    }
+    
+    assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
+    std::string C = InterpretASMConstraint(*I);
+    if (C.empty()) continue;
+    
+    if (!IsFirst) {
       Out << ", ";
-    Out << "\"" << Output[i].first << "\"("
-        << GetValueName(Output[i].second.first);
-    if (Output[i].second.second != -1)
-      Out << ".field" << Output[i].second.second; // Multiple retvals.
+      IsFirst = false;
+    }
+    
+    assert(ValueCount >= ResultVals.size() && "Input can't refer to result");
+    Value *SrcVal = CI.getOperand(ValueCount-ResultVals.size()+1);
+    
+    Out << "\"" << C << "\"(";
+    if (!I->isIndirect)
+      writeOperand(SrcVal);
+    else
+      writeOperandDeref(SrcVal);
     Out << ")";
   }
-  Out << "\n        :";
-  for (unsigned i = 0, e = Input.size(); i != e; ++i) {
-    if (i)
+  
+  // Convert over the clobber constraints.
+  IsFirst = true;
+  ValueCount = 0;
+  for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),
+       E = Constraints.end(); I != E; ++I) {
+    if (I->Type != InlineAsm::isClobber)
+      continue;  // Ignore non-input constraints.
+
+    assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
+    std::string C = InterpretASMConstraint(*I);
+    if (C.empty()) continue;
+    
+    if (!IsFirst) {
       Out << ", ";
-    Out << "\"" << Input[i].first << "\"(";
-    writeOperand(Input[i].second);
-    Out << ")";
+      IsFirst = false;
+    }
+    
+    Out << '\"' << C << '"';
   }
-  if (Clobber.size())
-    Out << "\n        :" << Clobber.substr(1);
+  
   Out << ")";
 }
 

Added: llvm/trunk/test/CodeGen/CBackend/2008-06-04-IndirectMem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CBackend/2008-06-04-IndirectMem.ll?rev=51952&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/CBackend/2008-06-04-IndirectMem.ll (added)
+++ llvm/trunk/test/CodeGen/CBackend/2008-06-04-IndirectMem.ll Wed Jun  4 13:03:28 2008
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llc -march=c | grep {"m"(llvm_cbe_newcw))}
+; PR2407
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i386-pc-linux-gnu"
+
+define void @foo() {
+  %newcw = alloca i16             ; <i16*> [#uses=2]
+  call void asm sideeffect "fldcw $0", "*m,~{dirflag},~{fpsr},~{flags}"( i16*
+%newcw ) nounwind 
+  ret void
+}





More information about the llvm-commits mailing list