Modify LowerFormalArguments to correctly handle vaarg arguments for Mips64.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144552 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka
2011-11-14 19:01:09 +00:00
parent a3f7e229b6
commit bad53f41c2

View File

@ -2621,24 +2621,40 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
} }
if (isVarArg && IsO32) { if (isVarArg) {
unsigned NumOfRegs = IsO32 ? 4 : 8;
const unsigned *ArgRegs = IsO32 ? O32IntRegs : Mips64IntRegs;
unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs, NumOfRegs);
int FirstRegSlotOffset = IsO32 ? 0 : -64 ; // offset of $a0's slot.
TargetRegisterClass *RC
= IsO32 ? Mips::CPURegsRegisterClass : Mips::CPU64RegsRegisterClass;
unsigned RegSize = RC->getSize();
int RegSlotOffset = FirstRegSlotOffset + Idx * RegSize;
// Offset of the first variable argument from stack pointer.
int FirstVaArgOffset;
if (IsO32 || (Idx == NumOfRegs)) {
FirstVaArgOffset =
(CCInfo.getNextStackOffset() + RegSize - 1) / RegSize * RegSize;
} else
FirstVaArgOffset = RegSlotOffset;
// Record the frame index of the first variable argument // Record the frame index of the first variable argument
// which is a value necessary to VASTART. // which is a value necessary to VASTART.
unsigned NextStackOffset = CCInfo.getNextStackOffset(); LastFI = MFI->CreateFixedObject(RegSize, FirstVaArgOffset, true);
assert(NextStackOffset % 4 == 0 &&
"NextStackOffset must be aligned to 4-byte boundaries.");
LastFI = MFI->CreateFixedObject(4, NextStackOffset, true);
MipsFI->setVarArgsFrameIndex(LastFI); MipsFI->setVarArgsFrameIndex(LastFI);
// If NextStackOffset is smaller than o32's 16-byte reserved argument area, // Copy the integer registers that have not been used for argument passing
// copy the integer registers that have not been used for argument passing // to the argument register save area. For O32, the save area is allocated
// to the caller's stack frame. // in the caller's stack frame, while for N32/64, it is allocated in the
for (; NextStackOffset < 16; NextStackOffset += 4) { // callee's stack frame.
TargetRegisterClass *RC = Mips::CPURegsRegisterClass; for (int StackOffset = RegSlotOffset;
unsigned Idx = NextStackOffset / 4; Idx < NumOfRegs; ++Idx, StackOffset += RegSize) {
unsigned Reg = AddLiveIn(DAG.getMachineFunction(), O32IntRegs[Idx], RC); unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgRegs[Idx], RC);
SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, MVT::i32); SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg,
LastFI = MFI->CreateFixedObject(4, NextStackOffset, true); MVT::getIntegerVT(RegSize * 8));
LastFI = MFI->CreateFixedObject(RegSize, StackOffset, true);
SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy());
OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff,
MachinePointerInfo(), MachinePointerInfo(),