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 -#include +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..1a3e373f25374 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,16 @@ void SystemZTargetStreamer::emitConstantPools() { EXRLTargets2Sym.clear(); } +SystemZHLASMAsmStreamer &SystemZTargetHLASMStreamer::getHLASMStreamer() { + return static_cast(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 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)