LLVM 23.0.0git
SystemZHLASMAsmStreamer.cpp
Go to the documentation of this file.
1//===- SystemZHLASMAsmStreamer.cpp - HLASM Assembly Text Output -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
12#include "llvm/MC/MCExpr.h"
18#include <sstream>
19
20using namespace llvm;
21
23 Assembler->registerSymbol(Sym);
24}
25
27 // Comments are emitted on a new line before the instruction.
28 if (IsVerboseAsm)
30
31 std::istringstream Stream(Str);
33 std::string Line;
34 while (std::getline(Stream, Line, '\n'))
35 Lines.push_back(Line);
36
37 for (auto S : Lines) {
38 if (LLVM_LIKELY(S.length() < ContIndicatorColumn)) {
39 FOS << S;
40 // Each line in HLASM must fill the full 80 characters.
41 FOS.PadToColumn(InstLimit);
42 FOS << "\n";
43 } else {
44 // If last character before end of the line is not a space
45 // we must insert an additional non-space character that
46 // is not part of the statement coding. We just reuse
47 // the existing character by making the new substring start
48 // 1 character sooner, thus "duplicating" that character
49 // If The last character is a space. We insert an X instead.
50 std::string TmpSubStr = S.substr(0, ContIndicatorColumn);
51 if (!TmpSubStr.compare(ContIndicatorColumn - 1, 1, " "))
52 TmpSubStr.replace(ContIndicatorColumn - 1, 1, "X");
53
54 FOS << TmpSubStr;
55 FOS.PadToColumn(InstLimit);
56 FOS << "\n";
57
58 size_t Emitted = ContIndicatorColumn - 1;
59
60 while (Emitted < S.length()) {
61 if ((S.length() - Emitted) < ContLen)
62 TmpSubStr = S.substr(Emitted, S.length());
63 else {
64 TmpSubStr = S.substr(Emitted, ContLen);
65 if (!TmpSubStr.compare(ContLen - 1, 1, " "))
66 TmpSubStr.replace(ContLen - 1, 1, "X");
67 }
68 FOS.PadToColumn(ContStartColumn);
69 FOS << TmpSubStr;
70 FOS.PadToColumn(InstLimit);
71 FOS << "\n";
72 Emitted += ContLen - 1;
73 }
74 }
75 }
76 Str.clear();
77}
78
80 uint32_t Subsection) {
81 MAI->printSwitchToSection(*Section, Subsection,
82 getContext().getTargetTriple(), OS);
83 MCStreamer::changeSection(Section, Subsection);
84 EmitEOL();
85}
86
88 std::optional<int64_t> Value,
89 unsigned ValueSize,
90 unsigned MaxBytesToEmit) {
91 if (!isPowerOf2_64(ByteAlignment))
92 report_fatal_error("Only power-of-two alignments are supported ");
93
94 OS << " DS 0";
95 switch (ValueSize) {
96 default:
97 llvm_unreachable("Invalid size for machine code value!");
98 case 1:
99 OS << "B";
100 break;
101 case 2:
102 OS << "H";
103 break;
104 case 4:
105 OS << "F";
106 break;
107 case 8:
108 OS << "D";
109 break;
110 case 16:
111 OS << "Q";
112 break;
113 }
114
115 EmitEOL();
116}
117
119 if (!IsVerboseAsm)
120 return;
121
122 T.toVector(CommentToEmit);
123
124 if (EOL)
125 CommentToEmit.push_back('\n'); // Place comment in a new line.
126}
127
129 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0)
130 return;
131
132 StringRef Comments = CommentToEmit;
133
134 assert(Comments.back() == '\n' && "Comment array not newline terminated");
135 do {
136 // Emit a line of comments, but not exceeding 80 characters.
137 size_t Position = std::min(InstLimit - 2, Comments.find('\n'));
138 FOS << MAI->getCommentString() << ' ' << Comments.substr(0, Position)
139 << '\n';
140
141 if (Comments[Position] == '\n')
142 Position++;
143 Comments = Comments.substr(Position);
144 } while (!Comments.empty());
145
146 CommentToEmit.clear();
147}
148
150 int64_t Fill,
151 uint8_t FillLen,
152 unsigned MaxBytesToEmit) {
153 emitAlignmentDS(Alignment.value(), Fill, FillLen, MaxBytesToEmit);
154}
155
157 const MCSubtargetInfo *STI,
158 unsigned MaxBytesToEmit) {
159 // Emit with a text fill value.
160 if (MAI->getTextAlignFillValue())
161 emitAlignmentDS(Alignment.value(), MAI->getTextAlignFillValue(), 1,
162 MaxBytesToEmit);
163 else
164 emitAlignmentDS(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
165}
166
169 "Cannot emit contents before setting section!");
170 if (Data.empty())
171 return;
172
173 OS << " DC ";
174 size_t Len = Data.size();
176 Chars.resize(Len);
177 OS << "XL" << Len;
178 uint32_t Index = 0;
179 for (uint8_t C : Data) {
180 Chars[Index] = C;
181 Index++;
182 }
183
184 OS << '\'' << toHex(Chars) << '\'';
185
186 EmitEOL();
187}
188
190 const MCSubtargetInfo &STI) {
191
192 InstPrinter->printInst(&Inst, 0, "", STI, OS);
193 EmitEOL();
194}
195
196static void emitXATTR(raw_ostream &OS, StringRef Name, MCSectionGOFF *ADA,
197 bool IsIndirectReference, GOFF::ESDLinkageType Linkage,
198 GOFF::ESDExecutable Executable,
199 GOFF::ESDBindingScope BindingScope) {
200 llvm::ListSeparator Sep(",");
201 OS << Name << " XATTR ";
202 OS << Sep << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK")
203 << ")";
204
205 const bool NotUnspecified = (Executable != GOFF::ESD_EXE_Unspecified);
206 if (NotUnspecified || IsIndirectReference) {
207 OS << Sep << "REFERENCE(";
208 llvm::ListSeparator SepRef(",");
209
210 if (NotUnspecified)
211 OS << SepRef << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA");
212
213 if (IsIndirectReference)
214 OS << SepRef << "INDIRECT";
215
216 OS << ")";
217 }
218 if (ADA)
219 OS << Sep << "PSECT(" << ADA->getName() << ")";
220 if (BindingScope != GOFF::ESD_BSC_Unspecified) {
221 OS << Sep << "SCOPE(";
222 switch (BindingScope) {
224 OS << "SECTION";
225 break;
227 OS << "MODULE";
228 break;
230 OS << "LIBRARY";
231 break;
233 OS << "EXPORT";
234 break;
235 default:
236 break;
237 }
238 OS << ')';
239 }
240}
241
243 MCSymbolGOFF *Sym = static_cast<MCSymbolGOFF *>(Symbol);
244
246
247 // Emit label and ENTRY statement only if not implied by CSECT. Do not emit a
248 // label if the symbol is on a PR section.
249 bool EmitLabelAndEntry =
250 !static_cast<MCSectionGOFF *>(getCurrentSectionOnly())->isPR();
251 if (!Sym->isTemporary() && Sym->isInEDSection()) {
252 EmitLabelAndEntry =
253 Sym->getName() !=
254 static_cast<MCSectionGOFF &>(Sym->getSection()).getParent()->getName();
255 if (EmitLabelAndEntry) {
256 OS << " ENTRY " << Sym->getName();
257 EmitEOL();
258 }
259
260 emitXATTR(OS, Sym->getName(), Sym->getADA(), Sym->isIndirect(),
261 Sym->getLinkage(), Sym->getCodeData(), Sym->getBindingScope());
262 EmitEOL();
263 if (Sym->hasExternalName())
264 OS << Sym->getName() << " ALIAS C'" << Sym->getExternalName() << "'\n";
265 }
266
267 if (EmitLabelAndEntry) {
268 OS << Sym->getName() << " DS 0H";
269 EmitEOL();
270 }
271}
272
275 return static_cast<MCSymbolGOFF *>(Sym)->setSymbolAttribute(Attribute);
276}
277
279 String.consume_back("\n");
280 OS << String;
281 EmitEOL();
282}
283
284// Slight duplicate of MCExpr::print due to HLASM only recognizing limited
285// arithmetic operators (+-*/).
287 unsigned Size, bool Parens) {
288 switch (Value->getKind()) {
289 case MCExpr::Constant: {
290 OS << "XL" << Size << '\'';
291 MAI->printExpr(OS, *Value);
292 OS << '\'';
293 return;
294 }
295 case MCExpr::Binary: {
297 int64_t Const;
298 // Or is handled differently.
299 if (BE.getOpcode() == MCBinaryExpr::Or) {
300 emitHLASMValueImpl(BE.getLHS(), Size, true);
301 OS << ',';
302 emitHLASMValueImpl(BE.getRHS(), Size, true);
303 return;
304 }
305
306 if (Parens)
307 OS << "AD(";
309
310 switch (BE.getOpcode()) {
311 case MCBinaryExpr::LShr: {
312 Const = cast<MCConstantExpr>(BE.getRHS())->getValue();
313 OS << '/' << (1 << Const);
314 if (Parens)
315 OS << ')';
316 return;
317 }
319 OS << '+';
320 break;
322 OS << '/';
323 break;
325 OS << '*';
326 break;
328 OS << '-';
329 break;
330 default:
332 "Unrecognized HLASM arithmetic expression!");
333 }
335 if (Parens)
336 OS << ')';
337 return;
338 }
339 case MCExpr::Target:
340 MAI->printExpr(OS, *Value);
341 return;
342 default:
343 Parens &= isa<MCSymbolRefExpr>(Value);
344 if (Parens)
345 OS << "AD(";
346 MAI->printExpr(OS, *Value);
347 if (Parens)
348 OS << ')';
349 return;
350 }
351}
352
354 SMLoc Loc) {
355 assert(Size <= 8 && "Invalid size");
357 "Cannot emit contents before setting section!");
358
360 OS << " DC ";
362 EmitEOL();
363}
364
366 for (auto &Symbol : getAssembler().symbols()) {
367 if (Symbol.isTemporary() || !Symbol.isRegistered() || Symbol.isDefined())
368 continue;
369 auto &Sym = static_cast<MCSymbolGOFF &>(const_cast<MCSymbol &>(Symbol));
370 OS << " " << (Sym.isWeak() ? "WXTRN" : "EXTRN") << " " << Sym.getName();
371 EmitEOL();
372 emitXATTR(OS, Sym.getName(), Sym.getADA(), Sym.isIndirect(),
373 Sym.getLinkage(), Sym.getCodeData(), Sym.getBindingScope());
374 EmitEOL();
375 if (Sym.hasExternalName())
376 OS << Sym.getName() << " ALIAS C'" << Sym.getExternalName() << "'\n";
377 }
378
379 // Finish the assembly output.
380 OS << " END";
381 EmitEOL();
382}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_LIKELY(EXPR)
Definition Compiler.h:335
DXIL Finalize Linkage
static void emitXATTR(raw_ostream &OS, StringRef Name, MCSectionGOFF *ADA, GOFF::ESDLinkageType Linkage, GOFF::ESDExecutable Executable, GOFF::ESDBindingScope BindingScope)
This file contains the MCSymbolGOFF class.
#define T
This file contains some functions that are useful when dealing with strings.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
A helper class to return the specified delimiter string after the first invocation of operator String...
Binary assembler expressions.
Definition MCExpr.h:299
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition MCExpr.h:446
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition MCExpr.h:449
Opcode getOpcode() const
Get the kind of this binary expression.
Definition MCExpr.h:443
@ Div
Signed division.
Definition MCExpr.h:304
@ LShr
Logical shift right.
Definition MCExpr.h:323
@ Sub
Subtraction.
Definition MCExpr.h:324
@ Mul
Multiplication.
Definition MCExpr.h:317
@ Or
Bitwise or.
Definition MCExpr.h:319
@ Add
Addition.
Definition MCExpr.h:302
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
@ Constant
Constant expressions.
Definition MCExpr.h:42
@ Target
Target specific expression.
Definition MCExpr.h:46
@ Binary
Binary expressions.
Definition MCExpr.h:41
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
MCSectionGOFF * getParent() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:516
StringRef getName() const
Definition MCSection.h:586
MCContext & getContext() const
Definition MCStreamer.h:322
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCSection * getCurrentSectionOnly() const
Definition MCStreamer.h:427
virtual void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Emit the expression Value into the output as a native integer of the given Size bytes.
virtual void changeSection(MCSection *, uint32_t)
This is called by popSection and switchSection, if the current section changes.
Generic base class for all target subtargets.
StringRef getExternalName() const
GOFF::ESDExecutable getCodeData() const
bool hasExternalName() const
bool isInEDSection() const
GOFF::ESDBindingScope getBindingScope() const
bool isIndirect() const
GOFF::ESDLinkageType getLinkage() const
MCSectionGOFF * getADA() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition MCSymbol.h:251
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition MCSymbol.h:205
Represents a location in source code.
Definition SMLoc.h:22
void resize(size_type N)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:591
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
char back() const
back - Get the last character in the string.
Definition StringRef.h:152
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition StringRef.h:290
void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0) override
Emit nops until the byte alignment ByteAlignment is reached.
void emitHLASMValueImpl(const MCExpr *Value, unsigned Size, bool Parens=false)
void emitRawTextImpl(StringRef String) override
EmitRawText - If this file is backed by an assembly streamer, this dumps the specified string in the ...
void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override
Emit the expression Value into the output as a native integer of the given Size bytes.
void emitBytes(StringRef Data) override
Emit the bytes in Data into the output.
void emitAlignmentDS(uint64_t ByteAlignment, std::optional< int64_t > Value, unsigned ValueSize, unsigned MaxBytesToEmit)
void finishImpl() override
Streamer specific finalization.
void visitUsedSymbol(const MCSymbol &Sym) override
void AddComment(const Twine &T, bool EOL=true) override
Add a comment that can be emitted to the generated .s file to make the output of the compiler more re...
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
void emitValueToAlignment(Align Alignment, int64_t Fill, uint8_t FillLen, unsigned MaxBytesToEmit) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
void changeSection(MCSection *Section, uint32_t Subsection) override
This is called by popSection and switchSection, if the current section changes.
void emitLabel(MCSymbol *Symbol, SMLoc Loc) override
Emit a label for Symbol into the current section.
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override
Add the given Attribute to Symbol.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
ESDExecutable
Definition GOFF.h:109
@ ESD_EXE_Unspecified
Definition GOFF.h:110
@ ESD_EXE_CODE
Definition GOFF.h:112
ESDBindingScope
Definition GOFF.h:134
@ ESD_BSC_Library
Definition GOFF.h:138
@ ESD_BSC_Module
Definition GOFF.h:137
@ ESD_BSC_Unspecified
Definition GOFF.h:135
@ ESD_BSC_ImportExport
Definition GOFF.h:139
@ ESD_BSC_Section
Definition GOFF.h:136
ESDLinkageType
Definition GOFF.h:142
@ ESD_LT_OS
Definition GOFF.h:142
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:284
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)
Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77