Index: lib/Target/Mips/MipsCallingConv.td =================================================================== --- lib/Target/Mips/MipsCallingConv.td +++ lib/Target/Mips/MipsCallingConv.td @@ -105,10 +105,25 @@ CCIfType<[f64], CCAssignToReg<[D0_64, D2_64]>> ]>; -// In soft-mode, register A0_64, instead of V1_64, is used to return a long -// double value. -def RetCC_F128Soft : CallingConv<[ - CCIfType<[i64], CCAssignToReg<[V0_64, A0_64]>> +// For soft-float, f128 values are returned in A0_64 rather than V1_64. +def RetCC_F128SoftFloat : CallingConv<[ + CCAssignToReg<[V0_64, A0_64]> +]>; + +// For hard-float, f128 values are returned as a pair of f64's rather than a +// pair of i64's. +def RetCC_F128HardFloat : CallingConv<[ + CCBitConvertToType, + CCAssignToReg<[D0_64, D2_64]> +]>; + +// Handle F128 specially since we can't identify the original type during the +// tablegen-erated code. +def RetCC_F128 : CallingConv<[ + CCIfSubtarget<"abiUsesSoftFloat()", + CCIfType<[i64], CCDelegateTo>>, + CCIfNotSubtarget<"abiUsesSoftFloat()", + CCIfType<[i64], CCDelegateTo>> ]>; //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsISelLowering.h =================================================================== --- lib/Target/Mips/MipsISelLowering.h +++ lib/Target/Mips/MipsISelLowering.h @@ -367,13 +367,6 @@ bool IsSoftFloat, Function::const_arg_iterator FuncArg); - void analyzeCallResult(const SmallVectorImpl &Ins, - bool IsSoftFloat, const SDNode *CallNode, - const Type *RetTy) const; - - void analyzeReturn(const SmallVectorImpl &Outs, - bool IsSoftFloat, const Type *RetTy) const; - const CCState &getCCInfo() const { return CCInfo; } /// hasByValArg - Returns true if function has byval arguments. Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -2373,6 +2373,8 @@ return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs); } +static bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode); + #include "MipsGenCallingConv.inc" //===----------------------------------------------------------------------===// @@ -2686,10 +2688,11 @@ SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, *DAG.getContext()); - MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo); - MipsCCInfo.analyzeCallResult(Ins, Subtarget.abiUsesSoftFloat(), - CallNode, RetTy); + if (originalTypeIsF128(RetTy, CallNode)) + CCInfo.AnalyzeCallResult(Ins, RetCC_F128); + else + CCInfo.AnalyzeCallResult(Ins, RetCC_Mips); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { @@ -2886,8 +2889,10 @@ MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo); // Analyze return values. - MipsCCInfo.analyzeReturn(Outs, Subtarget.abiUsesSoftFloat(), - MF.getFunction()->getReturnType()); + if (originalTypeIsF128(MF.getFunction()->getReturnType(), nullptr)) + CCInfo.AnalyzeReturn(Outs, RetCC_F128); + else + CCInfo.AnalyzeReturn(Outs, RetCC_Mips); SDValue Flag; SmallVector RetOps(1, Chain); @@ -3471,44 +3476,6 @@ } } -template -void MipsTargetLowering::MipsCC:: -analyzeReturn(const SmallVectorImpl &RetVals, bool IsSoftFloat, - const SDNode *CallNode, const Type *RetTy) const { - CCAssignFn *Fn; - - if (IsSoftFloat && originalTypeIsF128(RetTy, CallNode)) - Fn = RetCC_F128Soft; - else - Fn = RetCC_Mips; - - for (unsigned I = 0, E = RetVals.size(); I < E; ++I) { - MVT VT = RetVals[I].VT; - ISD::ArgFlagsTy Flags = RetVals[I].Flags; - MVT RegVT = this->getRegVT(VT, RetTy, CallNode, IsSoftFloat); - - if (Fn(I, VT, RegVT, CCValAssign::Full, Flags, this->CCInfo)) { -#ifndef NDEBUG - dbgs() << "Call result #" << I << " has unhandled type " - << EVT(VT).getEVTString() << '\n'; -#endif - llvm_unreachable(nullptr); - } - } -} - -void MipsTargetLowering::MipsCC:: -analyzeCallResult(const SmallVectorImpl &Ins, bool IsSoftFloat, - const SDNode *CallNode, const Type *RetTy) const { - analyzeReturn(Ins, IsSoftFloat, CallNode, RetTy); -} - -void MipsTargetLowering::MipsCC:: -analyzeReturn(const SmallVectorImpl &Outs, bool IsSoftFloat, - const Type *RetTy) const { - analyzeReturn(Outs, IsSoftFloat, nullptr, RetTy); -} - void MipsTargetLowering::MipsCC::handleByValArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo,