Index: llvm/trunk/lib/Target/Mips/MipsCallingConv.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsCallingConv.td +++ llvm/trunk/lib/Target/Mips/MipsCallingConv.td @@ -295,7 +295,20 @@ CCIfByVal> ]>; +def CC_Mips16RetHelper : CallingConv<[ + CCIfByVal>, + + // Integer arguments are passed in integer registers. + CCIfType<[i32], CCAssignToReg<[V0, V1, A0, A1]>> +]>; + def CC_Mips_FixedArg : CallingConv<[ + // Mips16 needs special handling on some functions. + CCIf<"State.getCallingConv() != CallingConv::Fast", + CCIf<"static_cast(&State)->getSpecialCallingConv() == " + "MipsCCState::Mips16RetHelperConv", + CCDelegateTo>>, + CCIfByVal>, // f128 needs to be handled similarly to f32 and f64 on hard-float. However, @@ -330,15 +343,6 @@ CCDelegateTo ]>; -//== - -def CC_Mips16RetHelper : CallingConv<[ - CCIfByVal>, - - // Integer arguments are passed in integer registers. - CCIfType<[i32], CCAssignToReg<[V0, V1, A0, A1]>> -]>; - //===----------------------------------------------------------------------===// // Callee-saved register lists. //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/Target/Mips/MipsISelLowering.h =================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h @@ -360,15 +360,10 @@ /// arguments and inquire about calling convention information. class MipsCC { public: - enum SpecialCallingConvType { - Mips16RetHelperConv, NoSpecialCallingConv - }; - MipsCC(CallingConv::ID CallConv, const MipsSubtarget &Subtarget, CCState &Info); void analyzeCallOperands(const SmallVectorImpl &Outs, - const SDNode *CallNode, std::vector &FuncArgs, CCState &State); @@ -387,8 +382,6 @@ MVT getRegVT(MVT VT, const Type *OrigTy, const SDNode *CallNode, bool IsSoftFloat) const; - SpecialCallingConvType getSpecialCallingConv(const SDNode *Callee) const; - CallingConv::ID CallConv; const MipsSubtarget &Subtarget; }; Index: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp @@ -75,6 +75,27 @@ namespace { class MipsCCState : public CCState { +public: + enum SpecialCallingConvType { Mips16RetHelperConv, NoSpecialCallingConv }; + + /// Determine the SpecialCallingConvType for the given callee + static SpecialCallingConvType + getSpecialCallingConvForCallee(const SDNode *Callee, + const MipsSubtarget &Subtarget) { + SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv; + if (Subtarget.inMips16HardFloat()) { + if (const GlobalAddressSDNode *G = + dyn_cast(Callee)) { + llvm::StringRef Sym = G->getGlobal()->getName(); + Function *F = G->getGlobal()->getParent()->getFunction(Sym); + if (F && F->hasFnAttribute("__Mips16RetHelper")) { + SpecialCallingConv = Mips16RetHelperConv; + } + } + } + return SpecialCallingConv; + } + private: /// Identify lowered values that originated from f128 arguments and record /// this for use by RetCC_MipsN. @@ -131,6 +152,10 @@ /// Records whether the value has been lowered from an f128. SmallVector OriginalArgWasF128; + // Used to handle MIPS16-specific calling convention tweaks. + // FIXME: This should probably be a fully fledged calling convention. + SpecialCallingConvType SpecialCallingConv; + public: // FIXME: Remove this from a public inteface ASAP. It's a temporary trap door // to allow analyzeCallOperands to be removed incrementally. @@ -144,8 +169,9 @@ void ClearOriginalArgWasF128() { OriginalArgWasF128.clear(); } MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, - SmallVectorImpl &locs, LLVMContext &C) - : CCState(CC, isVarArg, MF, locs, C) {} + SmallVectorImpl &locs, LLVMContext &C, + SpecialCallingConvType SpecialCC = NoSpecialCallingConv) + : CCState(CC, isVarArg, MF, locs, C), SpecialCallingConv(SpecialCC) {} void AnalyzeFormalArguments(const SmallVectorImpl &Ins, CCAssignFn Fn) { @@ -178,6 +204,7 @@ } bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; } + SpecialCallingConvType getSpecialCallingConv() { return SpecialCallingConv; } }; } @@ -2588,12 +2615,13 @@ // Analyze operands of the call, assigning locations to each operand. SmallVector ArgLocs; - MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, - *DAG.getContext()); + MipsCCState CCInfo( + CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, *DAG.getContext(), + MipsCCState::getSpecialCallingConvForCallee(Callee.getNode(), Subtarget)); MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo); CCInfo.PreAnalyzeCallOperandsForF128_(Outs, CLI.getArgs(), Callee.getNode()); - MipsCCInfo.analyzeCallOperands(Outs, Callee.getNode(), CLI.getArgs(), CCInfo); + MipsCCInfo.analyzeCallOperands(Outs, CLI.getArgs(), CCInfo); CCInfo.ClearOriginalArgWasF128(); // Get a count of how many bytes are to be pushed on the stack. @@ -3572,23 +3600,6 @@ return (ES && Ty->isIntegerTy(128) && isF128SoftLibCall(ES->getSymbol())); } -MipsTargetLowering::MipsCC::SpecialCallingConvType -MipsTargetLowering::MipsCC::getSpecialCallingConv(const SDNode *Callee) const { - MipsCC::SpecialCallingConvType SpecialCallingConv = - MipsCC::NoSpecialCallingConv; - if (Subtarget.inMips16HardFloat()) { - if (const GlobalAddressSDNode *G = - dyn_cast(Callee)) { - llvm::StringRef Sym = G->getGlobal()->getName(); - Function *F = G->getGlobal()->getParent()->getFunction(Sym); - if (F && F->hasFnAttribute("__Mips16RetHelper")) { - SpecialCallingConv = MipsCC::Mips16RetHelperConv; - } - } - } - return SpecialCallingConv; -} - MipsTargetLowering::MipsCC::MipsCC(CallingConv::ID CC, const MipsSubtarget &Subtarget_, CCState &Info) @@ -3598,18 +3609,12 @@ } void MipsTargetLowering::MipsCC::analyzeCallOperands( - const SmallVectorImpl &Args, const SDNode *CallNode, + const SmallVectorImpl &Args, std::vector &FuncArgs, CCState &State) { - MipsCC::SpecialCallingConvType SpecialCallingConv = - getSpecialCallingConv(CallNode); assert((CallConv != CallingConv::Fast || !State.isVarArg()) && "CallingConv::Fast shouldn't be used for vararg functions."); unsigned NumOpnds = Args.size(); - llvm::CCAssignFn *FixedFn = CC_Mips_FixedArg; - if (CallConv != CallingConv::Fast && - SpecialCallingConv == Mips16RetHelperConv) - FixedFn = CC_Mips16RetHelper; for (unsigned I = 0; I != NumOpnds; ++I) { MVT ArgVT = Args[I].VT; @@ -3619,7 +3624,7 @@ if (State.isVarArg() && !Args[I].IsFixed) R = CC_Mips_VarArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); else - R = FixedFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); + R = CC_Mips_FixedArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); if (R) { #ifndef NDEBUG