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 | 0594789f0707d93c6346a70fde3f13ed8726179c (patch) | |
tree | 78449230108d512185328c406033f32f37a93412 /llvm/lib/Target/Sparc | |
parent | ae0275e018f029eb8352ec4267f3f2b01d4d43da (diff) | |
download | bcm5719-llvm-0594789f0707d93c6346a70fde3f13ed8726179c.tar.gz bcm5719-llvm-0594789f0707d93c6346a70fde3f13ed8726179c.zip |
Implement support for byval arguments in Sparc backend.
llvm-svn: 123974
Diffstat (limited to 'llvm/lib/Target/Sparc')
-rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.cpp | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 74d471e2c83..f78d5fa5070 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/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!"); |