diff options
Diffstat (limited to 'lib/Target/PowerPC/PPCISelLowering.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index b9949590a2..f1c1735c5a 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -110,6 +110,9 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); + // RET must be custom lowered, to meet ABI requirements + setOperationAction(ISD::RET , MVT::Other, Custom); + // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); @@ -440,6 +443,30 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, Op.getOperand(1), Op.getOperand(2)); } + case ISD::RET: { + SDOperand Copy; + + switch(Op.getNumOperands()) { + default: + assert(0 && "Do not know how to return this many arguments!"); + abort(); + case 1: + return SDOperand(); // ret void is legal + case 2: { + MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); + unsigned ArgReg = MVT::isInteger(ArgVT) ? PPC::R3 : PPC::F1; + Copy = DAG.getCopyToReg(Op.getOperand(0), ArgReg, Op.getOperand(1), + SDOperand()); + break; + } + case 3: + Copy = DAG.getCopyToReg(Op.getOperand(0), PPC::R3, Op.getOperand(2), + SDOperand()); + Copy = DAG.getCopyToReg(Copy, PPC::R4, Op.getOperand(1),Copy.getValue(1)); + break; + } + return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); + } } return SDOperand(); } @@ -835,30 +862,6 @@ PPCTargetLowering::LowerCallTo(SDOperand Chain, return std::make_pair(RetVal, Chain); } -SDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, - SelectionDAG &DAG) { - SDOperand Copy; - switch (Op.getValueType()) { - default: assert(0 && "Unknown type to return!"); - case MVT::i32: - Copy = DAG.getCopyToReg(Chain, PPC::R3, Op, SDOperand()); - break; - case MVT::f32: - case MVT::f64: - Copy = DAG.getCopyToReg(Chain, PPC::F1, Op, SDOperand()); - break; - case MVT::i64: - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, - DAG.getConstant(1, MVT::i32)); - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, - DAG.getConstant(0, MVT::i32)); - Copy = DAG.getCopyToReg(Chain, PPC::R3, Hi, SDOperand()); - Copy = DAG.getCopyToReg(Copy, PPC::R4, Lo, Copy.getValue(1)); - break; - } - return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); -} - std::pair<SDOperand, SDOperand> PPCTargetLowering:: LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { |