forked from OSchip/llvm-project
[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 llvm-svn: 221056
This commit is contained in:
parent
7cbf58af15
commit
eac09608d0
|
@ -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<MipsCCState *>(&State)->WasOriginalArgF128(ValNo)",
|
||||
CCBitConvertToType<f64>>>>,
|
||||
|
||||
CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_Mips_FastCC>>,
|
||||
|
||||
// FIXME: There wasn't an EABI case in the original code and it seems unlikely
|
||||
|
|
|
@ -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<ISD::OutputArg> &Outs,
|
||||
std::vector<TargetLowering::ArgListEntry> &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<ISD::InputArg> &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<bool, 4> 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<ISD::OutputArg> &Outs,
|
||||
std::vector<TargetLowering::ArgListEntry> &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<ISD::InputArg> &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<CCValAssign> &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<CCValAssign, 16> 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<CCValAssign, 16> 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<ISD::InputArg> &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
|
||||
|
|
|
@ -366,7 +366,6 @@ namespace llvm {
|
|||
CCState &State);
|
||||
void analyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
bool IsSoftFloat,
|
||||
Function::const_arg_iterator FuncArg,
|
||||
CCState &State);
|
||||
|
||||
/// hasByValArg - Returns true if function has byval arguments.
|
||||
|
|
Loading…
Reference in New Issue