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(const MCAsmInfo
*MAI
, unsigned Base
,
27 int64_t Disp
, unsigned Index
,
33 printFormattedRegName(MAI
, Index
, O
);
38 printFormattedRegName(MAI
, Base
, O
);
43 void SystemZInstPrinter::printOperand(const MCOperand
&MO
, const MCAsmInfo
*MAI
,
49 printFormattedRegName(MAI
, MO
.getReg(), O
);
54 MO
.getExpr()->print(O
, MAI
);
56 llvm_unreachable("Invalid operand");
59 void SystemZInstPrinter::printFormattedRegName(const MCAsmInfo
*MAI
,
60 unsigned RegNo
, raw_ostream
&O
) {
61 const char *RegName
= getRegisterName(RegNo
);
62 if (MAI
->getAssemblerDialect() == AD_HLASM
) {
63 // Skip register prefix so that only register number is left
64 assert(isalpha(RegName
[0]) && isdigit(RegName
[1]));
70 void SystemZInstPrinter::printInst(const MCInst
*MI
, uint64_t Address
,
71 StringRef Annot
, const MCSubtargetInfo
&STI
,
73 printInstruction(MI
, Address
, O
);
74 printAnnotation(O
, Annot
);
78 static void printUImmOperand(const MCInst
*MI
, int OpNum
, raw_ostream
&O
) {
79 int64_t Value
= MI
->getOperand(OpNum
).getImm();
80 assert(isUInt
<N
>(Value
) && "Invalid uimm argument");
85 static void printSImmOperand(const MCInst
*MI
, int OpNum
, raw_ostream
&O
) {
86 int64_t Value
= MI
->getOperand(OpNum
).getImm();
87 assert(isInt
<N
>(Value
) && "Invalid simm argument");
91 void SystemZInstPrinter::printU1ImmOperand(const MCInst
*MI
, int OpNum
,
93 printUImmOperand
<1>(MI
, OpNum
, O
);
96 void SystemZInstPrinter::printU2ImmOperand(const MCInst
*MI
, int OpNum
,
98 printUImmOperand
<2>(MI
, OpNum
, O
);
101 void SystemZInstPrinter::printU3ImmOperand(const MCInst
*MI
, int OpNum
,
103 printUImmOperand
<3>(MI
, OpNum
, O
);
106 void SystemZInstPrinter::printU4ImmOperand(const MCInst
*MI
, int OpNum
,
108 printUImmOperand
<4>(MI
, OpNum
, O
);
111 void SystemZInstPrinter::printU6ImmOperand(const MCInst
*MI
, int OpNum
,
113 printUImmOperand
<6>(MI
, OpNum
, O
);
116 void SystemZInstPrinter::printS8ImmOperand(const MCInst
*MI
, int OpNum
,
118 printSImmOperand
<8>(MI
, OpNum
, O
);
121 void SystemZInstPrinter::printU8ImmOperand(const MCInst
*MI
, int OpNum
,
123 printUImmOperand
<8>(MI
, OpNum
, O
);
126 void SystemZInstPrinter::printU12ImmOperand(const MCInst
*MI
, int OpNum
,
128 printUImmOperand
<12>(MI
, OpNum
, O
);
131 void SystemZInstPrinter::printS16ImmOperand(const MCInst
*MI
, int OpNum
,
133 printSImmOperand
<16>(MI
, OpNum
, O
);
136 void SystemZInstPrinter::printU16ImmOperand(const MCInst
*MI
, int OpNum
,
138 printUImmOperand
<16>(MI
, OpNum
, O
);
141 void SystemZInstPrinter::printS32ImmOperand(const MCInst
*MI
, int OpNum
,
143 printSImmOperand
<32>(MI
, OpNum
, O
);
146 void SystemZInstPrinter::printU32ImmOperand(const MCInst
*MI
, int OpNum
,
148 printUImmOperand
<32>(MI
, OpNum
, O
);
151 void SystemZInstPrinter::printU48ImmOperand(const MCInst
*MI
, int OpNum
,
153 printUImmOperand
<48>(MI
, OpNum
, O
);
156 void SystemZInstPrinter::printPCRelOperand(const MCInst
*MI
, int OpNum
,
158 const MCOperand
&MO
= MI
->getOperand(OpNum
);
161 O
.write_hex(MO
.getImm());
163 MO
.getExpr()->print(O
, &MAI
);
166 void SystemZInstPrinter::printPCRelTLSOperand(const MCInst
*MI
,
167 uint64_t Address
, int OpNum
,
169 // Output the PC-relative operand.
170 printPCRelOperand(MI
, OpNum
, O
);
172 // Output the TLS marker if present.
173 if ((unsigned)OpNum
+ 1 < MI
->getNumOperands()) {
174 const MCOperand
&MO
= MI
->getOperand(OpNum
+ 1);
175 const MCSymbolRefExpr
&refExp
= cast
<MCSymbolRefExpr
>(*MO
.getExpr());
176 switch (refExp
.getKind()) {
177 case MCSymbolRefExpr::VK_TLSGD
:
180 case MCSymbolRefExpr::VK_TLSLDM
:
184 llvm_unreachable("Unexpected symbol kind");
186 O
<< refExp
.getSymbol().getName();
190 void SystemZInstPrinter::printOperand(const MCInst
*MI
, int OpNum
,
192 printOperand(MI
->getOperand(OpNum
), &MAI
, O
);
195 void SystemZInstPrinter::printBDAddrOperand(const MCInst
*MI
, int OpNum
,
197 printAddress(&MAI
, MI
->getOperand(OpNum
).getReg(),
198 MI
->getOperand(OpNum
+ 1).getImm(), 0, O
);
201 void SystemZInstPrinter::printBDXAddrOperand(const MCInst
*MI
, int OpNum
,
203 printAddress(&MAI
, MI
->getOperand(OpNum
).getReg(),
204 MI
->getOperand(OpNum
+ 1).getImm(),
205 MI
->getOperand(OpNum
+ 2).getReg(), O
);
208 void SystemZInstPrinter::printBDLAddrOperand(const MCInst
*MI
, int OpNum
,
210 unsigned Base
= MI
->getOperand(OpNum
).getReg();
211 uint64_t Disp
= MI
->getOperand(OpNum
+ 1).getImm();
212 uint64_t Length
= MI
->getOperand(OpNum
+ 2).getImm();
213 O
<< Disp
<< '(' << Length
;
216 printRegName(O
, Base
);
221 void SystemZInstPrinter::printBDRAddrOperand(const MCInst
*MI
, int OpNum
,
223 unsigned Base
= MI
->getOperand(OpNum
).getReg();
224 uint64_t Disp
= MI
->getOperand(OpNum
+ 1).getImm();
225 unsigned Length
= MI
->getOperand(OpNum
+ 2).getReg();
227 printRegName(O
, Length
);
230 printRegName(O
, Base
);
235 void SystemZInstPrinter::printBDVAddrOperand(const MCInst
*MI
, int OpNum
,
237 printAddress(&MAI
, MI
->getOperand(OpNum
).getReg(),
238 MI
->getOperand(OpNum
+ 1).getImm(),
239 MI
->getOperand(OpNum
+ 2).getReg(), O
);
242 void SystemZInstPrinter::printCond4Operand(const MCInst
*MI
, int OpNum
,
244 static const char *const CondNames
[] = {
245 "o", "h", "nle", "l", "nhe", "lh", "ne",
246 "e", "nlh", "he", "nl", "le", "nh", "no"
248 uint64_t Imm
= MI
->getOperand(OpNum
).getImm();
249 assert(Imm
> 0 && Imm
< 15 && "Invalid condition");
250 O
<< CondNames
[Imm
- 1];