Merged from r221056:

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

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/branches/release_35@223034 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Sanders
2014-12-01 15:24:14 +00:00
parent 3c7ce872b2
commit 83eda6b665
3 changed files with 90 additions and 27 deletions
+15
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
+75 -26
View File
@@ -94,10 +94,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,
const TargetMachine &TM, SmallVectorImpl<CCValAssign> &locs, LLVMContext &C)
: CCState(CC, isVarArg, MF, TM, locs, C) {}
@@ -2531,12 +2573,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(),
getTargetMachine(), ArgLocs, *DAG.getContext());
MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
getTargetMachine(), 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();
@@ -2617,6 +2661,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;
@@ -2808,14 +2855,16 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
getTargetMachine(), ArgLocs, *DAG.getContext());
MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
getTargetMachine(), 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());
@@ -2854,16 +2903,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
@@ -3543,11 +3600,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
@@ -3561,24 +3615,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
-1
View File
@@ -365,7 +365,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.