[llvm] [GOFF] Emit symbols for functions. (PR #144437)
Kai Nacke via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 19 10:38:07 PST 2025
https://github.com/redstar updated https://github.com/llvm/llvm-project/pull/144437
>From 6261752c43e16feb0ac3b42915c8de943cc96601 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 16 Jun 2025 17:27:16 -0400
Subject: [PATCH 1/7] [GOFF] Emit symbols for functions.
A function entry is mapped to a LD symbol with an offset to the begin of the section.
---
llvm/include/llvm/MC/MCGOFFStreamer.h | 7 +--
llvm/include/llvm/MC/MCSymbolGOFF.h | 22 ++++++++-
llvm/lib/MC/CMakeLists.txt | 1 +
llvm/lib/MC/GOFFObjectWriter.cpp | 1 +
llvm/lib/MC/MCGOFFStreamer.cpp | 57 ++++++++++++++++++++++
llvm/lib/MC/MCSymbolGOFF.cpp | 39 +++++++++++++++
llvm/test/CodeGen/SystemZ/zos-section-1.ll | 34 ++++++++-----
7 files changed, 143 insertions(+), 18 deletions(-)
create mode 100644 llvm/lib/MC/MCSymbolGOFF.cpp
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 8888d9e7bdbb3..6fa6e6481347f 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -28,9 +28,10 @@ class MCGOFFStreamer : public MCObjectStreamer {
GOFFObjectWriter &getWriter();
- bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
- return false;
- }
+ void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Align ByteAlignment) override {}
};
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 11d4df4aea634..b58b520cc5c49 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -28,7 +28,10 @@ class MCSymbolGOFF : public MCSymbol {
GOFF::LDAttr LDAttributes;
enum SymbolFlags : uint16_t {
- SF_LD = 0x01, // LD attributes are set.
+ SF_LD = 0x01, // LD attributes are set.
+ // Leave place for EX attributes.
+ SF_Hidden = 0x04, // Symbol is hidden, aka not exported.
+ SF_Weak = 0x08, // Symbol is weak.
};
public:
@@ -39,7 +42,8 @@ class MCSymbolGOFF : public MCSymbol {
modifyFlags(SF_LD, SF_LD);
LDAttributes = Attr;
}
- GOFF::LDAttr getLDAttributes() const { return LDAttributes; }
+ const GOFF::LDAttr &getLDAttributes() const { return LDAttributes; }
+ GOFF::LDAttr &getLDAttributes() { return LDAttributes; }
bool hasLDAttributes() const { return getFlags() & SF_LD; }
void setADA(MCSectionGOFF *AssociatedDataArea) {
@@ -47,6 +51,20 @@ class MCSymbolGOFF : public MCSymbol {
AssociatedDataArea->RequiresNonZeroLength = true;
}
MCSectionGOFF *getADA() const { return ADA; }
+
+ bool isExternal() const { return IsExternal; }
+ void setExternal(bool Value) const { IsExternal = Value; }
+
+ void setHidden(bool Value = true) {
+ modifyFlags(Value ? SF_Hidden : 0, SF_Hidden);
+ }
+ bool isHidden() const { return getFlags() & SF_Hidden; }
+ bool isExported() const { return !isHidden(); }
+
+ void setWeak(bool Value = true) { modifyFlags(Value ? SF_Weak : 0, SF_Weak); }
+ bool isWeak() const { return getFlags() & SF_Weak; }
+
+ void initAttributes();
};
} // end namespace llvm
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index 70c4577aeec0a..1388f130bb806 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -50,6 +50,7 @@ add_llvm_component_library(LLVMMC
MCSubtargetInfo.cpp
MCSymbol.cpp
MCSymbolELF.cpp
+ MCSymbolGOFF.cpp
MCSymbolXCOFF.cpp
MCTargetOptions.cpp
MCTargetOptionsCommandFlags.cpp
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index a3eaaa743039d..b42ba148ef65b 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -328,6 +328,7 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
Section.getEDAttributes().NameSpace, Symbol.getLDAttributes());
if (Symbol.getADA())
LD.ADAEsdId = Symbol.getADA()->getOrdinal();
+ LD.Offset = Asm.getSymbolOffset(Symbol);
writeSymbol(LD);
}
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index ad6397bce70f0..c76e8cd1dc3c8 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -15,7 +15,9 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCGOFFObjectWriter.h"
+#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/MC/TargetRegistry.h"
using namespace llvm;
@@ -37,6 +39,61 @@ void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
}
}
+void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCObjectStreamer::emitLabel(Symbol, Loc);
+ static_cast<MCSymbolGOFF *>(Symbol)->initAttributes();
+}
+
+bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
+ MCSymbolAttr Attribute) {
+ auto *Symbol = static_cast<MCSymbolGOFF *>(Sym);
+ switch (Attribute) {
+ case MCSA_Invalid:
+ case MCSA_Cold:
+ case MCSA_ELF_TypeFunction:
+ case MCSA_ELF_TypeIndFunction:
+ case MCSA_ELF_TypeObject:
+ case MCSA_ELF_TypeTLS:
+ case MCSA_ELF_TypeCommon:
+ case MCSA_ELF_TypeNoType:
+ case MCSA_ELF_TypeGnuUniqueObject:
+ case MCSA_LGlobal:
+ case MCSA_Extern:
+ case MCSA_Exported:
+ case MCSA_IndirectSymbol:
+ case MCSA_Internal:
+ case MCSA_LazyReference:
+ case MCSA_NoDeadStrip:
+ case MCSA_SymbolResolver:
+ case MCSA_AltEntry:
+ case MCSA_PrivateExtern:
+ case MCSA_Protected:
+ case MCSA_Reference:
+ case MCSA_WeakDefinition:
+ case MCSA_WeakDefAutoPrivate:
+ case MCSA_WeakAntiDep:
+ case MCSA_Memtag:
+ return false;
+
+ case MCSA_Global:
+ Symbol->setExternal(true);
+ break;
+ case MCSA_Local:
+ Symbol->setExternal(false);
+ break;
+ case MCSA_Weak:
+ case MCSA_WeakReference:
+ Symbol->setExternal(true);
+ Symbol->setWeak();
+ break;
+ case MCSA_Hidden:
+ Symbol->setHidden(true);
+ break;
+ }
+
+ return true;
+}
+
MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
std::unique_ptr<MCObjectWriter> &&OW,
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
new file mode 100644
index 0000000000000..86de21b11bc0a
--- /dev/null
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -0,0 +1,39 @@
+//===- MCSymbolGOFF.cpp - GOFF Symbol Representation ----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCSymbolGOFF.h"
+#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+void MCSymbolGOFF::initAttributes() {
+ if (hasLDAttributes())
+ return;
+
+ if (isDefined()) {
+ MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(getSection());
+ GOFF::ESDBindingScope BindingScope =
+ isExternal() ? (isExported() ? GOFF::ESD_BSC_ImportExport
+ : GOFF::ESD_BSC_Library)
+ : GOFF::ESD_BSC_Section;
+ GOFF::ESDBindingStrength BindingStrength =
+ isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong;
+ if (Section.isED()) {
+ setLDAttributes(GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, BindingStrength,
+ GOFF::ESD_LT_XPLink, GOFF::ESD_AMODE_64,
+ BindingScope});
+ } else if (Section.isPR()) {
+ // For data symbols, the attributes are already determind in TLOFI.
+ // TODO Does it make sense to it to here?
+ } else
+ llvm_unreachable("Unexpected section type for label");
+ }
+ // TODO Handle external symbol.
+}
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index b98584df54d5a..6caa8f4d607de 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -104,26 +104,34 @@ entry:
; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; ESD record, type LD.
+; The name is me.
+; CHECK-NEXT: 000320 03 00 00 02 [[ME:00 00 00 09]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 000330 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 000360 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
+
; Text record for the code section C_CODE64.
; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 000320 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000330 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
+; CHECK-NEXT: 000370 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000380 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
; Text record for the section .&ppa2.
-; CHECK: 0003c0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000410 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the ADA section test#S.
-; CHECK: 000410 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000460 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000470 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the section B_IDRL.
-; CHECK: 000460 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000470 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 0004b0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 {{..}} {{.*}}
; End record.
-; CHECK: 0004b0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000500 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>From 194ba3a6efd669d3737efa033e767a45bd6f756e Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 29 Oct 2025 13:19:28 -0400
Subject: [PATCH 2/7] Add HLASM output and external references
Adds HLASM output and tests for it, per reviewer comment.
Also adds external references, because it fits very well
into the implementation.
---
llvm/include/llvm/MC/MCDirectives.h | 4 +
llvm/include/llvm/MC/MCGOFFAttributes.h | 8 +
llvm/include/llvm/MC/MCGOFFStreamer.h | 3 +
llvm/include/llvm/MC/MCSymbolGOFF.h | 28 +++-
llvm/lib/MC/GOFFObjectWriter.cpp | 21 +++
llvm/lib/MC/MCAsmStreamer.cpp | 3 +
llvm/lib/MC/MCELFStreamer.cpp | 2 +
llvm/lib/MC/MCGOFFStreamer.cpp | 19 +++
llvm/lib/MC/MCMachOStreamer.cpp | 2 +
llvm/lib/MC/MCSymbolGOFF.cpp | 28 ++--
.../MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 158 +++++++++++++++++-
.../MCTargetDesc/SystemZHLASMAsmStreamer.h | 7 +-
.../MCTargetDesc/SystemZTargetStreamer.cpp | 17 +-
.../MCTargetDesc/SystemZTargetStreamer.h | 7 +-
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 23 +++
llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll | 2 +-
llvm/test/CodeGen/SystemZ/zos-section-1.ll | 52 ++++--
llvm/test/CodeGen/SystemZ/zos-section-2.ll | 34 ++--
llvm/test/CodeGen/SystemZ/zos-symbol-1.ll | 37 ++++
19 files changed, 395 insertions(+), 60 deletions(-)
create mode 100644 llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
diff --git a/llvm/include/llvm/MC/MCDirectives.h b/llvm/include/llvm/MC/MCDirectives.h
index f8b7e05b3719b..f69144367c8e7 100644
--- a/llvm/include/llvm/MC/MCDirectives.h
+++ b/llvm/include/llvm/MC/MCDirectives.h
@@ -48,6 +48,10 @@ enum MCSymbolAttr {
MCSA_WeakDefAutoPrivate, ///< .weak_def_can_be_hidden (MachO)
MCSA_WeakAntiDep, ///< .weak_anti_dep (COFF)
MCSA_Memtag, ///< .memtag (ELF)
+
+ // Attributes specific for HLASM.
+ MCSA_Code, ///< symbol is code (GOFF)
+ MCSA_Data, ///< symbol is data (GOFF)
};
enum MCDataRegionType {
diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index c996f0cae2c69..1631d59462935 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -80,6 +80,14 @@ struct PRAttr {
uint32_t SortKey = 0;
};
+// Attributes for ER symbols.
+struct ERAttr {
+ GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
+ GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong;
+ GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
+ GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
+};
+
// Predefined GOFF class names.
constexpr StringLiteral CLASS_CODE = "C_CODE64";
constexpr StringLiteral CLASS_WSA = "C_WSA64";
diff --git a/llvm/include/llvm/MC/MCGOFFStreamer.h b/llvm/include/llvm/MC/MCGOFFStreamer.h
index 6fa6e6481347f..3d13ddf216aa3 100644
--- a/llvm/include/llvm/MC/MCGOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCGOFFStreamer.h
@@ -14,6 +14,7 @@
namespace llvm {
class GOFFObjectWriter;
+class MCSymbolGOFF;
class MCGOFFStreamer : public MCObjectStreamer {
@@ -34,6 +35,8 @@ class MCGOFFStreamer : public MCObjectStreamer {
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Align ByteAlignment) override {}
+
+ void emitExterns();
};
} // end namespace llvm
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index b58b520cc5c49..58305a00ec235 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -23,13 +23,21 @@ namespace llvm {
class MCSymbolGOFF : public MCSymbol {
// Associated data area of the section. Needs to be emitted first.
- MCSectionGOFF *ADA;
+ MCSectionGOFF *ADA = nullptr;
+
+ // Owner of the symbol if symbol is an external reference. External references
+ // need a section, too, but adding them to a section would make the symbol
+ // defined.
+ MCSectionGOFF *Owner = nullptr;
GOFF::LDAttr LDAttributes;
+ GOFF::ERAttr ERAttributes;
+
+ GOFF::ESDExecutable CodeData = GOFF::ESDExecutable::ESD_EXE_Unspecified;
enum SymbolFlags : uint16_t {
SF_LD = 0x01, // LD attributes are set.
- // Leave place for EX attributes.
+ SF_ER = 0x02, // ER attributes are set.
SF_Hidden = 0x04, // Symbol is hidden, aka not exported.
SF_Weak = 0x08, // Symbol is weak.
};
@@ -46,12 +54,25 @@ class MCSymbolGOFF : public MCSymbol {
GOFF::LDAttr &getLDAttributes() { return LDAttributes; }
bool hasLDAttributes() const { return getFlags() & SF_LD; }
+ void setERAttributes(GOFF::ERAttr Attr) {
+ modifyFlags(SF_ER, SF_ER);
+ ERAttributes = Attr;
+ }
+ const GOFF::ERAttr &getERAttributes() const { return ERAttributes; }
+ GOFF::ERAttr &getERAttributes() { return ERAttributes; }
+ bool hasERAttributes() const { return getFlags() & SF_ER; }
+
void setADA(MCSectionGOFF *AssociatedDataArea) {
ADA = AssociatedDataArea;
AssociatedDataArea->RequiresNonZeroLength = true;
}
MCSectionGOFF *getADA() const { return ADA; }
+ void setOwner(MCSectionGOFF *Owner) {
+ this->Owner = Owner;
+ }
+ MCSectionGOFF *getOwner() const { return Owner; }
+
bool isExternal() const { return IsExternal; }
void setExternal(bool Value) const { IsExternal = Value; }
@@ -64,6 +85,9 @@ class MCSymbolGOFF : public MCSymbol {
void setWeak(bool Value = true) { modifyFlags(Value ? SF_Weak : 0, SF_Weak); }
bool isWeak() const { return getFlags() & SF_Weak; }
+ void setCodeData(GOFF::ESDExecutable Value) { CodeData = Value; }
+ GOFF::ESDExecutable getCodeData() const { return CodeData; }
+
void initAttributes();
};
} // end namespace llvm
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index b42ba148ef65b..51f95813eabc8 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -266,6 +266,17 @@ class GOFFSymbol {
BehavAttrs.setBindingScope(Attr.BindingScope);
BehavAttrs.setAlignment(EDAttr.Alignment);
}
+
+ GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
+ const GOFF::ERAttr &Attr)
+ : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID),
+ SymbolType(GOFF::ESD_ST_ExternalReference),
+ NameSpace(GOFF::ESD_NS_NormalName) {
+ BehavAttrs.setExecutable(Attr.Executable);
+ BehavAttrs.setBindingStrength(Attr.BindingStrength);
+ BehavAttrs.setLinkageType(Attr.Linkage);
+ BehavAttrs.setBindingScope(Attr.BindingScope);
+ }
};
class GOFFWriter {
@@ -279,6 +290,7 @@ class GOFFWriter {
void defineSectionSymbols(const MCSectionGOFF &Section);
void defineLabel(const MCSymbolGOFF &Symbol);
+ void defineExtern(const MCSymbolGOFF &Symbol);
void defineSymbols();
public:
@@ -332,6 +344,12 @@ void GOFFWriter::defineLabel(const MCSymbolGOFF &Symbol) {
writeSymbol(LD);
}
+void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) {
+ GOFFSymbol ER(Symbol.getName(), Symbol.getIndex(),
+ Symbol.getOwner()->getOrdinal(), Symbol.getERAttributes());
+ writeSymbol(ER);
+}
+
void GOFFWriter::defineSymbols() {
unsigned Ordinal = 0;
// Process all sections.
@@ -349,6 +367,9 @@ void GOFFWriter::defineSymbols() {
if (Symbol.hasLDAttributes()) {
Symbol.setIndex(++Ordinal);
defineLabel(Symbol);
+ } else if (Symbol.hasERAttributes()) {
+ Symbol.setIndex(++Ordinal);
+ defineExtern(Symbol);
}
}
}
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 885fa55b65d50..60e3757f60fed 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -774,6 +774,9 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
// Assemblers currently do not support a .cold directive.
case MCSA_Exported:
// Non-AIX assemblers currently do not support exported visibility.
+ case MCSA_Code:
+ case MCSA_Data:
+ // Only for HLASM.
return false;
case MCSA_Memtag:
OS << "\t.memtag\t";
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 1bc1b92610871..4d4148c506b4f 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -151,6 +151,8 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
case MCSA_IndirectSymbol:
case MCSA_Exported:
case MCSA_WeakAntiDep:
+ case MCSA_Code:
+ case MCSA_Data:
return false;
case MCSA_NoDeadStrip:
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index c76e8cd1dc3c8..62a9117fe895f 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCGOFFStreamer.h"
+#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
@@ -75,6 +76,12 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Memtag:
return false;
+ case MCSA_Code:
+ Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
+ break;
+ case MCSA_Data:
+ Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
+ break;
case MCSA_Global:
Symbol->setExternal(true);
break;
@@ -94,6 +101,18 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
return true;
}
+void MCGOFFStreamer::emitExterns() {
+ for (auto &Symbol : getAssembler().symbols()) {
+ if (Symbol.isTemporary())
+ continue;
+ if (Symbol.isRegistered()) {
+ auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
+ Sym.setOwner(static_cast<MCSectionGOFF *>(getCurrentSection().first));
+ Sym.initAttributes();
+ }
+ }
+}
+
MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
std::unique_ptr<MCObjectWriter> &&OW,
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 2b7a248e6d109..da148f81012f7 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -299,6 +299,8 @@ bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Exported:
case MCSA_Memtag:
case MCSA_WeakAntiDep:
+ case MCSA_Code:
+ case MCSA_Data:
return false;
case MCSA_Global:
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 86de21b11bc0a..5e248dea033a4 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -13,20 +13,26 @@
using namespace llvm;
void MCSymbolGOFF::initAttributes() {
- if (hasLDAttributes())
+ // Temporary labels are not emitted into the object file.
+ if (isTemporary())
return;
+ // Do not initialize the attributes multiple times.
+ if (hasLDAttributes() || hasERAttributes())
+ return;
+
+ GOFF::ESDBindingScope BindingScope =
+ isExternal()
+ ? (isExported() ? GOFF::ESD_BSC_ImportExport : GOFF::ESD_BSC_Library)
+ : GOFF::ESD_BSC_Section;
+ GOFF::ESDBindingStrength BindingStrength =
+ isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
+ : GOFF::ESDBindingStrength::ESD_BST_Strong;
+
if (isDefined()) {
MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(getSection());
- GOFF::ESDBindingScope BindingScope =
- isExternal() ? (isExported() ? GOFF::ESD_BSC_ImportExport
- : GOFF::ESD_BSC_Library)
- : GOFF::ESD_BSC_Section;
- GOFF::ESDBindingStrength BindingStrength =
- isWeak() ? GOFF::ESDBindingStrength::ESD_BST_Weak
- : GOFF::ESDBindingStrength::ESD_BST_Strong;
if (Section.isED()) {
- setLDAttributes(GOFF::LDAttr{false, GOFF::ESD_EXE_CODE, BindingStrength,
+ setLDAttributes(GOFF::LDAttr{false, CodeData, BindingStrength,
GOFF::ESD_LT_XPLink, GOFF::ESD_AMODE_64,
BindingScope});
} else if (Section.isPR()) {
@@ -34,6 +40,8 @@ void MCSymbolGOFF::initAttributes() {
// TODO Does it make sense to it to here?
} else
llvm_unreachable("Unexpected section type for label");
+ } else {
+ setERAttributes(GOFF::ERAttr{CodeData, BindingStrength,
+ GOFF::ESD_LT_XPLink, BindingScope});
}
- // TODO Handle external symbol.
}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 72bb37265259e..8553f8bc14f56 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -8,12 +8,19 @@
#include "SystemZHLASMAsmStreamer.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/BinaryFormat/GOFF.h"
+#include "llvm/MC/MCGOFFAttributes.h"
+#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Signals.h"
#include <sstream>
using namespace llvm;
+void SystemZHLASMAsmStreamer::visitUsedSymbol(const MCSymbol &Sym) {
+ Assembler->registerSymbol(Sym);
+}
+
void SystemZHLASMAsmStreamer::EmitEOL() {
// Comments are emitted on a new line before the instruction.
if (IsVerboseAsm)
@@ -183,17 +190,132 @@ void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
EmitEOL();
}
+static void emitXATTR(raw_ostream &OS, StringRef Name,
+ GOFF::ESDLinkageType Linkage,
+ GOFF::ESDExecutable Executable,
+ GOFF::ESDBindingScope BindingScope) {
+ llvm::ListSeparator Sep(",");
+ OS << Name << " XATTR ";
+ OS << Sep << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK")
+ << ")";
+ if (Executable != GOFF::ESD_EXE_Unspecified)
+ OS << Sep << "REFERENCE("
+ << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA") << ")";
+ if (BindingScope != GOFF::ESD_BSC_Unspecified) {
+ OS << Sep << "SCOPE(";
+ switch (BindingScope) {
+ case GOFF::ESD_BSC_Section:
+ OS << "SECTION";
+ break;
+ case GOFF::ESD_BSC_Module:
+ OS << "MODULE";
+ break;
+ case GOFF::ESD_BSC_Library:
+ OS << "LIBRARY";
+ break;
+ case GOFF::ESD_BSC_ImportExport:
+ OS << "EXPORT";
+ break;
+ default:
+ break;
+ }
+ OS << ')';
+ }
+ OS << '\n';
+}
+
+static bool sameNameAsCSECT(MCSymbolGOFF *Sym) {
+ if (Sym->hasLDAttributes() && Sym->isInSection()) {
+ MCSectionGOFF &ED = static_cast<MCSectionGOFF &>(Sym->getSection());
+ return Sym->getName() == ED.getParent()->getName();
+ }
+ return false;
+}
+
void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+ MCSymbolGOFF *Sym = static_cast<MCSymbolGOFF *>(Symbol);
+
+ MCStreamer::emitLabel(Sym, Loc);
+ Sym->initAttributes();
+
+ // Emit ENTRY statement only if not implied by CSECT.
+ bool EmitEntry = !sameNameAsCSECT(Sym);
+
+ if (!Sym->isTemporary() && Sym->hasLDAttributes()) {
+ GOFF::LDAttr &LD = Sym->getLDAttributes();
+ if (EmitEntry) {
+ OS << " ENTRY " << Sym->getName();
+ EmitEOL();
+ }
- MCStreamer::emitLabel(Symbol, Loc);
+ emitXATTR(OS, Sym->getName(), LD.Linkage, LD.Executable, LD.BindingScope);
+ EmitEOL();
+ }
- Symbol->print(OS, MAI);
// TODO Need to adjust this based on Label type
- OS << " DS 0H";
- // TODO Update LabelSuffix in SystemZMCAsmInfoGOFF once tests have been
- // moved to HLASM syntax.
- // OS << MAI->getLabelSuffix();
- EmitEOL();
+ if (EmitEntry) {
+ OS << Sym->getName() << " DS 0H";
+ // TODO Update LabelSuffix in SystemZMCAsmInfoGOFF once tests have been
+ // moved to HLASM syntax.
+ // OS << MAI->getLabelSuffix();
+ EmitEOL();
+ }
+}
+
+bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
+ MCSymbolAttr Attribute) {
+ auto *Symbol = static_cast<MCSymbolGOFF *>(Sym);
+ switch (Attribute) {
+ case MCSA_Invalid:
+ case MCSA_Cold:
+ case MCSA_ELF_TypeFunction:
+ case MCSA_ELF_TypeIndFunction:
+ case MCSA_ELF_TypeObject:
+ case MCSA_ELF_TypeTLS:
+ case MCSA_ELF_TypeCommon:
+ case MCSA_ELF_TypeNoType:
+ case MCSA_ELF_TypeGnuUniqueObject:
+ case MCSA_LGlobal:
+ case MCSA_Extern:
+ case MCSA_Exported:
+ case MCSA_IndirectSymbol:
+ case MCSA_Internal:
+ case MCSA_LazyReference:
+ case MCSA_NoDeadStrip:
+ case MCSA_SymbolResolver:
+ case MCSA_AltEntry:
+ case MCSA_PrivateExtern:
+ case MCSA_Protected:
+ case MCSA_Reference:
+ case MCSA_WeakDefinition:
+ case MCSA_WeakDefAutoPrivate:
+ case MCSA_WeakAntiDep:
+ case MCSA_Memtag:
+ return false;
+
+ case MCSA_Code:
+ Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
+ break;
+ case MCSA_Data:
+ Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
+ break;
+ case MCSA_Global:
+ Symbol->setExternal(true);
+ break;
+ case MCSA_Local:
+ Symbol->setExternal(false);
+ break;
+ case MCSA_Weak:
+ case MCSA_WeakReference:
+ Symbol->setExternal(true);
+ Symbol->setWeak();
+ break;
+ case MCSA_Hidden:
+ Symbol->setHidden(true);
+ break;
+ }
+
+ return true;
}
void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {
@@ -276,6 +398,7 @@ void SystemZHLASMAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
assert(getCurrentSectionOnly() &&
"Cannot emit contents before setting section!");
+ MCStreamer::emitValueImpl(Value, Size, Loc);
OS << " DC ";
emitHLASMValueImpl(Value, Size, true);
EmitEOL();
@@ -285,3 +408,24 @@ void SystemZHLASMAsmStreamer::emitEnd() {
OS << " END";
EmitEOL();
}
+
+void SystemZHLASMAsmStreamer::emitExterns() {
+ for (auto &Symbol : getAssembler().symbols()) {
+ if (Symbol.isTemporary())
+ continue;
+ if (Symbol.isRegistered()) {
+ auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
+ Sym.setOwner(static_cast<MCSectionGOFF *>(getCurrentSection().first));
+ Sym.initAttributes();
+ GOFF::ERAttr &ER = Sym.getERAttributes();
+ OS << " "
+ << (ER.BindingStrength == GOFF::ESDBindingStrength::ESD_BST_Weak
+ ? "WXTRN"
+ : "EXTRN")
+ << " " << Sym.getName();
+ EmitEOL();
+ emitXATTR(OS, Sym.getName(), ER.Linkage, ER.Executable, ER.BindingScope);
+ EmitEOL();
+ }
+ }
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
index 93b1ac4d901aa..81cfdad472244 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
@@ -28,6 +28,7 @@
#include "llvm/Support/FormattedStream.h"
namespace llvm {
+class MCSymbolGOFF;
class SystemZHLASMAsmStreamer final : public MCStreamer {
constexpr static size_t InstLimit = 80;
@@ -100,14 +101,13 @@ class SystemZHLASMAsmStreamer final : public MCStreamer {
/// @name MCStreamer Interface
/// @{
+ void visitUsedSymbol(const MCSymbol &Sym) override;
void changeSection(MCSection *Section, uint32_t Subsection) override;
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
void emitLabel(MCSymbol *Symbol, SMLoc Loc) override;
- bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
- return false;
- }
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Align ByteAlignment) override {}
@@ -123,6 +123,7 @@ class SystemZHLASMAsmStreamer final : public MCStreamer {
/// @}
void emitEnd();
+ void emitExterns();
};
} // namespace llvm
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
index 1a3e373f25374..d25c77e21d9f8 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
@@ -15,6 +15,7 @@
#include "SystemZTargetStreamer.h"
#include "SystemZHLASMAsmStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCGOFFStreamer.h"
#include "llvm/MC/MCObjectFileInfo.h"
using namespace llvm;
@@ -38,12 +39,12 @@ SystemZHLASMAsmStreamer &SystemZTargetHLASMStreamer::getHLASMStreamer() {
return static_cast<SystemZHLASMAsmStreamer &>(getStreamer());
}
-void SystemZTargetHLASMStreamer::emitExtern(StringRef Sym) {
- getStreamer().emitRawText(Twine(" EXTRN ") + Twine(Sym));
-}
-
void SystemZTargetHLASMStreamer::emitEnd() { getHLASMStreamer().emitEnd(); }
+void SystemZTargetHLASMStreamer::emitExterns() {
+ getHLASMStreamer().emitExterns();
+}
+
// HLASM statements can only perform a single operation at a time
const MCExpr *SystemZTargetHLASMStreamer::createWordDiffExpr(
MCContext &Ctx, const MCSymbol *Hi, const MCSymbol *Lo) {
@@ -66,3 +67,11 @@ const MCExpr *SystemZTargetGOFFStreamer::createWordDiffExpr(
MCSymbolRefExpr::create(Lo, Ctx), Ctx),
MCConstantExpr::create(1, Ctx), Ctx);
}
+
+MCGOFFStreamer &SystemZTargetGOFFStreamer::getGOFFStreamer() {
+ return static_cast<MCGOFFStreamer &>(getStreamer());
+}
+
+void SystemZTargetGOFFStreamer::emitExterns() {
+ getGOFFStreamer().emitExterns();
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
index 3fc09bc8c683a..31433cc9739c6 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
@@ -20,6 +20,7 @@
#include <utility>
namespace llvm {
+class MCGOFFStreamer;
class SystemZHLASMAsmStreamer;
class SystemZTargetStreamer : public MCTargetStreamer {
@@ -57,8 +58,8 @@ class SystemZTargetStreamer : public MCTargetStreamer {
virtual void emitMachine(StringRef CPUOrCommand) {};
- virtual void emitExtern(StringRef Str) {};
virtual void emitEnd() {};
+ virtual void emitExterns() {};
virtual const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) {
@@ -69,6 +70,8 @@ class SystemZTargetStreamer : public MCTargetStreamer {
class SystemZTargetGOFFStreamer : public SystemZTargetStreamer {
public:
SystemZTargetGOFFStreamer(MCStreamer &S) : SystemZTargetStreamer(S) {}
+ MCGOFFStreamer &getGOFFStreamer();
+ void emitExterns() override;
const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) override;
};
@@ -80,8 +83,8 @@ class SystemZTargetHLASMStreamer : public SystemZTargetStreamer {
SystemZTargetHLASMStreamer(MCStreamer &S, formatted_raw_ostream &OS)
: SystemZTargetStreamer(S), OS(OS) {}
SystemZHLASMAsmStreamer &getHLASMStreamer();
- void emitExtern(StringRef Sym) override;
void emitEnd() override;
+ void emitExterns() override;
const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) override;
};
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index e31d7c6a86476..87ff2f0353161 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -26,6 +26,7 @@
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCSectionELF.h"
@@ -1112,6 +1113,22 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
if (TT.isOSzOS()) {
emitADASection();
emitIDRLSection(M);
+ // Emit EXTRN declarations.
+ OutStreamer->pushSection();
+ for (auto &GO : M.global_objects()) {
+ if (GO.isDeclaration()) {
+ MCSymbol *Sym = TM.getSymbol(&GO);
+ OutStreamer->emitSymbolAttribute(
+ Sym, GO.hasExternalWeakLinkage() ? MCSA_WeakReference : MCSA_Global);
+ OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO) ? MCSA_Code
+ : MCSA_Data);
+ }
+ }
+ OutStreamer->switchSection(
+ static_cast<MCSectionGOFF *>(getObjFileLowering().getTextSection())
+ ->getParent());
+ getTargetStreamer()->emitExterns();
+ OutStreamer->popSection();
}
emitAttributes(M);
// Emit the END instruction in case of HLASM output. This must be the last
@@ -1570,6 +1587,9 @@ void SystemZAsmPrinter::emitPPA2(Module &M) {
// Make CELQSTRT symbol.
const char *StartSymbolName = "CELQSTRT";
MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
+ OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Code);
+ // TODO Mark as OS linkage.
+ OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Global);
// Create symbol and assign to class field for use in PPA1.
PPA2Sym = OutContext.createTempSymbol("PPA2", false);
@@ -1734,6 +1754,9 @@ void SystemZAsmPrinter::emitFunctionEntryLabel() {
OutStreamer->AddComment(" Bit 2: 0 = Does not use alloca");
}
OutStreamer->emitInt32(DSAAndFlags);
+
+ // Functions denote CODE.
+ OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Code);
}
AsmPrinter::emitFunctionEntryLabel();
diff --git a/llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll b/llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll
index b28f0dd17599a..43ac737b29778 100644
--- a/llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple s390x-ibm-zos < %s | FileCheck %s
+; RUN: llc -mtriple s390x-ibm-zos -emit-gnuas-syntax-on-zos=false < %s | FileCheck %s
define signext i32 @_Z9computeitv() personality ptr @__zos_cxx_personality_v2 {
ret i32 0
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index 6caa8f4d607de..0e6619157261d 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -104,34 +104,50 @@ entry:
; CHECK-NEXT: 000300 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000310 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; ESD record, type ER.
+; The name is CELQSTRT.
+; CHECK-NEXT: 000320 03 00 00 04 [[CELQSTRT:00 00 00 09]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000360 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+
; ESD record, type LD.
; The name is me.
-; CHECK-NEXT: 000320 03 00 00 02 [[ME:00 00 00 09]] [[C_CODE64]] 00 00 00 00
-; CHECK-NEXT: 000330 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000360 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
+; CHECK-NEXT: 000370 03 00 00 02 [[ME:00 00 00 0a]] [[C_CODE64]] 00 00 00 00
+; CHECK-NEXT: 000380 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000390 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003a0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
+; CHECK-NEXT: 0003b0 00 04 20 00 00 00 00 02 94 85 00 00 00 00 00 00
+
+; ESD record, type ER.
+; The name is other.
+; CHECK-NEXT: 0003c0 03 00 00 04 [[OTHER:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003e0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000400 00 04 20 00 00 00 00 05 96 a3 88 85 99 00 00 00
; Text record for the code section C_CODE64.
; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 000370 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000380 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
+; CHECK-NEXT: 000410 03 11 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} 00 c3 00 c5 00 c5 00 f1
; Text record for the section .&ppa2.
-; CHECK: 000410 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000420 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 0004b0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the ADA section test#S.
-; CHECK: 000460 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000470 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000500 03 10 00 00 [[TESTS]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the section B_IDRL.
-; CHECK: 0004b0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0004c0 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000550 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
; End record.
-; CHECK: 000500 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 0005a0 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index 0f608c1206b96..bf3fd8234eb33 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -147,29 +147,37 @@ source_filename = "test.ll"
; CHECK-NEXT: 0004e0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 0004f0 00 01 20 00 00 00 00 06 a3 85 a2 a3 7b c3 00 00
+; ESD record, type ER.
+; The name is CELQSTRT.
+; CHECK-NEXT: 000500 03 00 00 04 [[CELQSTRT:00 00 00 0f]] [[ROOTSD]] 00 00 00 00
+; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
+; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000540 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+
; Text record for the code section C_CODE64.
; The regular expression matches the lower byte of the length.
-; CHECK-NEXT: 000500 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000510 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK-NEXT: 000550 03 10 00 00 [[C_CODE64]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the section .&ppa2.
-; CHECK: 000550 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000560 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 0005a0 03 10 00 00 [[PPA2]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 {{..}} {{.*}}
; Text record for the section data.
; Length is 4, and the content is 0x2a = 42.
-; CHECK: 0005a0 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 0005b0 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
+; CHECK: 0005f0 03 10 00 00 [[DATA_PR]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000600 00 00 00 00 00 00 00 04 00 00 00 2a 00 00 00 00
; There is no text record for section bss!
; Text record for the section B_IDRL.
-; CHECK: 0005f0 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000600 00 00 00 00 00 00 00 {{..}} {{.*}}
+; CHECK: 000640 03 10 00 01 [[BIDRL]] 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 000650 00 00 00 00 00 00 00 {{..}} {{.*}}
; End record.
-; CHECK: 000640 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-; CHECK-NEXT: 000680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK: 000690 03 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+; CHECK-NEXT: 0006d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
new file mode 100644
index 0000000000000..eaae1b7bbcfd2
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
@@ -0,0 +1,37 @@
+; RUN: llc <%s --mtriple s390x-ibm-zos -emit-gnuas-syntax-on-zos=false | FileCheck %s
+
+declare extern_weak void @other1(...)
+declare void @other2(...)
+
+define internal void @me1() {
+entry:
+ ret void
+}
+
+define hidden void @me2() {
+entry:
+ tail call void @other1()
+ ret void
+}
+
+define default void @me3() {
+entry:
+ tail call void @other2()
+ ret void
+}
+
+; CHECK: ENTRY me1
+; CHECK-NEXT: me1 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(SECTION)
+
+; CHECK: ENTRY me2
+; CHECK-NEXT: me2 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(LIBRARY)
+
+; CHECK: ENTRY me3
+; CHECK-NEXT: me3 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+
+; CHECK: EXTRN CELQSTRT
+; CHECK-NEXT: CELQSTRT XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+; CHECK-NEXT: WXTRN other1
+; CHECK-NEXT: other1 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+; CHECK-NEXT: EXTRN other2
+; CHECK-NEXT: other2 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
\ No newline at end of file
>From c19957c59feabbcfb36107f019e915acb6787050 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Mon, 3 Nov 2025 17:36:29 -0500
Subject: [PATCH 3/7] Fix some formatting issues.
---
llvm/include/llvm/MC/MCSymbolGOFF.h | 4 +---
llvm/lib/MC/MCSymbolGOFF.cpp | 4 ++--
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 5 +++--
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 58305a00ec235..301be80a8b575 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -68,9 +68,7 @@ class MCSymbolGOFF : public MCSymbol {
}
MCSectionGOFF *getADA() const { return ADA; }
- void setOwner(MCSectionGOFF *Owner) {
- this->Owner = Owner;
- }
+ void setOwner(MCSectionGOFF *Owner) { this->Owner = Owner; }
MCSectionGOFF *getOwner() const { return Owner; }
bool isExternal() const { return IsExternal; }
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 5e248dea033a4..33c7d658038bd 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -41,7 +41,7 @@ void MCSymbolGOFF::initAttributes() {
} else
llvm_unreachable("Unexpected section type for label");
} else {
- setERAttributes(GOFF::ERAttr{CodeData, BindingStrength,
- GOFF::ESD_LT_XPLink, BindingScope});
+ setERAttributes(GOFF::ERAttr{CodeData, BindingStrength, GOFF::ESD_LT_XPLink,
+ BindingScope});
}
}
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 87ff2f0353161..0a02397ab100b 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1118,8 +1118,9 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
for (auto &GO : M.global_objects()) {
if (GO.isDeclaration()) {
MCSymbol *Sym = TM.getSymbol(&GO);
- OutStreamer->emitSymbolAttribute(
- Sym, GO.hasExternalWeakLinkage() ? MCSA_WeakReference : MCSA_Global);
+ OutStreamer->emitSymbolAttribute(Sym, GO.hasExternalWeakLinkage()
+ ? MCSA_WeakReference
+ : MCSA_Global);
OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO) ? MCSA_Code
: MCSA_Data);
}
>From 2fa73af9d9f9fc87c939e175f90343aa8738d638 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 7 Nov 2025 15:46:26 -0500
Subject: [PATCH 4/7] ER symbols also need to set AMODE
---
llvm/include/llvm/MC/MCGOFFAttributes.h | 1 +
llvm/lib/MC/GOFFObjectWriter.cpp | 1 +
llvm/lib/MC/MCSymbolGOFF.cpp | 2 +-
llvm/test/CodeGen/SystemZ/zos-section-1.ll | 4 ++--
llvm/test/CodeGen/SystemZ/zos-section-2.ll | 2 +-
5 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h
index 1631d59462935..e771f36f35346 100644
--- a/llvm/include/llvm/MC/MCGOFFAttributes.h
+++ b/llvm/include/llvm/MC/MCGOFFAttributes.h
@@ -85,6 +85,7 @@ struct ERAttr {
GOFF::ESDExecutable Executable = GOFF::ESD_EXE_Unspecified;
GOFF::ESDBindingStrength BindingStrength = GOFF::ESD_BST_Strong;
GOFF::ESDLinkageType Linkage = GOFF::ESD_LT_XPLink;
+ GOFF::ESDAmode Amode;
GOFF::ESDBindingScope BindingScope = GOFF::ESD_BSC_Unspecified;
};
diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp
index 51f95813eabc8..07aecf13bce37 100644
--- a/llvm/lib/MC/GOFFObjectWriter.cpp
+++ b/llvm/lib/MC/GOFFObjectWriter.cpp
@@ -275,6 +275,7 @@ class GOFFSymbol {
BehavAttrs.setExecutable(Attr.Executable);
BehavAttrs.setBindingStrength(Attr.BindingStrength);
BehavAttrs.setLinkageType(Attr.Linkage);
+ BehavAttrs.setAmode(Attr.Amode);
BehavAttrs.setBindingScope(Attr.BindingScope);
}
};
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 33c7d658038bd..2d067155d45aa 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -42,6 +42,6 @@ void MCSymbolGOFF::initAttributes() {
llvm_unreachable("Unexpected section type for label");
} else {
setERAttributes(GOFF::ERAttr{CodeData, BindingStrength, GOFF::ESD_LT_XPLink,
- BindingScope});
+ GOFF::ESD_AMODE_64, BindingScope});
}
}
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index 0e6619157261d..728686127bacd 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -109,7 +109,7 @@ entry:
; CHECK-NEXT: 000320 03 00 00 04 [[CELQSTRT:00 00 00 09]] [[ROOTSD]] 00 00 00 00
; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000360 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
; ESD record, type LD.
@@ -125,7 +125,7 @@ entry:
; CHECK-NEXT: 0003c0 03 00 00 04 [[OTHER:00 00 00 0b]] [[ROOTSD]] 00 00 00 00
; CHECK-NEXT: 0003d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 0003e0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 0003f0 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000400 00 04 20 00 00 00 00 05 96 a3 88 85 99 00 00 00
; Text record for the code section C_CODE64.
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index bf3fd8234eb33..d3a0d75acba88 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -152,7 +152,7 @@ source_filename = "test.ll"
; CHECK-NEXT: 000500 03 00 00 04 [[CELQSTRT:00 00 00 0f]] [[ROOTSD]] 00 00 00 00
; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
-; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02
+; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
; CHECK-NEXT: 000540 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
; Text record for the code section C_CODE64.
>From 43dcc134f279af6836a635748c8db084f420a92f Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 7 Nov 2025 17:49:56 -0500
Subject: [PATCH 5/7] Add linkage attribute
---
llvm/include/llvm/MC/MCDirectives.h | 4 ++--
llvm/include/llvm/MC/MCSymbolGOFF.h | 4 ++++
llvm/lib/MC/MCELFStreamer.cpp | 3 +++
llvm/lib/MC/MCGOFFStreamer.cpp | 6 ++++++
llvm/lib/MC/MCMachOStreamer.cpp | 2 ++
llvm/lib/MC/MCSymbolGOFF.cpp | 7 +++----
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 2 +-
llvm/test/CodeGen/SystemZ/zos-section-1.ll | 2 +-
llvm/test/CodeGen/SystemZ/zos-section-2.ll | 2 +-
9 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/MC/MCDirectives.h b/llvm/include/llvm/MC/MCDirectives.h
index f69144367c8e7..39ecadb9cd029 100644
--- a/llvm/include/llvm/MC/MCDirectives.h
+++ b/llvm/include/llvm/MC/MCDirectives.h
@@ -48,10 +48,10 @@ enum MCSymbolAttr {
MCSA_WeakDefAutoPrivate, ///< .weak_def_can_be_hidden (MachO)
MCSA_WeakAntiDep, ///< .weak_anti_dep (COFF)
MCSA_Memtag, ///< .memtag (ELF)
-
- // Attributes specific for HLASM.
MCSA_Code, ///< symbol is code (GOFF)
MCSA_Data, ///< symbol is data (GOFF)
+ MCSA_OSLinkage, ///< symbol uses OS linkage (GOFF)
+ MCSA_XPLinkage, ///< symbol uses XP linkage (GOFF)
};
enum MCDataRegionType {
diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index 301be80a8b575..f1397a6b3822c 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -34,6 +34,7 @@ class MCSymbolGOFF : public MCSymbol {
GOFF::ERAttr ERAttributes;
GOFF::ESDExecutable CodeData = GOFF::ESDExecutable::ESD_EXE_Unspecified;
+ GOFF::ESDLinkageType Linkage = GOFF::ESDLinkageType::ESD_LT_XPLink;
enum SymbolFlags : uint16_t {
SF_LD = 0x01, // LD attributes are set.
@@ -86,6 +87,9 @@ class MCSymbolGOFF : public MCSymbol {
void setCodeData(GOFF::ESDExecutable Value) { CodeData = Value; }
GOFF::ESDExecutable getCodeData() const { return CodeData; }
+ void setLinkage(GOFF::ESDLinkageType Value) { Linkage = Value; }
+ GOFF::ESDLinkageType getLinkage() const { return Linkage; }
+
void initAttributes();
};
} // end namespace llvm
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 4d4148c506b4f..a296977f7ae98 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -18,6 +18,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
@@ -153,6 +154,8 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
case MCSA_WeakAntiDep:
case MCSA_Code:
case MCSA_Data:
+ case MCSA_OSLinkage:
+ case MCSA_XPLinkage:
return false;
case MCSA_NoDeadStrip:
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 62a9117fe895f..8450f7cfb5381 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -82,6 +82,12 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Data:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
break;
+ case MCSA_OSLinkage:
+ Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_OS);
+ break;
+ case MCSA_XPLinkage:
+ Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_XPLink);
+ break;
case MCSA_Global:
Symbol->setExternal(true);
break;
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index da148f81012f7..3b0acd71e2057 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -301,6 +301,8 @@ bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_WeakAntiDep:
case MCSA_Code:
case MCSA_Data:
+ case MCSA_OSLinkage:
+ case MCSA_XPLinkage:
return false;
case MCSA_Global:
diff --git a/llvm/lib/MC/MCSymbolGOFF.cpp b/llvm/lib/MC/MCSymbolGOFF.cpp
index 2d067155d45aa..345572418ecd8 100644
--- a/llvm/lib/MC/MCSymbolGOFF.cpp
+++ b/llvm/lib/MC/MCSymbolGOFF.cpp
@@ -32,16 +32,15 @@ void MCSymbolGOFF::initAttributes() {
if (isDefined()) {
MCSectionGOFF &Section = static_cast<MCSectionGOFF &>(getSection());
if (Section.isED()) {
- setLDAttributes(GOFF::LDAttr{false, CodeData, BindingStrength,
- GOFF::ESD_LT_XPLink, GOFF::ESD_AMODE_64,
- BindingScope});
+ setLDAttributes(GOFF::LDAttr{false, CodeData, BindingStrength, Linkage,
+ GOFF::ESD_AMODE_64, BindingScope});
} else if (Section.isPR()) {
// For data symbols, the attributes are already determind in TLOFI.
// TODO Does it make sense to it to here?
} else
llvm_unreachable("Unexpected section type for label");
} else {
- setERAttributes(GOFF::ERAttr{CodeData, BindingStrength, GOFF::ESD_LT_XPLink,
+ setERAttributes(GOFF::ERAttr{CodeData, BindingStrength, Linkage,
GOFF::ESD_AMODE_64, BindingScope});
}
}
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 0a02397ab100b..193e6ef6d1e64 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1589,7 +1589,7 @@ void SystemZAsmPrinter::emitPPA2(Module &M) {
const char *StartSymbolName = "CELQSTRT";
MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Code);
- // TODO Mark as OS linkage.
+ OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_OSLinkage);
OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Global);
// Create symbol and assign to class field for use in PPA1.
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
index 728686127bacd..cae371b07d0eb 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll
@@ -110,7 +110,7 @@ entry:
; CHECK-NEXT: 000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 000340 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
; CHECK-NEXT: 000350 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000360 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+; CHECK-NEXT: 000360 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
; ESD record, type LD.
; The name is me.
diff --git a/llvm/test/CodeGen/SystemZ/zos-section-2.ll b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
index d3a0d75acba88..f59bace65ca73 100644
--- a/llvm/test/CodeGen/SystemZ/zos-section-2.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-section-2.ll
@@ -153,7 +153,7 @@ source_filename = "test.ll"
; CHECK-NEXT: 000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
; CHECK-NEXT: 000520 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
; CHECK-NEXT: 000530 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 02
-; CHECK-NEXT: 000540 00 04 20 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
+; CHECK-NEXT: 000540 00 04 00 00 00 00 00 08 c3 c5 d3 d8 e2 e3 d9 e3
; Text record for the code section C_CODE64.
; The regular expression matches the lower byte of the length.
>From ee1434b325d46403b98cb1c369b69be04db22a08 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Fri, 7 Nov 2025 18:02:27 -0500
Subject: [PATCH 6/7] Update the asm output for the linkage type
---
llvm/lib/MC/MCAsmStreamer.cpp | 2 ++
.../Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 6 ++++++
llvm/test/CodeGen/SystemZ/zos-symbol-1.ll | 2 +-
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 60e3757f60fed..18db8ef99c2cf 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -776,6 +776,8 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
// Non-AIX assemblers currently do not support exported visibility.
case MCSA_Code:
case MCSA_Data:
+ case MCSA_OSLinkage:
+ case MCSA_XPLinkage:
// Only for HLASM.
return false;
case MCSA_Memtag:
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 8553f8bc14f56..7294d0a12b7ce 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -299,6 +299,12 @@ bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Data:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
break;
+ case MCSA_OSLinkage:
+ Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_OS);
+ break;
+ case MCSA_XPLinkage:
+ Symbol->setLinkage(GOFF::ESDLinkageType::ESD_LT_XPLink);
+ break;
case MCSA_Global:
Symbol->setExternal(true);
break;
diff --git a/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
index eaae1b7bbcfd2..bd4361aaafdcb 100644
--- a/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-symbol-1.ll
@@ -30,7 +30,7 @@ entry:
; CHECK-NEXT: me3 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
; CHECK: EXTRN CELQSTRT
-; CHECK-NEXT: CELQSTRT XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
+; CHECK-NEXT: CELQSTRT XATTR LINKAGE(OS),REFERENCE(CODE),SCOPE(EXPORT)
; CHECK-NEXT: WXTRN other1
; CHECK-NEXT: other1 XATTR LINKAGE(XPLINK),REFERENCE(CODE),SCOPE(EXPORT)
; CHECK-NEXT: EXTRN other2
>From 214d716d483c6536c56fb45138bbca035b25c846 Mon Sep 17 00:00:00 2001
From: Kai Nacke <kai.peter.nacke at ibm.com>
Date: Wed, 19 Nov 2025 13:37:36 -0500
Subject: [PATCH 7/7] Replace MCSA_Code/Data
Use MCSA_ELF_TypeFunction/TypeObject instead.
---
llvm/include/llvm/MC/MCDirectives.h | 2 --
llvm/lib/MC/MCAsmStreamer.cpp | 2 --
llvm/lib/MC/MCELFStreamer.cpp | 2 --
llvm/lib/MC/MCGOFFStreamer.cpp | 6 ++----
llvm/lib/MC/MCMachOStreamer.cpp | 2 --
.../SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp | 6 ++----
llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 9 +++++----
7 files changed, 9 insertions(+), 20 deletions(-)
diff --git a/llvm/include/llvm/MC/MCDirectives.h b/llvm/include/llvm/MC/MCDirectives.h
index 39ecadb9cd029..3b9c4670399c9 100644
--- a/llvm/include/llvm/MC/MCDirectives.h
+++ b/llvm/include/llvm/MC/MCDirectives.h
@@ -48,8 +48,6 @@ enum MCSymbolAttr {
MCSA_WeakDefAutoPrivate, ///< .weak_def_can_be_hidden (MachO)
MCSA_WeakAntiDep, ///< .weak_anti_dep (COFF)
MCSA_Memtag, ///< .memtag (ELF)
- MCSA_Code, ///< symbol is code (GOFF)
- MCSA_Data, ///< symbol is data (GOFF)
MCSA_OSLinkage, ///< symbol uses OS linkage (GOFF)
MCSA_XPLinkage, ///< symbol uses XP linkage (GOFF)
};
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 18db8ef99c2cf..7ff570c7df402 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -774,8 +774,6 @@ bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
// Assemblers currently do not support a .cold directive.
case MCSA_Exported:
// Non-AIX assemblers currently do not support exported visibility.
- case MCSA_Code:
- case MCSA_Data:
case MCSA_OSLinkage:
case MCSA_XPLinkage:
// Only for HLASM.
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index a296977f7ae98..13a7f6d999e61 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -152,8 +152,6 @@ bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
case MCSA_IndirectSymbol:
case MCSA_Exported:
case MCSA_WeakAntiDep:
- case MCSA_Code:
- case MCSA_Data:
case MCSA_OSLinkage:
case MCSA_XPLinkage:
return false;
diff --git a/llvm/lib/MC/MCGOFFStreamer.cpp b/llvm/lib/MC/MCGOFFStreamer.cpp
index 8450f7cfb5381..81472ba5e4de6 100644
--- a/llvm/lib/MC/MCGOFFStreamer.cpp
+++ b/llvm/lib/MC/MCGOFFStreamer.cpp
@@ -51,9 +51,7 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
switch (Attribute) {
case MCSA_Invalid:
case MCSA_Cold:
- case MCSA_ELF_TypeFunction:
case MCSA_ELF_TypeIndFunction:
- case MCSA_ELF_TypeObject:
case MCSA_ELF_TypeTLS:
case MCSA_ELF_TypeCommon:
case MCSA_ELF_TypeNoType:
@@ -76,10 +74,10 @@ bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Memtag:
return false;
- case MCSA_Code:
+ case MCSA_ELF_TypeFunction:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
break;
- case MCSA_Data:
+ case MCSA_ELF_TypeObject:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
break;
case MCSA_OSLinkage:
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 3b0acd71e2057..b8e7772f4e16f 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -299,8 +299,6 @@ bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Exported:
case MCSA_Memtag:
case MCSA_WeakAntiDep:
- case MCSA_Code:
- case MCSA_Data:
case MCSA_OSLinkage:
case MCSA_XPLinkage:
return false;
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index 7294d0a12b7ce..ac0dd84fe9941 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -268,9 +268,7 @@ bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
switch (Attribute) {
case MCSA_Invalid:
case MCSA_Cold:
- case MCSA_ELF_TypeFunction:
case MCSA_ELF_TypeIndFunction:
- case MCSA_ELF_TypeObject:
case MCSA_ELF_TypeTLS:
case MCSA_ELF_TypeCommon:
case MCSA_ELF_TypeNoType:
@@ -293,10 +291,10 @@ bool SystemZHLASMAsmStreamer::emitSymbolAttribute(MCSymbol *Sym,
case MCSA_Memtag:
return false;
- case MCSA_Code:
+ case MCSA_ELF_TypeFunction:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_CODE);
break;
- case MCSA_Data:
+ case MCSA_ELF_TypeObject:
Symbol->setCodeData(GOFF::ESDExecutable::ESD_EXE_DATA);
break;
case MCSA_OSLinkage:
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 193e6ef6d1e64..b895ae9546e5a 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1121,8 +1121,9 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
OutStreamer->emitSymbolAttribute(Sym, GO.hasExternalWeakLinkage()
? MCSA_WeakReference
: MCSA_Global);
- OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO) ? MCSA_Code
- : MCSA_Data);
+ OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO)
+ ? MCSA_ELF_TypeFunction
+ : MCSA_ELF_TypeObject);
}
}
OutStreamer->switchSection(
@@ -1588,7 +1589,7 @@ void SystemZAsmPrinter::emitPPA2(Module &M) {
// Make CELQSTRT symbol.
const char *StartSymbolName = "CELQSTRT";
MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
- OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Code);
+ OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_ELF_TypeFunction);
OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_OSLinkage);
OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Global);
@@ -1757,7 +1758,7 @@ void SystemZAsmPrinter::emitFunctionEntryLabel() {
OutStreamer->emitInt32(DSAAndFlags);
// Functions denote CODE.
- OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Code);
+ OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
}
AsmPrinter::emitFunctionEntryLabel();
More information about the llvm-commits
mailing list