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) {}
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
- CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
- *DAG.getContext());
- MipsCC::SpecialCallingConvType SpecialCallingConv =
- getSpecialCallingConv(Callee);
- MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo, SpecialCallingConv);
+ MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
+ *DAG.getContext());
+ MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo);
- MipsCCInfo.analyzeCallOperands(Outs, IsVarArg,
- Subtarget.abiUsesSoftFloat(),
- Callee.getNode(), CLI.getArgs());
+ 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();
}
}
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;
// 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.PreAnalyzeFormalArgumentsForF128_(Ins);
+ MipsCCInfo.analyzeFormalArguments(Ins, UseSoftFloat, CCInfo);
+ CCInfo.ClearOriginalArgWasF128();
MipsFI->setFormalArgInfo(CCInfo.getNextStackOffset(),
MipsCCInfo.hasByValArg());
// 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
}
if (IsVarArg)
- writeVarArgRegs(OutChains, MipsCCInfo, Chain, DL, DAG);
+ writeVarArgRegs(OutChains, MipsCCInfo, Chain, DL, DAG, CCInfo);
// All stores are grouped in one node to allow the matching between
// the size of Ins and InVals. This only happens when on varg functions
}
MipsTargetLowering::MipsCC::SpecialCallingConvType
- MipsTargetLowering::getSpecialCallingConv(SDValue Callee) const {
+MipsTargetLowering::MipsCC::getSpecialCallingConv(const SDNode *Callee) const {
MipsCC::SpecialCallingConvType SpecialCallingConv =
MipsCC::NoSpecialCallingConv;
if (Subtarget.inMips16HardFloat()) {
- if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ if (const GlobalAddressSDNode *G =
+ dyn_cast<const GlobalAddressSDNode>(Callee)) {
llvm::StringRef Sym = G->getGlobal()->getName();
Function *F = G->getGlobal()->getParent()->getFunction(Sym);
if (F && F->hasFnAttribute("__Mips16RetHelper")) {
return SpecialCallingConv;
}
-MipsTargetLowering::MipsCC::MipsCC(
- CallingConv::ID CC, const MipsSubtarget &Subtarget_, CCState &Info,
- MipsCC::SpecialCallingConvType SpecialCallingConv_)
- : CCInfo(Info), CallConv(CC), Subtarget(Subtarget_),
- SpecialCallingConv(SpecialCallingConv_) {
+MipsTargetLowering::MipsCC::MipsCC(CallingConv::ID CC,
+ const MipsSubtarget &Subtarget_,
+ CCState &Info)
+ : CallConv(CC), Subtarget(Subtarget_) {
// Pre-allocate reserved argument area.
- CCInfo.AllocateStack(reservedArgArea(), 1);
+ Info.AllocateStack(reservedArgArea(), 1);
}
-
-void MipsTargetLowering::MipsCC::
-analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Args,
- bool IsVarArg, bool IsSoftFloat, const SDNode *CallNode,
- std::vector<ArgListEntry> &FuncArgs) {
+void MipsTargetLowering::MipsCC::analyzeCallOperands(
+ const SmallVectorImpl<ISD::OutputArg> &Args, bool IsVarArg,
+ bool IsSoftFloat, const SDNode *CallNode,
+ std::vector<ArgListEntry> &FuncArgs, CCState &State) {
+ MipsCC::SpecialCallingConvType SpecialCallingConv =
+ getSpecialCallingConv(CallNode);
assert((CallConv != CallingConv::Fast || !IsVarArg) &&
"CallingConv::Fast shouldn't be used for vararg functions.");
unsigned NumOpnds = Args.size();
- llvm::CCAssignFn *FixedFn = fixedArgFn(), *VarFn = varArgFn();
+ llvm::CCAssignFn *FixedFn = CC_Mips_FixedArg;
+ if (CallConv != CallingConv::Fast &&
+ SpecialCallingConv == Mips16RetHelperConv)
+ FixedFn = CC_Mips16RetHelper;
for (unsigned I = 0; I != NumOpnds; ++I) {
MVT ArgVT = Args[I].VT;
bool R;
if (ArgFlags.isByVal()) {
- handleByValArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags);
+ handleByValArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State);
continue;
}
if (IsVarArg && !Args[I].IsFixed)
- R = VarFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo);
- else {
- MVT RegVT = getRegVT(ArgVT, FuncArgs[Args[I].OrigArgIndex].Ty, CallNode,
- IsSoftFloat);
- R = FixedFn(I, ArgVT, RegVT, CCValAssign::Full, ArgFlags, CCInfo);
- }
+ R = CC_Mips_VarArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State);
+ else
+ R = FixedFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State);
if (R) {
#ifndef NDEBUG
}
}
-void MipsTargetLowering::MipsCC::
-analyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Args,
- bool IsSoftFloat, Function::const_arg_iterator FuncArg) {
+void MipsTargetLowering::MipsCC::analyzeFormalArguments(
+ const SmallVectorImpl<ISD::InputArg> &Args, bool IsSoftFloat,
+ CCState &State) {
unsigned NumArgs = Args.size();
- llvm::CCAssignFn *FixedFn = fixedArgFn();
- 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);
+ handleByValArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State);
continue;
}
- MVT RegVT = getRegVT(ArgVT, FuncArg->getType(), nullptr, IsSoftFloat);
-
- if (!FixedFn(I, ArgVT, RegVT, CCValAssign::Full, ArgFlags, CCInfo))
+ if (!CC_Mips_FixedArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State))
continue;
#ifndef NDEBUG
void MipsTargetLowering::MipsCC::handleByValArg(unsigned ValNo, MVT ValVT,
MVT LocVT,
CCValAssign::LocInfo LocInfo,
- ISD::ArgFlagsTy ArgFlags) {
+ ISD::ArgFlagsTy ArgFlags,
+ CCState &State) {
assert(ArgFlags.getByValSize() && "Byval argument's size shouldn't be 0.");
struct ByValArgInfo ByVal;
RegSizeInBytes * 2);
if (useRegsForByval())
- allocateRegs(ByVal, ByValSize, Align);
+ allocateRegs(ByVal, ByValSize, Align, State);
// Allocate space on caller's stack.
ByVal.Address =
- CCInfo.AllocateStack(ByValSize - RegSizeInBytes * ByVal.NumRegs, Align);
- CCInfo.addLoc(CCValAssign::getMem(ValNo, ValVT, ByVal.Address, LocVT,
- LocInfo));
+ State.AllocateStack(ByValSize - RegSizeInBytes * ByVal.NumRegs, Align);
+ State.addLoc(
+ CCValAssign::getMem(ValNo, ValVT, ByVal.Address, LocVT, LocInfo));
ByValArgs.push_back(ByVal);
}
return makeArrayRef(Mips64IntRegs);
}
-llvm::CCAssignFn *MipsTargetLowering::MipsCC::fixedArgFn() const {
- if (CallConv == CallingConv::Fast)
- return CC_Mips_FastCC;
-
- if (SpecialCallingConv == Mips16RetHelperConv)
- return CC_Mips16RetHelper;
- return Subtarget.isABI_O32()
- ? (Subtarget.isFP64bit() ? CC_MipsO32_FP64 : CC_MipsO32_FP32)
- : CC_MipsN;
-}
-
-llvm::CCAssignFn *MipsTargetLowering::MipsCC::varArgFn() const {
- return Subtarget.isABI_O32()
- ? (Subtarget.isFP64bit() ? CC_MipsO32_FP64 : CC_MipsO32_FP32)
- : CC_MipsN_VarArg;
-}
-
const MCPhysReg *MipsTargetLowering::MipsCC::shadowRegs() const {
return Subtarget.isABI_O32() ? O32IntRegs : Mips64DPRegs;
}
void MipsTargetLowering::MipsCC::allocateRegs(ByValArgInfo &ByVal,
unsigned ByValSize,
- unsigned Align) {
+ unsigned Align, CCState &State) {
unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
const ArrayRef<MCPhysReg> IntArgRegs = intArgRegs();
const MCPhysReg *ShadowRegs = shadowRegs();
"RegSizeInBytes.");
ByVal.FirstIdx =
- CCInfo.getFirstUnallocated(IntArgRegs.data(), IntArgRegs.size());
+ State.getFirstUnallocated(IntArgRegs.data(), IntArgRegs.size());
// If Align > RegSizeInBytes, the first arg register must be even.
if ((Align > RegSizeInBytes) && (ByVal.FirstIdx % 2)) {
- CCInfo.AllocateReg(IntArgRegs[ByVal.FirstIdx], ShadowRegs[ByVal.FirstIdx]);
+ State.AllocateReg(IntArgRegs[ByVal.FirstIdx], ShadowRegs[ByVal.FirstIdx]);
++ByVal.FirstIdx;
}
// Mark the registers allocated.
for (unsigned I = ByVal.FirstIdx; ByValSize && (I < IntArgRegs.size());
ByValSize -= RegSizeInBytes, ++I, ++ByVal.NumRegs)
- CCInfo.AllocateReg(IntArgRegs[I], ShadowRegs[I]);
+ State.AllocateReg(IntArgRegs[I], ShadowRegs[I]);
}
MVT MipsTargetLowering::MipsCC::getRegVT(MVT VT, const Type *OrigTy,
void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,
const MipsCC &CC, SDValue Chain,
- SDLoc DL, SelectionDAG &DAG) const {
+ SDLoc DL, SelectionDAG &DAG,
+ CCState &State) const {
const ArrayRef<MCPhysReg> ArgRegs = CC.intArgRegs();
- const CCState &CCInfo = CC.getCCInfo();
- unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs.data(), ArgRegs.size());
+ unsigned Idx = State.getFirstUnallocated(ArgRegs.data(), ArgRegs.size());
unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();
MVT RegTy = MVT::getIntegerVT(RegSizeInBytes * 8);
const TargetRegisterClass *RC = getRegClassFor(RegTy);
if (ArgRegs.size() == Idx)
VaArgOffset =
- RoundUpToAlignment(CCInfo.getNextStackOffset(), RegSizeInBytes);
+ RoundUpToAlignment(State.getNextStackOffset(), RegSizeInBytes);
else
VaArgOffset = (int)CC.reservedArgArea() -
(int)(RegSizeInBytes * (ArgRegs.size() - Idx));