diff options
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 32 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 8 |
2 files changed, 22 insertions, 18 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index a021c0e2d7..03e0d38d10 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1041,6 +1041,11 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { } std::vector<MVT::ValueType> NodeTys; + NodeTys.push_back(MVT::Other); // Returns a chain + NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + + std::vector<SDOperand> Ops; + unsigned CallOpc = PPCISD::CALL; // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol @@ -1055,11 +1060,8 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { else { // Otherwise, this is an indirect call. We have to use a MTCTR/BCTRL pair // to do the call, we can't use PPCISD::CALL. - std::vector<SDOperand> Ops; Ops.push_back(Chain); Ops.push_back(Callee); - NodeTys.push_back(MVT::Other); - NodeTys.push_back(MVT::Flag); if (InFlag.Val) Ops.push_back(InFlag); @@ -1075,25 +1077,27 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { NodeTys.push_back(MVT::Flag); Ops.clear(); Ops.push_back(Chain); - Ops.push_back(InFlag); - Chain = DAG.getNode(PPCISD::BCTRL, NodeTys, Ops); - InFlag = Chain.getValue(1); + CallOpc = PPCISD::BCTRL; Callee.Val = 0; } - // Create the PPCISD::CALL node itself. + // If this is a direct call, pass the chain and the callee. if (Callee.Val) { - NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. - std::vector<SDOperand> Ops; Ops.push_back(Chain); Ops.push_back(Callee); - if (InFlag.Val) - Ops.push_back(InFlag); - Chain = DAG.getNode(PPCISD::CALL, NodeTys, Ops); - InFlag = Chain.getValue(1); } + // Add argument registers to the end of the list so that they are known live + // into the call. + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) + Ops.push_back(DAG.getRegister(RegsToPass[i].first, + RegsToPass[i].second.getValueType())); + + if (InFlag.Val) + Ops.push_back(InFlag); + Chain = DAG.getNode(CallOpc, NodeTys, Ops); + InFlag = Chain.getValue(1); + std::vector<SDOperand> ResultVals; NodeTys.clear(); diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index c93e0d4d83..460826b314 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -71,7 +71,7 @@ def PPCstd_32 : SDNode<"PPCISD::STD_32" , SDTStore, [SDNPHasChain]>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeq,[SDNPHasChain]>; -def SDT_PPCCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; +def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; def PPCcall : SDNode<"PPCISD::CALL", SDT_PPCCall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall, @@ -310,11 +310,11 @@ let isCall = 1, noResults = 1, PPC970_Unit = 7, LR,CTR, CR0,CR1,CR5,CR6,CR7] in { // Convenient aliases for call instructions - def BL : IForm<18, 0, 1, (ops calltarget:$func), + def BL : IForm<18, 0, 1, (ops calltarget:$func, variable_ops), "bl $func", BrB, []>; // See Pat patterns below. - def BLA : IForm<18, 1, 1, (ops aaddr:$func), + def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops), "bla $func", BrB, [(PPCcall imm:$func)]>; - def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops), "bctrl", BrB, + def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB, [(PPCbctrl)]>; } |