diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Nios2/Nios2ISelLowering.cpp')
| -rw-r--r-- | contrib/llvm/lib/Target/Nios2/Nios2ISelLowering.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/Nios2/Nios2ISelLowering.cpp b/contrib/llvm/lib/Target/Nios2/Nios2ISelLowering.cpp index 99aa43f960c1..008ce1570722 100644 --- a/contrib/llvm/lib/Target/Nios2/Nios2ISelLowering.cpp +++ b/contrib/llvm/lib/Target/Nios2/Nios2ISelLowering.cpp @@ -32,9 +32,38 @@ Nios2TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL, SelectionDAG &DAG) const { + // CCValAssign - represent the assignment of + // the return value to a location + SmallVector<CCValAssign, 16> RVLocs; + MachineFunction &MF = DAG.getMachineFunction(); + + // CCState - Info about the registers and stack slot. + CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); + // Analyze return values. + CCInfo.CheckReturn(Outs, RetCC_Nios2EABI); + SDValue Flag; SmallVector<SDValue, 4> RetOps(1, Chain); + // Copy the result values into the output registers. + for (unsigned i = 0; i != RVLocs.size(); ++i) { + SDValue Val = OutVals[i]; + CCValAssign &VA = RVLocs[i]; + assert(VA.isRegLoc() && "Can only return in registers!"); + + if (RVLocs[i].getValVT() != RVLocs[i].getLocVT()) + Val = DAG.getNode(ISD::BITCAST, DL, RVLocs[i].getLocVT(), Val); + + Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Flag); + + // Guarantee that all emitted copies are stuck together with flags. + Flag = Chain.getValue(1); + RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); + } + + if (Flag.getNode()) + RetOps.push_back(Flag); + return DAG.getNode(Nios2ISD::Ret, DL, MVT::Other, RetOps); } |
