mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-24 13:18:17 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user