[PowerPC][AIX] Implement formal arguments passed in stack memory.

This patch is the callee side counterpart for https://reviews.llvm.org/D73209.
It removes the fatal error when we pass more formal arguments than available
registers.

Differential Revision: https://reviews.llvm.org/D74225
This commit is contained in:
Zarko Todorovski 2020-03-12 11:01:40 -04:00 committed by Sean Fertile
parent 69993350ae
commit d688312660
2 changed files with 1070 additions and 40 deletions

View File

@ -6990,56 +6990,76 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
MachineFunction &MF = DAG.getMachineFunction();
CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.getContext());
const EVT PtrVT = getPointerTy(MF.getDataLayout());
// Reserve space for the linkage area on the stack.
const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
// On AIX a minimum of 8 words is saved to the parameter save area.
const unsigned MinParameterSaveArea = 8 * PtrByteSize;
CCInfo.AllocateStack(LinkageSize + MinParameterSaveArea, PtrByteSize);
CCInfo.AllocateStack(LinkageSize, PtrByteSize);
CCInfo.AnalyzeFormalArguments(Ins, CC_AIX);
for (CCValAssign &VA : ArgLocs) {
EVT ValVT = VA.getValVT();
MVT LocVT = VA.getLocVT();
ISD::ArgFlagsTy Flags = Ins[VA.getValNo()].Flags;
assert(!Flags.isByVal() &&
"Passing structure by value is unimplemented for formal arguments.");
assert((VA.isRegLoc() || VA.isMemLoc()) &&
"Unexpected location for function call argument.");
if (VA.isMemLoc()) {
// For compatibility with the AIX XL compiler, the float args in the
// parameter save area are initialized even if the argument is available
// in register. The caller is required to initialize both the register
// and memory, however, the callee can choose to expect it in either. The
// memloc is dismissed here because the argument is retrieved from the
// register.
if (VA.needsCustom())
// and memory, however, the callee can choose to expect it in either.
// The memloc is dismissed here because the argument is retrieved from
// the register.
if (VA.isMemLoc() && VA.needsCustom())
continue;
report_fatal_error(
"Handling of formal arguments on the stack is unimplemented!");
}
assert(VA.isRegLoc() && "Unexpected argument location.");
EVT ValVT = VA.getValVT();
MVT LocVT = VA.getLocVT();
if (VA.isRegLoc()) {
MVT::SimpleValueType SVT = ValVT.getSimpleVT().SimpleTy;
unsigned VReg =
MF.addLiveIn(VA.getLocReg(), getRegClassForSVT(SVT, IsPPC64));
SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, LocVT);
if (ValVT.isScalarInteger() &&
(ValVT.getSizeInBits() < LocVT.getSizeInBits())) {
ISD::ArgFlagsTy Flags = Ins[VA.getValNo()].Flags;
ArgValue =
truncateScalarIntegerArg(Flags, ValVT, DAG, ArgValue, LocVT, dl);
}
InVals.push_back(ArgValue);
continue;
}
const unsigned LocSize = LocVT.getStoreSize();
const unsigned ValSize = ValVT.getStoreSize();
assert((ValSize <= LocSize) && "Object size is larger than size of MemLoc");
int CurArgOffset = VA.getLocMemOffset();
// Objects are right-justified because AIX is big-endian.
if (LocSize > ValSize)
CurArgOffset += LocSize - ValSize;
MachineFrameInfo &MFI = MF.getFrameInfo();
// Potential tail calls could cause overwriting of argument stack slots.
const bool IsImmutable =
!(getTargetMachine().Options.GuaranteedTailCallOpt &&
(CallConv == CallingConv::Fast));
int FI = MFI.CreateFixedObject(ValSize, CurArgOffset, IsImmutable);
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
SDValue ArgValue = DAG.getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
InVals.push_back(ArgValue);
}
// On AIX a minimum of 8 words is saved to the parameter save area.
const unsigned MinParameterSaveArea = 8 * PtrByteSize;
// Area that is at least reserved in the caller of this function.
unsigned MinReservedArea = CCInfo.getNextStackOffset();
unsigned CallerReservedArea =
std::max(CCInfo.getNextStackOffset(), LinkageSize + MinParameterSaveArea);
// Set the size that is at least reserved in caller of this function. Tail
// call optimized function's reserved stack space needs to be aligned so
// that taking the difference between two stack areas will result in an
// aligned stack.
MinReservedArea =
EnsureStackAlignment(Subtarget.getFrameLowering(), MinReservedArea);
CallerReservedArea =
EnsureStackAlignment(Subtarget.getFrameLowering(), CallerReservedArea);
PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
FuncInfo->setMinReservedArea(MinReservedArea);
FuncInfo->setMinReservedArea(CallerReservedArea);
return Chain;
}

File diff suppressed because it is too large Load Diff