Partial implementation of calling functions with byval arguments:
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 20 Aug 2007 15:18:24 +0000 (15:18 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 20 Aug 2007 15:18:24 +0000 (15:18 +0000)
 *) The needed information is propagated to the DAG
 *) The X86-64 backend detects it and aborts

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

include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/Target/X86/X86ISelLowering.cpp

index e44f741224acf529430e28d5b53ccc4e82f6cc97..510dd6e91fed1850081cf07007616dce8f14e2d4 100644 (file)
@@ -841,9 +841,10 @@ public:
     bool isInReg;
     bool isSRet;
     bool isNest;
+    bool isByVal;
 
     ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
-      isSRet(false), isNest(false) { };
+      isSRet(false), isNest(false), isByVal(false) { };
   };
   typedef std::vector<ArgListEntry> ArgListTy;
   virtual std::pair<SDOperand, SDOperand>
index a99640a1704364147535fa6456f470586ba7ba39..78539d454ed7780f24c8d22c86ff9897b4da53f2 100644 (file)
@@ -2905,6 +2905,7 @@ void SelectionDAGLowering::LowerCallTo(Instruction &I,
     Entry.isInReg = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::InReg);
     Entry.isSRet  = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::StructRet);
     Entry.isNest  = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::Nest);
+    Entry.isByVal = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ByVal);
     Args.push_back(Entry);
   }
 
@@ -3967,6 +3968,15 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
       Flags |= ISD::ParamFlags::InReg;
     if (Args[i].isSRet)
       Flags |= ISD::ParamFlags::StructReturn;
+    if (Args[i].isByVal) {
+      Flags |= ISD::ParamFlags::ByVal;
+      const PointerType *Ty = cast<PointerType>(Args[i].Ty);
+      const StructType *STy = cast<StructType>(Ty->getElementType());
+      unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
+      unsigned StructSize  = getTargetData()->getTypeSize(STy);
+      Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
+      Flags |= (StructSize  << ISD::ParamFlags::ByValSizeOffs);
+    }
     if (Args[i].isNest)
       Flags |= ISD::ParamFlags::Nest;
     Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs;
index 179c47af25971faa45d288a7211d78cedacd2569..f32e6f6ead233a366733733d0fa96783d97a35c8 100644 (file)
@@ -1378,7 +1378,27 @@ X86TargetLowering::LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG,
         StackPtr = DAG.getRegister(getStackPtrReg(), getPointerTy());
       SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy());
       PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
-      MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+
+      SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo());
+      unsigned Flags    = cast<ConstantSDNode>(FlagsOp)->getValue();
+      if (Flags & ISD::ParamFlags::ByVal) {
+        unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >>
+                               ISD::ParamFlags::ByValAlignOffs);
+        unsigned  Size = (Flags & ISD::ParamFlags::ByValSize) >>
+            ISD::ParamFlags::ByValSizeOffs;
+
+        SDOperand AlignNode = DAG.getConstant(Align, MVT::i32);
+        SDOperand  SizeNode = DAG.getConstant(Size, MVT::i32);
+
+        assert(0 && "Not Implemented");
+
+        SDOperand Copy = DAG.getNode(ISD::MEMCPY, MVT::Other, Chain, PtrOff,
+                                     Arg, SizeNode, AlignNode);
+        MemOpChains.push_back(Copy);
+      }
+      else {
+        MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+      }
     }
   }