static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { SDOperand Copy = DAG.getCopyToReg(Op.getOperand(0), Alpha::R26, DAG.getNode(AlphaISD::GlobalRetAddr, MVT::i64), SDOperand()); switch (Op.getNumOperands()) { default: assert(0 && "Do not know how to return this many arguments!"); abort(); case 1: break; //return SDOperand(); // ret void is legal case 3: { MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); unsigned ArgReg; if (MVT::isInteger(ArgVT)) ArgReg = Alpha::R0; else { assert(MVT::isFloatingPoint(ArgVT)); ArgReg = Alpha::F0; } Copy = DAG.getCopyToReg(Copy, ArgReg, Op.getOperand(1), Copy.getValue(1)); if (DAG.getMachineFunction().liveout_empty()) DAG.getMachineFunction().addLiveOut(ArgReg); break; } } return DAG.getNode(AlphaISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); }
SDOperand IA64TargetLowering:: LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { default: assert(0 && "Should not custom lower this!"); case ISD::GlobalTLSAddress: assert(0 && "TLS not implemented for IA64."); case ISD::RET: { SDOperand AR_PFSVal, Copy; switch(Op.getNumOperands()) { default: assert(0 && "Do not know how to return this many arguments!"); abort(); case 1: AR_PFSVal = DAG.getCopyFromReg(Op.getOperand(0), VirtGPR, MVT::i64); AR_PFSVal = DAG.getCopyToReg(AR_PFSVal.getValue(1), IA64::AR_PFS, AR_PFSVal); return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, AR_PFSVal); case 3: { // Copy the result into the output register & restore ar.pfs MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); unsigned ArgReg = MVT::isInteger(ArgVT) ? IA64::r8 : IA64::F8; AR_PFSVal = DAG.getCopyFromReg(Op.getOperand(0), VirtGPR, MVT::i64); Copy = DAG.getCopyToReg(AR_PFSVal.getValue(1), ArgReg, Op.getOperand(1), SDOperand()); AR_PFSVal = DAG.getCopyToReg(Copy.getValue(0), IA64::AR_PFS, AR_PFSVal, Copy.getValue(1)); return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, AR_PFSVal, AR_PFSVal.getValue(1)); } } return SDOperand(); } case ISD::VAARG: { MVT::ValueType VT = getPointerTy(); const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); SDOperand VAList = DAG.getLoad(VT, Op.getOperand(0), Op.getOperand(1), SV, 0); // Increment the pointer, VAList, to the next vaarg SDOperand VAIncr = DAG.getNode(ISD::ADD, VT, VAList, DAG.getConstant(MVT::getSizeInBits(VT)/8, VT)); // Store the incremented VAList to the legalized pointer VAIncr = DAG.getStore(VAList.getValue(1), VAIncr, Op.getOperand(1), SV, 0); // Load the actual argument out of the pointer VAList return DAG.getLoad(Op.getValueType(), VAIncr, VAList, NULL, 0); } case ISD::VASTART: { // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV, 0); } // Frame & Return address. Currently unimplemented case ISD::RETURNADDR: break; case ISD::FRAMEADDR: break; } return SDOperand(); }