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