Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMAsmStreamer.cpp
213845 views
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
9
#include "SystemZHLASMAsmStreamer.h"
10
#include "llvm/ADT/StringExtras.h"
11
#include "llvm/Support/Casting.h"
12
#include "llvm/Support/Signals.h"
13
#include <sstream>
14
15
using namespace llvm;
16
17
void SystemZHLASMAsmStreamer::EmitEOL() {
18
// Comments are emitted on a new line before the instruction.
19
if (IsVerboseAsm)
20
EmitComment();
21
22
std::istringstream Stream(Str);
23
SmallVector<std::string> Lines;
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
70
void SystemZHLASMAsmStreamer::changeSection(MCSection *Section,
71
uint32_t Subsection) {
72
Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
73
Subsection);
74
MCStreamer::changeSection(Section, Subsection);
75
}
76
77
void SystemZHLASMAsmStreamer::emitAlignmentDS(uint64_t ByteAlignment,
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
108
void SystemZHLASMAsmStreamer::AddComment(const Twine &T, bool EOL) {
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
118
void SystemZHLASMAsmStreamer::EmitComment() {
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
139
void SystemZHLASMAsmStreamer::emitValueToAlignment(Align Alignment,
140
int64_t Fill,
141
uint8_t FillLen,
142
unsigned MaxBytesToEmit) {
143
emitAlignmentDS(Alignment.value(), Fill, FillLen, MaxBytesToEmit);
144
}
145
146
void SystemZHLASMAsmStreamer::emitCodeAlignment(Align Alignment,
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
157
void SystemZHLASMAsmStreamer::emitBytes(StringRef Data) {
158
assert(getCurrentSectionOnly() &&
159
"Cannot emit contents before setting section!");
160
if (Data.empty())
161
return;
162
163
OS << " DC ";
164
size_t Len = Data.size();
165
SmallVector<uint8_t> Chars;
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
179
void SystemZHLASMAsmStreamer::emitInstruction(const MCInst &Inst,
180
const MCSubtargetInfo &STI) {
181
182
InstPrinter->printInst(&Inst, 0, "", STI, OS);
183
EmitEOL();
184
}
185
186
void SystemZHLASMAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
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
199
void SystemZHLASMAsmStreamer::emitRawTextImpl(StringRef String) {
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 (+-*/).
207
void SystemZHLASMAsmStreamer::emitHLASMValueImpl(const MCExpr *Value,
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(";
229
emitHLASMValueImpl(BE.getLHS(), Size);
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
}
239
case MCBinaryExpr::Add:
240
OS << '+';
241
break;
242
case MCBinaryExpr::Div:
243
OS << '/';
244
break;
245
case MCBinaryExpr::Mul:
246
OS << '*';
247
break;
248
case MCBinaryExpr::Sub:
249
OS << '-';
250
break;
251
default:
252
getContext().reportError(SMLoc(),
253
"Unrecognized HLASM arithmetic expression!");
254
}
255
emitHLASMValueImpl(BE.getRHS(), Size);
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
273
void SystemZHLASMAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
274
SMLoc Loc) {
275
assert(Size <= 8 && "Invalid size");
276
assert(getCurrentSectionOnly() &&
277
"Cannot emit contents before setting section!");
278
279
OS << " DC ";
280
emitHLASMValueImpl(Value, Size, true);
281
EmitEOL();
282
}
283
284
void SystemZHLASMAsmStreamer::emitEnd() {
285
OS << " END";
286
EmitEOL();
287
}
288
289