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)); }
SDValue LanaiTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, SDLoc DL, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of the return value to a location SmallVector<CCValAssign, 16> RVLocs; // CCState - Info about the registers and stack slot. CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, *DAG.getContext()); // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_Lanai32); SDValue Flag; SmallVector<SDValue, 4> RetOps(1, Chain); // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Flag); // Guarantee that all emitted copies are stuck together with flags. Flag = Chain.getValue(1); RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); } // The Lanai ABI for returning structs by value requires that we copy // the sret argument into rv for the return. We saved the argument into // a virtual register in the entry block, so now we copy the value out // and into rv. if (DAG.getMachineFunction().getFunction()->hasStructRetAttr()) { MachineFunction &MF = DAG.getMachineFunction(); LanaiMachineFunctionInfo *LanaiMFI = MF.getInfo<LanaiMachineFunctionInfo>(); unsigned Reg = LanaiMFI->getSRetReturnReg(); assert(Reg && "SRetReturnReg should have been set in LowerFormalArguments()."); SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy(DAG.getDataLayout())); Chain = DAG.getCopyToReg(Chain, DL, Lanai::RV, Val, Flag); Flag = Chain.getValue(1); RetOps.push_back( DAG.getRegister(Lanai::RV, getPointerTy(DAG.getDataLayout()))); } RetOps[0] = Chain; // Update chain unsigned Opc = LanaiISD::RET_FLAG; if (Flag.getNode()) RetOps.push_back(Flag); // Return Void return DAG.getNode(Opc, DL, MVT::Other, ArrayRef<SDValue>(&RetOps[0], RetOps.size())); }
SDValue AlphaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, DebugLoc dl, SelectionDAG &DAG) const { SDValue Copy = DAG.getCopyToReg(Chain, dl, Alpha::R26, DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc(), MVT::i64), SDValue()); switch (Outs.size()) { default: llvm_unreachable("Do not know how to return this many arguments!"); case 0: break; //return SDValue(); // ret void is legal case 1: { EVT ArgVT = Outs[0].Val.getValueType(); unsigned ArgReg; if (ArgVT.isInteger()) ArgReg = Alpha::R0; else { assert(ArgVT.isFloatingPoint()); ArgReg = Alpha::F0; } Copy = DAG.getCopyToReg(Copy, dl, ArgReg, Outs[0].Val, Copy.getValue(1)); if (DAG.getMachineFunction().getRegInfo().liveout_empty()) DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg); break; } case 2: { EVT ArgVT = Outs[0].Val.getValueType(); unsigned ArgReg1, ArgReg2; if (ArgVT.isInteger()) { ArgReg1 = Alpha::R0; ArgReg2 = Alpha::R1; } else { assert(ArgVT.isFloatingPoint()); ArgReg1 = Alpha::F0; ArgReg2 = Alpha::F1; } Copy = DAG.getCopyToReg(Copy, dl, ArgReg1, Outs[0].Val, Copy.getValue(1)); if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg1) == DAG.getMachineFunction().getRegInfo().liveout_end()) DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg1); Copy = DAG.getCopyToReg(Copy, dl, ArgReg2, Outs[1].Val, Copy.getValue(1)); if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg2) == DAG.getMachineFunction().getRegInfo().liveout_end()) DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg2); break; } } return DAG.getNode(AlphaISD::RET_FLAG, dl, MVT::Other, Copy, Copy.getValue(1)); }
SDValue BlackfinTargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, DebugLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); SmallVector<CCValAssign, 16> ArgLocs; CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), getTargetMachine(), ArgLocs, *DAG.getContext()); CCInfo.AllocateStack(12, 4); // ABI requires 12 bytes stack space CCInfo.AnalyzeFormalArguments(Ins, CC_Blackfin); for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; if (VA.isRegLoc()) { EVT RegVT = VA.getLocVT(); TargetRegisterClass *RC = VA.getLocReg() == BF::P0 ? BF::PRegisterClass : BF::DRegisterClass; assert(RC->contains(VA.getLocReg()) && "Unexpected regclass in CCState"); assert(RC->hasType(RegVT) && "Unexpected regclass in CCState"); unsigned Reg = MF.getRegInfo().createVirtualRegister(RC); MF.getRegInfo().addLiveIn(VA.getLocReg(), Reg); SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); // If this is an 8 or 16-bit value, it is really passed promoted to 32 // bits. Insert an assert[sz]ext to capture this, then truncate to the // right size. if (VA.getLocInfo() == CCValAssign::SExt) ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, DAG.getValueType(VA.getValVT())); else if (VA.getLocInfo() == CCValAssign::ZExt) ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, DAG.getValueType(VA.getValVT())); if (VA.getLocInfo() != CCValAssign::Full) ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); InVals.push_back(ArgValue); } else { assert(VA.isMemLoc() && "CCValAssign must be RegLoc or MemLoc"); unsigned ObjSize = VA.getLocVT().getStoreSize(); int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, MachinePointerInfo(), false, false, 0)); } } return Chain; }
SDValue PTXTargetLowering:: LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, DebugLoc dl, SelectionDAG &DAG) const { if (isVarArg) llvm_unreachable("PTX does not support varargs"); switch (CallConv) { default: llvm_unreachable("Unsupported calling convention."); case CallingConv::PTX_Kernel: assert(Outs.size() == 0 && "Kernel must return void."); return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain); case CallingConv::PTX_Device: //assert(Outs.size() <= 1 && "Can at most return one value."); break; } MachineFunction& MF = DAG.getMachineFunction(); PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>(); SmallVector<CCValAssign, 16> RVLocs; CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), getTargetMachine(), RVLocs, *DAG.getContext()); SDValue Flag; CCInfo.AnalyzeReturn(Outs, RetCC_PTX); for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { CCValAssign& VA = RVLocs[i]; assert(VA.isRegLoc() && "CCValAssign must be RegLoc"); unsigned Reg = VA.getLocReg(); DAG.getMachineFunction().getRegInfo().addLiveOut(Reg); Chain = DAG.getCopyToReg(Chain, dl, Reg, OutVals[i], Flag); // Guarantee that all emitted copies are stuck together, // avoiding something bad Flag = Chain.getValue(1); MFI->addRetReg(Reg); } if (Flag.getNode() == 0) { return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain); } else { return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag); } }
SDValue BlackfinTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, DebugLoc dl, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of the return value to locations. SmallVector<CCValAssign, 16> RVLocs; // CCState - Info about the registers and stack slot. CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), DAG.getTarget(), RVLocs, *DAG.getContext()); // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_Blackfin); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { for (unsigned i = 0; i != RVLocs.size(); ++i) DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } SDValue Flag; // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); SDValue Opi = OutVals[i]; // Expand to i32 if necessary switch (VA.getLocInfo()) { default: llvm_unreachable("Unknown loc info!"); case CCValAssign::Full: break; case CCValAssign::SExt: Opi = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Opi); break; case CCValAssign::ZExt: Opi = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Opi); break; case CCValAssign::AExt: Opi = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Opi); break; } Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Opi, SDValue()); // Guarantee that all emitted copies are stuck together with flags. Flag = Chain.getValue(1); } if (Flag.getNode()) { return DAG.getNode(BFISD::RET_FLAG, dl, MVT::Other, Chain, Flag); } else { return DAG.getNode(BFISD::RET_FLAG, dl, MVT::Other, Chain); } }
SDValue MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, DebugLoc dl, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of the return value to a location SmallVector<CCValAssign, 16> RVLocs; // ISRs cannot return any value. if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) { report_fatal_error("ISRs cannot return any value"); return SDValue(); } // CCState - Info about the registers and stack slot. CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { for (unsigned i = 0; i != RVLocs.size(); ++i) if (RVLocs[i].isRegLoc()) DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } SDValue Flag; // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag); // Guarantee that all emitted copies are stuck together, // avoiding something bad. Flag = Chain.getValue(1); } unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); if (Flag.getNode()) return DAG.getNode(Opc, dl, MVT::Other, Chain, Flag); // Return Void return DAG.getNode(Opc, dl, MVT::Other, Chain); }
SDValue SystemZTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, DebugLoc dl, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of the return value to a location SmallVector<CCValAssign, 16> RVLocs; // CCState - Info about the registers and stack slot. CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), getTargetMachine(), RVLocs, *DAG.getContext()); // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_SystemZ); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { for (unsigned i = 0; i != RVLocs.size(); ++i) if (RVLocs[i].isRegLoc()) DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } SDValue Flag; // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; SDValue ResValue = OutVals[i]; assert(VA.isRegLoc() && "Can only return in registers!"); // If this is an 8/16/32-bit value, it is really should be passed promoted // to 64 bits. if (VA.getLocInfo() == CCValAssign::SExt) ResValue = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), ResValue); else if (VA.getLocInfo() == CCValAssign::ZExt) ResValue = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), ResValue); else if (VA.getLocInfo() == CCValAssign::AExt) ResValue = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), ResValue); Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), ResValue, Flag); // Guarantee that all emitted copies are stuck together, // avoiding something bad. Flag = Chain.getValue(1); } if (Flag.getNode()) return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain, Flag); // Return Void return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain); }
SDValue VectorProcTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, DebugLoc DL, SelectionDAG &DAG) const { MachineFunction &MF = DAG.getMachineFunction(); // CCValAssign - represent the assignment of the return value to locations. SmallVector<CCValAssign, 16> RVLocs; // CCState - Info about the registers and stack slot. CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), DAG.getTarget(), RVLocs, *DAG.getContext()); // Analyze return values. CCInfo.AnalyzeReturn(Outs, RetCC_VectorProc32); SDValue Flag; SmallVector<SDValue, 4> RetOps(1, Chain); // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], 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 (MF.getFunction()->hasStructRetAttr()) { VectorProcMachineFunctionInfo *SFI = MF.getInfo<VectorProcMachineFunctionInfo>(); unsigned Reg = SFI->getSRetReturnReg(); if (!Reg) llvm_unreachable("sret virtual register not created in the entry block"); SDValue Val = DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy()); Chain = DAG.getCopyToReg(Chain, DL, VectorProc::S0, Val, Flag); Flag = Chain.getValue(1); RetOps.push_back(DAG.getRegister(VectorProc::S0, getPointerTy())); } RetOps[0] = Chain; // Update chain. // Add the flag if we have it. if (Flag.getNode()) RetOps.push_back(Flag); return DAG.getNode(VectorProcISD::RET_FLAG, DL, MVT::Other, &RetOps[0], RetOps.size()); }
SDValue ARCompactTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, DebugLoc dl, SelectionDAG &DAG) const { //DEBUG(dbgs() << "ARCompactTargetLowering::LowerReturn()\n"); MachineFunction &MF = DAG.getMachineFunction(); // CCValAssign - represent the assignment of the return value to locations. SmallVector<CCValAssign, 16> RVLocs; // CCState - Info about the registers and stack slot. CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), DAG.getTarget(), RVLocs, *DAG.getContext()); // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_ARCompact32); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. if (MF.getRegInfo().liveout_empty()) { for (unsigned i = 0; i != RVLocs.size(); ++i) if (RVLocs[i].isRegLoc()) { MF.getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } } SDValue Flag; // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag); // Guarantee that all emitted copies are stuck together with flags. Flag = Chain.getValue(1); } // TODO: Check this value. unsigned int RetAddrOffset = 8; // Call Instruction + Delay Slot SDValue RetAddrOffsetNode = DAG.getConstant(RetAddrOffset, MVT::i32); if (Flag.getNode()) { return DAG.getNode(ARCISD::RET_FLAG, dl, MVT::Other, Chain, RetAddrOffsetNode, Flag); } return DAG.getNode(ARCISD::RET_FLAG, dl, MVT::Other, Chain, RetAddrOffsetNode); }
SDValue WebAssemblyTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); EVT PtrVT = getPointerTy(DAG.getMachineFunction().getDataLayout()); auto *MFI = DAG.getMachineFunction().getInfo<WebAssemblyFunctionInfo>(); const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); SDValue ArgN = DAG.getCopyFromReg(DAG.getEntryNode(), DL, MFI->getVarargBufferVreg(), PtrVT); return DAG.getStore(Op.getOperand(0), DL, ArgN, Op.getOperand(1), MachinePointerInfo(SV), false, false, 0); }
SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { // Non-zero depths are not supported by WebAssembly currently. Use the // legalizer's default expansion, which is to return 0 (what this function is // documented to do). if (Op.getConstantOperandVal(0) > 0) return SDValue(); DAG.getMachineFunction().getFrameInfo()->setFrameAddressIsTaken(true); EVT VT = Op.getValueType(); unsigned FP = Subtarget->getRegisterInfo()->getFrameRegister(DAG.getMachineFunction()); return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT); }
SDValue PTXTargetLowering:: LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, DebugLoc dl, SelectionDAG &DAG) const { if (isVarArg) llvm_unreachable("PTX does not support varargs"); switch (CallConv) { default: llvm_unreachable("Unsupported calling convention."); case CallingConv::PTX_Kernel: assert(Outs.size() == 0 && "Kernel must return void."); return DAG.getNode(PTXISD::EXIT, dl, MVT::Other, Chain); case CallingConv::PTX_Device: assert(Outs.size() <= 1 && "Can at most return one value."); break; } // PTX_Device // return void if (Outs.size() == 0) return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain); assert(Outs[0].VT == MVT::i32 && "Can return only basic types"); SDValue Flag; unsigned reg = PTX::R0; MachineFunction &MF = DAG.getMachineFunction(); PTXMachineFunctionInfo *MFI = MF.getInfo<PTXMachineFunctionInfo>(); MFI->setRetReg(reg); // If this is the first return lowered for this function, add the regs to the // liveout set for the function if (DAG.getMachineFunction().getRegInfo().liveout_empty()) DAG.getMachineFunction().getRegInfo().addLiveOut(reg); // Copy the result values into the output registers Chain = DAG.getCopyToReg(Chain, dl, reg, OutVals[0], Flag); // Guarantee that all emitted copies are stuck together, // avoiding something bad Flag = Chain.getValue(1); return DAG.getNode(PTXISD::RET, dl, MVT::Other, Chain, Flag); }
SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const { MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); MFI->setReturnAddressIsTaken(true); if (verifyReturnAddressArgumentIsConstant(Op, DAG)) return SDValue(); unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); SDLoc dl(Op); auto PtrVT = getPointerTy(DAG.getDataLayout()); if (Depth > 0) { SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); SDValue Offset = DAG.getConstant(DAG.getDataLayout().getPointerSize(), dl, MVT::i16); return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset), MachinePointerInfo(), false, false, false, 0); } // Just load the return address. SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI, MachinePointerInfo(), false, false, false, 0); }
SDValue WebAssemblyTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); SDValue Chain = Op.getOperand(0); const auto *JT = cast<JumpTableSDNode>(Op.getOperand(1)); SDValue Index = Op.getOperand(2); assert(JT->getTargetFlags() == 0 && "WebAssembly doesn't set target flags"); SmallVector<SDValue, 8> Ops; Ops.push_back(Chain); Ops.push_back(Index); MachineJumpTableInfo *MJTI = DAG.getMachineFunction().getJumpTableInfo(); const auto &MBBs = MJTI->getJumpTables()[JT->getIndex()].MBBs; // TODO: For now, we just pick something arbitrary for a default case for now. // We really want to sniff out the guard and put in the real default case (and // delete the guard). Ops.push_back(DAG.getBasicBlock(MBBs[0])); // Add an operand for each case. for (auto MBB : MBBs) Ops.push_back(DAG.getBasicBlock(MBB)); return DAG.getNode(WebAssemblyISD::SWITCH, DL, MVT::Other, Ops); }
SDValue Y86TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs, *DAG.getContext()); CCInfo.AnalyzeCallResult(Ins, RetCC_Y86); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { CCValAssign &VA = RVLocs[i]; EVT CopyVT = VA.getValVT(); Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), CopyVT, InFlag).getValue(1); InFlag = Chain.getValue(2); InVals.push_back(Chain.getValue(0)); } return Chain; }
//===----------------------------------------------------------------------===// // Misc Lower Operation implementation //===----------------------------------------------------------------------===// SDValue Cpu0TargetLowering:: LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { MachineFunction &MF = DAG.getMachineFunction(); Cpu0FunctionInfo *Cpu0FI = MF.getInfo<Cpu0FunctionInfo>(); unsigned SP = Cpu0::SP; assert(getTargetMachine().getFrameLowering()->getStackAlignment() >= cast<ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue() && "Cannot lower if the alignment of the allocated space is larger than \ that of the stack."); SDValue Chain = Op.getOperand(0); SDValue Size = Op.getOperand(1); DebugLoc dl = Op.getDebugLoc(); // Get a reference from Cpu0 stack pointer SDValue StackPointer = DAG.getCopyFromReg(Chain, dl, SP, getPointerTy()); // Subtract the dynamic size from the actual stack size to // obtain the new stack size. SDValue Sub = DAG.getNode(ISD::SUB, dl, getPointerTy(), StackPointer, Size); // The Sub result contains the new stack start address, so it // must be placed in the stack pointer register. Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, SP, Sub, SDValue()); // This node always has two return values: a new stack pointer // value and a chain SDVTList VTLs = DAG.getVTList(getPointerTy(), MVT::Other); SDValue Ptr = DAG.getFrameIndex(Cpu0FI->getDynAllocFI(), getPointerTy()); SDValue Ops[] = { Chain, Ptr, Chain.getValue(1) }; return DAG.getNode(Cpu0ISD::DynAlloc, dl, VTLs, Ops, 3); }
static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) { MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); MFI->setReturnAddressIsTaken(true); EVT VT = Op.getValueType(); DebugLoc dl = Op.getDebugLoc(); unsigned RetReg = SP::I7; uint64_t depth = Op.getConstantOperandVal(0); SDValue RetAddr; if (depth == 0) RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT); else { // flush first to make sure the windowed registers' values are in stack SDValue Chain = getFLUSHW(Op, DAG); RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT); for (uint64_t i = 0; i != depth; ++i) { SDValue Ptr = DAG.getNode(ISD::ADD, dl, MVT::i32, RetAddr, DAG.getIntPtrConstant((i == depth-1)?60:56)); RetAddr = DAG.getLoad(MVT::i32, dl, Chain, Ptr, MachinePointerInfo(), false, false, 0); } } return RetAddr; }
SDValue DCPU16TargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, DebugLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { switch (CallConv) { default: llvm_unreachable("Unsupported calling convention"); case CallingConv::C: case CallingConv::Fast: return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); case CallingConv::DCPU16_INTR: { if (Ins.size() != 1 || Ins[0].VT != MVT::i16) report_fatal_error("Interrupt handlers take exactly one integer or unsigned argument"); // Copy to virtual register from A MachineRegisterInfo &RegInfo = DAG.getMachineFunction().getRegInfo(); unsigned VReg = RegInfo.createVirtualRegister(DCPU16::GR16RegisterClass); RegInfo.addLiveIn(DCPU16::A, VReg); SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i16); InVals.push_back(ArgValue); return Chain; } } }
SDValue WebAssemblyTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); EVT PtrVT = getPointerTy(DAG.getMachineFunction().getDataLayout()); // The incoming non-fixed arguments are placed on the top of the stack, with // natural alignment, at the point of the call, so the base pointer is just // the current frame pointer. DAG.getMachineFunction().getFrameInfo()->setFrameAddressIsTaken(true); unsigned FP = Subtarget->getRegisterInfo()->getFrameRegister(DAG.getMachineFunction()); SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, FP, PtrVT); const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); return DAG.getStore(Op.getOperand(0), DL, FrameAddr, Op.getOperand(1), MachinePointerInfo(SV), false, false, 0); }
SDValue BPFTargetLowering::LowerCallResult( SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc DL, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); if (Ins.size() >= 2) { DiagnosticInfoUnsupported Err(DL, *MF.getFunction(), "only small returns supported", SDValue()); DAG.getContext()->diagnose(Err); } CCInfo.AnalyzeCallResult(Ins, RetCC_BPF64); // Copy all of the result registers out of their specified physreg. for (auto &Val : RVLocs) { Chain = DAG.getCopyFromReg(Chain, DL, Val.getLocReg(), Val.getValVT(), InFlag).getValue(1); InFlag = Chain.getValue(2); InVals.push_back(Chain.getValue(0)); } return Chain; }
SDValue MipsTargetLowering:: LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) { if (!Subtarget->isMips1()) return Op; MachineFunction &MF = DAG.getMachineFunction(); unsigned CCReg = AddLiveIn(MF, Mips::FCR31, Mips::CCRRegisterClass); SDValue Chain = DAG.getEntryNode(); DebugLoc dl = Op.getDebugLoc(); SDValue Src = Op.getOperand(0); // Set the condition register SDValue CondReg = DAG.getCopyFromReg(Chain, dl, CCReg, MVT::i32); CondReg = DAG.getCopyToReg(Chain, dl, Mips::AT, CondReg); CondReg = DAG.getCopyFromReg(CondReg, dl, Mips::AT, MVT::i32); SDValue Cst = DAG.getConstant(3, MVT::i32); SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i32, CondReg, Cst); Cst = DAG.getConstant(2, MVT::i32); SDValue Xor = DAG.getNode(ISD::XOR, dl, MVT::i32, Or, Cst); SDValue InFlag(0, 0); CondReg = DAG.getCopyToReg(Chain, dl, Mips::FCR31, Xor, InFlag); // Emit the round instruction and bit convert to integer SDValue Trunc = DAG.getNode(MipsISD::FPRound, dl, MVT::f32, Src, CondReg.getValue(1)); SDValue BitCvt = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Trunc); return BitCvt; }
SDValue MBlazeTargetLowering:: LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, DebugLoc dl, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of // the return value to a location SmallVector<CCValAssign, 16> RVLocs; // CCState - Info about the registers and stack slot. CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_MBlaze); // If this is the first return lowered for this function, add // the regs to the liveout set for the function. if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { for (unsigned i = 0; i != RVLocs.size(); ++i) if (RVLocs[i].isRegLoc()) DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } SDValue Flag; // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag); // guarantee that all emitted copies are // stuck together, avoiding something bad Flag = Chain.getValue(1); } // Return on MBlaze is always a "rtsd R15, 8" if (Flag.getNode()) return DAG.getNode(MBlazeISD::Ret, dl, MVT::Other, Chain, DAG.getRegister(MBlaze::R15, MVT::i32), Flag); else // Return Void return DAG.getNode(MBlazeISD::Ret, dl, MVT::Other, Chain, DAG.getRegister(MBlaze::R15, MVT::i32)); }
SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { // CCValAssign - represent the assignment of the return value to a location SmallVector<CCValAssign, 16> RVLocs; unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); DebugLoc dl = Op.getDebugLoc(); // CCState - Info about the registers and stack slot. CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs); // Analize return values of ISD::RET CCInfo.AnalyzeReturn(Op.getNode(), RetCC_MSP430); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { for (unsigned i = 0; i != RVLocs.size(); ++i) if (RVLocs[i].isRegLoc()) DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } // The chain is always operand #0 SDValue Chain = Op.getOperand(0); SDValue Flag; // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); // ISD::RET => ret chain, (regnum1,val1), ... // So i*2+1 index only the regnums Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Op.getOperand(i*2+1), Flag); // Guarantee that all emitted copies are stuck together, // avoiding something bad. Flag = Chain.getValue(1); } if (Flag.getNode()) return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain, Flag); // Return Void return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain); }
static void fail(SDLoc DL, SelectionDAG &DAG, const char *Msg, SDValue Val) { MachineFunction &MF = DAG.getMachineFunction(); std::string Str; raw_string_ostream OS(Str); OS << Msg; Val->print(OS); OS.flush(); DAG.getContext()->diagnose( DiagnosticInfoUnsupported(*MF.getFunction(), Str, DL.getDebugLoc())); }
SDValue SparcTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, DebugLoc dl, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of the return value to locations. SmallVector<CCValAssign, 16> RVLocs; // CCState - Info about the registers and stack slot. CCState CCInfo(CallConv, isVarArg, DAG.getTarget(), RVLocs, *DAG.getContext()); // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_Sparc32); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { for (unsigned i = 0; i != RVLocs.size(); ++i) if (RVLocs[i].isRegLoc()) DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } SDValue Flag; // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Outs[i].Val, Flag); // Guarantee that all emitted copies are stuck together with flags. Flag = Chain.getValue(1); } if (Flag.getNode()) return DAG.getNode(SPISD::RET_FLAG, dl, MVT::Other, Chain, Flag); return DAG.getNode(SPISD::RET_FLAG, dl, MVT::Other, Chain); }
SDValue AVM2TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); MFI->setFrameAddressIsTaken(true); EVT VT = Op.getValueType(); DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful assert((cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0) && "only current frame addr supported"); SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, AVM2::EBP, VT); return FrameAddr; }
SDValue WebAssemblyTargetLowering::LowerFormalArguments( SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc DL, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); if (CallConv != CallingConv::C) fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions"); if (IsVarArg) fail(DL, DAG, "WebAssembly doesn't support varargs yet"); if (MF.getFunction()->hasStructRetAttr()) fail(DL, DAG, "WebAssembly doesn't support struct return yet"); unsigned ArgNo = 0; for (const ISD::InputArg &In : Ins) { if (In.Flags.isZExt()) fail(DL, DAG, "WebAssembly hasn't implemented zext arguments"); if (In.Flags.isSExt()) fail(DL, DAG, "WebAssembly hasn't implemented sext arguments"); if (In.Flags.isInReg()) fail(DL, DAG, "WebAssembly hasn't implemented inreg arguments"); if (In.Flags.isSRet()) fail(DL, DAG, "WebAssembly hasn't implemented sret arguments"); if (In.Flags.isByVal()) fail(DL, DAG, "WebAssembly hasn't implemented byval arguments"); if (In.Flags.isInAlloca()) fail(DL, DAG, "WebAssembly hasn't implemented inalloca arguments"); if (In.Flags.isNest()) fail(DL, DAG, "WebAssembly hasn't implemented nest arguments"); if (In.Flags.isReturned()) fail(DL, DAG, "WebAssembly hasn't implemented returned arguments"); if (In.Flags.isInConsecutiveRegs()) fail(DL, DAG, "WebAssembly hasn't implemented cons regs arguments"); if (In.Flags.isInConsecutiveRegsLast()) fail(DL, DAG, "WebAssembly hasn't implemented cons regs last arguments"); if (In.Flags.isSplit()) fail(DL, DAG, "WebAssembly hasn't implemented split arguments"); // FIXME Do something with In.getOrigAlign()? InVals.push_back( In.Used ? DAG.getNode(WebAssemblyISD::ARGUMENT, DL, In.VT, DAG.getTargetConstant(ArgNo, DL, MVT::i32)) : DAG.getNode(ISD::UNDEF, DL, In.VT)); ++ArgNo; } // Record the number of arguments, since argument indices and local variable // indices are in the same index space. MF.getInfo<WebAssemblyFunctionInfo>()->setNumArguments(ArgNo); return Chain; }
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) { MachineFunction &MF = DAG.getMachineFunction(); auto *FuncInfo = MF.getInfo<ARCFunctionInfo>(); // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. SDLoc dl(Op); EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout()); SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT); const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), MachinePointerInfo(SV)); }
SDValue ARCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { const ARCRegisterInfo &ARI = *Subtarget.getRegisterInfo(); MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo &MFI = MF.getFrameInfo(); MFI.setFrameAddressIsTaken(true); EVT VT = Op.getValueType(); SDLoc dl(Op); assert(cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0 && "Only support lowering frame addr of current frame."); unsigned FrameReg = ARI.getFrameRegister(MF); return DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT); }