1 //===- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax -===//
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
7 //===----------------------------------------------------------------------===//
9 #include "SystemZInstPrinter.h"
10 #include "llvm/MC/MCExpr.h"
11 #include "llvm/MC/MCInst.h"
12 #include "llvm/MC/MCSymbol.h"
13 #include "llvm/Support/Casting.h"
14 #include "llvm/Support/ErrorHandling.h"
15 #include "llvm/Support/MathExtras.h"
16 #include "llvm/Support/raw_ostream.h"
22 #define DEBUG_TYPE "asm-printer"
24 #include "SystemZGenAsmWriter.inc"
26 void SystemZInstPrinter::printAddress(unsigned Base
, int64_t Disp
,
27 unsigned Index
, raw_ostream
&O
) {
32 O
<< '%' << getRegisterName(Index
);
37 O
<< '%' << getRegisterName(Base
);
42 void SystemZInstPrinter::printOperand(const MCOperand
&MO
, const MCAsmInfo
*MAI
,
48 O
<< '%' << getRegisterName(MO
.getReg());
53 MO
.getExpr()->print(O
, MAI
);
55 llvm_unreachable("Invalid operand");
58 void SystemZInstPrinter::printInst(const MCInst
*MI
, uint64_t Address
,
59 StringRef Annot
, const MCSubtargetInfo
&STI
,
61 printInstruction(MI
, Address
, O
);
62 printAnnotation(O
, Annot
);
65 void SystemZInstPrinter::printRegName(raw_ostream
&O
, unsigned RegNo
) const {
66 O
<< '%' << getRegisterName(RegNo
);
70 static void printUImmOperand(const MCInst
*MI
, int OpNum
, raw_ostream
&O
) {
71 int64_t Value
= MI
->getOperand(OpNum
).getImm();
72 assert(isUInt
<N
>(Value
) && "Invalid uimm argument");
77 static void printSImmOperand(const MCInst
*MI
, int OpNum
, raw_ostream
&O
) {
78 int64_t Value
= MI
->getOperand(OpNum
).getImm();
79 assert(isInt
<N
>(Value
) && "Invalid simm argument");
83 void SystemZInstPrinter::printU1ImmOperand(const MCInst
*MI
, int OpNum
,
85 printUImmOperand
<1>(MI
, OpNum
, O
);
88 void SystemZInstPrinter::printU2ImmOperand(const MCInst
*MI
, int OpNum
,
90 printUImmOperand
<2>(MI
, OpNum
, O
);
93 void SystemZInstPrinter::printU3ImmOperand(const MCInst
*MI
, int OpNum
,
95 printUImmOperand
<3>(MI
, OpNum
, O
);
98 void SystemZInstPrinter::printU4ImmOperand(const MCInst
*MI
, int OpNum
,
100 printUImmOperand
<4>(MI
, OpNum
, O
);
103 void SystemZInstPrinter::printU6ImmOperand(const MCInst
*MI
, int OpNum
,
105 printUImmOperand
<6>(MI
, OpNum
, O
);
108 void SystemZInstPrinter::printS8ImmOperand(const MCInst
*MI
, int OpNum
,
110 printSImmOperand
<8>(MI
, OpNum
, O
);
113 void SystemZInstPrinter::printU8ImmOperand(const MCInst
*MI
, int OpNum
,
115 printUImmOperand
<8>(MI
, OpNum
, O
);
118 void SystemZInstPrinter::printU12ImmOperand(const MCInst
*MI
, int OpNum
,
120 printUImmOperand
<12>(MI
, OpNum
, O
);
123 void SystemZInstPrinter::printS16ImmOperand(const MCInst
*MI
, int OpNum
,
125 printSImmOperand
<16>(MI
, OpNum
, O
);
128 void SystemZInstPrinter::printU16ImmOperand(const MCInst
*MI
, int OpNum
,
130 printUImmOperand
<16>(MI
, OpNum
, O
);
133 void SystemZInstPrinter::printS32ImmOperand(const MCInst
*MI
, int OpNum
,
135 printSImmOperand
<32>(MI
, OpNum
, O
);
138 void SystemZInstPrinter::printU32ImmOperand(const MCInst
*MI
, int OpNum
,
140 printUImmOperand
<32>(MI
, OpNum
, O
);
143 void SystemZInstPrinter::printU48ImmOperand(const MCInst
*MI
, int OpNum
,
145 printUImmOperand
<48>(MI
, OpNum
, O
);
148 void SystemZInstPrinter::printPCRelOperand(const MCInst
*MI
, int OpNum
,
150 const MCOperand
&MO
= MI
->getOperand(OpNum
);
153 O
.write_hex(MO
.getImm());
155 MO
.getExpr()->print(O
, &MAI
);
158 void SystemZInstPrinter::printPCRelTLSOperand(const MCInst
*MI
, int OpNum
,
160 // Output the PC-relative operand.
161 printPCRelOperand(MI
, OpNum
, O
);
163 // Output the TLS marker if present.
164 if ((unsigned)OpNum
+ 1 < MI
->getNumOperands()) {
165 const MCOperand
&MO
= MI
->getOperand(OpNum
+ 1);
166 const MCSymbolRefExpr
&refExp
= cast
<MCSymbolRefExpr
>(*MO
.getExpr());
167 switch (refExp
.getKind()) {
168 case MCSymbolRefExpr::VK_TLSGD
:
171 case MCSymbolRefExpr::VK_TLSLDM
:
175 llvm_unreachable("Unexpected symbol kind");
177 O
<< refExp
.getSymbol().getName();
181 void SystemZInstPrinter::printOperand(const MCInst
*MI
, int OpNum
,
183 printOperand(MI
->getOperand(OpNum
), &MAI
, O
);
186 void SystemZInstPrinter::printBDAddrOperand(const MCInst
*MI
, int OpNum
,
188 printAddress(MI
->getOperand(OpNum
).getReg(),
189 MI
->getOperand(OpNum
+ 1).getImm(), 0, O
);
192 void SystemZInstPrinter::printBDXAddrOperand(const MCInst
*MI
, int OpNum
,
194 printAddress(MI
->getOperand(OpNum
).getReg(),
195 MI
->getOperand(OpNum
+ 1).getImm(),
196 MI
->getOperand(OpNum
+ 2).getReg(), O
);
199 void SystemZInstPrinter::printBDLAddrOperand(const MCInst
*MI
, int OpNum
,
201 unsigned Base
= MI
->getOperand(OpNum
).getReg();
202 uint64_t Disp
= MI
->getOperand(OpNum
+ 1).getImm();
203 uint64_t Length
= MI
->getOperand(OpNum
+ 2).getImm();
204 O
<< Disp
<< '(' << Length
;
206 O
<< ",%" << getRegisterName(Base
);
210 void SystemZInstPrinter::printBDRAddrOperand(const MCInst
*MI
, int OpNum
,
212 unsigned Base
= MI
->getOperand(OpNum
).getReg();
213 uint64_t Disp
= MI
->getOperand(OpNum
+ 1).getImm();
214 unsigned Length
= MI
->getOperand(OpNum
+ 2).getReg();
215 O
<< Disp
<< "(%" << getRegisterName(Length
);
217 O
<< ",%" << getRegisterName(Base
);
221 void SystemZInstPrinter::printBDVAddrOperand(const MCInst
*MI
, int OpNum
,
223 printAddress(MI
->getOperand(OpNum
).getReg(),
224 MI
->getOperand(OpNum
+ 1).getImm(),
225 MI
->getOperand(OpNum
+ 2).getReg(), O
);
228 void SystemZInstPrinter::printCond4Operand(const MCInst
*MI
, int OpNum
,
230 static const char *const CondNames
[] = {
231 "o", "h", "nle", "l", "nhe", "lh", "ne",
232 "e", "nlh", "he", "nl", "le", "nh", "no"
234 uint64_t Imm
= MI
->getOperand(OpNum
).getImm();
235 assert(Imm
> 0 && Imm
< 15 && "Invalid condition");
236 O
<< CondNames
[Imm
- 1];