void Mips16TargetLowering:: getOpndList(SmallVectorImpl<SDValue> &Ops, std::deque< std::pair<unsigned, SDValue> > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { SelectionDAG &DAG = CLI.DAG; MachineFunction &MF = DAG.getMachineFunction(); MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>(); const char* Mips16HelperFunction = 0; bool NeedMips16Helper = false; if (Subtarget->inMips16HardFloat()) { // // currently we don't have symbols tagged with the mips16 or mips32 // qualifier so we will assume that we don't know what kind it is. // and generate the helper // bool LookupHelper = true; if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) { Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() }; if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls), Find)) LookupHelper = false; else { const char *Symbol = S->getSymbol(); Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" }; const Mips16HardFloatInfo::FuncSignature *Signature = Mips16HardFloatInfo::findFuncSignature(Symbol); if (!IsPICCall && (Signature && (FuncInfo->StubsNeeded.find(Symbol) == FuncInfo->StubsNeeded.end()))) { FuncInfo->StubsNeeded[Symbol] = Signature; // // S2 is normally saved if the stub is for a function which // returns a float or double value and is not otherwise. This is // because more work is required after the function the stub // is calling completes, and so the stub cannot directly return // and the stub has no stack space to store the return address so // S2 is used for that purpose. // In order to take advantage of not saving S2, we need to also // optimize the call in the stub and this requires some further // functionality in MipsAsmPrinter which we don't have yet. // So for now we always save S2. The optimization will be done // in a follow-on patch. // if (1 || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet)) FuncInfo->setSaveS2(); } // one more look at list of intrinsics if (std::binary_search(Mips16IntrinsicHelper, array_endof(Mips16IntrinsicHelper), IntrinsicFind)) { const Mips16IntrinsicHelperType *h =(std::find(Mips16IntrinsicHelper, array_endof(Mips16IntrinsicHelper), IntrinsicFind)); Mips16HelperFunction = h->Helper; NeedMips16Helper = true; LookupHelper = false; } } } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(CLI.Callee)) { Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, G->getGlobal()->getName().data() }; if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls), Find)) LookupHelper = false; } if (LookupHelper) Mips16HelperFunction = getMips16HelperFunction(CLI.RetTy, CLI.Args, NeedMips16Helper); } SDValue JumpTarget = Callee; // T9 should contain the address of the callee function if // -reloction-model=pic or it is an indirect call. if (IsPICCall || !GlobalOrExternal) { unsigned V0Reg = Mips::V0; if (NeedMips16Helper) { RegsToPass.push_front(std::make_pair(V0Reg, Callee)); JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, getPointerTy()); ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget); JumpTarget = getAddrGlobal(S, JumpTarget.getValueType(), DAG, MipsII::MO_GOT, Chain, FuncInfo->callPtrInfo(S->getSymbol())); } else RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee)); } Ops.push_back(JumpTarget); MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage, CLI, Callee, Chain); }
void Mips16TargetLowering:: getOpndList(SmallVectorImpl<SDValue> &Ops, std::deque< std::pair<unsigned, SDValue> > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { SelectionDAG &DAG = CLI.DAG; MachineFunction &MF = DAG.getMachineFunction(); MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>(); const char* Mips16HelperFunction = 0; bool NeedMips16Helper = false; if (Subtarget->inMips16HardFloat()) { // // currently we don't have symbols tagged with the mips16 or mips32 // qualifier so we will assume that we don't know what kind it is. // and generate the helper // bool LookupHelper = true; if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) { Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() }; if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls), Find)) LookupHelper = false; else { Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(), ""}; // one more look at list of intrinsics if (std::binary_search(Mips16IntrinsicHelper, array_endof(Mips16IntrinsicHelper), IntrinsicFind)) { const Mips16IntrinsicHelperType *h =(std::find(Mips16IntrinsicHelper, array_endof(Mips16IntrinsicHelper), IntrinsicFind)); Mips16HelperFunction = h->Helper; NeedMips16Helper = true; LookupHelper = false; } } } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(CLI.Callee)) { Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, G->getGlobal()->getName().data() }; if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls), Find)) LookupHelper = false; } if (LookupHelper) Mips16HelperFunction = getMips16HelperFunction(CLI.RetTy, CLI.Args, NeedMips16Helper); } SDValue JumpTarget = Callee; // T9 should contain the address of the callee function if // -reloction-model=pic or it is an indirect call. if (IsPICCall || !GlobalOrExternal) { unsigned V0Reg = Mips::V0; if (NeedMips16Helper) { RegsToPass.push_front(std::make_pair(V0Reg, Callee)); JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, getPointerTy()); ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget); JumpTarget = getAddrGlobal(S, JumpTarget.getValueType(), DAG, MipsII::MO_GOT, Chain, FuncInfo->callPtrInfo(S->getSymbol())); } else RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee)); } Ops.push_back(JumpTarget); MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, InternalLinkage, CLI, Callee, Chain); }