Author: dsanders Date: Mon Dec 1 07:55:59 2014 New Revision: 223019 URL: http://llvm.org/viewvc/llvm-project?rev=223019&view=rev Log: Merged from r218509:
[mips] Generalize the handling of f128 return values to support f128 arguments. Summary: This will allow us to handle f128 arguments without duplicating code from CCState::AnalyzeFormalArguments() or CCState::AnalyzeCallOperands(). No functional change. Reviewers: vmedic Reviewed By: vmedic Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D5292 Modified: llvm/branches/release_35/lib/Target/Mips/MipsCallingConv.td llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.cpp llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.h Modified: llvm/branches/release_35/lib/Target/Mips/MipsCallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_35/lib/Target/Mips/MipsCallingConv.td?rev=223019&r1=223018&r2=223019&view=diff ============================================================================== --- llvm/branches/release_35/lib/Target/Mips/MipsCallingConv.td (original) +++ llvm/branches/release_35/lib/Target/Mips/MipsCallingConv.td Mon Dec 1 07:55:59 2014 @@ -20,6 +20,27 @@ class CCIfSubtarget<string F, CCAction A // The inverse of CCIfSubtarget class CCIfSubtargetNot<string F, CCAction A> : CCIfSubtarget<F, A, "!">; +// 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<f64>, + 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<RetCC_F128SoftFloat>>>, + CCIfSubtargetNot<"abiUsesSoftFloat()", + CCIfType<[i64], CCDelegateTo<RetCC_F128HardFloat>>> +]>; + //===----------------------------------------------------------------------===// // Mips O32 Calling Convention //===----------------------------------------------------------------------===// @@ -92,6 +113,20 @@ def CC_MipsN_VarArg : CallingConv<[ ]>; def RetCC_MipsN : CallingConv<[ + // f128 needs to be handled similarly to f32 and f64. However, f128 is not + // legal and is lowered to i128 which is further lowered to a pair of i64's. + // This presents us with a problem for the calling convention since hard-float + // still needs to pass them in FPU registers, and soft-float needs to use $v0, + // and $a0 instead of the usual $v0, and $v1. We therefore resort to a + // pre-analyze (see PreAnalyzeReturnForF128()) step to pass information on + // whether the result was originally an f128 into the tablegen-erated code. + // + // f128 should only occur for the N64 ABI where long double is 128-bit. On + // N32, long double is equivalent to double. + CCIfType<[i64], + CCIf<"static_cast<MipsCCState *>(&State)->WasOriginalArgF128(ValNo)", + CCDelegateTo<RetCC_F128>>>, + // Aggregate returns are positioned at the lowest address in the slot for // both little and big-endian targets. When passing in registers, this // requires that big-endian targets shift the value into the upper bits. @@ -113,27 +148,6 @@ def RetCC_MipsN : CallingConv<[ CCIfType<[f64], CCAssignToReg<[D0_64, D2_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<f64>, - 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<RetCC_F128SoftFloat>>>, - CCIfSubtargetNot<"abiUsesSoftFloat()", - CCIfType<[i64], CCDelegateTo<RetCC_F128HardFloat>>> -]>; - //===----------------------------------------------------------------------===// // Mips EABI Calling Convention //===----------------------------------------------------------------------===// Modified: llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.cpp?rev=223019&r1=223018&r2=223019&view=diff ============================================================================== --- llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.cpp Mon Dec 1 07:55:59 2014 @@ -70,6 +70,66 @@ static const MCPhysReg Mips64DPRegs[8] = Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64 }; +static bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode); + +namespace { +class MipsCCState : public CCState { +private: + /// Identify lowered values that originated from f128 arguments and record + /// this for use by RetCC_MipsN. + void + PreAnalyzeCallResultForF128(const SmallVectorImpl<ISD::InputArg> &Ins, + const TargetLowering::CallLoweringInfo &CLI) { + const MachineFunction &MF = getMachineFunction(); + for (unsigned i = 0; i < Ins.size(); ++i) + OriginalArgWasF128.push_back( + originalTypeIsF128(CLI.RetTy, CLI.Callee.getNode())); + } + + /// Identify lowered values that originated from f128 arguments and record + /// this for use by RetCC_MipsN. + void PreAnalyzeReturnForF128(const SmallVectorImpl<ISD::OutputArg> &Outs) { + const MachineFunction &MF = getMachineFunction(); + for (unsigned i = 0; i < Outs.size(); ++i) + OriginalArgWasF128.push_back( + originalTypeIsF128(MF.getFunction()->getReturnType(), nullptr)); + } + + /// Records whether the value has been lowered from an f128. + SmallVector<bool, 4> OriginalArgWasF128; + +public: + MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, + const TargetMachine &TM, SmallVectorImpl<CCValAssign> &locs, LLVMContext &C) + : CCState(CC, isVarArg, MF, TM, locs, C) {} + + void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, + CCAssignFn Fn, + const TargetLowering::CallLoweringInfo &CLI) { + PreAnalyzeCallResultForF128(Ins, CLI); + CCState::AnalyzeCallResult(Ins, Fn); + OriginalArgWasF128.clear(); + } + + void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, + CCAssignFn Fn) { + PreAnalyzeReturnForF128(Outs); + CCState::AnalyzeReturn(Outs, Fn); + OriginalArgWasF128.clear(); + } + + bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, + CCAssignFn Fn) { + PreAnalyzeReturnForF128(ArgsFlags); + bool Return = CCState::CheckReturn(ArgsFlags, Fn); + OriginalArgWasF128.clear(); + return Return; + } + + bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; } +}; +} + // If I is a shifted mask, set the size (Size) and the first bit of the // mask (Pos), and return true. // For example, if I is 0x003ff800, (Pos, Size) = (11, 11). @@ -2365,8 +2425,6 @@ static bool CC_MipsO32_FP64(unsigned Val return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State, F64Regs); } -static bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode); - #include "MipsGenCallingConv.inc" //===----------------------------------------------------------------------===// @@ -2661,29 +2719,22 @@ MipsTargetLowering::LowerCall(TargetLowe // Handle result values, copying them out of physregs into vregs that we // return. - return LowerCallResult(Chain, InFlag, CallConv, IsVarArg, - Ins, DL, DAG, InVals, CLI.Callee.getNode(), CLI.RetTy); + return LowerCallResult(Chain, InFlag, CallConv, IsVarArg, Ins, DL, DAG, + InVals, CLI); } /// LowerCallResult - Lower the result values of a call into the /// appropriate copies out of appropriate physical registers. -SDValue -MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, - CallingConv::ID CallConv, bool IsVarArg, - const SmallVectorImpl<ISD::InputArg> &Ins, - SDLoc DL, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals, - const SDNode *CallNode, - const Type *RetTy) const { +SDValue MipsTargetLowering::LowerCallResult( + SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc DL, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals, + TargetLowering::CallLoweringInfo &CLI) const { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), - getTargetMachine(), RVLocs, *DAG.getContext()); - - if (originalTypeIsF128(RetTy, CallNode)) - CCInfo.AnalyzeCallResult(Ins, RetCC_F128); - else - CCInfo.AnalyzeCallResult(Ins, RetCC_Mips); + MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), + getTargetMachine(), RVLocs, *DAG.getContext()); + CCInfo.AnalyzeCallResult(Ins, RetCC_Mips, CLI); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { @@ -2896,8 +2947,8 @@ MipsTargetLowering::CanLowerReturn(Calli const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const { SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CallConv, IsVarArg, MF, getTargetMachine(), - RVLocs, Context); + MipsCCState CCInfo(CallConv, IsVarArg, MF, getTargetMachine(), + RVLocs, Context); return CCInfo.CheckReturn(Outs, RetCC_Mips); } @@ -2913,15 +2964,12 @@ MipsTargetLowering::LowerReturn(SDValue MachineFunction &MF = DAG.getMachineFunction(); // CCState - Info about the registers and stack slot. - CCState CCInfo(CallConv, IsVarArg, MF, getTargetMachine(), RVLocs, - *DAG.getContext()); + MipsCCState CCInfo(CallConv, IsVarArg, MF, getTargetMachine(), RVLocs, + *DAG.getContext()); MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo); // Analyze return values. - if (originalTypeIsF128(MF.getFunction()->getReturnType(), nullptr)) - CCInfo.AnalyzeReturn(Outs, RetCC_F128); - else - CCInfo.AnalyzeReturn(Outs, RetCC_Mips); + CCInfo.AnalyzeReturn(Outs, RetCC_Mips); SDValue Flag; SmallVector<SDValue, 4> RetOps(1, Chain); Modified: llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.h?rev=223019&r1=223018&r2=223019&view=diff ============================================================================== --- llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.h (original) +++ llvm/branches/release_35/lib/Target/Mips/MipsISelLowering.h Mon Dec 1 07:55:59 2014 @@ -449,13 +449,13 @@ namespace llvm { unsigned Flag) const; MipsCC::SpecialCallingConvType getSpecialCallingConv(SDValue Callee) const; + // Lower Operand helpers SDValue LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl<ISD::InputArg> &Ins, - SDLoc dl, SelectionDAG &DAG, - SmallVectorImpl<SDValue> &InVals, - const SDNode *CallNode, const Type *RetTy) const; + const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, + SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, + TargetLowering::CallLoweringInfo &CLI) const; // Lower Operand specifics SDValue lowerBR_JT(SDValue Op, SelectionDAG &DAG) const; _______________________________________________ llvm-branch-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/llvm-branch-commits
