Changes in directory llvm/lib/Target/ARM:
ARMISelDAGToDAG.cpp updated: 1.16 -> 1.17 --- Log message: implement function calling of functions with up to 4 arguments --- Diffs of the changes: (+45 -3) ARMISelDAGToDAG.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 45 insertions(+), 3 deletions(-) Index: llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp diff -u llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.16 llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.17 --- llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp:1.16 Sat Jul 15 20:02:57 2006 +++ llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp Tue Jul 25 15:17:19 2006 @@ -75,17 +75,38 @@ assert(isTailCall == false && "tail call not supported"); SDOperand Callee = Op.getOperand(4); unsigned NumOps = (Op.getNumOperands() - 5) / 2; - assert(NumOps == 0); // Count how many bytes are to be pushed on the stack. Initially // only the link register. unsigned NumBytes = 4; + assert(NumOps <= 4); //no args on the stack + // Adjust the stack pointer for the new arguments... // These operations are automatically eliminated by the prolog/epilog pass Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes, MVT::i32)); + static const unsigned regs[] = { + ARM::R0, ARM::R1, ARM::R2, ARM::R3 + }; + + std::vector<std::pair<unsigned, SDOperand> > RegsToPass; + + for (unsigned i = 0; i != NumOps; ++i) { + SDOperand Arg = Op.getOperand(5+2*i); + RegsToPass.push_back(std::make_pair(regs[i], Arg)); + } + + // Build a sequence of copy-to-reg nodes chained together with token chain + // and flag operands which copy the outgoing args into the appropriate regs. + SDOperand InFlag; + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second, + InFlag); + InFlag = Chain.getValue(1); + } + 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. @@ -103,14 +124,35 @@ Ops.push_back(Callee); unsigned CallOpc = ARMISD::CALL; + if (InFlag.Val) + Ops.push_back(InFlag); Chain = DAG.getNode(CallOpc, NodeTys, Ops); + InFlag = Chain.getValue(1); + + std::vector<SDOperand> ResultVals; + NodeTys.clear(); - assert(Op.Val->getValueType(0) == MVT::Other); + // If the call has results, copy the values out of the ret val registers. + switch (Op.Val->getValueType(0)) { + default: assert(0 && "Unexpected ret value!"); + case MVT::Other: + break; + case MVT::i32: + Chain = DAG.getCopyFromReg(Chain, ARM::R0, MVT::i32, InFlag).getValue(1); + ResultVals.push_back(Chain.getValue(0)); + NodeTys.push_back(MVT::i32); + } Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, DAG.getConstant(NumBytes, MVT::i32)); + NodeTys.push_back(MVT::Other); + + if (ResultVals.empty()) + return Chain; - return Chain; + ResultVals.push_back(Chain); + SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, ResultVals); + return Res.getValue(Op.ResNo); } static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits