Skip to content

Conversation

@tltao
Copy link
Contributor

@tltao tltao commented Sep 12, 2024

Building on top of #107415

Introduce a skeleton implementation of a new SystemZ specific HLASM asm streamer base on current MCAsmStreamer. Since this will require some migration for z/OS specific testcases, adding an option to help with the migration process.

@llvmbot llvmbot added backend:SystemZ llvm:mc Machine (object) code labels Sep 12, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 12, 2024

@llvm/pr-subscribers-mc

@llvm/pr-subscribers-backend-systemz

Author: None (tltao)

Changes

Building on top of #107415

Introduce a skeleton implementation of a new SystemZ specific HLASM asm streamer base on current MCAsmStreamer.


Full diff: https://github.com/llvm/llvm-project/pull/108433.diff

7 Files Affected:

  • (modified) llvm/include/llvm/MC/TargetRegistry.h (+12)
  • (modified) llvm/lib/MC/TargetRegistry.cpp (+8-2)
  • (modified) llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt (+1)
  • (added) llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp (+24)
  • (added) llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h (+93)
  • (modified) llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp (+25)
  • (added) llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll (+9)
diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 42d510c17bce39..1850139ba81491 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -208,6 +208,10 @@ class Target {
   using AsmTargetStreamerCtorTy =
       MCTargetStreamer *(*)(MCStreamer &S, formatted_raw_ostream &OS,
                             MCInstPrinter *InstPrint);
+  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,
@@ -316,6 +320,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;
@@ -927,6 +935,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 3be6f1d4634990..0d343a2c4e4d5f 100644
--- a/llvm/lib/MC/TargetRegistry.cpp
+++ b/llvm/lib/MC/TargetRegistry.cpp
@@ -93,8 +93,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 6700d793697087..b92974bb2cc526 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_llvm_component_library(LLVMSystemZDesc
   SystemZELFObjectWriter.cpp
   SystemZGOFFObjectWriter.cpp
+  SystemZHLASMAsmStreamer.cpp
   SystemZInstPrinter.cpp
   SystemZMCAsmBackend.cpp
   SystemZMCAsmInfo.cpp
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
new file mode 100644
index 00000000000000..f0830f95ff312b
--- /dev/null
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -0,0 +1,24 @@
+//===- 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"
+
+void SystemZHLASMAsmStreamer::changeSection(MCSection *Section,
+                                            uint32_t Subsection) {
+  MCStreamer::changeSection(Section, Subsection);
+}
+
+void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
+  MCStreamer::emitLabel(Symbol, Loc);
+
+  Symbol->print(OS, MAI);
+  // TODO: update LabelSuffix in SystemZMCAsmInfoGOFF once tests have been
+  // moved to HLASM syntax.
+  // OS << MAI->getLabelSuffix();
+  OS << '\n';
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
new file mode 100644
index 00000000000000..a7c7df20be9039
--- /dev/null
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
@@ -0,0 +1,93 @@
+//===- 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 {
+  std::unique_ptr<formatted_raw_ostream> OSOwner;
+  formatted_raw_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), OSOwner(std::move(os)), OS(*OSOwner),
+        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; }
+
+  /// 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 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 {}
+
+  /// @}
+};
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp
index f58674ee118ee9..3f86e78c126c16 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "SystemZMCTargetDesc.h"
+#include "SystemZHLASMAsmStreamer.h"
 #include "SystemZInstPrinter.h"
 #include "SystemZMCAsmInfo.h"
 #include "SystemZTargetStreamer.h"
@@ -19,6 +20,7 @@
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/CommandLine.h"
 
 using namespace llvm;
 
@@ -32,6 +34,12 @@ using namespace llvm;
 #define GET_REGINFO_MC_DESC
 #include "SystemZGenRegisterInfo.inc"
 
+// Temporary option to assist with the migration to a new HLASMAsmStreamer on
+// z/OS
+static cl::opt<bool> GNUAsOnzOSCL("emit-gnuas-syntax-on-zos",
+                                  cl::desc("Emit GNU Assembly Syntax on z/OS."),
+                                  cl::init(true));
+
 const unsigned SystemZMC::GR32Regs[16] = {
   SystemZ::R0L, SystemZ::R1L, SystemZ::R2L, SystemZ::R3L,
   SystemZ::R4L, SystemZ::R5L, SystemZ::R6L, SystemZ::R7L,
@@ -229,6 +237,20 @@ static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
   return new SystemZTargetAsmStreamer(S, OS);
 }
 
+static MCStreamer *createAsmStreamer(MCContext &Ctx,
+                                     std::unique_ptr<formatted_raw_ostream> OS,
+                                     MCInstPrinter *IP,
+                                     std::unique_ptr<MCCodeEmitter> CE,
+                                     std::unique_ptr<MCAsmBackend> TAB) {
+
+  auto TT = Ctx.getTargetTriple();
+  if (TT.isOSzOS() && !GNUAsOnzOSCL)
+    return new SystemZHLASMAsmStreamer(Ctx, std::move(OS), IP, std::move(CE),
+                                       std::move(TAB));
+
+  return llvm::createAsmStreamer(Ctx, std::move(OS), IP, std::move(CE),
+                                 std::move(TAB));
+}
 static MCTargetStreamer *
 createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
   return new SystemZTargetELFStreamer(S);
@@ -269,6 +291,9 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZTargetMC() {
                                         createSystemZMCInstPrinter);
 
   // Register the asm streamer.
+  TargetRegistry::RegisterAsmStreamer(getTheSystemZTarget(), createAsmStreamer);
+
+  // Register the asm target streamer.
   TargetRegistry::RegisterAsmTargetStreamer(getTheSystemZTarget(),
                                             createAsmTargetStreamer);
 
diff --git a/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
new file mode 100644
index 00000000000000..212a23cc1add73
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
@@ -0,0 +1,9 @@
+; RUN: llc < %s -emit-gnuas-syntax-on-zos=0 --mtriple=s390x-ibm-zos | FileCheck --match-full-lines %s
+
+; empty function
+; CHECK: foo
+; CHECK-NEXT: L#func_end0
+define void @foo() {
+entry:
+  ret void
+}

@tltao tltao changed the title [SystemZ] Introduce new AsmStreamer for z/OS specific HLASM format output [MC][SystemZ] Introduce new AsmStreamer for z/OS specific HLASM format output Sep 12, 2024
@tltao tltao changed the title [MC][SystemZ] Introduce new AsmStreamer for z/OS specific HLASM format output [SystemZ] Introduce new AsmStreamer for z/OS specific HLASM format output Sep 12, 2024
@tltao tltao changed the title [SystemZ] Introduce new AsmStreamer for z/OS specific HLASM format output [SystemZ][z/OS] Introduce new AsmStreamer for z/OS specific HLASM format output Sep 12, 2024
Comment on lines +37 to +38
// Temporary option to assist with the migration to a new HLASMAsmStreamer on
// z/OS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move 'on' to the next line and add '.' at the end.

@uweigand
Copy link
Member

Hi @tltao I think this is superseded by #130535 ... can this be closed now?

@tltao
Copy link
Contributor Author

tltao commented Mar 21, 2025

Hi @tltao I think this is superseded by #130535 ... can this be closed now?

Thanks, I missed this PR.

@tltao tltao closed this Mar 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:SystemZ llvm:mc Machine (object) code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants