#include "llvm/ADT/ArrayRef.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/IR/CallingConv.h"
namespace llvm {
/// The registers to use for the variable argument list.
const ArrayRef<MCPhysReg> 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.
"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;
}
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<SDValue> &OutChains, SelectionDAG &DAG,
const ISD::ArgFlagsTy &Flags, SmallVectorImpl<SDValue> &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();
unsigned RegAreaSize = NumRegs * GPRSizeInBytes;
unsigned FrameObjSize = std::max(Flags.getByValSize(), RegAreaSize);
int FrameObjOffset;
- ArrayRef<MCPhysReg> ByValArgRegs = Subtarget.getABI().GetByValArgRegs();
+ const MipsABIInfo &ABI = Subtarget.getABI();
+ ArrayRef<MCPhysReg> 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();
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.
//===--------------------------------------------------------------------===//
class MipsFunctionInfo;
class MipsSubtarget;
+ class MipsCCState;
class MipsTargetLowering : public TargetLowering {
bool isMicroMips;
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;
SmallVectorImpl<SDValue> &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,