[llvm] 5ac411a - [SystemZ][z/OS] Add the PPA1 to SystemZAsmPrinter
Yusra Syeda via llvm-commits
llvm-commits at lists.llvm.org
Wed May 18 11:13:28 PDT 2022
Author: Yusra Syeda
Date: 2022-05-18T14:13:17-04:00
New Revision: 5ac411aea802f5983b7979b9198ba7d8fb38f64d
URL: https://github.com/llvm/llvm-project/commit/5ac411aea802f5983b7979b9198ba7d8fb38f64d
DIFF: https://github.com/llvm/llvm-project/commit/5ac411aea802f5983b7979b9198ba7d8fb38f64d.diff
LOG: [SystemZ][z/OS] Add the PPA1 to SystemZAsmPrinter
Differential Revision: https://reviews.llvm.org/D125725
Added:
llvm/include/llvm/BinaryFormat/GOFF.h
Modified:
llvm/include/llvm/MC/MCContext.h
llvm/include/llvm/MC/MCObjectFileInfo.h
llvm/include/llvm/MC/MCSectionGOFF.h
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/lib/MC/MCContext.cpp
llvm/lib/MC/MCObjectFileInfo.cpp
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
llvm/test/MC/GOFF/ppa1.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h
new file mode 100644
index 000000000000..40d323cac99c
--- /dev/null
+++ b/llvm/include/llvm/BinaryFormat/GOFF.h
@@ -0,0 +1,31 @@
+//===-- llvm/BinaryFormat/GOFF.h - GOFF definitions --------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains common, non-processor-specific data structures and
+// constants for the GOFF file format.
+//
+// GOFF specifics can be found in MVS Program Management: Advanced Facilities
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINARYFORMAT_GOFF_H
+#define LLVM_BINARYFORMAT_GOFF_H
+
+namespace llvm {
+
+namespace GOFF {
+
+// \brief Subsections of the primary C_CODE section in the object file.
+enum SubsectionKind : uint8_t {
+ SK_PPA1 = 2,
+};
+
+} // end namespace GOFF
+
+} // end namespace llvm
+
+#endif // LLVM_BINARYFORMAT_GOFF_H
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index b639473b2d8e..5b81ba31b83c 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -613,7 +613,8 @@ class MCContext {
unsigned Flags,
unsigned EntrySize);
- MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind);
+ MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind,
+ MCSection *Parent, const MCExpr *SubsectionId);
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind, StringRef COMDATSymName,
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index f1e63e0ba7be..e4ae85e91531 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -225,6 +225,9 @@ class MCObjectFileInfo {
MCSection *GIATsSection = nullptr;
MCSection *GLJMPSection = nullptr;
+ // GOFF specific sections.
+ MCSection *PPA1Section = nullptr;
+
// XCOFF specific sections
MCSection *TOCBaseSection = nullptr;
MCSection *ReadOnly8Section = nullptr;
@@ -423,6 +426,9 @@ class MCObjectFileInfo {
MCSection *getGIATsSection() const { return GIATsSection; }
MCSection *getGLJMPSection() const { return GLJMPSection; }
+ // GOFF specific sections.
+ MCSection *getPPA1Section() const { return PPA1Section; }
+
// XCOFF specific sections
MCSection *getTOCBaseSection() const { return TOCBaseSection; }
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index ce36d92ebd56..d866329461ce 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -15,6 +15,7 @@
#ifndef LLVM_MC_MCSECTIONGOFF_H
#define LLVM_MC_MCSECTIONGOFF_H
+#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/MC/MCSection.h"
#include "llvm/Support/raw_ostream.h"
@@ -24,9 +25,12 @@ class MCExpr;
class MCSectionGOFF final : public MCSection {
private:
+ MCSection *Parent;
+ const MCExpr *SubsectionId;
+
friend class MCContext;
- MCSectionGOFF(StringRef Name, SectionKind K)
- : MCSection(SV_GOFF, Name, K, nullptr) {}
+ MCSectionGOFF(StringRef Name, SectionKind K, MCSection *P, const MCExpr *Sub)
+ : MCSection(SV_GOFF, Name, K, nullptr), Parent(P), SubsectionId(Sub) {}
public:
void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
@@ -39,6 +43,9 @@ class MCSectionGOFF final : public MCSection {
bool isVirtualSection() const override { return false; }
+ MCSection *getParent() const { return Parent; }
+ const MCExpr *getSubsectionId() const { return SubsectionId; }
+
static bool classof(const MCSection *S) { return S->getVariant() == SV_GOFF; }
};
} // end namespace llvm
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index d34ba6fd77d9..7e2dd1546b5b 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2593,8 +2593,8 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
auto *Symbol = TM.getSymbol(GO);
if (Kind.isBSS())
- return getContext().getGOFFSection(Symbol->getName(),
- SectionKind::getBSS());
+ return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(),
+ nullptr, nullptr);
return getContext().getObjectFileInfo()->getTextSection();
}
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 827fe691fc44..887969fcd841 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -634,11 +634,14 @@ Optional<unsigned> MCContext::getELFUniqueIDForEntsize(StringRef SectionName,
return (I != ELFEntrySizeMap.end()) ? Optional<unsigned>(I->second) : None;
}
-MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind) {
+MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,
+ MCSection *Parent,
+ const MCExpr *SubsectionId) {
// Do the lookup. If we don't have a hit, return a new section.
auto &GOFFSection = GOFFUniquingMap[Section.str()];
if (!GOFFSection)
- GOFFSection = new (GOFFAllocator.Allocate()) MCSectionGOFF(Section, Kind);
+ GOFFSection = new (GOFFAllocator.Allocate())
+ MCSectionGOFF(Section, Kind, Parent, SubsectionId);
return GOFFSection;
}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 3ee8167c3832..d56f72cfc388 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -523,8 +523,13 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
}
void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
- TextSection = Ctx->getGOFFSection(".text", SectionKind::getText());
- BSSSection = Ctx->getGOFFSection(".bss", SectionKind::getBSS());
+ TextSection =
+ Ctx->getGOFFSection(".text", SectionKind::getText(), nullptr, nullptr);
+ BSSSection =
+ Ctx->getGOFFSection(".bss", SectionKind::getBSS(), nullptr, nullptr);
+ PPA1Section =
+ Ctx->getGOFFSection(".ppa1", SectionKind::getMetadata(), TextSection,
+ MCConstantExpr::create(GOFF::SK_PPA1, *Ctx));
}
void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 75f19e01e9b2..3142abb2b08c 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -819,13 +819,253 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
emitStackMaps(SM);
}
+void SystemZAsmPrinter::emitFunctionBodyEnd() {
+ if (TM.getTargetTriple().isOSzOS()) {
+ // Emit symbol for the end of function if the z/OS target streamer
+ // is used. This is needed to calculate the size of the function.
+ MCSymbol *FnEndSym = createTempSymbol("func_end");
+ OutStreamer->emitLabel(FnEndSym);
+
+ OutStreamer->PushSection();
+ OutStreamer->SwitchSection(getObjFileLowering().getPPA1Section());
+ emitPPA1(FnEndSym);
+ OutStreamer->PopSection();
+
+ CurrentFnPPA1Sym = nullptr;
+ CurrentFnEPMarkerSym = nullptr;
+ }
+}
+
+static void emitPPA1Flags(std::unique_ptr<MCStreamer> &OutStreamer, bool VarArg,
+ bool StackProtector, bool FPRMask, bool VRMask) {
+ enum class PPA1Flag1 : uint8_t {
+ DSA64Bit = (0x80 >> 0),
+ VarArg = (0x80 >> 7),
+ LLVM_MARK_AS_BITMASK_ENUM(DSA64Bit)
+ };
+ enum class PPA1Flag2 : uint8_t {
+ ExternalProcedure = (0x80 >> 0),
+ STACKPROTECTOR = (0x80 >> 3),
+ LLVM_MARK_AS_BITMASK_ENUM(ExternalProcedure)
+ };
+ enum class PPA1Flag3 : uint8_t {
+ FPRMask = (0x80 >> 2),
+ LLVM_MARK_AS_BITMASK_ENUM(FPRMask)
+ };
+ enum class PPA1Flag4 : uint8_t {
+ EPMOffsetPresent = (0x80 >> 0),
+ VRMask = (0x80 >> 2),
+ ProcedureNamePresent = (0x80 >> 7),
+ LLVM_MARK_AS_BITMASK_ENUM(EPMOffsetPresent)
+ };
+
+ // Declare optional section flags that can be modified.
+ auto Flags1 = PPA1Flag1(0);
+ auto Flags2 = PPA1Flag2::ExternalProcedure;
+ auto Flags3 = PPA1Flag3(0);
+ auto Flags4 = PPA1Flag4::EPMOffsetPresent | PPA1Flag4::ProcedureNamePresent;
+
+ Flags1 |= PPA1Flag1::DSA64Bit;
+
+ if (VarArg)
+ Flags1 |= PPA1Flag1::VarArg;
+
+ if (StackProtector)
+ Flags2 |= PPA1Flag2::STACKPROTECTOR;
+
+ // SavedGPRMask, SavedFPRMask, and SavedVRMask are precomputed in.
+ if (FPRMask)
+ Flags3 |= PPA1Flag3::FPRMask; // Add emit FPR mask flag.
+
+ if (VRMask)
+ Flags4 |= PPA1Flag4::VRMask; // Add emit VR mask flag.
+
+ OutStreamer->AddComment("PPA1 Flags 1");
+ if ((Flags1 & PPA1Flag1::DSA64Bit) == PPA1Flag1::DSA64Bit)
+ OutStreamer->AddComment(" Bit 0: 1 = 64-bit DSA");
+ else
+ OutStreamer->AddComment(" Bit 0: 0 = 32-bit DSA");
+ if ((Flags1 & PPA1Flag1::VarArg) == PPA1Flag1::VarArg)
+ OutStreamer->AddComment(" Bit 7: 1 = Vararg function");
+ OutStreamer->emitInt8(static_cast<uint8_t>(Flags1)); // Flags 1.
+
+ OutStreamer->AddComment("PPA1 Flags 2");
+ if ((Flags2 & PPA1Flag2::ExternalProcedure) == PPA1Flag2::ExternalProcedure)
+ OutStreamer->AddComment(" Bit 0: 1 = External procedure");
+ if ((Flags2 & PPA1Flag2::STACKPROTECTOR) == PPA1Flag2::STACKPROTECTOR)
+ OutStreamer->AddComment(" Bit 3: 1 = STACKPROTECT is enabled");
+ else
+ OutStreamer->AddComment(" Bit 3: 0 = STACKPROTECT is not enabled");
+ OutStreamer->emitInt8(static_cast<uint8_t>(Flags2)); // Flags 2.
+
+ OutStreamer->AddComment("PPA1 Flags 3");
+ if ((Flags3 & PPA1Flag3::FPRMask) == PPA1Flag3::FPRMask)
+ OutStreamer->AddComment(" Bit 2: 1 = FP Reg Mask is in optional area");
+ OutStreamer->emitInt8(
+ static_cast<uint8_t>(Flags3)); // Flags 3 (optional sections).
+
+ OutStreamer->AddComment("PPA1 Flags 4");
+ if ((Flags4 & PPA1Flag4::VRMask) == PPA1Flag4::VRMask)
+ OutStreamer->AddComment(" Bit 2: 1 = Vector Reg Mask is in optional area");
+ OutStreamer->emitInt8(static_cast<uint8_t>(
+ Flags4)); // Flags 4 (optional sections, always emit these).
+}
+
+void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) {
+ const TargetRegisterInfo *TRI = MF->getRegInfo().getTargetRegisterInfo();
+ const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
+ const auto TargetHasVector = Subtarget.hasVector();
+
+ const SystemZMachineFunctionInfo *ZFI =
+ MF->getInfo<SystemZMachineFunctionInfo>();
+ const auto *ZFL = static_cast<const SystemZXPLINKFrameLowering *>(
+ Subtarget.getFrameLowering());
+ const MachineFrameInfo &MFFrame = MF->getFrameInfo();
+
+ // Get saved GPR/FPR/VPR masks.
+ const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
+ uint16_t SavedGPRMask = 0;
+ uint16_t SavedFPRMask = 0;
+ uint8_t SavedVRMask = 0;
+ int64_t OffsetFPR = 0;
+ int64_t OffsetVR = 0;
+ const int64_t TopOfStack =
+ MFFrame.getOffsetAdjustment() + MFFrame.getStackSize();
+
+ // Loop over the spilled registers. The CalleeSavedInfo can't be used because
+ // it does not contain all spilled registers.
+ for (unsigned I = ZFI->getSpillGPRRegs().LowGPR,
+ E = ZFI->getSpillGPRRegs().HighGPR;
+ I && E && I <= E; ++I) {
+ unsigned V = TRI->getEncodingValue((Register)I);
+ assert(V < 16 && "GPR index out of range");
+ SavedGPRMask |= 1 << (15 - V);
+ }
+
+ for (auto &CS : CSI) {
+ unsigned Reg = CS.getReg();
+ unsigned I = TRI->getEncodingValue(Reg);
+
+ if (SystemZ::FP64BitRegClass.contains(Reg)) {
+ assert(I < 16 && "FPR index out of range");
+ SavedFPRMask |= 1 << (15 - I);
+ int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
+ if (Temp < OffsetFPR)
+ OffsetFPR = Temp;
+ } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
+ assert(I >= 16 && I <= 23 && "VPR index out of range");
+ unsigned BitNum = I - 16;
+ SavedVRMask |= 1 << (7 - BitNum);
+ int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
+ if (Temp < OffsetVR)
+ OffsetVR = Temp;
+ }
+ }
+
+ // Adjust the offset.
+ OffsetFPR += (OffsetFPR < 0) ? TopOfStack : 0;
+ OffsetVR += (OffsetVR < 0) ? TopOfStack : 0;
+
+ // Get alloca register.
+ uint8_t FrameReg = TRI->getEncodingValue(TRI->getFrameRegister(*MF));
+ uint8_t AllocaReg = ZFL->hasFP(*MF) ? FrameReg : 0;
+ assert(AllocaReg < 16 && "Can't have alloca register larger than 15");
+
+ // Build FPR save area offset.
+ uint32_t FrameAndFPROffset = 0;
+ if (SavedFPRMask) {
+ uint64_t FPRSaveAreaOffset = OffsetFPR;
+ assert(FPRSaveAreaOffset < 0x10000000 && "Offset out of range");
+
+ FrameAndFPROffset = FPRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
+ FrameAndFPROffset |= FrameReg << 28; // Put into top 4 bits.
+ }
+
+ // Build VR save area offset.
+ uint32_t FrameAndVROffset = 0;
+ if (TargetHasVector && SavedVRMask) {
+ uint64_t VRSaveAreaOffset = OffsetVR;
+ assert(VRSaveAreaOffset < 0x10000000 && "Offset out of range");
+
+ FrameAndVROffset = VRSaveAreaOffset & 0x0FFFFFFF; // Lose top 4 bits.
+ FrameAndVROffset |= FrameReg << 28; // Put into top 4 bits.
+ }
+
+ // Emit PPA1 section.
+ OutStreamer->AddComment("PPA1");
+ OutStreamer->emitLabel(CurrentFnPPA1Sym);
+ OutStreamer->AddComment("Version");
+ OutStreamer->emitInt8(0x02); // Version.
+ OutStreamer->AddComment("LE Signature X'CE'");
+ OutStreamer->emitInt8(0xCE); // CEL signature.
+ OutStreamer->AddComment("Saved GPR Mask");
+ OutStreamer->emitInt16(SavedGPRMask);
+
+ emitPPA1Flags(OutStreamer, MF->getFunction().isVarArg(),
+ MFFrame.hasStackProtectorIndex(), SavedFPRMask != 0,
+ TargetHasVector && SavedVRMask != 0);
+
+ OutStreamer->AddComment("Length/4 of Parms");
+ OutStreamer->emitInt16(
+ static_cast<uint16_t>(MFFrame.getMaxCallFrameSize() / 4)); // Parms/4.
+ OutStreamer->AddComment("Length of Code");
+ OutStreamer->emitAbsoluteSymbolDiff(FnEndSym, CurrentFnEPMarkerSym, 4);
+
+ // Emit saved FPR mask and offset to FPR save area (0x20 of flags 3).
+ if (SavedFPRMask) {
+ OutStreamer->AddComment("FPR mask");
+ OutStreamer->emitInt16(SavedFPRMask);
+ OutStreamer->AddComment("AR mask");
+ OutStreamer->emitInt16(0); // AR Mask, unused currently.
+ OutStreamer->AddComment("FPR Save Area Locator");
+ OutStreamer->AddComment(Twine(" Bit 0-3: Register R")
+ .concat(utostr(FrameAndFPROffset >> 28))
+ .str());
+ OutStreamer->AddComment(Twine(" Bit 4-31: Offset ")
+ .concat(utostr(FrameAndFPROffset & 0x0FFFFFFF))
+ .str());
+ OutStreamer->emitInt32(FrameAndFPROffset); // Offset to FPR save area with
+ // register to add value to
+ // (alloca reg).
+ }
+
+ // Emit saved VR mask to VR save area.
+ if (TargetHasVector && SavedVRMask) {
+ OutStreamer->AddComment("VR mask");
+ OutStreamer->emitInt8(SavedVRMask);
+ OutStreamer->emitInt8(0); // Reserved.
+ OutStreamer->emitInt16(0); // Also reserved.
+ OutStreamer->AddComment("VR Save Area Locator");
+ OutStreamer->AddComment(Twine(" Bit 0-3: Register R")
+ .concat(utostr(FrameAndVROffset >> 28))
+ .str());
+ OutStreamer->AddComment(Twine(" Bit 4-31: Offset ")
+ .concat(utostr(FrameAndVROffset & 0x0FFFFFFF))
+ .str());
+ OutStreamer->emitInt32(FrameAndVROffset);
+ }
+
+ // Emit offset to entry point optional section (0x80 of flags 4).
+ OutStreamer->emitAbsoluteSymbolDiff(CurrentFnEPMarkerSym, CurrentFnPPA1Sym,
+ 4);
+}
+
void SystemZAsmPrinter::emitFunctionEntryLabel() {
const SystemZSubtarget &Subtarget =
static_cast<const SystemZSubtarget &>(MF->getSubtarget());
if (Subtarget.getTargetTriple().isOSzOS()) {
MCContext &OutContext = OutStreamer->getContext();
- MCSymbol *EPMarkerSym = OutContext.createTempSymbol("CM_", true);
+
+ // Save information for later use.
+ std::string N(MF->getFunction().hasName()
+ ? Twine(MF->getFunction().getName()).concat("_").str()
+ : "");
+
+ CurrentFnEPMarkerSym =
+ OutContext.createTempSymbol(Twine("EPM_").concat(N).str(), true);
+ CurrentFnPPA1Sym =
+ OutContext.createTempSymbol(Twine("PPA1_").concat(N).str(), true);
// EntryPoint Marker
const MachineFrameInfo &MFFrame = MF->getFrameInfo();
@@ -844,11 +1084,14 @@ void SystemZAsmPrinter::emitFunctionEntryLabel() {
// Emit entry point marker section.
OutStreamer->AddComment("XPLINK Routine Layout Entry");
- OutStreamer->emitLabel(EPMarkerSym);
+ OutStreamer->emitLabel(CurrentFnEPMarkerSym);
OutStreamer->AddComment("Eyecatcher 0x00C300C500C500");
OutStreamer->emitIntValueInHex(0x00C300C500C500, 7); // Eyecatcher.
OutStreamer->AddComment("Mark Type C'1'");
OutStreamer->emitInt8(0xF1); // Mark Type.
+ OutStreamer->AddComment("Offset to PPA1");
+ OutStreamer->emitAbsoluteSymbolDiff(CurrentFnPPA1Sym, CurrentFnEPMarkerSym,
+ 4);
if (OutStreamer->isVerboseAsm()) {
OutStreamer->AddComment("DSA Size 0x" + Twine::utohexstr(DSASize));
OutStreamer->AddComment("Entry Flags");
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
index 7839938f5ae5..f14b4a184f62 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
@@ -26,6 +26,8 @@ class raw_ostream;
class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
private:
StackMaps SM;
+ MCSymbol *CurrentFnPPA1Sym; // PPA1 Symbol.
+ MCSymbol *CurrentFnEPMarkerSym; // Entry Point Marker.
SystemZTargetStreamer *getTargetStreamer() {
MCTargetStreamer *TS = OutStreamer->getTargetStreamer();
@@ -45,9 +47,12 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
BASR33 = 7, // b'x111' == BASR r3,r3
};
+ void emitPPA1(MCSymbol *FnEndSym);
+
public:
SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
- : AsmPrinter(TM, std::move(Streamer)), SM(*this) {}
+ : AsmPrinter(TM, std::move(Streamer)), SM(*this),
+ CurrentFnPPA1Sym(nullptr), CurrentFnEPMarkerSym(nullptr) {}
// Override AsmPrinter.
StringRef getPassName() const override { return "SystemZ Assembly Printer"; }
@@ -64,6 +69,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
return AsmPrinter::doInitialization(M);
}
void emitFunctionEntryLabel() override;
+ void emitFunctionBodyEnd() override;
private:
void emitCallInformation(CallType CT);
diff --git a/llvm/test/MC/GOFF/ppa1.ll b/llvm/test/MC/GOFF/ppa1.ll
index c494b1a70988..85231fb77434 100644
--- a/llvm/test/MC/GOFF/ppa1.ll
+++ b/llvm/test/MC/GOFF/ppa1.ll
@@ -1,7 +1,7 @@
; RUN: llc -mtriple s390x-ibm-zos < %s | FileCheck %s
; REQUIRES: systemz-registered-target
-; CHECK: @@CM_0: * @void_test
+; CHECK: @@EPM_void_test_0: * @void_test
; CHECK: * XPLINK Routine Layout Entry
; CHECK: .long 12779717 * Eyecatcher 0x00C300C500C500
; CHECK: .short 197
@@ -10,6 +10,24 @@
; CHECK: .long 128 * DSA Size 0x80
; CHECK: * Entry Flags
; CHECK: * Bit 2: 0 = Does not use alloca
+; CHECK: @@func_end0:
+; CHECK: .section ".ppa1"
+; CHECK: @@PPA1_void_test_0: * PPA1
+; CHECK: .byte 2 * Version
+; CHECK: .byte 206 * LE Signature X'CE'
+; CHECK: .short 768 * Saved GPR Mask
+; CHECK: .byte 128 * PPA1 Flags 1
+; CHECK: * Bit 0: 1 = 64-bit DSA
+; CHECK: .byte 128 * PPA1 Flags 2
+; CHECK: * Bit 0: 1 = External procedure
+; CHECK: * Bit 3: 0 = STACKPROTECT is not enabled
+; CHECK: .byte 0 * PPA1 Flags 3
+; CHECK: .byte 129 * PPA1 Flags 4
+; CHECK: .short 0 * Length/4 of Parms
+; CHECK: .long @@func_end0-@@EPM_void_test_0 * Length of Code
+; CHECK: .long @@EPM_void_test_0-@@PPA1_void_test_0
+; CHECK: .section ".text"
+; CHECK: * -- End function
define void @void_test() {
entry:
ret void
More information about the llvm-commits
mailing list