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/SystemZInstPrinter.cpp
35294 views
1
//===- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax -===//
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 "SystemZInstPrinter.h"
10
#include "llvm/MC/MCExpr.h"
11
#include "llvm/MC/MCInst.h"
12
#include "llvm/MC/MCRegister.h"
13
#include "llvm/MC/MCSymbol.h"
14
#include "llvm/Support/Casting.h"
15
#include "llvm/Support/ErrorHandling.h"
16
#include "llvm/Support/MathExtras.h"
17
#include "llvm/Support/raw_ostream.h"
18
#include <cassert>
19
#include <cstdint>
20
21
using namespace llvm;
22
23
#define DEBUG_TYPE "asm-printer"
24
25
#include "SystemZGenAsmWriter.inc"
26
27
void SystemZInstPrinter::printAddress(const MCAsmInfo *MAI, MCRegister Base,
28
const MCOperand &DispMO, MCRegister Index,
29
raw_ostream &O) {
30
printOperand(DispMO, MAI, O);
31
if (Base || Index) {
32
O << '(';
33
if (Index) {
34
printFormattedRegName(MAI, Index, O);
35
O << ',';
36
}
37
if (Base)
38
printFormattedRegName(MAI, Base, O);
39
else
40
O << '0';
41
O << ')';
42
}
43
}
44
45
void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI,
46
raw_ostream &O) {
47
if (MO.isReg()) {
48
if (!MO.getReg())
49
O << '0';
50
else
51
printFormattedRegName(MAI, MO.getReg(), O);
52
}
53
else if (MO.isImm())
54
markup(O, Markup::Immediate) << MO.getImm();
55
else if (MO.isExpr())
56
MO.getExpr()->print(O, MAI);
57
else
58
llvm_unreachable("Invalid operand");
59
}
60
61
void SystemZInstPrinter::printFormattedRegName(const MCAsmInfo *MAI,
62
MCRegister Reg,
63
raw_ostream &O) const {
64
const char *RegName = getRegisterName(Reg);
65
if (MAI->getAssemblerDialect() == AD_HLASM) {
66
// Skip register prefix so that only register number is left
67
assert(isalpha(RegName[0]) && isdigit(RegName[1]));
68
markup(O, Markup::Register) << (RegName + 1);
69
} else
70
markup(O, Markup::Register) << '%' << RegName;
71
}
72
73
void SystemZInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {
74
printFormattedRegName(&MAI, Reg, O);
75
}
76
77
void SystemZInstPrinter::printInst(const MCInst *MI, uint64_t Address,
78
StringRef Annot, const MCSubtargetInfo &STI,
79
raw_ostream &O) {
80
printInstruction(MI, Address, O);
81
printAnnotation(O, Annot);
82
}
83
84
template <unsigned N>
85
void SystemZInstPrinter::printUImmOperand(const MCInst *MI, int OpNum,
86
raw_ostream &O) {
87
const MCOperand &MO = MI->getOperand(OpNum);
88
if (MO.isExpr()) {
89
O << *MO.getExpr();
90
return;
91
}
92
uint64_t Value = static_cast<uint64_t>(MO.getImm());
93
assert(isUInt<N>(Value) && "Invalid uimm argument");
94
markup(O, Markup::Immediate) << Value;
95
}
96
97
template <unsigned N>
98
void SystemZInstPrinter::printSImmOperand(const MCInst *MI, int OpNum,
99
raw_ostream &O) {
100
const MCOperand &MO = MI->getOperand(OpNum);
101
if (MO.isExpr()) {
102
O << *MO.getExpr();
103
return;
104
}
105
int64_t Value = MI->getOperand(OpNum).getImm();
106
assert(isInt<N>(Value) && "Invalid simm argument");
107
markup(O, Markup::Immediate) << Value;
108
}
109
110
void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
111
raw_ostream &O) {
112
printUImmOperand<1>(MI, OpNum, O);
113
}
114
115
void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
116
raw_ostream &O) {
117
printUImmOperand<2>(MI, OpNum, O);
118
}
119
120
void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
121
raw_ostream &O) {
122
printUImmOperand<3>(MI, OpNum, O);
123
}
124
125
void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
126
raw_ostream &O) {
127
printUImmOperand<4>(MI, OpNum, O);
128
}
129
130
void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
131
raw_ostream &O) {
132
printSImmOperand<8>(MI, OpNum, O);
133
}
134
135
void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
136
raw_ostream &O) {
137
printUImmOperand<8>(MI, OpNum, O);
138
}
139
140
void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
141
raw_ostream &O) {
142
printUImmOperand<12>(MI, OpNum, O);
143
}
144
145
void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
146
raw_ostream &O) {
147
printSImmOperand<16>(MI, OpNum, O);
148
}
149
150
void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
151
raw_ostream &O) {
152
printUImmOperand<16>(MI, OpNum, O);
153
}
154
155
void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
156
raw_ostream &O) {
157
printSImmOperand<32>(MI, OpNum, O);
158
}
159
160
void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
161
raw_ostream &O) {
162
printUImmOperand<32>(MI, OpNum, O);
163
}
164
165
void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,
166
raw_ostream &O) {
167
printUImmOperand<48>(MI, OpNum, O);
168
}
169
170
void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
171
raw_ostream &O) {
172
const MCOperand &MO = MI->getOperand(OpNum);
173
if (MO.isImm()) {
174
WithMarkup M = markup(O, Markup::Immediate);
175
O << "0x";
176
O.write_hex(MO.getImm());
177
} else
178
MO.getExpr()->print(O, &MAI);
179
}
180
181
void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI,
182
uint64_t Address, int OpNum,
183
raw_ostream &O) {
184
// Output the PC-relative operand.
185
printPCRelOperand(MI, OpNum, O);
186
187
// Output the TLS marker if present.
188
if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
189
const MCOperand &MO = MI->getOperand(OpNum + 1);
190
const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
191
switch (refExp.getKind()) {
192
case MCSymbolRefExpr::VK_TLSGD:
193
O << ":tls_gdcall:";
194
break;
195
case MCSymbolRefExpr::VK_TLSLDM:
196
O << ":tls_ldcall:";
197
break;
198
default:
199
llvm_unreachable("Unexpected symbol kind");
200
}
201
O << refExp.getSymbol().getName();
202
}
203
}
204
205
void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
206
raw_ostream &O) {
207
printOperand(MI->getOperand(OpNum), &MAI, O);
208
}
209
210
void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
211
raw_ostream &O) {
212
printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
213
0, O);
214
}
215
216
void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
217
raw_ostream &O) {
218
printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
219
MI->getOperand(OpNum + 2).getReg(), O);
220
}
221
222
void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
223
raw_ostream &O) {
224
unsigned Base = MI->getOperand(OpNum).getReg();
225
const MCOperand &DispMO = MI->getOperand(OpNum + 1);
226
uint64_t Length = MI->getOperand(OpNum + 2).getImm();
227
printOperand(DispMO, &MAI, O);
228
O << '(' << Length;
229
if (Base) {
230
O << ",";
231
printRegName(O, Base);
232
}
233
O << ')';
234
}
235
236
void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
237
raw_ostream &O) {
238
unsigned Base = MI->getOperand(OpNum).getReg();
239
const MCOperand &DispMO = MI->getOperand(OpNum + 1);
240
unsigned Length = MI->getOperand(OpNum + 2).getReg();
241
printOperand(DispMO, &MAI, O);
242
O << "(";
243
printRegName(O, Length);
244
if (Base) {
245
O << ",";
246
printRegName(O, Base);
247
}
248
O << ')';
249
}
250
251
void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
252
raw_ostream &O) {
253
printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
254
MI->getOperand(OpNum + 2).getReg(), O);
255
}
256
257
void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
258
raw_ostream &O) {
259
static const char *const CondNames[] = {
260
"o", "h", "nle", "l", "nhe", "lh", "ne",
261
"e", "nlh", "he", "nl", "le", "nh", "no"
262
};
263
uint64_t Imm = MI->getOperand(OpNum).getImm();
264
assert(Imm > 0 && Imm < 15 && "Invalid condition");
265
O << CondNames[Imm - 1];
266
}
267
268