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
,
45 O
<< '%' << getRegisterName(MO
.getReg());
49 MO
.getExpr()->print(O
, MAI
);
51 llvm_unreachable("Invalid operand");
54 void SystemZInstPrinter::printInst(const MCInst
*MI
, raw_ostream
&O
,
56 const MCSubtargetInfo
&STI
) {
57 printInstruction(MI
, O
);
58 printAnnotation(O
, Annot
);
61 void SystemZInstPrinter::printRegName(raw_ostream
&O
, unsigned RegNo
) const {
62 O
<< '%' << getRegisterName(RegNo
);
66 static void printUImmOperand(const MCInst
*MI
, int OpNum
, raw_ostream
&O
) {
67 int64_t Value
= MI
->getOperand(OpNum
).getImm();
68 assert(isUInt
<N
>(Value
) && "Invalid uimm argument");
73 static void printSImmOperand(const MCInst
*MI
, int OpNum
, raw_ostream
&O
) {
74 int64_t Value
= MI
->getOperand(OpNum
).getImm();
75 assert(isInt
<N
>(Value
) && "Invalid simm argument");
79 void SystemZInstPrinter::printU1ImmOperand(const MCInst
*MI
, int OpNum
,
81 printUImmOperand
<1>(MI
, OpNum
, O
);
84 void SystemZInstPrinter::printU2ImmOperand(const MCInst
*MI
, int OpNum
,
86 printUImmOperand
<2>(MI
, OpNum
, O
);
89 void SystemZInstPrinter::printU3ImmOperand(const MCInst
*MI
, int OpNum
,
91 printUImmOperand
<3>(MI
, OpNum
, O
);
94 void SystemZInstPrinter::printU4ImmOperand(const MCInst
*MI
, int OpNum
,
96 printUImmOperand
<4>(MI
, OpNum
, O
);
99 void SystemZInstPrinter::printU6ImmOperand(const MCInst
*MI
, int OpNum
,
101 printUImmOperand
<6>(MI
, OpNum
, O
);
104 void SystemZInstPrinter::printS8ImmOperand(const MCInst
*MI
, int OpNum
,
106 printSImmOperand
<8>(MI
, OpNum
, O
);
109 void SystemZInstPrinter::printU8ImmOperand(const MCInst
*MI
, int OpNum
,
111 printUImmOperand
<8>(MI
, OpNum
, O
);
114 void SystemZInstPrinter::printU12ImmOperand(const MCInst
*MI
, int OpNum
,
116 printUImmOperand
<12>(MI
, OpNum
, O
);
119 void SystemZInstPrinter::printS16ImmOperand(const MCInst
*MI
, int OpNum
,
121 printSImmOperand
<16>(MI
, OpNum
, O
);
124 void SystemZInstPrinter::printU16ImmOperand(const MCInst
*MI
, int OpNum
,
126 printUImmOperand
<16>(MI
, OpNum
, O
);
129 void SystemZInstPrinter::printS32ImmOperand(const MCInst
*MI
, int OpNum
,
131 printSImmOperand
<32>(MI
, OpNum
, O
);
134 void SystemZInstPrinter::printU32ImmOperand(const MCInst
*MI
, int OpNum
,
136 printUImmOperand
<32>(MI
, OpNum
, O
);
139 void SystemZInstPrinter::printU48ImmOperand(const MCInst
*MI
, int OpNum
,
141 printUImmOperand
<48>(MI
, OpNum
, O
);
144 void SystemZInstPrinter::printPCRelOperand(const MCInst
*MI
, int OpNum
,
146 const MCOperand
&MO
= MI
->getOperand(OpNum
);
149 O
.write_hex(MO
.getImm());
151 MO
.getExpr()->print(O
, &MAI
);
154 void SystemZInstPrinter::printPCRelTLSOperand(const MCInst
*MI
, int OpNum
,
156 // Output the PC-relative operand.
157 printPCRelOperand(MI
, OpNum
, O
);
159 // Output the TLS marker if present.
160 if ((unsigned)OpNum
+ 1 < MI
->getNumOperands()) {
161 const MCOperand
&MO
= MI
->getOperand(OpNum
+ 1);
162 const MCSymbolRefExpr
&refExp
= cast
<MCSymbolRefExpr
>(*MO
.getExpr());
163 switch (refExp
.getKind()) {
164 case MCSymbolRefExpr::VK_TLSGD
:
167 case MCSymbolRefExpr::VK_TLSLDM
:
171 llvm_unreachable("Unexpected symbol kind");
173 O
<< refExp
.getSymbol().getName();
177 void SystemZInstPrinter::printOperand(const MCInst
*MI
, int OpNum
,
179 printOperand(MI
->getOperand(OpNum
), &MAI
, O
);
182 void SystemZInstPrinter::printBDAddrOperand(const MCInst
*MI
, int OpNum
,
184 printAddress(MI
->getOperand(OpNum
).getReg(),
185 MI
->getOperand(OpNum
+ 1).getImm(), 0, O
);
188 void SystemZInstPrinter::printBDXAddrOperand(const MCInst
*MI
, int OpNum
,
190 printAddress(MI
->getOperand(OpNum
).getReg(),
191 MI
->getOperand(OpNum
+ 1).getImm(),
192 MI
->getOperand(OpNum
+ 2).getReg(), O
);
195 void SystemZInstPrinter::printBDLAddrOperand(const MCInst
*MI
, int OpNum
,
197 unsigned Base
= MI
->getOperand(OpNum
).getReg();
198 uint64_t Disp
= MI
->getOperand(OpNum
+ 1).getImm();
199 uint64_t Length
= MI
->getOperand(OpNum
+ 2).getImm();
200 O
<< Disp
<< '(' << Length
;
202 O
<< ",%" << getRegisterName(Base
);
206 void SystemZInstPrinter::printBDRAddrOperand(const MCInst
*MI
, int OpNum
,
208 unsigned Base
= MI
->getOperand(OpNum
).getReg();
209 uint64_t Disp
= MI
->getOperand(OpNum
+ 1).getImm();
210 unsigned Length
= MI
->getOperand(OpNum
+ 2).getReg();
211 O
<< Disp
<< "(%" << getRegisterName(Length
);
213 O
<< ",%" << getRegisterName(Base
);
217 void SystemZInstPrinter::printBDVAddrOperand(const MCInst
*MI
, int OpNum
,
219 printAddress(MI
->getOperand(OpNum
).getReg(),
220 MI
->getOperand(OpNum
+ 1).getImm(),
221 MI
->getOperand(OpNum
+ 2).getReg(), O
);
224 void SystemZInstPrinter::printCond4Operand(const MCInst
*MI
, int OpNum
,
226 static const char *const CondNames
[] = {
227 "o", "h", "nle", "l", "nhe", "lh", "ne",
228 "e", "nlh", "he", "nl", "le", "nh", "no"
230 uint64_t Imm
= MI
->getOperand(OpNum
).getImm();
231 assert(Imm
> 0 && Imm
< 15 && "Invalid condition");
232 O
<< CondNames
[Imm
- 1];