LLVM 18.0.0git
SystemZInstPrinter.cpp
Go to the documentation of this file.
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
10#include "llvm/MC/MCExpr.h"
11#include "llvm/MC/MCInst.h"
12#include "llvm/MC/MCRegister.h"
13#include "llvm/MC/MCSymbol.h"
18#include <cassert>
19#include <cstdint>
20
21using namespace llvm;
22
23#define DEBUG_TYPE "asm-printer"
24
25#include "SystemZGenAsmWriter.inc"
26
28 const MCOperand &DispMO, MCRegister Index,
29 raw_ostream &O) {
30 printOperand(DispMO, MAI, O);
31 if (Base || Index) {
32 O << '(';
33 if (Index) {
35 if (Base)
36 O << ',';
37 }
38 if (Base)
40 O << ')';
41 }
42}
43
45 raw_ostream &O) {
46 if (MO.isReg()) {
47 if (!MO.getReg())
48 O << '0';
49 else
51 }
52 else if (MO.isImm())
54 else if (MO.isExpr())
55 MO.getExpr()->print(O, MAI);
56 else
57 llvm_unreachable("Invalid operand");
58}
59
61 MCRegister Reg,
62 raw_ostream &O) const {
63 const char *RegName = getRegisterName(Reg);
65 // Skip register prefix so that only register number is left
66 assert(isalpha(RegName[0]) && isdigit(RegName[1]));
67 markup(O, Markup::Register) << (RegName + 1);
68 } else
69 markup(O, Markup::Register) << '%' << RegName;
70}
71
73 printFormattedRegName(&MAI, Reg, O);
74}
75
77 StringRef Annot, const MCSubtargetInfo &STI,
78 raw_ostream &O) {
80 printAnnotation(O, Annot);
81}
82
83template <unsigned N>
84void SystemZInstPrinter::printUImmOperand(const MCInst *MI, int OpNum,
85 raw_ostream &O) {
86 const MCOperand &MO = MI->getOperand(OpNum);
87 if (MO.isExpr()) {
88 O << *MO.getExpr();
89 return;
90 }
91 uint64_t Value = static_cast<uint64_t>(MO.getImm());
92 assert(isUInt<N>(Value) && "Invalid uimm argument");
94}
95
96template <unsigned N>
97void SystemZInstPrinter::printSImmOperand(const MCInst *MI, int OpNum,
98 raw_ostream &O) {
99 const MCOperand &MO = MI->getOperand(OpNum);
100 if (MO.isExpr()) {
101 O << *MO.getExpr();
102 return;
103 }
104 int64_t Value = MI->getOperand(OpNum).getImm();
105 assert(isInt<N>(Value) && "Invalid simm argument");
107}
108
109void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
110 raw_ostream &O) {
111 printUImmOperand<1>(MI, OpNum, O);
112}
113
114void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
115 raw_ostream &O) {
116 printUImmOperand<2>(MI, OpNum, O);
117}
118
119void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
120 raw_ostream &O) {
121 printUImmOperand<3>(MI, OpNum, O);
122}
123
124void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
125 raw_ostream &O) {
126 printUImmOperand<4>(MI, OpNum, O);
127}
128
129void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
130 raw_ostream &O) {
131 printSImmOperand<8>(MI, OpNum, O);
132}
133
134void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
135 raw_ostream &O) {
136 printUImmOperand<8>(MI, OpNum, O);
137}
138
139void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
140 raw_ostream &O) {
141 printUImmOperand<12>(MI, OpNum, O);
142}
143
144void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
145 raw_ostream &O) {
146 printSImmOperand<16>(MI, OpNum, O);
147}
148
149void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
150 raw_ostream &O) {
151 printUImmOperand<16>(MI, OpNum, O);
152}
153
154void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
155 raw_ostream &O) {
156 printSImmOperand<32>(MI, OpNum, O);
157}
158
159void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
160 raw_ostream &O) {
161 printUImmOperand<32>(MI, OpNum, O);
162}
163
164void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,
165 raw_ostream &O) {
166 printUImmOperand<48>(MI, OpNum, O);
167}
168
169void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
170 raw_ostream &O) {
171 const MCOperand &MO = MI->getOperand(OpNum);
172 if (MO.isImm()) {
173 WithMarkup M = markup(O, Markup::Immediate);
174 O << "0x";
175 O.write_hex(MO.getImm());
176 } else
177 MO.getExpr()->print(O, &MAI);
178}
179
180void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI,
181 uint64_t Address, int OpNum,
182 raw_ostream &O) {
183 // Output the PC-relative operand.
184 printPCRelOperand(MI, OpNum, O);
185
186 // Output the TLS marker if present.
187 if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
188 const MCOperand &MO = MI->getOperand(OpNum + 1);
189 const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
190 switch (refExp.getKind()) {
192 O << ":tls_gdcall:";
193 break;
195 O << ":tls_ldcall:";
196 break;
197 default:
198 llvm_unreachable("Unexpected symbol kind");
199 }
200 O << refExp.getSymbol().getName();
201 }
202}
203
204void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
205 raw_ostream &O) {
206 printOperand(MI->getOperand(OpNum), &MAI, O);
207}
208
209void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
210 raw_ostream &O) {
211 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
212 0, O);
213}
214
215void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
216 raw_ostream &O) {
217 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
218 MI->getOperand(OpNum + 2).getReg(), O);
219}
220
221void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
222 raw_ostream &O) {
223 unsigned Base = MI->getOperand(OpNum).getReg();
224 const MCOperand &DispMO = MI->getOperand(OpNum + 1);
225 uint64_t Length = MI->getOperand(OpNum + 2).getImm();
226 printOperand(DispMO, &MAI, O);
227 O << '(' << Length;
228 if (Base) {
229 O << ",";
230 printRegName(O, Base);
231 }
232 O << ')';
233}
234
235void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
236 raw_ostream &O) {
237 unsigned Base = MI->getOperand(OpNum).getReg();
238 const MCOperand &DispMO = MI->getOperand(OpNum + 1);
239 unsigned Length = MI->getOperand(OpNum + 2).getReg();
240 printOperand(DispMO, &MAI, O);
241 O << "(";
243 if (Base) {
244 O << ",";
245 printRegName(O, Base);
246 }
247 O << ')';
248}
249
250void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
251 raw_ostream &O) {
252 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
253 MI->getOperand(OpNum + 2).getReg(), O);
254}
255
256void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
257 raw_ostream &O) {
258 static const char *const CondNames[] = {
259 "o", "h", "nle", "l", "nhe", "lh", "ne",
260 "e", "nlh", "he", "nl", "le", "nh", "no"
261 };
262 uint64_t Imm = MI->getOperand(OpNum).getImm();
263 assert(Imm > 0 && Imm < 15 && "Invalid condition");
264 O << CondNames[Imm - 1];
265}
IRTranslator LLVM IR MI
#define RegName(no)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
unsigned getAssemblerDialect() const
Definition: MCAsmInfo.h:686
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
WithMarkup markup(raw_ostream &OS, Markup M) const
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:51
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
int64_t getImm() const
Definition: MCInst.h:80
bool isImm() const
Definition: MCInst.h:62
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69
bool isReg() const
Definition: MCInst.h:61
const MCExpr * getExpr() const
Definition: MCInst.h:114
bool isExpr() const
Definition: MCInst.h:65
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:402
VariantKind getKind() const
Definition: MCExpr.h:404
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:206
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
void printRegName(raw_ostream &O, MCRegister Reg) const override
Print the assembler register name.
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
void printOperand(const MCOperand &MO, const MCAsmInfo *MAI, raw_ostream &O)
void printAddress(const MCAsmInfo *MAI, MCRegister Base, const MCOperand &DispMO, MCRegister Index, raw_ostream &O)
void printFormattedRegName(const MCAsmInfo *MAI, MCRegister Reg, raw_ostream &O) const
static const char * getRegisterName(MCRegister Reg)
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O)
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#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.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:440