diff options
author | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2011-01-21 14:00:01 +0000 |
---|---|---|
committer | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2011-01-21 14:00:01 +0000 |
commit | 46713296e0da8f413b94b9c2b82b079e6e3bd6e2 (patch) | |
tree | ed2d72c45994f4f941bac81f3960c1827dac39ac /lib/Target/Sparc | |
parent | e7c85a4c1d0c5692ba06494993ebeca562c1ed80 (diff) |
Implement support for byval arguments in Sparc backend.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123974 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/SparcISelLowering.cpp | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 74d471e2c8..f78d5fa507 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -313,6 +313,30 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Keep stack frames 8-byte aligned. ArgsSize = (ArgsSize+7) & ~7; + MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + + //Create local copies for byval args. + SmallVector<SDValue, 8> ByValArgs; + for (unsigned i = 0, e = Outs.size(); i != e; ++i) { + ISD::ArgFlagsTy Flags = Outs[i].Flags; + if (!Flags.isByVal()) + continue; + + SDValue Arg = OutVals[i]; + unsigned Size = Flags.getByValSize(); + unsigned Align = Flags.getByValAlign(); + + int FI = MFI->CreateStackObject(Size, Align, false); + SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy()); + SDValue SizeNode = DAG.getConstant(Size, MVT::i32); + + Chain = DAG.getMemcpy(Chain, dl, FIPtr, Arg, SizeNode, Align, + false, //isVolatile, + (Size <= 32), //AlwaysInline if size <= 32 + MachinePointerInfo(), MachinePointerInfo()); + ByValArgs.push_back(FIPtr); + } + Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true)); SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; @@ -320,12 +344,18 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee, const unsigned StackOffset = 92; // Walk the register/memloc assignments, inserting copies/loads. - for (unsigned i = 0, realArgIdx = 0, e = ArgLocs.size(); + for (unsigned i = 0, realArgIdx = 0, byvalArgIdx = 0, e = ArgLocs.size(); i != e; ++i, ++realArgIdx) { CCValAssign &VA = ArgLocs[i]; SDValue Arg = OutVals[realArgIdx]; + ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags; + + //Use local copy if it is a byval arg. + if (Flags.isByVal()) + Arg = ByValArgs[byvalArgIdx++]; + // Promote the value if needed. switch (VA.getLocInfo()) { default: llvm_unreachable("Unknown loc info!"); |