Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,7 @@ void SystemZAsmPrinter::emitFunctionBodyEnd() {

static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg,
bool StackProtector, bool FPRMask, bool VRMask,
bool EHBlock, bool HasName) {
bool EHBlock, bool HasArgAreaLength, bool HasName) {
enum class PPA1Flag1 : uint8_t {
DSA64Bit = (0x80 >> 0),
VarArg = (0x80 >> 7),
Expand All @@ -1282,8 +1282,9 @@ static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg,
LLVM_MARK_AS_BITMASK_ENUM(ExternalProcedure)
};
enum class PPA1Flag3 : uint8_t {
HasArgAreaLength = (0x80 >> 1),
FPRMask = (0x80 >> 2),
LLVM_MARK_AS_BITMASK_ENUM(FPRMask)
LLVM_MARK_AS_BITMASK_ENUM(HasArgAreaLength)
};
enum class PPA1Flag4 : uint8_t {
EPMOffsetPresent = (0x80 >> 0),
Expand All @@ -1307,6 +1308,9 @@ static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg,
if (StackProtector)
Flags2 |= PPA1Flag2::STACKPROTECTOR;

if (HasArgAreaLength)
Flags3 |= PPA1Flag3::HasArgAreaLength; // Add emit ArgAreaLength flag.

// SavedGPRMask, SavedFPRMask, and SavedVRMask are precomputed in.
if (FPRMask)
Flags3 |= PPA1Flag3::FPRMask; // Add emit FPR mask flag.
Expand Down Expand Up @@ -1339,6 +1343,9 @@ static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg,
OutStreamer->emitInt8(static_cast<uint8_t>(Flags2)); // Flags 2.

OutStreamer->AddComment("PPA1 Flags 3");
if ((Flags3 & PPA1Flag3::HasArgAreaLength) == PPA1Flag3::HasArgAreaLength)
OutStreamer->AddComment(
" Bit 1: 1 = Argument Area Length is in optional area");
if ((Flags3 & PPA1Flag3::FPRMask) == PPA1Flag3::FPRMask)
OutStreamer->AddComment(" Bit 2: 1 = FP Reg Mask is in optional area");
OutStreamer->emitInt8(
Expand Down Expand Up @@ -1477,19 +1484,38 @@ void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) {

bool NeedEmitEHBlock = !MF->getLandingPads().empty();

// Optional Argument Area Length.
// Note: This represents the length of the argument area that we reserve
// in our stack for setting up arguments for calls to other
// routines. If this optional field is not set, LE will reserve
// 128 bytes for the argument area. This optional field is
// created if greater than 128 bytes is required - to guarantee
// the required space is reserved on stack extension in the new
// extension. This optional field is also created if the
// routine has alloca(). This may reduce stack space
// if alloca() call causes a stack extension.
bool HasArgAreaLength =
(AllocaReg != 0) || (MFFrame.getMaxCallFrameSize() > 128);

bool HasName =
MF->getFunction().hasName() && MF->getFunction().getName().size() > 0;

emitPPA1Flags(OutStreamer, MF->getFunction().isVarArg(),
MFFrame.hasStackProtectorIndex(), SavedFPRMask != 0,
TargetHasVector && SavedVRMask != 0, NeedEmitEHBlock, HasName);
TargetHasVector && SavedVRMask != 0, NeedEmitEHBlock,
HasArgAreaLength, HasName);

OutStreamer->AddComment("Length/4 of Parms");
OutStreamer->emitInt16(
static_cast<uint16_t>(ZFI->getSizeOfFnParams() / 4)); // Parms/4.
OutStreamer->AddComment("Length of Code");
OutStreamer->emitAbsoluteSymbolDiff(FnEndSym, CurrentFnEPMarkerSym, 4);

if (HasArgAreaLength) {
OutStreamer->AddComment("Argument Area Length");
OutStreamer->emitInt32(MFFrame.getMaxCallFrameSize());
}

// Emit saved FPR mask and offset to FPR save area (0x20 of flags 3).
if (SavedFPRMask) {
OutStreamer->AddComment("FPR mask");
Expand Down
66 changes: 66 additions & 0 deletions llvm/test/CodeGen/SystemZ/zos-ppa1-argarea.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
; RUN: llc < %s -mtriple=s390x-ibm-zos -emit-gnuas-syntax-on-zos=0 | FileCheck %s
%struct.LargeStruct_t = type { [33 x i32] }

@GlobLargeS = hidden global %struct.LargeStruct_t zeroinitializer, align 4
@GlobInt = hidden global i32 0, align 4

; === Check that function with small frame does not emit PPA1 Argument Area Length.
define void @fSmallOutArgArea() {
; CHECK-LABEL: L#EPM_fSmallOutArgArea_0 DS 0H
; CHECK: * Bit 1: 1 = Leaf function
; CHECK: * Bit 2: 0 = Does not use alloca
; CHECK: DC XL4'00000008'
; CHECK: fSmallOutArgArea DS 0H
; CHECK: L#PPA1_fSmallOutArgArea_0 DS 0H
; CHECK: * PPA1 Flags 3
; CHECK: DC XL1'00'
ret void
}

; === Check that function with large frame does emit PPA1 Argument Area Length.
define void @fLargeOutArgArea() {
; CHECK-LABEL: L#EPM_fLargeOutArgArea_0 DS 0H
; CHECK: * Bit 1: 0 = Non-leaf function
; CHECK: * Bit 2: 0 = Does not use alloca
; CHECK: DC XL4'00000220'
; CHECK: fLargeOutArgArea DS 0H
; CHECK: L#PPA1_fLargeOutArgArea_0 DS 0H
; CHECK: * PPA1 Flags 3
; CHECK: * Bit 1: 1 = Argument Area Length is in optional area
; CHECK: DC XL1'40'
; CHECK: * Argument Area Length
; CHECK: DC XL4'00000140'
%1 = load [33 x i32], ptr @GlobLargeS, align 4
call void @fLargeParm([33 x i32] inreg %1)
ret void
}

; === Check that function with parameter does emit PPA1 Length/4 of parms
define void @fLargeParm([33 x i64] inreg %arr) {
; CHECK-LABEL: L#EPM_fLargeParm_0 DS 0H
; CHECK: * Length/4 of Parms
; CHECK: DC XL2'0042'
%1 = extractvalue [33 x i64] %arr, 1
call void @foo(i64 %1)
ret void
}

; === Check that function with alloca call does emit PPA1 Argument Area Length.
define hidden void @fHasAlloca() {
; CHECK-LABEL: L#EPM_fHasAlloca_0 DS 0H
; CHECK: * Bit 2: 1 = Uses alloca
; CHECK: fHasAlloca DS 0H
; CHECK: L#PPA1_fHasAlloca_0 DS 0H
; CHECK: * PPA1 Flags 3
; CHECK: * Bit 1: 1 = Argument Area Length is in optional area
; CHECK: DC XL1'40'
; CHECK: * Argument Area Length
; CHECK: DC XL4'00000040'
%p = alloca ptr, align 4
%1 = load i32, ptr @GlobInt, align 4
%2 = alloca i8, i32 %1, align 8
store ptr %2, ptr %p, align 4
ret void
}

declare void @foo(i64)