diff --git a/lib/Target/Mips/MipsABIInfo.cpp b/lib/Target/Mips/MipsABIInfo.cpp index 04a8e3252ba..f885369845e 100644 --- a/lib/Target/Mips/MipsABIInfo.cpp +++ b/lib/Target/Mips/MipsABIInfo.cpp @@ -35,3 +35,11 @@ const ArrayRef MipsABIInfo::GetVarArgRegs() const { return makeArrayRef(Mips64IntRegs); llvm_unreachable("Unhandled ABI"); } + +unsigned MipsABIInfo::GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const { + if (IsO32()) + return CC != CallingConv::Fast ? 16 : 0; + if (IsN32() || IsN64() || IsEABI()) + return 0; + llvm_unreachable("Unhandled ABI"); +} diff --git a/lib/Target/Mips/MipsABIInfo.h b/lib/Target/Mips/MipsABIInfo.h index a3b3cb973cc..bea585e41bd 100644 --- a/lib/Target/Mips/MipsABIInfo.h +++ b/lib/Target/Mips/MipsABIInfo.h @@ -12,6 +12,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/IR/CallingConv.h" namespace llvm { @@ -44,6 +45,10 @@ public: /// The registers to use for the variable argument list. const ArrayRef GetVarArgRegs() const; + /// Obtain the size of the area allocated by the callee for arguments. + /// CallingConv::FastCall affects the value for O32. + unsigned GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const; + /// Ordering of ABI's /// MipsGenSubtargetInfo.inc will use this to resolve conflicts when given /// multiple ABI options. diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 9aac8e19ad2..27fb5e4ec40 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2791,7 +2791,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, "ByVal args of size 0 should have been ignored by front-end."); assert(ByValIdx < CCInfo.getInRegsParamsCount()); copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg, - MipsCCInfo, FirstByValReg, LastByValReg, VA); + MipsCCInfo, FirstByValReg, LastByValReg, VA, CCInfo); CCInfo.nextInRegsParam(); continue; } @@ -3414,18 +3414,14 @@ MipsTargetLowering::MipsCC::MipsCC(CallingConv::ID CC, CCState &Info) : CallConv(CC), Subtarget(Subtarget_) { // Pre-allocate reserved argument area. - Info.AllocateStack(reservedArgArea(), 1); -} - -unsigned MipsTargetLowering::MipsCC::reservedArgArea() const { - return (Subtarget.isABI_O32() && (CallConv != CallingConv::Fast)) ? 16 : 0; + Info.AllocateStack(Subtarget.getABI().GetCalleeAllocdArgSizeInBytes(CC), 1); } void MipsTargetLowering::copyByValRegs( SDValue Chain, SDLoc DL, std::vector &OutChains, SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags, SmallVectorImpl &InVals, const Argument *FuncArg, const MipsCC &CC, unsigned FirstReg, - unsigned LastReg, const CCValAssign &VA) const { + unsigned LastReg, const CCValAssign &VA, MipsCCState &State) const { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); unsigned GPRSizeInBytes = Subtarget.getGPRSizeInBytes(); @@ -3433,11 +3429,13 @@ void MipsTargetLowering::copyByValRegs( unsigned RegAreaSize = NumRegs * GPRSizeInBytes; unsigned FrameObjSize = std::max(Flags.getByValSize(), RegAreaSize); int FrameObjOffset; - ArrayRef ByValArgRegs = Subtarget.getABI().GetByValArgRegs(); + const MipsABIInfo &ABI = Subtarget.getABI(); + ArrayRef ByValArgRegs = ABI.GetByValArgRegs(); if (RegAreaSize) - FrameObjOffset = (int)CC.reservedArgArea() - - (int)((ByValArgRegs.size() - FirstReg) * GPRSizeInBytes); + FrameObjOffset = + (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) - + (int)((ByValArgRegs.size() - FirstReg) * GPRSizeInBytes); else FrameObjOffset = VA.getLocMemOffset(); @@ -3581,9 +3579,12 @@ void MipsTargetLowering::writeVarArgRegs(std::vector &OutChains, if (ArgRegs.size() == Idx) VaArgOffset = RoundUpToAlignment(State.getNextStackOffset(), RegSizeInBytes); - else - VaArgOffset = (int)CC.reservedArgArea() - - (int)(RegSizeInBytes * (ArgRegs.size() - Idx)); + else { + const MipsABIInfo &ABI = Subtarget.getABI(); + VaArgOffset = + (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) - + (int)(RegSizeInBytes * (ArgRegs.size() - Idx)); + } // Record the frame index of the first variable argument // which is a value necessary to VASTART. diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 35d86f5ba30..e7345b2c202 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -210,6 +210,7 @@ namespace llvm { //===--------------------------------------------------------------------===// class MipsFunctionInfo; class MipsSubtarget; + class MipsCCState; class MipsTargetLowering : public TargetLowering { bool isMicroMips; @@ -363,10 +364,6 @@ namespace llvm { MipsCC(CallingConv::ID CallConv, const MipsSubtarget &Subtarget, CCState &Info); - /// reservedArgArea - The size of the area the caller reserves for - /// register arguments. This is 16-byte if ABI is O32. - unsigned reservedArgArea() const; - private: CallingConv::ID CallConv; const MipsSubtarget &Subtarget; @@ -446,7 +443,7 @@ namespace llvm { SmallVectorImpl &InVals, const Argument *FuncArg, const MipsCC &CC, unsigned FirstReg, unsigned LastReg, - const CCValAssign &VA) const; + const CCValAssign &VA, MipsCCState &State) const; /// passByValArg - Pass a byval argument in registers or on stack. void passByValArg(SDValue Chain, SDLoc DL,