From 1b5dcc34b701639f94008658a2042abc43b9b910 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 31 Aug 2007 15:06:30 +0000 Subject: [PATCH] Initial support for calling functions with byval arguments on x86-64 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41643 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 52 +++++++++++++++++------------- lib/Target/X86/X86ISelLowering.h | 7 ++++ test/CodeGen/X86/byval2.ll | 19 +++++++++++ 3 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 test/CodeGen/X86/byval2.ll diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 85c9691e5e0..084c8468ad9 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1036,6 +1036,34 @@ X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) { &ArgValues[0], ArgValues.size()).getValue(Op.ResNo); } +SDOperand +X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG, + const SDOperand &StackPtr, + const CCValAssign &VA, + SDOperand Chain, + SDOperand Arg) { + SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy()); + PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); + SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); + unsigned Flags = cast(FlagsOp)->getValue(); + if (Flags & ISD::ParamFlags::ByVal) { + unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >> + ISD::ParamFlags::ByValAlignOffs); + + assert (Align >= 8); + unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> + ISD::ParamFlags::ByValSizeOffs; + + SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); + SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); + + return DAG.getNode(ISD::MEMCPY, MVT::Other, Chain, PtrOff, Arg, SizeNode, + AlignNode); + } else { + return DAG.getStore(Chain, Arg, PtrOff, NULL, 0); + } +} + SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC) { SDOperand Chain = Op.getOperand(0); @@ -1375,29 +1403,9 @@ X86TargetLowering::LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG, assert(VA.isMemLoc()); if (StackPtr.Val == 0) StackPtr = DAG.getRegister(getStackPtrReg(), getPointerTy()); - SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); - SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); - unsigned Flags = cast(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)); - } + MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain, + Arg)); } } diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 24ca1ea44bf..41eaec27832 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -19,6 +19,7 @@ #include "X86RegisterInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/CallingConvLower.h" namespace llvm { namespace X86ISD { @@ -378,6 +379,12 @@ namespace llvm { SDNode *LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode*TheCall, unsigned CallingConv, SelectionDAG &DAG); + + SDOperand LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG, + const SDOperand &StackPtr, + const CCValAssign &VA, SDOperand Chain, + SDOperand Arg); + // C and StdCall Calling Convention implementation. SDOperand LowerCCCArguments(SDOperand Op, SelectionDAG &DAG, bool isStdCall = false); diff --git a/test/CodeGen/X86/byval2.ll b/test/CodeGen/X86/byval2.ll new file mode 100644 index 00000000000..04d34839c0e --- /dev/null +++ b/test/CodeGen/X86/byval2.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep rep.movsl | count 2 + +%struct.s = type { i64, i64, i64 } + +define void @g(i64 %a, i64 %b, i64 %c) { +entry: + %d = alloca %struct.s, align 16 + %tmp = getelementptr %struct.s* %d, i32 0, i32 0 + store i64 %a, i64* %tmp, align 16 + %tmp2 = getelementptr %struct.s* %d, i32 0, i32 1 + store i64 %b, i64* %tmp2, align 16 + %tmp4 = getelementptr %struct.s* %d, i32 0, i32 2 + store i64 %c, i64* %tmp4, align 16 + call void @f( %struct.s* %d byval) + call void @f( %struct.s* %d byval) + ret void +} + +declare void @f(%struct.s* byval) -- 2.34.1