Skip to content

Commit 6cf41ad

Browse files
ysyedaYusra Syeda
andauthored
[SystemZ][z/OS] Add vararg support to z/OS (#68834)
This PR adds vararg support to z/OS and updates the call-zos-vararg.ll lit test. Co-authored-by: Yusra Syeda <[email protected]>
1 parent 0ce6255 commit 6cf41ad

File tree

3 files changed

+228
-81
lines changed

3 files changed

+228
-81
lines changed

llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,30 @@ void SystemZXPLINKFrameLowering::emitPrologue(MachineFunction &MF,
12751275
for (MachineBasicBlock &B : llvm::drop_begin(MF))
12761276
B.addLiveIn(Regs.getFramePointerRegister());
12771277
}
1278+
1279+
// Save GPRs used for varargs, if any.
1280+
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
1281+
bool IsVarArg = MF.getFunction().isVarArg();
1282+
1283+
if (IsVarArg) {
1284+
// FixedRegs is the number of used registers, accounting for shadow
1285+
// registers.
1286+
unsigned FixedRegs = ZFI->getVarArgsFirstGPR() + ZFI->getVarArgsFirstFPR();
1287+
auto &GPRs = SystemZ::XPLINK64ArgGPRs;
1288+
for (unsigned I = FixedRegs; I < SystemZ::XPLINK64NumArgGPRs; I++) {
1289+
uint64_t StartOffset = MFFrame.getOffsetAdjustment() +
1290+
MFFrame.getStackSize() + Regs.getCallFrameSize() +
1291+
getOffsetOfLocalArea() + I * 8;
1292+
unsigned Reg = GPRs[I];
1293+
BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STG))
1294+
.addReg(Reg)
1295+
.addReg(Regs.getStackPointerRegister())
1296+
.addImm(StartOffset)
1297+
.addReg(0);
1298+
if (!MBB.isLiveIn(Reg))
1299+
MBB.addLiveIn(Reg);
1300+
}
1301+
}
12781302
}
12791303

12801304
void SystemZXPLINKFrameLowering::emitEpilogue(MachineFunction &MF,

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1613,7 +1613,23 @@ SDValue SystemZTargetLowering::LowerFormalArguments(
16131613
InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, ArgValue));
16141614
}
16151615

1616-
// FIXME: Add support for lowering varargs for XPLINK64 in a later patch.
1616+
if (IsVarArg && Subtarget.isTargetXPLINK64()) {
1617+
// Save the number of non-varargs registers for later use by va_start, etc.
1618+
FuncInfo->setVarArgsFirstGPR(NumFixedGPRs);
1619+
FuncInfo->setVarArgsFirstFPR(NumFixedFPRs);
1620+
1621+
auto *Regs = static_cast<SystemZXPLINK64Registers *>(
1622+
Subtarget.getSpecialRegisters());
1623+
1624+
// Likewise the address (in the form of a frame index) of where the
1625+
// first stack vararg would be. The 1-byte size here is arbitrary.
1626+
// FIXME: Pre-include call frame size in the offset, should not
1627+
// need to manually add it here.
1628+
int64_t VarArgOffset = CCInfo.getStackSize() + Regs->getCallFrameSize();
1629+
int FI = MFI.CreateFixedObject(1, VarArgOffset, true);
1630+
FuncInfo->setVarArgsFrameIndex(FI);
1631+
}
1632+
16171633
if (IsVarArg && Subtarget.isTargetELF()) {
16181634
// Save the number of non-varargs registers for later use by va_start, etc.
16191635
FuncInfo->setVarArgsFirstGPR(NumFixedGPRs);

0 commit comments

Comments
 (0)