Partial implementation of calling functions with byval arguments:
[oota-llvm.git] / lib / CodeGen / SelectionDAG / SelectionDAGISel.cpp
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;