LLVM 24.0.0git
SystemZInstPrinterCommon.cpp
Go to the documentation of this file.
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
11#include "llvm/MC/MCExpr.h"
12#include "llvm/MC/MCInst.h"
13#include "llvm/MC/MCRegister.h"
14#include "llvm/MC/MCSymbol.h"
19#include <cassert>
20#include <cstdint>
21
22using namespace llvm;
23
24#define DEBUG_TYPE "asm-printer"
25
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)
39 else
40 O << '0';
41 O << ')';
42 }
43}
44
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())
55 else if (MO.isExpr())
56 MAI->printExpr(O, *MO.getExpr());
57 else
58 llvm_unreachable("Invalid operand");
59}
60
64
65template <unsigned N>
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");
76}
77
78template <unsigned N>
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");
89}
90
92 raw_ostream &O) {
93 printUImmOperand<1>(MI, OpNum, O);
94}
95
97 raw_ostream &O) {
98 printUImmOperand<2>(MI, OpNum, O);
99}
100
102 raw_ostream &O) {
103 printUImmOperand<3>(MI, OpNum, O);
104}
105
107 raw_ostream &O) {
108 printUImmOperand<4>(MI, OpNum, O);
109}
110
112 raw_ostream &O) {
113 printSImmOperand<8>(MI, OpNum, O);
114}
115
117 raw_ostream &O) {
118 printUImmOperand<8>(MI, OpNum, O);
119}
120
122 raw_ostream &O) {
123 int64_t Value = MI->getOperand(OpNum).getImm();
124 if (Value >= 0)
125 printUImmOperand<8>(MI, OpNum, O);
126 else
127 printSImmOperand<8>(MI, OpNum, O);
128}
129
131 raw_ostream &O) {
132 printUImmOperand<12>(MI, OpNum, O);
133}
134
136 raw_ostream &O) {
137 printSImmOperand<16>(MI, OpNum, O);
138}
139
141 raw_ostream &O) {
142 printUImmOperand<16>(MI, OpNum, O);
143}
144
146 raw_ostream &O) {
147 int64_t Value = MI->getOperand(OpNum).getImm();
148 if (Value >= 0)
149 printUImmOperand<16>(MI, OpNum, O);
150 else
151 printSImmOperand<16>(MI, OpNum, O);
152}
153
155 raw_ostream &O) {
156 printSImmOperand<32>(MI, OpNum, O);
157}
158
160 raw_ostream &O) {
161 printUImmOperand<32>(MI, OpNum, O);
162}
163
165 raw_ostream &O) {
166 int64_t Value = MI->getOperand(OpNum).getImm();
167 if (Value >= 0)
168 printUImmOperand<32>(MI, OpNum, O);
169 else
170 printSImmOperand<32>(MI, OpNum, O);
171}
172
174 raw_ostream &O) {
175 printUImmOperand<48>(MI, OpNum, O);
176}
177
179 uint64_t Address, int OpNum,
180 raw_ostream &O) {
181 const MCOperand &MO = MI->getOperand(OpNum);
182
183 // If the label has already been resolved to an immediate offset (say, when
184 // we're running the disassembler), just print the immediate.
185 if (MO.isImm()) {
186 int64_t Offset = MO.getImm();
189 else
191 return;
192 }
193
194 // If the branch target is simply an address then print it in hex.
195 const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(MO.getExpr());
196 int64_t TargetAddress;
197 if (BranchTarget && BranchTarget->evaluateAsAbsolute(TargetAddress)) {
198 markup(O, Markup::Target) << formatHex((uint64_t)TargetAddress);
199 } else {
200 // Otherwise, just print the expression.
201 MAI.printExpr(O, *MO.getExpr());
202 }
203}
204
206 uint64_t Address, int OpNum,
207 raw_ostream &O) {
208 // Output the PC-relative operand.
209 printPCRelOperand(MI, Address, OpNum, O);
210
211 // Output the TLS marker if present.
212 if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
213 const MCOperand &MO = MI->getOperand(OpNum + 1);
214 const MCSymbolRefExpr &RefExp = cast<MCSymbolRefExpr>(*MO.getExpr());
215 switch (RefExp.getSpecifier()) {
216 case SystemZ::S_TLSGD:
217 O << ":tls_gdcall:";
218 break;
220 O << ":tls_ldcall:";
221 break;
222 default:
223 llvm_unreachable("Unexpected symbol kind");
224 }
225 O << RefExp.getSymbol().getName();
226 }
227}
228
230 raw_ostream &O) {
231 printOperand(MI->getOperand(OpNum), &MAI, O);
232}
233
235 raw_ostream &O) {
236 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
237 0, O);
238}
239
241 raw_ostream &O) {
242 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
243 MI->getOperand(OpNum + 2).getReg(), O);
244}
245
247 raw_ostream &O) {
248 MCRegister Base = MI->getOperand(OpNum).getReg();
249 const MCOperand &DispMO = MI->getOperand(OpNum + 1);
250 uint64_t Length = MI->getOperand(OpNum + 2).getImm();
251 printOperand(DispMO, &MAI, O);
252 O << '(' << Length;
253 if (Base) {
254 O << ",";
255 printRegName(O, Base);
256 }
257 O << ')';
258}
259
261 raw_ostream &O) {
262 MCRegister Base = MI->getOperand(OpNum).getReg();
263 const MCOperand &DispMO = MI->getOperand(OpNum + 1);
264 MCRegister Length = MI->getOperand(OpNum + 2).getReg();
265 printOperand(DispMO, &MAI, O);
266 O << "(";
268 if (Base) {
269 O << ",";
270 printRegName(O, Base);
271 }
272 O << ')';
273}
274
276 raw_ostream &O) {
277 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
278 MI->getOperand(OpNum + 2).getReg(), O);
279}
280
282 raw_ostream &O) {
283 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
284 MI->getOperand(OpNum + 2).getReg(), O);
285}
286
288 raw_ostream &O) {
289 static const char *const CondNames[] = {"o", "h", "nle", "l", "nhe",
290 "lh", "ne", "e", "nlh", "he",
291 "nl", "le", "nh", "no"};
292 uint64_t Imm = MI->getOperand(OpNum).getImm();
293 assert(Imm > 0 && Imm < 15 && "Invalid condition");
294 O << CondNames[Imm - 1];
295}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
IRTranslator LLVM IR MI
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:67
WithMarkup markup(raw_ostream &OS, Markup M)
format_object< int64_t > formatHex(int64_t Value) const
const MCAsmInfo & MAI
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
bool PrintBranchImmAsAddress
If true, a branch immediate (e.g.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
int64_t getImm() const
Definition MCInst.h:84
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
const MCSymbol & getSymbol() const
Definition MCExpr.h:226
uint16_t getSpecifier() const
Definition MCExpr.h:232
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printU2ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printU3ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printBDXAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printBDVAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printU4ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printPCRelOperand(const MCInst *MI, uint64_t Address, int OpNum, raw_ostream &O)
void printS8ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printBDLAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printOperand(const MCOperand &MO, const MCAsmInfo *MAI, raw_ostream &O)
void printPCRelTLSOperand(const MCInst *MI, uint64_t Address, int OpNum, raw_ostream &O)
void printRegName(raw_ostream &O, MCRegister Reg) override
Print the assembler register name.
virtual void printFormattedRegName(const MCAsmInfo *MAI, MCRegister Reg, raw_ostream &O)
void printLXAAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printU12ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printU32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printBDAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printU1ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printX32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printU48ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printU8ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printAddress(const MCAsmInfo *MAI, MCRegister Base, const MCOperand &DispMO, MCRegister Index, raw_ostream &O)
void printCond4Operand(const MCInst *MI, int OpNum, raw_ostream &O)
void printBDRAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printS32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printX16ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printS16ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printU16ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
void printX8ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O)
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.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559