Skip to content

Commit

Permalink
[SystemZ][z/OS] Add vararg support to z/OS (#68834)
Browse files Browse the repository at this point in the history
This PR adds vararg support to z/OS and updates the call-zos-vararg.ll
lit test.

Co-authored-by: Yusra Syeda <yusra.syeda@ibm.com>
  • Loading branch information
ysyeda and Yusra Syeda committed Oct 12, 2023
1 parent 0ce6255 commit 6cf41ad
Show file tree
Hide file tree
Showing 3 changed files with 228 additions and 81 deletions.
24 changes: 24 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,30 @@ void SystemZXPLINKFrameLowering::emitPrologue(MachineFunction &MF,
for (MachineBasicBlock &B : llvm::drop_begin(MF))
B.addLiveIn(Regs.getFramePointerRegister());
}

// Save GPRs used for varargs, if any.
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
bool IsVarArg = MF.getFunction().isVarArg();

if (IsVarArg) {
// FixedRegs is the number of used registers, accounting for shadow
// registers.
unsigned FixedRegs = ZFI->getVarArgsFirstGPR() + ZFI->getVarArgsFirstFPR();
auto &GPRs = SystemZ::XPLINK64ArgGPRs;
for (unsigned I = FixedRegs; I < SystemZ::XPLINK64NumArgGPRs; I++) {
uint64_t StartOffset = MFFrame.getOffsetAdjustment() +
MFFrame.getStackSize() + Regs.getCallFrameSize() +
getOffsetOfLocalArea() + I * 8;
unsigned Reg = GPRs[I];
BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STG))
.addReg(Reg)
.addReg(Regs.getStackPointerRegister())
.addImm(StartOffset)
.addReg(0);
if (!MBB.isLiveIn(Reg))
MBB.addLiveIn(Reg);
}
}
}

void SystemZXPLINKFrameLowering::emitEpilogue(MachineFunction &MF,
Expand Down
18 changes: 17 additions & 1 deletion llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1613,7 +1613,23 @@ SDValue SystemZTargetLowering::LowerFormalArguments(
InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, ArgValue));
}

// FIXME: Add support for lowering varargs for XPLINK64 in a later patch.
if (IsVarArg && Subtarget.isTargetXPLINK64()) {
// Save the number of non-varargs registers for later use by va_start, etc.
FuncInfo->setVarArgsFirstGPR(NumFixedGPRs);
FuncInfo->setVarArgsFirstFPR(NumFixedFPRs);

auto *Regs = static_cast<SystemZXPLINK64Registers *>(
Subtarget.getSpecialRegisters());

// Likewise the address (in the form of a frame index) of where the
// first stack vararg would be. The 1-byte size here is arbitrary.
// FIXME: Pre-include call frame size in the offset, should not
// need to manually add it here.
int64_t VarArgOffset = CCInfo.getStackSize() + Regs->getCallFrameSize();
int FI = MFI.CreateFixedObject(1, VarArgOffset, true);
FuncInfo->setVarArgsFrameIndex(FI);
}

if (IsVarArg && Subtarget.isTargetELF()) {
// Save the number of non-varargs registers for later use by va_start, etc.
FuncInfo->setVarArgsFirstGPR(NumFixedGPRs);
Expand Down

0 comments on commit 6cf41ad

Please sign in to comment.