-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[MC][SystemZ] Introduce Target Specific HLASM Streamer for z/OS #130535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-backend-systemz Author: None (tltao) ChangesA more fleshed out version of a previous PR #107415. The goal is to provide platforms an alternative to the current MCAsmStreamer which only supports the GNU Asm syntax. Will be accompanied by an RFC. Also this PR is meant to give an overview of a more "complete" implementation. I would expect it to be broken down to smaller PRs when we are ready to merge. Patch is 30.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130535.diff 13 Files Affected:
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 11c0f95364037..bad67dbc4af18 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -37,7 +37,9 @@ class MCSectionGOFF final : public MCSection {
void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
uint32_t /*Subsection*/) const override {
- OS << "\t.section\t\"" << getName() << "\"\n";
+ // TODO: This isn't fully correct HLASM syntax, but we are not
+ // ready to implement the full solution yet.
+ OS << getName() << " CSECT\n";
}
bool useCodeAlign() const override { return false; }
diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 363fa03f27a70..0851049f465cb 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -208,8 +208,13 @@ class Target {
using AsmTargetStreamerCtorTy =
MCTargetStreamer *(*)(MCStreamer &S, formatted_raw_ostream &OS,
MCInstPrinter *InstPrint);
- using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)(
- MCStreamer &S, const MCSubtargetInfo &STI);
+ using AsmStreamerCtorTy =
+ MCStreamer *(*)(MCContext & Ctx,
+ std::unique_ptr<formatted_raw_ostream> OS,
+ MCInstPrinter *IP, std::unique_ptr<MCCodeEmitter> CE,
+ std::unique_ptr<MCAsmBackend> TAB);
+ using ObjectTargetStreamerCtorTy =
+ MCTargetStreamer *(*)(MCStreamer & S, const MCSubtargetInfo &STI);
using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT,
MCContext &Ctx);
using MCSymbolizerCtorTy = MCSymbolizer *(*)(
@@ -316,6 +321,10 @@ class Target {
/// registered (default = nullptr).
AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr;
+ /// Construction function for this target's AsmStreamer, if
+ /// registered (default = nullptr).
+ AsmStreamerCtorTy AsmStreamerCtorFn = nullptr;
+
/// Construction function for this target's obj TargetStreamer, if
/// registered (default = nullptr).
ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr;
@@ -938,6 +947,10 @@ struct TargetRegistry {
T.NullTargetStreamerCtorFn = Fn;
}
+ static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
+ T.AsmStreamerCtorFn = Fn;
+ }
+
static void RegisterAsmTargetStreamer(Target &T,
Target::AsmTargetStreamerCtorTy Fn) {
T.AsmTargetStreamerCtorFn = Fn;
diff --git a/llvm/lib/MC/TargetRegistry.cpp b/llvm/lib/MC/TargetRegistry.cpp
index 8f253266c4a7c..ec1c5a91d2728 100644
--- a/llvm/lib/MC/TargetRegistry.cpp
+++ b/llvm/lib/MC/TargetRegistry.cpp
@@ -92,8 +92,14 @@ MCStreamer *Target::createAsmStreamer(MCContext &Ctx,
std::unique_ptr<MCCodeEmitter> CE,
std::unique_ptr<MCAsmBackend> TAB) const {
formatted_raw_ostream &OSRef = *OS;
- MCStreamer *S = llvm::createAsmStreamer(Ctx, std::move(OS), IP,
- std::move(CE), std::move(TAB));
+ MCStreamer *S;
+ if (AsmStreamerCtorFn)
+ S = AsmStreamerCtorFn(Ctx, std::move(OS), IP, std::move(CE),
+ std::move(TAB));
+ else
+ S = llvm::createAsmStreamer(Ctx, std::move(OS), IP, std::move(CE),
+ std::move(TAB));
+
createAsmTargetStreamer(*S, OSRef, IP);
return S;
}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt
index 9c00706531b88..c95445637d0b2 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt
@@ -2,6 +2,7 @@ add_llvm_component_library(LLVMSystemZDesc
SystemZELFObjectWriter.cpp
SystemZGNUInstPrinter.cpp
SystemZGOFFObjectWriter.cpp
+ SystemZHLASMAsmStreamer.cpp
SystemZHLASMInstPrinter.cpp
SystemZInstPrinterCommon.cpp
SystemZMCAsmBackend.cpp
@@ -9,6 +10,7 @@ add_llvm_component_library(LLVMSystemZDesc
SystemZMCCodeEmitter.cpp
SystemZMCExpr.cpp
SystemZMCTargetDesc.cpp
+ SystemZTargetStreamer.cpp
LINK_COMPONENTS
CodeGenTypes
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
new file mode 100644
index 0000000000000..165feec7a7d43
--- /dev/null
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -0,0 +1,282 @@
+//===- SystemZHLASMAsmStreamer.cpp - HLASM Assembly Text Output -----------===//
+//
+// 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 "SystemZHLASMAsmStreamer.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Signals.h"
+#include <sstream>
+
+#include <cmath>
+
+void SystemZHLASMAsmStreamer::EmitEOL() {
+ // Comments are emitted on a new line before the instruction.
+ if (IsVerboseAsm)
+ EmitComment();
+
+ std::istringstream Stream(Str);
+ SmallVector<std::string> Lines;
+ std::string Line;
+ while (std::getline(Stream, Line, '\n'))
+ Lines.push_back(Line);
+
+ for (auto S : Lines) {
+ if (LLVM_LIKELY(S.length() < ContIndicatorColumn)) {
+ FOS << S;
+ // Each line in HLASM must fill the full 80 characters.
+ FOS.PadToColumn(InstLimit);
+ FOS << "\n";
+ } else {
+ // If last character before end of the line is not a space
+ // we must insert an additional non-space character that
+ // is not part of the statement coding. We just reuse
+ // the existing character by making the new substring start
+ // 1 character sooner, thus "duplicating" that character
+ // If The last character is a space. We insert an X instead.
+ std::string TmpSubStr = S.substr(0, ContIndicatorColumn);
+ if (!TmpSubStr.compare(ContIndicatorColumn - 1, 1, " "))
+ TmpSubStr.replace(ContIndicatorColumn - 1, 1, "X");
+
+ FOS << TmpSubStr;
+ FOS.PadToColumn(InstLimit);
+ FOS << "\n";
+
+ size_t Emitted = ContIndicatorColumn - 1;
+
+ while (Emitted < S.length()) {
+ if ((S.length() - Emitted) < ContLen)
+ TmpSubStr = S.substr(Emitted, S.length());
+ else {
+ TmpSubStr = S.substr(Emitted, ContLen);
+ if (!TmpSubStr.compare(ContLen - 1, 1, " "))
+ TmpSubStr.replace(ContLen - 1, 1, "X");
+ }
+ FOS.PadToColumn(ContStartColumn);
+ FOS << TmpSubStr;
+ FOS.PadToColumn(InstLimit);
+ FOS << "\n";
+ Emitted += ContLen - 1;
+ }
+ }
+ }
+ Str.clear();
+}
+
+void SystemZHLASMAsmStreamer::changeSection(MCSection *Section,
+ uint32_t Subsection) {
+ Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
+ Subsection);
+ MCStreamer::changeSection(Section, Subsection);
+}
+
+void SystemZHLASMAsmStreamer::emitAlignmentDS(uint64_t ByteAlignment,
+ std::optional<int64_t> Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {
+ if (!isPowerOf2_64(ByteAlignment))
+ report_fatal_error("Only power-of-two alignments are supported ");
+
+ OS << " DS 0";
+ switch (ValueSize) {
+ default:
+ llvm_unreachable("Invalid size for machine code value!");
+ case 1:
+ OS << "B";
+ break;
+ case 2:
+ OS << "H";
+ break;
+ case 4:
+ OS << "F";
+ break;
+ case 8:
+ OS << "D";
+ break;
+ case 16:
+ OS << "Q";
+ break;
+ }
+
+ EmitEOL();
+}
+
+void SystemZHLASMAsmStreamer::AddComment(const Twine &T, bool EOL) {
+ if (!IsVerboseAsm)
+ return;
+
+ T.toVector(CommentToEmit);
+
+ if (EOL)
+ CommentToEmit.push_back('\n'); // Place comment in a new line.
+}
+
+void SystemZHLASMAsmStreamer::EmitComment() {
+ if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0)
+ return;
+
+ StringRef Comments = CommentToEmit;
+
+ assert(Comments.back() == '\n' && "Comment array not newline terminated");
+ do {
+ // Emit a line of comments, but not exceeding 80 characters.
+ size_t Position = std::min(InstLimit - 2, Comments.find('\n'));
+ FOS << MAI->getCommentString() << ' ' << Comments.substr(0, Position)
+ << '\n';
+
+ if (Comments[Position] == '\n')
+ Position++;
+ Comments = Comments.substr(Position);
+ } while (!Comments.empty());
+
+ CommentToEmit.clear();
+}
+
+void SystemZHLASMAsmStreamer::emitValueToAlignment(Align Alignment,
+ int64_t Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {
+ emitAlignmentDS(Alignment.value(), Value, ValueSize, MaxBytesToEmit);
+}
+
+void SystemZHLASMAsmStreamer::emitCodeAlignment(Align Alignment,
+ const MCSubtargetInfo *STI,
+ unsigned MaxBytesToEmit) {
+ // Emit with a text fill value.
+ if (MAI->getTextAlignFillValue())
+ emitAlignmentDS(Alignment.value(), MAI->getTextAlignFillValue(), 1,
+ MaxBytesToEmit);
+ else
+ emitAlignmentDS(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
+}
+
+void SystemZHLASMAsmStreamer::emitBytes(StringRef Data) {
+ assert(getCurrentSectionOnly() &&
+ "Cannot emit contents before setting section!");
+ if (Data.empty())
+ return;
+
+ OS << " DC ";
+ size_t Len = Data.size();
+ SmallVector<uint8_t> Chars;
+ Chars.resize(Len);
+ OS << "XL" << Len;
+ uint32_t Index = 0;
+ for (uint8_t C : Data) {
+ Chars[Index] = C;
+ Index++;
+ }
+
+ OS << '\'' << toHex(Chars) << '\'';
+
+ EmitEOL();
+}
+
+void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+
+ InstPrinter->printInst(&Inst, 0, "", STI, OS);
+ EmitEOL();
+}
+
+void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+
+ MCStreamer::emitLabel(Symbol, Loc);
+
+ 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();
+}
+
+void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {
+ String.consume_back("\n");
+ OS << String;
+ EmitEOL();
+}
+
+// Slight duplicate of MCExpr::print due to HLASM only recognizing limited
+// arithmetic operators (+-*/).
+void SystemZHLASMAsmStreamer::emitHLASMValueImpl(const MCExpr *Value,
+ unsigned Size, bool Parens) {
+ switch (Value->getKind()) {
+ case MCExpr::Constant: {
+ OS << "XL" << Size << '\'';
+ Value->print(OS, MAI);
+ OS << '\'';
+ return;
+ }
+ case MCExpr::Binary: {
+ const MCBinaryExpr &BE = cast<MCBinaryExpr>(*Value);
+ int64_t Const;
+ // Or is handled differently.
+ if (BE.getOpcode() == MCBinaryExpr::Or) {
+ emitHLASMValueImpl(BE.getLHS(), Size, true);
+ OS << ',';
+ emitHLASMValueImpl(BE.getRHS(), Size, true);
+ return;
+ }
+
+ if (Parens)
+ OS << "A(";
+ emitHLASMValueImpl(BE.getLHS(), Size);
+
+ switch (BE.getOpcode()) {
+ case MCBinaryExpr::LShr: {
+ Const = cast<MCConstantExpr>(BE.getRHS())->getValue();
+ OS << '/' << (1 << Const);
+ if (Parens)
+ OS << ')';
+ return;
+ }
+ case MCBinaryExpr::Add:
+ OS << '+';
+ break;
+ case MCBinaryExpr::Div:
+ OS << '/';
+ break;
+ case MCBinaryExpr::Mul:
+ OS << '*';
+ break;
+ case MCBinaryExpr::Sub:
+ OS << '-';
+ break;
+ default:
+ getContext().reportError(SMLoc(),
+ "Unrecognized HLASM arithmetic expression!");
+ }
+ emitHLASMValueImpl(BE.getRHS(), Size);
+ if (Parens)
+ OS << ')';
+ return;
+ }
+ case MCExpr::Target:
+ Value->print(OS, MAI);
+ return;
+ default:
+ if (Parens)
+ OS << "A(";
+ Value->print(OS, MAI);
+ if (Parens)
+ OS << ')';
+ return;
+ }
+}
+
+void SystemZHLASMAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
+ SMLoc Loc) {
+ assert(Size <= 8 && "Invalid size");
+ assert(getCurrentSectionOnly() &&
+ "Cannot emit contents before setting section!");
+
+ OS << " DC ";
+ emitHLASMValueImpl(Value, Size, true);
+ EmitEOL();
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
new file mode 100644
index 0000000000000..bf04eb850c403
--- /dev/null
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
@@ -0,0 +1,122 @@
+//===- SystemZHLASMAsmStreamer.h - HLASM Assembly Text Output ---*- 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 file declares the SystemZHLASMAsmStreamer class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/FormattedStream.h"
+
+using namespace llvm;
+
+class SystemZHLASMAsmStreamer final : public MCStreamer {
+ constexpr static size_t InstLimit = 80;
+ constexpr static size_t ContIndicatorColumn = 72;
+ constexpr static size_t ContStartColumn = 15;
+ constexpr static size_t ContLen = ContIndicatorColumn - ContStartColumn;
+ std::unique_ptr<formatted_raw_ostream> FOSOwner;
+ formatted_raw_ostream &FOS;
+ std::string Str;
+ raw_string_ostream OS;
+ const MCAsmInfo *MAI;
+ std::unique_ptr<MCInstPrinter> InstPrinter;
+ std::unique_ptr<MCAssembler> Assembler;
+ SmallString<128> CommentToEmit;
+ raw_svector_ostream CommentStream;
+ raw_null_ostream NullStream;
+ bool IsVerboseAsm = false;
+
+public:
+ SystemZHLASMAsmStreamer(MCContext &Context,
+ std::unique_ptr<formatted_raw_ostream> os,
+ MCInstPrinter *printer,
+ std::unique_ptr<MCCodeEmitter> emitter,
+ std::unique_ptr<MCAsmBackend> asmbackend)
+ : MCStreamer(Context), FOSOwner(std::move(os)), FOS(*FOSOwner), OS(Str),
+ MAI(Context.getAsmInfo()), InstPrinter(printer),
+ Assembler(std::make_unique<MCAssembler>(
+ Context, std::move(asmbackend), std::move(emitter),
+ (asmbackend) ? asmbackend->createObjectWriter(NullStream)
+ : nullptr)),
+ CommentStream(CommentToEmit) {
+ assert(InstPrinter);
+ if (Assembler->getBackendPtr())
+ setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
+
+ Context.setUseNamesOnTempLabels(true);
+ auto *TO = Context.getTargetOptions();
+ if (!TO)
+ return;
+ IsVerboseAsm = TO->AsmVerbose;
+ if (IsVerboseAsm)
+ InstPrinter->setCommentStream(CommentStream);
+ }
+
+ MCAssembler &getAssembler() { return *Assembler; }
+
+ void EmitEOL();
+ void EmitComment();
+
+ /// Add a comment that can be emitted to the generated .s file to make the
+ /// output of the compiler more readable. This only affects the MCAsmStreamer
+ /// and only when verbose assembly output is enabled.
+ void AddComment(const Twine &T, bool EOL = true) override;
+
+ void emitBytes(StringRef Data) override;
+
+ void emitAlignmentDS(uint64_t ByteAlignment, std::optional<int64_t> Value,
+ unsigned ValueSize, unsigned MaxBytesToEmit);
+ void emitValueToAlignment(Align Alignment, int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0) override;
+
+ void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
+ unsigned MaxBytesToEmit = 0) override;
+
+ /// Return true if this streamer supports verbose assembly at all.
+ bool isVerboseAsm() const override { return IsVerboseAsm; }
+
+ /// Do we support EmitRawText?
+ bool hasRawTextSupport() const override { return true; }
+
+ /// @name MCStreamer Interface
+ /// @{
+
+ 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;
+ }
+
+ void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ Align ByteAlignment) override {}
+
+ void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, Align ByteAlignment = Align(1),
+ SMLoc Loc = SMLoc()) override {}
+ void emitRawTextImpl(StringRef String) override;
+ void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
+
+ void emitHLASMValueImpl(const MCExpr *Value, unsigned Size,
+ bool Parens = false);
+ /// @}
+};
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp
index ef9881932f7c0..1ecfd4ec4640e 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "SystemZHLASMInstPrinter.h"
+#include "SystemZInstrInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRegister.h"
#include "llvm/Support/raw_ostream.h"
@@ -34,8 +35,8 @@ void SystemZHLASMInstPrinter::printInst(const MCInst *MI, uint64_t Address,
raw_string_ostream RSO(Str);
printInstruction(MI, Address, RSO);
// Eat the first tab character and replace it with a space since it is
- // hardcoded in AsmWriterEmitter::EmitPrintInstruction
- // TODO: introduce a line prefix member to AsmWriter to avoid this problem
+ // hardcoded in AsmWriterEmitter::EmitPrintInstruction.
+ // TODO Introduce a line prefix member to AsmWriter to avoid this problem.
if (!Str.empty() && Str.front() == '\t')
O << " " << Str.substr(1, Str.length());
else
@@ -43,3 +44,18 @@ void SystemZHLASMInstPrinter::printInst(const MCInst *MI, uint64_t Address,
printAnnotation(O, Annot);
}
+
+void SystemZHLASMInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ const MCOperand &MO = MI->getOperand(OpNum);
+ if (MO.isImm()) {
+ WithMarkup M = markup(O, Markup::Immediate);
+ O << "0x";
+ O.write_hex(MO.getImm());
+ } else {
+ // Don't print @PLT.
+ // TODO May need to do something more here.
+ const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*(MO.getExpr()));
+ O << SRE.getSymbol().getName();
+ }
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h
index 2732986dbca7d..8cd3c004f4035 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h
@@ -36,6 +36,12 @@ class SystemZHLASMInstPrinter : public SystemZInstPrinter...
[truncated]
|
|
@llvm/pr-subscribers-mc Author: None (tltao) ChangesA more fleshed out version of a previous PR #107415. The goal is to provide platforms an alternative to the current MCAsmStreamer which only supports the GNU Asm syntax. Will be accompanied by an RFC. Also this PR is meant to give an overview of a more "complete" implementation. I would expect it to be broken down to smaller PRs when we are ready to merge. Patch is 30.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130535.diff 13 Files Affected:
diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
index 11c0f95364037..bad67dbc4af18 100644
--- a/llvm/include/llvm/MC/MCSectionGOFF.h
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -37,7 +37,9 @@ class MCSectionGOFF final : public MCSection {
void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
uint32_t /*Subsection*/) const override {
- OS << "\t.section\t\"" << getName() << "\"\n";
+ // TODO: This isn't fully correct HLASM syntax, but we are not
+ // ready to implement the full solution yet.
+ OS << getName() << " CSECT\n";
}
bool useCodeAlign() const override { return false; }
diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 363fa03f27a70..0851049f465cb 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -208,8 +208,13 @@ class Target {
using AsmTargetStreamerCtorTy =
MCTargetStreamer *(*)(MCStreamer &S, formatted_raw_ostream &OS,
MCInstPrinter *InstPrint);
- using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)(
- MCStreamer &S, const MCSubtargetInfo &STI);
+ using AsmStreamerCtorTy =
+ MCStreamer *(*)(MCContext & Ctx,
+ std::unique_ptr<formatted_raw_ostream> OS,
+ MCInstPrinter *IP, std::unique_ptr<MCCodeEmitter> CE,
+ std::unique_ptr<MCAsmBackend> TAB);
+ using ObjectTargetStreamerCtorTy =
+ MCTargetStreamer *(*)(MCStreamer & S, const MCSubtargetInfo &STI);
using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT,
MCContext &Ctx);
using MCSymbolizerCtorTy = MCSymbolizer *(*)(
@@ -316,6 +321,10 @@ class Target {
/// registered (default = nullptr).
AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr;
+ /// Construction function for this target's AsmStreamer, if
+ /// registered (default = nullptr).
+ AsmStreamerCtorTy AsmStreamerCtorFn = nullptr;
+
/// Construction function for this target's obj TargetStreamer, if
/// registered (default = nullptr).
ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr;
@@ -938,6 +947,10 @@ struct TargetRegistry {
T.NullTargetStreamerCtorFn = Fn;
}
+ static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
+ T.AsmStreamerCtorFn = Fn;
+ }
+
static void RegisterAsmTargetStreamer(Target &T,
Target::AsmTargetStreamerCtorTy Fn) {
T.AsmTargetStreamerCtorFn = Fn;
diff --git a/llvm/lib/MC/TargetRegistry.cpp b/llvm/lib/MC/TargetRegistry.cpp
index 8f253266c4a7c..ec1c5a91d2728 100644
--- a/llvm/lib/MC/TargetRegistry.cpp
+++ b/llvm/lib/MC/TargetRegistry.cpp
@@ -92,8 +92,14 @@ MCStreamer *Target::createAsmStreamer(MCContext &Ctx,
std::unique_ptr<MCCodeEmitter> CE,
std::unique_ptr<MCAsmBackend> TAB) const {
formatted_raw_ostream &OSRef = *OS;
- MCStreamer *S = llvm::createAsmStreamer(Ctx, std::move(OS), IP,
- std::move(CE), std::move(TAB));
+ MCStreamer *S;
+ if (AsmStreamerCtorFn)
+ S = AsmStreamerCtorFn(Ctx, std::move(OS), IP, std::move(CE),
+ std::move(TAB));
+ else
+ S = llvm::createAsmStreamer(Ctx, std::move(OS), IP, std::move(CE),
+ std::move(TAB));
+
createAsmTargetStreamer(*S, OSRef, IP);
return S;
}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt
index 9c00706531b88..c95445637d0b2 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt
@@ -2,6 +2,7 @@ add_llvm_component_library(LLVMSystemZDesc
SystemZELFObjectWriter.cpp
SystemZGNUInstPrinter.cpp
SystemZGOFFObjectWriter.cpp
+ SystemZHLASMAsmStreamer.cpp
SystemZHLASMInstPrinter.cpp
SystemZInstPrinterCommon.cpp
SystemZMCAsmBackend.cpp
@@ -9,6 +10,7 @@ add_llvm_component_library(LLVMSystemZDesc
SystemZMCCodeEmitter.cpp
SystemZMCExpr.cpp
SystemZMCTargetDesc.cpp
+ SystemZTargetStreamer.cpp
LINK_COMPONENTS
CodeGenTypes
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
new file mode 100644
index 0000000000000..165feec7a7d43
--- /dev/null
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -0,0 +1,282 @@
+//===- SystemZHLASMAsmStreamer.cpp - HLASM Assembly Text Output -----------===//
+//
+// 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 "SystemZHLASMAsmStreamer.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Signals.h"
+#include <sstream>
+
+#include <cmath>
+
+void SystemZHLASMAsmStreamer::EmitEOL() {
+ // Comments are emitted on a new line before the instruction.
+ if (IsVerboseAsm)
+ EmitComment();
+
+ std::istringstream Stream(Str);
+ SmallVector<std::string> Lines;
+ std::string Line;
+ while (std::getline(Stream, Line, '\n'))
+ Lines.push_back(Line);
+
+ for (auto S : Lines) {
+ if (LLVM_LIKELY(S.length() < ContIndicatorColumn)) {
+ FOS << S;
+ // Each line in HLASM must fill the full 80 characters.
+ FOS.PadToColumn(InstLimit);
+ FOS << "\n";
+ } else {
+ // If last character before end of the line is not a space
+ // we must insert an additional non-space character that
+ // is not part of the statement coding. We just reuse
+ // the existing character by making the new substring start
+ // 1 character sooner, thus "duplicating" that character
+ // If The last character is a space. We insert an X instead.
+ std::string TmpSubStr = S.substr(0, ContIndicatorColumn);
+ if (!TmpSubStr.compare(ContIndicatorColumn - 1, 1, " "))
+ TmpSubStr.replace(ContIndicatorColumn - 1, 1, "X");
+
+ FOS << TmpSubStr;
+ FOS.PadToColumn(InstLimit);
+ FOS << "\n";
+
+ size_t Emitted = ContIndicatorColumn - 1;
+
+ while (Emitted < S.length()) {
+ if ((S.length() - Emitted) < ContLen)
+ TmpSubStr = S.substr(Emitted, S.length());
+ else {
+ TmpSubStr = S.substr(Emitted, ContLen);
+ if (!TmpSubStr.compare(ContLen - 1, 1, " "))
+ TmpSubStr.replace(ContLen - 1, 1, "X");
+ }
+ FOS.PadToColumn(ContStartColumn);
+ FOS << TmpSubStr;
+ FOS.PadToColumn(InstLimit);
+ FOS << "\n";
+ Emitted += ContLen - 1;
+ }
+ }
+ }
+ Str.clear();
+}
+
+void SystemZHLASMAsmStreamer::changeSection(MCSection *Section,
+ uint32_t Subsection) {
+ Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
+ Subsection);
+ MCStreamer::changeSection(Section, Subsection);
+}
+
+void SystemZHLASMAsmStreamer::emitAlignmentDS(uint64_t ByteAlignment,
+ std::optional<int64_t> Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {
+ if (!isPowerOf2_64(ByteAlignment))
+ report_fatal_error("Only power-of-two alignments are supported ");
+
+ OS << " DS 0";
+ switch (ValueSize) {
+ default:
+ llvm_unreachable("Invalid size for machine code value!");
+ case 1:
+ OS << "B";
+ break;
+ case 2:
+ OS << "H";
+ break;
+ case 4:
+ OS << "F";
+ break;
+ case 8:
+ OS << "D";
+ break;
+ case 16:
+ OS << "Q";
+ break;
+ }
+
+ EmitEOL();
+}
+
+void SystemZHLASMAsmStreamer::AddComment(const Twine &T, bool EOL) {
+ if (!IsVerboseAsm)
+ return;
+
+ T.toVector(CommentToEmit);
+
+ if (EOL)
+ CommentToEmit.push_back('\n'); // Place comment in a new line.
+}
+
+void SystemZHLASMAsmStreamer::EmitComment() {
+ if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0)
+ return;
+
+ StringRef Comments = CommentToEmit;
+
+ assert(Comments.back() == '\n' && "Comment array not newline terminated");
+ do {
+ // Emit a line of comments, but not exceeding 80 characters.
+ size_t Position = std::min(InstLimit - 2, Comments.find('\n'));
+ FOS << MAI->getCommentString() << ' ' << Comments.substr(0, Position)
+ << '\n';
+
+ if (Comments[Position] == '\n')
+ Position++;
+ Comments = Comments.substr(Position);
+ } while (!Comments.empty());
+
+ CommentToEmit.clear();
+}
+
+void SystemZHLASMAsmStreamer::emitValueToAlignment(Align Alignment,
+ int64_t Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {
+ emitAlignmentDS(Alignment.value(), Value, ValueSize, MaxBytesToEmit);
+}
+
+void SystemZHLASMAsmStreamer::emitCodeAlignment(Align Alignment,
+ const MCSubtargetInfo *STI,
+ unsigned MaxBytesToEmit) {
+ // Emit with a text fill value.
+ if (MAI->getTextAlignFillValue())
+ emitAlignmentDS(Alignment.value(), MAI->getTextAlignFillValue(), 1,
+ MaxBytesToEmit);
+ else
+ emitAlignmentDS(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
+}
+
+void SystemZHLASMAsmStreamer::emitBytes(StringRef Data) {
+ assert(getCurrentSectionOnly() &&
+ "Cannot emit contents before setting section!");
+ if (Data.empty())
+ return;
+
+ OS << " DC ";
+ size_t Len = Data.size();
+ SmallVector<uint8_t> Chars;
+ Chars.resize(Len);
+ OS << "XL" << Len;
+ uint32_t Index = 0;
+ for (uint8_t C : Data) {
+ Chars[Index] = C;
+ Index++;
+ }
+
+ OS << '\'' << toHex(Chars) << '\'';
+
+ EmitEOL();
+}
+
+void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+
+ InstPrinter->printInst(&Inst, 0, "", STI, OS);
+ EmitEOL();
+}
+
+void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+
+ MCStreamer::emitLabel(Symbol, Loc);
+
+ 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();
+}
+
+void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {
+ String.consume_back("\n");
+ OS << String;
+ EmitEOL();
+}
+
+// Slight duplicate of MCExpr::print due to HLASM only recognizing limited
+// arithmetic operators (+-*/).
+void SystemZHLASMAsmStreamer::emitHLASMValueImpl(const MCExpr *Value,
+ unsigned Size, bool Parens) {
+ switch (Value->getKind()) {
+ case MCExpr::Constant: {
+ OS << "XL" << Size << '\'';
+ Value->print(OS, MAI);
+ OS << '\'';
+ return;
+ }
+ case MCExpr::Binary: {
+ const MCBinaryExpr &BE = cast<MCBinaryExpr>(*Value);
+ int64_t Const;
+ // Or is handled differently.
+ if (BE.getOpcode() == MCBinaryExpr::Or) {
+ emitHLASMValueImpl(BE.getLHS(), Size, true);
+ OS << ',';
+ emitHLASMValueImpl(BE.getRHS(), Size, true);
+ return;
+ }
+
+ if (Parens)
+ OS << "A(";
+ emitHLASMValueImpl(BE.getLHS(), Size);
+
+ switch (BE.getOpcode()) {
+ case MCBinaryExpr::LShr: {
+ Const = cast<MCConstantExpr>(BE.getRHS())->getValue();
+ OS << '/' << (1 << Const);
+ if (Parens)
+ OS << ')';
+ return;
+ }
+ case MCBinaryExpr::Add:
+ OS << '+';
+ break;
+ case MCBinaryExpr::Div:
+ OS << '/';
+ break;
+ case MCBinaryExpr::Mul:
+ OS << '*';
+ break;
+ case MCBinaryExpr::Sub:
+ OS << '-';
+ break;
+ default:
+ getContext().reportError(SMLoc(),
+ "Unrecognized HLASM arithmetic expression!");
+ }
+ emitHLASMValueImpl(BE.getRHS(), Size);
+ if (Parens)
+ OS << ')';
+ return;
+ }
+ case MCExpr::Target:
+ Value->print(OS, MAI);
+ return;
+ default:
+ if (Parens)
+ OS << "A(";
+ Value->print(OS, MAI);
+ if (Parens)
+ OS << ')';
+ return;
+ }
+}
+
+void SystemZHLASMAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
+ SMLoc Loc) {
+ assert(Size <= 8 && "Invalid size");
+ assert(getCurrentSectionOnly() &&
+ "Cannot emit contents before setting section!");
+
+ OS << " DC ";
+ emitHLASMValueImpl(Value, Size, true);
+ EmitEOL();
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
new file mode 100644
index 0000000000000..bf04eb850c403
--- /dev/null
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
@@ -0,0 +1,122 @@
+//===- SystemZHLASMAsmStreamer.h - HLASM Assembly Text Output ---*- 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 file declares the SystemZHLASMAsmStreamer class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/FormattedStream.h"
+
+using namespace llvm;
+
+class SystemZHLASMAsmStreamer final : public MCStreamer {
+ constexpr static size_t InstLimit = 80;
+ constexpr static size_t ContIndicatorColumn = 72;
+ constexpr static size_t ContStartColumn = 15;
+ constexpr static size_t ContLen = ContIndicatorColumn - ContStartColumn;
+ std::unique_ptr<formatted_raw_ostream> FOSOwner;
+ formatted_raw_ostream &FOS;
+ std::string Str;
+ raw_string_ostream OS;
+ const MCAsmInfo *MAI;
+ std::unique_ptr<MCInstPrinter> InstPrinter;
+ std::unique_ptr<MCAssembler> Assembler;
+ SmallString<128> CommentToEmit;
+ raw_svector_ostream CommentStream;
+ raw_null_ostream NullStream;
+ bool IsVerboseAsm = false;
+
+public:
+ SystemZHLASMAsmStreamer(MCContext &Context,
+ std::unique_ptr<formatted_raw_ostream> os,
+ MCInstPrinter *printer,
+ std::unique_ptr<MCCodeEmitter> emitter,
+ std::unique_ptr<MCAsmBackend> asmbackend)
+ : MCStreamer(Context), FOSOwner(std::move(os)), FOS(*FOSOwner), OS(Str),
+ MAI(Context.getAsmInfo()), InstPrinter(printer),
+ Assembler(std::make_unique<MCAssembler>(
+ Context, std::move(asmbackend), std::move(emitter),
+ (asmbackend) ? asmbackend->createObjectWriter(NullStream)
+ : nullptr)),
+ CommentStream(CommentToEmit) {
+ assert(InstPrinter);
+ if (Assembler->getBackendPtr())
+ setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
+
+ Context.setUseNamesOnTempLabels(true);
+ auto *TO = Context.getTargetOptions();
+ if (!TO)
+ return;
+ IsVerboseAsm = TO->AsmVerbose;
+ if (IsVerboseAsm)
+ InstPrinter->setCommentStream(CommentStream);
+ }
+
+ MCAssembler &getAssembler() { return *Assembler; }
+
+ void EmitEOL();
+ void EmitComment();
+
+ /// Add a comment that can be emitted to the generated .s file to make the
+ /// output of the compiler more readable. This only affects the MCAsmStreamer
+ /// and only when verbose assembly output is enabled.
+ void AddComment(const Twine &T, bool EOL = true) override;
+
+ void emitBytes(StringRef Data) override;
+
+ void emitAlignmentDS(uint64_t ByteAlignment, std::optional<int64_t> Value,
+ unsigned ValueSize, unsigned MaxBytesToEmit);
+ void emitValueToAlignment(Align Alignment, int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0) override;
+
+ void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
+ unsigned MaxBytesToEmit = 0) override;
+
+ /// Return true if this streamer supports verbose assembly at all.
+ bool isVerboseAsm() const override { return IsVerboseAsm; }
+
+ /// Do we support EmitRawText?
+ bool hasRawTextSupport() const override { return true; }
+
+ /// @name MCStreamer Interface
+ /// @{
+
+ 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;
+ }
+
+ void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ Align ByteAlignment) override {}
+
+ void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, Align ByteAlignment = Align(1),
+ SMLoc Loc = SMLoc()) override {}
+ void emitRawTextImpl(StringRef String) override;
+ void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
+
+ void emitHLASMValueImpl(const MCExpr *Value, unsigned Size,
+ bool Parens = false);
+ /// @}
+};
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp
index ef9881932f7c0..1ecfd4ec4640e 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "SystemZHLASMInstPrinter.h"
+#include "SystemZInstrInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCRegister.h"
#include "llvm/Support/raw_ostream.h"
@@ -34,8 +35,8 @@ void SystemZHLASMInstPrinter::printInst(const MCInst *MI, uint64_t Address,
raw_string_ostream RSO(Str);
printInstruction(MI, Address, RSO);
// Eat the first tab character and replace it with a space since it is
- // hardcoded in AsmWriterEmitter::EmitPrintInstruction
- // TODO: introduce a line prefix member to AsmWriter to avoid this problem
+ // hardcoded in AsmWriterEmitter::EmitPrintInstruction.
+ // TODO Introduce a line prefix member to AsmWriter to avoid this problem.
if (!Str.empty() && Str.front() == '\t')
O << " " << Str.substr(1, Str.length());
else
@@ -43,3 +44,18 @@ void SystemZHLASMInstPrinter::printInst(const MCInst *MI, uint64_t Address,
printAnnotation(O, Annot);
}
+
+void SystemZHLASMInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ const MCOperand &MO = MI->getOperand(OpNum);
+ if (MO.isImm()) {
+ WithMarkup M = markup(O, Markup::Immediate);
+ O << "0x";
+ O.write_hex(MO.getImm());
+ } else {
+ // Don't print @PLT.
+ // TODO May need to do something more here.
+ const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*(MO.getExpr()));
+ O << SRE.getSymbol().getName();
+ }
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h
index 2732986dbca7d..8cd3c004f4035 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h
@@ -36,6 +36,12 @@ class SystemZHLASMInstPrinter : public SystemZInstPrinter...
[truncated]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
| } else { | ||
| // Don't print @PLT. | ||
| // TODO May need to do something more here. | ||
| const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*(MO.getExpr())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://discourse.llvm.org/t/error-expected-relocatable-expression-with-mctargetexpr/84926/2 might be relevant. We should use MCTargetExpr and discourage MCSymbolRefExpr::VariantKind
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct me if I'm wrong, but this looks to be the only way to access the MCSymbol referenced by a MCExpr. Looking at some AArch64/RISC-V examples from AArch64MCExpr.cpp/RISCVMCExpr.cpp, they are still forced to cast to MCSymbolRefExpr sometimes:
const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
I'm not sure this is a case of using MCSymbolRefExpr::VariantKind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think more to the point is that this isn't really an assembler difference as such - it should rather be a codegen difference to begin with. On z/OS (no matter which assembler is used), there is no PLT, so z/OS codegen shouldn't generate @plt symbols at all, whether via VariantKind or some other way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, that makes sense. To properly migrate away from that however, looks to be a much bigger change and outside the scope of this PR. I will revert this change then, since once properly implemented, MCExpr::print should call SystemZMCExpr::printImpl.
Thanks for supporting z/OS HLASM without modifying the generic MC interface (the |
…antKind and wait for future implementation to SystemZMCExpr
uweigand
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks! It would be nice, now that you're adding a SystemZTargetStreamer.cpp file, to move the other TargetStreamer methods out of SystemZMCTargetDesc.cpp. The SystemZTargetStreamer::emitConstantPools routine should go to the new .cpp file; the SystemZTargetAsmStreamer and SystemZTargetELFStreamer classes should go to the .h file. (And the former should now probably be renamed to SystemZTargetGNUAsmStreamer.)
Good ideas. I will open a new PR to make those changes. In the meantime, should I break this PR down to smaller pieces or is it good to merge as is? |
|
Thanks. I'd be fine with merging this PR as-is. |
…2476) Now that we have a SystemZTargetStreamer file from #130535, move some TargetStreamer classes and methods from TargetDesc to the proper file. --------- Co-authored-by: Tony Tao <[email protected]>
…r file (#132476) Now that we have a SystemZTargetStreamer file from llvm/llvm-project#130535, move some TargetStreamer classes and methods from TargetDesc to the proper file. --------- Co-authored-by: Tony Tao <[email protected]>
A more fleshed out version of a previous PR #107415. The goal is to provide platforms an alternative to the current MCAsmStreamer which only supports the GNU Asm syntax.
RFC: https://discourse.llvm.org/t/rfc-llvm-add-support-for-target-specific-asm-streamer/85095
Also this PR is meant to give an overview of a more "complete" implementation. I would expect it to be broken down to smaller PRs when we are ready to merge.