From 61d2d3d2457554575ca00638c46db8dce5b0e158 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Sat, 1 Nov 2014 18:38:03 +0000 Subject: [PATCH] [mips] Move F128 argument handling into MipsCCState as we did for returns. NFC. Summary: There are a couple more changes to make before analyzeFormalArguments can be merged into the standard AnalyzeFormalArguments. I've had to temporarily poke a couple holes in MipsCCState's encapsulation to save having to make all the required changes for this merge all at once*. These will be removed shortly. * We must merge our ByVal argument handling with the implementation in CCState. This will be done over the next three patches, then the fourth will merge analyzeFormalArguments with AnalyzeFormalArguments. Depends on D5967 Reviewers: vmedic Reviewed By: vmedic Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D5969 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221056 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsCallingConv.td | 15 ++++ lib/Target/Mips/MipsISelLowering.cpp | 101 ++++++++++++++++++++------- lib/Target/Mips/MipsISelLowering.h | 1 - 3 files changed, 90 insertions(+), 27 deletions(-) diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td index a2130bb67a0..ae1b01b4019 100644 --- a/lib/Target/Mips/MipsCallingConv.td +++ b/lib/Target/Mips/MipsCallingConv.td @@ -298,6 +298,21 @@ def RetCC_Mips : CallingConv<[ ]>; def CC_Mips_FixedArg : CallingConv<[ + // f128 needs to be handled similarly to f32 and f64 on hard-float. 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. We therefore resort to a + // pre-analyze (see PreAnalyzeFormalArgsForF128()) step to pass information on + // whether the argument 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], + CCIfSubtargetNot<"abiUsesSoftFloat()", + CCIf<"static_cast(&State)->WasOriginalArgF128(ValNo)", + CCBitConvertToType>>>, + CCIfCC<"CallingConv::Fast", CCDelegateTo>, // FIXME: There wasn't an EABI case in the original code and it seems unlikely diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 8bc216021ad..5b87111d5ad 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -95,10 +95,52 @@ private: originalTypeIsF128(MF.getFunction()->getReturnType(), nullptr)); } + /// Identify lowered values that originated from f128 arguments and record + /// this. + void PreAnalyzeCallOperandsForF128( + const SmallVectorImpl &Outs, + std::vector &FuncArgs, SDNode *CallNode) { + const MachineFunction &MF = getMachineFunction(); + for (unsigned i = 0; i < Outs.size(); ++i) + OriginalArgWasF128.push_back( + originalTypeIsF128(FuncArgs[Outs[i].OrigArgIndex].Ty, CallNode)); + } + + /// Identify lowered values that originated from f128 arguments and record + /// this. + void + PreAnalyzeFormalArgumentsForF128(const SmallVectorImpl &Ins) { + const MachineFunction &MF = getMachineFunction(); + for (unsigned i = 0; i < Ins.size(); ++i) { + Function::const_arg_iterator FuncArg = MF.getFunction()->arg_begin(); + std::advance(FuncArg, Ins[i].OrigArgIndex); + + OriginalArgWasF128.push_back( + originalTypeIsF128(FuncArg->getType(), nullptr)); + } + } + /// Records whether the value has been lowered from an f128. SmallVector OriginalArgWasF128; public: + // FIXME: Remove this from a public inteface ASAP. It's a temporary trap door + // to allow analyzeCallOperands to be removed incrementally. + void PreAnalyzeCallOperandsForF128_( + const SmallVectorImpl &Outs, + std::vector &FuncArgs, SDNode *CallNode) { + PreAnalyzeCallOperandsForF128(Outs, FuncArgs, CallNode); + } + // FIXME: Remove this from a public inteface ASAP. It's a temporary trap door + // to allow analyzeFormalArguments to be removed incrementally. + void + PreAnalyzeFormalArgumentsForF128_(const SmallVectorImpl &Ins) { + PreAnalyzeFormalArgumentsForF128(Ins); + } + // FIXME: Remove this from a public inteface ASAP. It's a temporary trap door + // to clean up after the above functions. + void ClearOriginalArgWasF128() { OriginalArgWasF128.clear(); } + MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, SmallVectorImpl &locs, LLVMContext &C) : CCState(CC, isVarArg, MF, locs, C) {} @@ -2546,12 +2588,14 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // Analyze operands of the call, assigning locations to each operand. SmallVector ArgLocs; - CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, - *DAG.getContext()); + MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, + *DAG.getContext()); MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo); + CCInfo.PreAnalyzeCallOperandsForF128_(Outs, CLI.getArgs(), Callee.getNode()); MipsCCInfo.analyzeCallOperands(Outs, IsVarArg, Subtarget.abiUsesSoftFloat(), Callee.getNode(), CLI.getArgs(), CCInfo); + CCInfo.ClearOriginalArgWasF128(); // Get a count of how many bytes are to be pushed on the stack. unsigned NextStackOffset = CCInfo.getNextStackOffset(); @@ -2632,6 +2676,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, } } break; + case CCValAssign::BCvt: + Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg); + break; case CCValAssign::SExt: Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, LocVT, Arg); break; @@ -2829,14 +2876,16 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // Assign locations to all of the incoming arguments. SmallVector ArgLocs; - CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, - *DAG.getContext()); + MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, + *DAG.getContext()); MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo); Function::const_arg_iterator FuncArg = DAG.getMachineFunction().getFunction()->arg_begin(); bool UseSoftFloat = Subtarget.abiUsesSoftFloat(); - MipsCCInfo.analyzeFormalArguments(Ins, UseSoftFloat, FuncArg, CCInfo); + CCInfo.PreAnalyzeFormalArgumentsForF128_(Ins); + MipsCCInfo.analyzeFormalArguments(Ins, UseSoftFloat, CCInfo); + CCInfo.ClearOriginalArgWasF128(); MipsFI->setFormalArgInfo(CCInfo.getNextStackOffset(), MipsCCInfo.hasByValArg()); @@ -2875,16 +2924,24 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // If this is an 8 or 16-bit value, it has been passed promoted // to 32 bits. Insert an assert[sz]ext to capture this, then // truncate to the right size. - if (VA.getLocInfo() != CCValAssign::Full) { - unsigned Opcode = 0; - if (VA.getLocInfo() == CCValAssign::SExt) - Opcode = ISD::AssertSext; - else if (VA.getLocInfo() == CCValAssign::ZExt) - Opcode = ISD::AssertZext; - if (Opcode) - ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue, - DAG.getValueType(ValVT)); + switch (VA.getLocInfo()) { + default: + llvm_unreachable("Unknown loc info!"); + case CCValAssign::Full: + break; + case CCValAssign::SExt: + ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue, + DAG.getValueType(ValVT)); + ArgValue = DAG.getNode(ISD::TRUNCATE, DL, ValVT, ArgValue); + break; + case CCValAssign::ZExt: + ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue, + DAG.getValueType(ValVT)); ArgValue = DAG.getNode(ISD::TRUNCATE, DL, ValVT, ArgValue); + break; + case CCValAssign::BCvt: + ArgValue = DAG.getNode(ISD::BITCAST, DL, ValVT, ArgValue); + break; } // Handle floating point arguments passed in integer registers and @@ -3563,11 +3620,8 @@ void MipsTargetLowering::MipsCC::analyzeCallOperands( if (IsVarArg && !Args[I].IsFixed) R = CC_Mips_VarArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); - else { - MVT RegVT = getRegVT(ArgVT, FuncArgs[Args[I].OrigArgIndex].Ty, CallNode, - IsSoftFloat); - R = FixedFn(I, ArgVT, RegVT, CCValAssign::Full, ArgFlags, State); - } + else + R = FixedFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); if (R) { #ifndef NDEBUG @@ -3581,24 +3635,19 @@ void MipsTargetLowering::MipsCC::analyzeCallOperands( void MipsTargetLowering::MipsCC::analyzeFormalArguments( const SmallVectorImpl &Args, bool IsSoftFloat, - Function::const_arg_iterator FuncArg, CCState &State) { + CCState &State) { unsigned NumArgs = Args.size(); - unsigned CurArgIdx = 0; for (unsigned I = 0; I != NumArgs; ++I) { MVT ArgVT = Args[I].VT; ISD::ArgFlagsTy ArgFlags = Args[I].Flags; - std::advance(FuncArg, Args[I].OrigArgIndex - CurArgIdx); - CurArgIdx = Args[I].OrigArgIndex; if (ArgFlags.isByVal()) { handleByValArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State); continue; } - MVT RegVT = getRegVT(ArgVT, FuncArg->getType(), nullptr, IsSoftFloat); - - if (!CC_Mips_FixedArg(I, ArgVT, RegVT, CCValAssign::Full, ArgFlags, State)) + if (!CC_Mips_FixedArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State)) continue; #ifndef NDEBUG diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 1b4872528d4..3c7d683c771 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -366,7 +366,6 @@ namespace llvm { CCState &State); void analyzeFormalArguments(const SmallVectorImpl &Ins, bool IsSoftFloat, - Function::const_arg_iterator FuncArg, CCState &State); /// hasByValArg - Returns true if function has byval arguments. -- 2.34.1