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

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/include/llvm/MC/MCDirectives.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 4 additions & 3 deletions llvm/include/llvm/MC/MCGOFFStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,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 {}
};
Expand Down
19 changes: 17 additions & 2 deletions llvm/include/llvm/MC/MCSymbolGOFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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) {
Expand All @@ -48,6 +52,17 @@ class MCSymbolGOFF : public MCSymbol {
}
MCSectionGOFF *getADA() const { return ADA; }

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();

static bool classof(const MCSymbol *S) { return S->isGOFF(); }
};
} // end namespace llvm
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/MC/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ add_llvm_component_library(LLVMMC
MCSubtargetInfo.cpp
MCSymbol.cpp
MCSymbolELF.cpp
MCSymbolGOFF.cpp
MCSymbolXCOFF.cpp
MCTargetOptions.cpp
MCTargetOptionsCommandFlags.cpp
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/MC/GOFFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,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);
}

Expand Down
58 changes: 58 additions & 0 deletions llvm/lib/MC/MCGOFFStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
#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"
#include "llvm/Support/Casting.h"

using namespace llvm;

Expand All @@ -41,6 +44,61 @@ void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
MCObjectStreamer::changeSection(Section, Subsection);
}

void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCObjectStreamer::emitLabel(Symbol, Loc);
cast<MCSymbolGOFF>(Symbol)->initAttributes();
}

bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
MCSymbolAttr Attribute) {
auto *Symbol = 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,
Expand Down
45 changes: 45 additions & 0 deletions llvm/lib/MC/MCSymbolGOFF.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//===- 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/Casting.h"
#include "llvm/Support/ErrorHandling.h"

using namespace llvm;

void MCSymbolGOFF::initAttributes() {
// Temporary labels are not emitted into the object file.
if (isTemporary())
return;

// Do not initialize the attributes multiple times.
if (hasLDAttributes())
return;

if (isDefined()) {
MCSectionGOFF &Section = 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.
}
81 changes: 74 additions & 7 deletions llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

#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>
Expand Down Expand Up @@ -183,17 +186,74 @@ void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
EmitEOL();
}

static void emitXATTR(raw_ostream &OS, StringRef Name,
GOFF::ESDLinkageType Linkage,
GOFF::ESDExecutable Executable,
GOFF::ESDBindingScope BindingScope) {
OS << Name << " XATTR ";
OS << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK") << "),";
if (Executable != GOFF::ESD_EXE_Unspecified)
OS << "REFERENCE(" << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA")
<< "),";
if (BindingScope != GOFF::ESD_BSC_Unspecified) {
OS << "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 = cast<MCSectionGOFF>(Sym->getSection());
return Sym->getName() == ED.getParent()->getName();
}
return false;
}

void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCSymbolGOFF *Sym = cast<MCSymbolGOFF>(Symbol);

MCStreamer::emitLabel(Sym, Loc);
Sym->initAttributes();

// Emit ENTRY statement only if not implied by CSECT.
bool EmitEntry = !sameNameAsCSECT(Sym);

MCStreamer::emitLabel(Symbol, Loc);
if (!Sym->isTemporary() && Sym->hasLDAttributes()) {
GOFF::LDAttr &LD = Sym->getLDAttributes();
if (EmitEntry) {
OS << " ENTRY " << Sym->getName();
EmitEOL();
}

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();
}
}

void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {
Expand Down Expand Up @@ -285,3 +345,10 @@ void SystemZHLASMAsmStreamer::emitEnd() {
OS << " END";
EmitEOL();
}

void SystemZHLASMAsmStreamer::emitExtern(MCSymbolGOFF &Sym) {
Sym.initAttributes();
OS << " EXTRN " << Sym.getName();
EmitEOL();
// TODO Emit XATTR.
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "llvm/Support/FormattedStream.h"

namespace llvm {
class MCSymbolGOFF;

class SystemZHLASMAsmStreamer final : public MCStreamer {
constexpr static size_t InstLimit = 80;
Expand Down Expand Up @@ -123,6 +124,7 @@ class SystemZHLASMAsmStreamer final : public MCStreamer {
/// @}

void emitEnd();
void emitExtern(MCSymbolGOFF &Sym);
};
} // namespace llvm

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "SystemZHLASMAsmStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/Support/Casting.h"

using namespace llvm;

Expand All @@ -38,8 +40,8 @@ SystemZHLASMAsmStreamer &SystemZTargetHLASMStreamer::getHLASMStreamer() {
return static_cast<SystemZHLASMAsmStreamer &>(getStreamer());
}

void SystemZTargetHLASMStreamer::emitExtern(StringRef Sym) {
getStreamer().emitRawText(Twine(" EXTRN ") + Twine(Sym));
void SystemZTargetHLASMStreamer::emitExtern(MCSymbol *Symbol) {
getHLASMStreamer().emitExtern(*cast<MCSymbolGOFF>(Symbol));
}

void SystemZTargetHLASMStreamer::emitEnd() { getHLASMStreamer().emitEnd(); }
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class SystemZTargetStreamer : public MCTargetStreamer {

virtual void emitMachine(StringRef CPUOrCommand) {};

virtual void emitExtern(StringRef Str) {};
virtual void emitExtern(MCSymbol *Symbol) {};
virtual void emitEnd() {};

virtual const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
Expand All @@ -69,6 +69,7 @@ class SystemZTargetStreamer : public MCTargetStreamer {
class SystemZTargetGOFFStreamer : public SystemZTargetStreamer {
public:
SystemZTargetGOFFStreamer(MCStreamer &S) : SystemZTargetStreamer(S) {}
//void emitExtern(MCSymbol *Symbol) override;
const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) override;
};
Expand All @@ -80,7 +81,7 @@ class SystemZTargetHLASMStreamer : public SystemZTargetStreamer {
SystemZTargetHLASMStreamer(MCStreamer &S, formatted_raw_ostream &OS)
: SystemZTargetStreamer(S), OS(OS) {}
SystemZHLASMAsmStreamer &getHLASMStreamer();
void emitExtern(StringRef Sym) override;
void emitExtern(MCSymbol *Symbol) override;
void emitEnd() override;
const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
const MCSymbol *Lo) override;
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -1112,6 +1113,17 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
if (TT.isOSzOS()) {
emitADASection();
emitIDRLSection(M);
// Emit EXTRN declarations.
for (auto &GO : M.global_objects()) {
if (GO.isDeclaration()) {
MCSymbol *Sym = TM.getSymbol(&GO);
OutStreamer->emitSymbolAttribute(
Sym, GO.hasWeakLinkage() ? MCSA_WeakReference : MCSA_Global);
OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO) ? MCSA_Code
: MCSA_Data);
getTargetStreamer()->emitExtern(Sym);
}
}
}
emitAttributes(M);
// Emit the END instruction in case of HLASM output. This must be the last
Expand Down Expand Up @@ -1570,6 +1582,7 @@ void SystemZAsmPrinter::emitPPA2(Module &M) {
// Make CELQSTRT symbol.
const char *StartSymbolName = "CELQSTRT";
MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
getTargetStreamer()->emitExtern(CELQSTRT);

// Create symbol and assign to class field for use in PPA1.
PPA2Sym = OutContext.createTempSymbol("PPA2", false);
Expand Down
Loading