[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:
Daniel Sanders 2014-11-01 18:38:03 +00:00
parent 7cbf58af15
commit eac09608d0
3 changed files with 90 additions and 27 deletions

View File

@ -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

View File

@ -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

View File

@ -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.