diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2012-11-21 17:23:03 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2012-11-21 17:23:03 +0000 |
commit | 6cbeb4d839a7fc465c651f0df0b090052cd87a5c (patch) | |
tree | eee7ae6771e4bcbf3210a100e49b58416c83d2e0 /lib | |
parent | 6ee1e0867d24dff28683ec3525e61472c597b6af (diff) | |
download | external_llvm-6cbeb4d839a7fc465c651f0df0b090052cd87a5c.zip external_llvm-6cbeb4d839a7fc465c651f0df0b090052cd87a5c.tar.gz external_llvm-6cbeb4d839a7fc465c651f0df0b090052cd87a5c.tar.bz2 |
Add support for byval args. Patch by Job Noorman!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168439 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/MSP430/MSP430CallingConv.td | 3 | ||||
-rw-r--r-- | lib/Target/MSP430/MSP430ISelLowering.cpp | 60 |
2 files changed, 46 insertions, 17 deletions
diff --git a/lib/Target/MSP430/MSP430CallingConv.td b/lib/Target/MSP430/MSP430CallingConv.td index ad27cc9..b448cc4 100644 --- a/lib/Target/MSP430/MSP430CallingConv.td +++ b/lib/Target/MSP430/MSP430CallingConv.td @@ -24,6 +24,9 @@ def RetCC_MSP430 : CallingConv<[ // MSP430 Argument Calling Conventions //===----------------------------------------------------------------------===// def CC_MSP430 : CallingConv<[ + // Pass by value if the byval attribute is given + CCIfByVal<CCPassByVal<2, 2>>, + // Promote i8 arguments to i16. CCIfType<[i8], CCPromoteToType<i16>>, diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index fc677ae..6b6a348 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -357,22 +357,34 @@ MSP430TargetLowering::LowerCCCArguments(SDValue Chain, } else { // Sanity check assert(VA.isMemLoc()); - // Load the argument to a virtual register - unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; - if (ObjSize > 2) { - errs() << "LowerFormalArguments Unhandled argument type: " - << EVT(VA.getLocVT()).getEVTString() - << "\n"; + + SDValue InVal; + ISD::ArgFlagsTy Flags = Ins[i].Flags; + + if (Flags.isByVal()) { + int FI = MFI->CreateFixedObject(Flags.getByValSize(), + VA.getLocMemOffset(), true); + InVal = DAG.getFrameIndex(FI, getPointerTy()); + } else { + // Load the argument to a virtual register + unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; + if (ObjSize > 2) { + errs() << "LowerFormalArguments Unhandled argument type: " + << EVT(VA.getLocVT()).getEVTString() + << "\n"; + } + // Create the frame index object for this incoming parameter... + int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); + + // Create the SelectionDAG nodes corresponding to a load + //from this parameter + SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); + InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, + MachinePointerInfo::getFixedStack(FI), + false, false, false, 0); } - // Create the frame index object for this incoming parameter... - int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); - - // Create the SelectionDAG nodes corresponding to a load - //from this parameter - SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); - InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, - MachinePointerInfo::getFixedStack(FI), - false, false, false, 0)); + + InVals.push_back(InVal); } } @@ -498,9 +510,23 @@ MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, StackPtr, DAG.getIntPtrConstant(VA.getLocMemOffset())); + SDValue MemOp; + ISD::ArgFlagsTy Flags = Outs[i].Flags; + + if (Flags.isByVal()) { + SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16); + MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode, + Flags.getByValAlign(), + /*isVolatile*/false, + /*AlwaysInline=*/true, + MachinePointerInfo(), + MachinePointerInfo()); + } else { + MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(), + false, false, 0); + } - MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, - MachinePointerInfo(),false, false, 0)); + MemOpChains.push_back(MemOp); } } |