LLVM 22.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
13#include <sstream>
14
15using namespace llvm;
16
18 // Comments are emitted on a new line before the instruction.
19 if (IsVerboseAsm)
21
22 std::istringstream Stream(Str);
24 std::string Line;
25 while (std::getline(Stream, Line, '\n'))
26 Lines.push_back(Line);
27
28 for (auto S : Lines) {
29 if (LLVM_LIKELY(S.length() < ContIndicatorColumn)) {
30 FOS << S;
31 // Each line in HLASM must fill the full 80 characters.
32 FOS.PadToColumn(InstLimit);
33 FOS << "\n";
34 } else {
35 // If last character before end of the line is not a space
36 // we must insert an additional non-space character that
37 // is not part of the statement coding. We just reuse
38 // the existing character by making the new substring start
39 // 1 character sooner, thus "duplicating" that character
40 // If The last character is a space. We insert an X instead.
41 std::string TmpSubStr = S.substr(0, ContIndicatorColumn);
42 if (!TmpSubStr.compare(ContIndicatorColumn - 1, 1, " "))
43 TmpSubStr.replace(ContIndicatorColumn - 1, 1, "X");
44
45 FOS << TmpSubStr;
46 FOS.PadToColumn(InstLimit);
47 FOS << "\n";
48
49 size_t Emitted = ContIndicatorColumn - 1;
50
51 while (Emitted < S.length()) {
52 if ((S.length() - Emitted) < ContLen)
53 TmpSubStr = S.substr(Emitted, S.length());
54 else {
55 TmpSubStr = S.substr(Emitted, ContLen);
56 if (!TmpSubStr.compare(ContLen - 1, 1, " "))
57 TmpSubStr.replace(ContLen - 1, 1, "X");
58 }
59 FOS.PadToColumn(ContStartColumn);
60 FOS << TmpSubStr;
61 FOS.PadToColumn(InstLimit);
62 FOS << "\n";
63 Emitted += ContLen - 1;
64 }
65 }
66 }
67 Str.clear();
68}
69
71 uint32_t Subsection) {
72 MAI->printSwitchToSection(*Section, Subsection,
73 getContext().getTargetTriple(), OS);
74 MCStreamer::changeSection(Section, Subsection);
75}
76
78 std::optional<int64_t> Value,
79 unsigned ValueSize,
80 unsigned MaxBytesToEmit) {
81 if (!isPowerOf2_64(ByteAlignment))
82 report_fatal_error("Only power-of-two alignments are supported ");
83
84 OS << " DS 0";
85 switch (ValueSize) {
86 default:
87 llvm_unreachable("Invalid size for machine code value!");
88 case 1:
89 OS << "B";
90 break;
91 case 2:
92 OS << "H";
93 break;
94 case 4:
95 OS << "F";
96 break;
97 case 8:
98 OS << "D";
99 break;
100 case 16:
101 OS << "Q";
102 break;
103 }
104
105 EmitEOL();
106}
107
109 if (!IsVerboseAsm)
110 return;
111
112 T.toVector(CommentToEmit);
113
114 if (EOL)
115 CommentToEmit.push_back('\n'); // Place comment in a new line.
116}
117
119 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0)
120 return;
121
122 StringRef Comments = CommentToEmit;
123
124 assert(Comments.back() == '\n' && "Comment array not newline terminated");
125 do {
126 // Emit a line of comments, but not exceeding 80 characters.
127 size_t Position = std::min(InstLimit - 2, Comments.find('\n'));
128 FOS << MAI->getCommentString() << ' ' << Comments.substr(0, Position)
129 << '\n';
130
131 if (Comments[Position] == '\n')
132 Position++;
133 Comments = Comments.substr(Position);
134 } while (!Comments.empty());
135
136 CommentToEmit.clear();
137}
138
140 int64_t Fill,
141 uint8_t FillLen,
142 unsigned MaxBytesToEmit) {
143 emitAlignmentDS(Alignment.value(), Fill, FillLen, MaxBytesToEmit);
144}
145
147 const MCSubtargetInfo *STI,
148 unsigned MaxBytesToEmit) {
149 // Emit with a text fill value.
150 if (MAI->getTextAlignFillValue())
151 emitAlignmentDS(Alignment.value(), MAI->getTextAlignFillValue(), 1,
152 MaxBytesToEmit);
153 else
154 emitAlignmentDS(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
155}
156
159 "Cannot emit contents before setting section!");
160 if (Data.empty())
161 return;
162
163 OS << " DC ";
164 size_t Len = Data.size();
166 Chars.resize(Len);
167 OS << "XL" << Len;
168 uint32_t Index = 0;
169 for (uint8_t C : Data) {
170 Chars[Index] = C;
171 Index++;
172 }
173
174 OS << '\'' << toHex(Chars) << '\'';
175
176 EmitEOL();
177}
178
180 const MCSubtargetInfo &STI) {
181
182 InstPrinter->printInst(&Inst, 0, "", STI, OS);
183 EmitEOL();
184}
185
187
188 MCStreamer::emitLabel(Symbol, Loc);
189
190 Symbol->print(OS, MAI);
191 // TODO Need to adjust this based on Label type
192 OS << " DS 0H";
193 // TODO Update LabelSuffix in SystemZMCAsmInfoGOFF once tests have been
194 // moved to HLASM syntax.
195 // OS << MAI->getLabelSuffix();
196 EmitEOL();
197}
198
200 String.consume_back("\n");
201 OS << String;
202 EmitEOL();
203}
204
205// Slight duplicate of MCExpr::print due to HLASM only recognizing limited
206// arithmetic operators (+-*/).
208 unsigned Size, bool Parens) {
209 switch (Value->getKind()) {
210 case MCExpr::Constant: {
211 OS << "XL" << Size << '\'';
212 MAI->printExpr(OS, *Value);
213 OS << '\'';
214 return;
215 }
216 case MCExpr::Binary: {
217 const MCBinaryExpr &BE = cast<MCBinaryExpr>(*Value);
218 int64_t Const;
219 // Or is handled differently.
220 if (BE.getOpcode() == MCBinaryExpr::Or) {
221 emitHLASMValueImpl(BE.getLHS(), Size, true);
222 OS << ',';
223 emitHLASMValueImpl(BE.getRHS(), Size, true);
224 return;
225 }
226
227 if (Parens)
228 OS << "A(";
230
231 switch (BE.getOpcode()) {
232 case MCBinaryExpr::LShr: {
233 Const = cast<MCConstantExpr>(BE.getRHS())->getValue();
234 OS << '/' << (1 << Const);
235 if (Parens)
236 OS << ')';
237 return;
238 }
240 OS << '+';
241 break;
243 OS << '/';
244 break;
246 OS << '*';
247 break;
249 OS << '-';
250 break;
251 default:
253 "Unrecognized HLASM arithmetic expression!");
254 }
256 if (Parens)
257 OS << ')';
258 return;
259 }
260 case MCExpr::Target:
261 MAI->printExpr(OS, *Value);
262 return;
263 default:
264 if (Parens)
265 OS << "A(";
266 MAI->printExpr(OS, *Value);
267 if (Parens)
268 OS << ')';
269 return;
270 }
271}
272
274 SMLoc Loc) {
275 assert(Size <= 8 && "Invalid size");
277 "Cannot emit contents before setting section!");
278
279 OS << " DC ";
281 EmitEOL();
282}
283
285 OS << " END";
286 EmitEOL();
287}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:335
uint64_t Size
This file contains some functions that are useful when dealing with strings.
unsigned getTextAlignFillValue() const
Definition: MCAsmInfo.h:590
void printExpr(raw_ostream &, const MCExpr &) const
Definition: MCAsmInfo.cpp:153
virtual void printSwitchToSection(const MCSection &, uint32_t Subsection, const Triple &, raw_ostream &) const
Definition: MCAsmInfo.h:489
StringRef getCommentString() const
Definition: MCAsmInfo.h:538
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)
Definition: MCContext.cpp:1115
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
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:496
MCContext & getContext() const
Definition: MCStreamer.h:314
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:395
MCSection * getCurrentSectionOnly() const
Definition: MCStreamer.h:421
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.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
Represents a location in source code.
Definition: SMLoc.h:23
bool empty() const
Definition: SmallVector.h:82
void resize(size_type N)
Definition: SmallVector.h:639
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
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:581
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
char back() const
back - Get the last character in the string.
Definition: StringRef.h:163
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:301
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 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.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
LLVM Value Representation.
Definition: Value.h:75
formatted_raw_ostream & PadToColumn(unsigned NewCol)
PadToColumn - Align the output to some column number.
size_t GetNumBytesInBuffer() const
Definition: raw_ostream.h:191
#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
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:293
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85