Skip to content

[SystemZ][HLASM] Emit END instruction #146110

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

Merged
merged 2 commits into from
Jul 2, 2025
Merged

[SystemZ][HLASM] Emit END instruction #146110

merged 2 commits into from
Jul 2, 2025

Conversation

redstar
Copy link
Member

@redstar redstar commented Jun 27, 2025

A HLASM source file must end with the END instruction. It is implemented by adding a new function to the target streamer,. This change also turns SystemZHLASMSAsmString.h into a proper header file, and only uses the SystemZTargetHLASMStreamer when HLASM output is generated.

A HLASM source file must end with the END instruction.  It is implemented by adding a new function to the target streamer,.
This change also turns SystemZHLASMSAsmString.h into a proper header file, and only uses the SystemZTargetHLASMStreamer when HLASM output is generated.
@redstar redstar requested review from uweigand, tltao and JonPsson1 June 27, 2025 16:36
@redstar redstar self-assigned this Jun 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 27, 2025

@llvm/pr-subscribers-backend-systemz

Author: Kai Nacke (redstar)

Changes

A HLASM source file must end with the END instruction. It is implemented by adding a new function to the target streamer,. This change also turns SystemZHLASMSAsmString.h into a proper header file, and only uses the SystemZTargetHLASMStreamer when HLASM output is generated.


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

7 Files Affected:

  • (modified) llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp (+6-1)
  • (modified) llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h (+9-1)
  • (modified) llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp (+1-1)
  • (modified) llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp (+9)
  • (modified) llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h (+4)
  • (modified) llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp (+3)
  • (modified) llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll (+1)
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
index ec8c810809301..9121f0d44936f 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
@@ -12,7 +12,7 @@
 #include "llvm/Support/Signals.h"
 #include <sstream>
 
-#include <cmath>
+using namespace llvm;
 
 void SystemZHLASMAsmStreamer::EmitEOL() {
   // Comments are emitted on a new line before the instruction.
@@ -280,3 +280,8 @@ void SystemZHLASMAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
   emitHLASMValueImpl(Value, Size, true);
   EmitEOL();
 }
+
+void SystemZHLASMAsmStreamer::emitEnd() {
+  OS << " END";
+  EmitEOL();
+}
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
index edaaf984df651..c5275339ce016 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.h
@@ -10,6 +10,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#ifndef LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZHLASMASMSTREAMER_H
+#define LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZHLASMASMSTREAMER_H
+
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/MC/MCAsmBackend.h"
@@ -24,7 +27,7 @@
 #include "llvm/MC/MCTargetOptions.h"
 #include "llvm/Support/FormattedStream.h"
 
-using namespace llvm;
+namespace llvm {
 
 class SystemZHLASMAsmStreamer final : public MCStreamer {
   constexpr static size_t InstLimit = 80;
@@ -119,4 +122,9 @@ class SystemZHLASMAsmStreamer final : public MCStreamer {
   void emitHLASMValueImpl(const MCExpr *Value, unsigned Size,
                           bool Parens = false);
   /// @}
+
+  void emitEnd();
 };
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZHLASMASMSTREAMER_H
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp
index 86e340b7ff1bd..faef5bb926780 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp
@@ -203,7 +203,7 @@ static MCInstPrinter *createSystemZMCInstPrinter(const Triple &T,
 static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
                                                  formatted_raw_ostream &OS,
                                                  MCInstPrinter *InstPrint) {
-  if (S.getContext().getTargetTriple().isOSzOS())
+  if (S.getContext().getTargetTriple().isOSzOS() && !GNUAsOnzOSCL)
     return new SystemZTargetHLASMStreamer(S, OS);
   else
     return new SystemZTargetGNUStreamer(S, OS);
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
index 7720678097440..d740785fe352b 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "SystemZTargetStreamer.h"
+#include "SystemZHLASMAsmStreamer.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCObjectFileInfo.h"
 
@@ -33,10 +34,18 @@ void SystemZTargetStreamer::emitConstantPools() {
   EXRLTargets2Sym.clear();
 }
 
+SystemZHLASMAsmStreamer &SystemZTargetHLASMStreamer::getHLASMStreamer() {
+  return static_cast<SystemZHLASMAsmStreamer &>(getStreamer());
+}
+
 void SystemZTargetHLASMStreamer::emitExtern(StringRef Sym) {
   getStreamer().emitRawText(Twine(" EXTRN ") + Twine(Sym));
 }
 
+void SystemZTargetHLASMStreamer::emitEnd() {
+  getHLASMStreamer().emitEnd();
+}
+
 // HLASM statements can only perform a single operation at a time
 const MCExpr *SystemZTargetHLASMStreamer::createWordDiffExpr(
     MCContext &Ctx, const MCSymbol *Hi, const MCSymbol *Lo) {
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZTargetStreamer.h
index 7e3c5f00525f4..3fc09bc8c683a 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 SystemZHLASMAsmStreamer;
 
 class SystemZTargetStreamer : public MCTargetStreamer {
 public:
@@ -57,6 +58,7 @@ class SystemZTargetStreamer : public MCTargetStreamer {
   virtual void emitMachine(StringRef CPUOrCommand) {};
 
   virtual void emitExtern(StringRef Str) {};
+  virtual void emitEnd() {};
 
   virtual const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
                                            const MCSymbol *Lo) {
@@ -77,7 +79,9 @@ class SystemZTargetHLASMStreamer : public SystemZTargetStreamer {
 public:
   SystemZTargetHLASMStreamer(MCStreamer &S, formatted_raw_ostream &OS)
       : SystemZTargetStreamer(S), OS(OS) {}
+  SystemZHLASMAsmStreamer &getHLASMStreamer();
   void emitExtern(StringRef Sym) override;
+  void emitEnd() 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 eb0365d1f1893..e31d7c6a86476 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1114,6 +1114,9 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
     emitIDRLSection(M);
   }
   emitAttributes(M);
+  // Emit the END instruction in case of HLASM output. This must be the last
+  // instruction in the source file.
+  getTargetStreamer()->emitEnd();
 }
 
 void SystemZAsmPrinter::emitADASection() {
diff --git a/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
index fc52de6c387d1..a29646b8bcc61 100644
--- a/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-hlasm-out.ll
@@ -42,6 +42,7 @@ define void @foo() {
 ; CHECK: DS 0B
 ; CHECK-LABEL: L#.str.1 DS 0H
 ; CHECK: DC XL6'576F726C6400'
+; CHECK: END
 entry:
   %0 = load ptr, ptr @Greeting, align 8
   call void (ptr, ...) @outs(ptr noundef %0, ptr noundef @.str.1)

Copy link

github-actions bot commented Jun 27, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

void SystemZTargetHLASMStreamer::emitExtern(StringRef Sym) {
getStreamer().emitRawText(Twine(" EXTRN ") + Twine(Sym));
}

void SystemZTargetHLASMStreamer::emitEnd() { getHLASMStreamer().emitEnd(); }
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, but why not directly implement this as part of TargetStreamer similar to emitExtern?

Copy link
Member Author

Choose a reason for hiding this comment

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

emitExtern() hard codes the space at the begin. In case we want to change this (e.g. make the output more like the XL output), then we have to bring the formatting into the TargetStreamer. I think it also makes code sharing easier. I expect emitExtern() to become more complicated. For functions, it needs to emit a XATTR instruction, and for variables it needs to emit CATTR. The same code is needed when emitting a label. IMHO it becomes easier when the implementation is just in 1 class.
It's a design choice, other variants are surely possible.

Copy link
Contributor

@tltao tltao left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@uweigand uweigand left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@redstar redstar merged commit ebcf7f9 into main Jul 2, 2025
7 checks passed
@redstar redstar deleted the users/redstar/hlasmend branch July 2, 2025 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants