1 //=- SystemZInstPrinterCommon.cpp - Common SystemZ MCInst to assembly funcs -=//
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 "SystemZInstPrinterCommon.h"
10 #include "llvm/MC/MCExpr.h"
11 #include "llvm/MC/MCInst.h"
12 #include "llvm/MC/MCRegister.h"
13 #include "llvm/MC/MCSymbol.h"
14 #include "llvm/Support/Casting.h"
15 #include "llvm/Support/ErrorHandling.h"
16 #include "llvm/Support/MathExtras.h"
17 #include "llvm/Support/raw_ostream.h"
23 #define DEBUG_TYPE "asm-printer"
25 void SystemZInstPrinterCommon::printAddress(const MCAsmInfo
*MAI
,
27 const MCOperand
&DispMO
,
28 MCRegister Index
, raw_ostream
&O
) {
29 printOperand(DispMO
, MAI
, O
);
33 printRegName(O
, Index
);
37 printRegName(O
, Base
);
44 void SystemZInstPrinterCommon::printOperand(const MCOperand
&MO
,
51 printRegName(O
, MO
.getReg());
52 } else if (MO
.isImm())
53 markup(O
, Markup::Immediate
) << MO
.getImm();
55 MO
.getExpr()->print(O
, MAI
);
57 llvm_unreachable("Invalid operand");
60 void SystemZInstPrinterCommon::printRegName(raw_ostream
&O
, MCRegister Reg
) {
61 printFormattedRegName(&MAI
, Reg
, O
);
65 void SystemZInstPrinterCommon::printUImmOperand(const MCInst
*MI
, int OpNum
,
67 const MCOperand
&MO
= MI
->getOperand(OpNum
);
72 uint64_t Value
= static_cast<uint64_t>(MO
.getImm());
73 assert(isUInt
<N
>(Value
) && "Invalid uimm argument");
74 markup(O
, Markup::Immediate
) << Value
;
78 void SystemZInstPrinterCommon::printSImmOperand(const MCInst
*MI
, int OpNum
,
80 const MCOperand
&MO
= MI
->getOperand(OpNum
);
85 int64_t Value
= MI
->getOperand(OpNum
).getImm();
86 assert(isInt
<N
>(Value
) && "Invalid simm argument");
87 markup(O
, Markup::Immediate
) << Value
;
90 void SystemZInstPrinterCommon::printU1ImmOperand(const MCInst
*MI
, int OpNum
,
92 printUImmOperand
<1>(MI
, OpNum
, O
);
95 void SystemZInstPrinterCommon::printU2ImmOperand(const MCInst
*MI
, int OpNum
,
97 printUImmOperand
<2>(MI
, OpNum
, O
);
100 void SystemZInstPrinterCommon::printU3ImmOperand(const MCInst
*MI
, int OpNum
,
102 printUImmOperand
<3>(MI
, OpNum
, O
);
105 void SystemZInstPrinterCommon::printU4ImmOperand(const MCInst
*MI
, int OpNum
,
107 printUImmOperand
<4>(MI
, OpNum
, O
);
110 void SystemZInstPrinterCommon::printS8ImmOperand(const MCInst
*MI
, int OpNum
,
112 printSImmOperand
<8>(MI
, OpNum
, O
);
115 void SystemZInstPrinterCommon::printU8ImmOperand(const MCInst
*MI
, int OpNum
,
117 printUImmOperand
<8>(MI
, OpNum
, O
);
120 void SystemZInstPrinterCommon::printU12ImmOperand(const MCInst
*MI
, int OpNum
,
122 printUImmOperand
<12>(MI
, OpNum
, O
);
125 void SystemZInstPrinterCommon::printS16ImmOperand(const MCInst
*MI
, int OpNum
,
127 printSImmOperand
<16>(MI
, OpNum
, O
);
130 void SystemZInstPrinterCommon::printU16ImmOperand(const MCInst
*MI
, int OpNum
,
132 printUImmOperand
<16>(MI
, OpNum
, O
);
135 void SystemZInstPrinterCommon::printS32ImmOperand(const MCInst
*MI
, int OpNum
,
137 printSImmOperand
<32>(MI
, OpNum
, O
);
140 void SystemZInstPrinterCommon::printU32ImmOperand(const MCInst
*MI
, int OpNum
,
142 printUImmOperand
<32>(MI
, OpNum
, O
);
145 void SystemZInstPrinterCommon::printU48ImmOperand(const MCInst
*MI
, int OpNum
,
147 printUImmOperand
<48>(MI
, OpNum
, O
);
150 void SystemZInstPrinterCommon::printPCRelOperand(const MCInst
*MI
, int OpNum
,
152 const MCOperand
&MO
= MI
->getOperand(OpNum
);
154 WithMarkup M
= markup(O
, Markup::Immediate
);
156 O
.write_hex(MO
.getImm());
158 MO
.getExpr()->print(O
, &MAI
);
161 void SystemZInstPrinterCommon::printPCRelTLSOperand(const MCInst
*MI
,
162 uint64_t Address
, int OpNum
,
164 // Output the PC-relative operand.
165 printPCRelOperand(MI
, OpNum
, O
);
167 // Output the TLS marker if present.
168 if ((unsigned)OpNum
+ 1 < MI
->getNumOperands()) {
169 const MCOperand
&MO
= MI
->getOperand(OpNum
+ 1);
170 const MCSymbolRefExpr
&refExp
= cast
<MCSymbolRefExpr
>(*MO
.getExpr());
171 switch (refExp
.getKind()) {
172 case MCSymbolRefExpr::VK_TLSGD
:
175 case MCSymbolRefExpr::VK_TLSLDM
:
179 llvm_unreachable("Unexpected symbol kind");
181 O
<< refExp
.getSymbol().getName();
185 void SystemZInstPrinterCommon::printOperand(const MCInst
*MI
, int OpNum
,
187 printOperand(MI
->getOperand(OpNum
), &MAI
, O
);
190 void SystemZInstPrinterCommon::printBDAddrOperand(const MCInst
*MI
, int OpNum
,
192 printAddress(&MAI
, MI
->getOperand(OpNum
).getReg(), MI
->getOperand(OpNum
+ 1),
196 void SystemZInstPrinterCommon::printBDXAddrOperand(const MCInst
*MI
, int OpNum
,
198 printAddress(&MAI
, MI
->getOperand(OpNum
).getReg(), MI
->getOperand(OpNum
+ 1),
199 MI
->getOperand(OpNum
+ 2).getReg(), O
);
202 void SystemZInstPrinterCommon::printBDLAddrOperand(const MCInst
*MI
, int OpNum
,
204 unsigned Base
= MI
->getOperand(OpNum
).getReg();
205 const MCOperand
&DispMO
= MI
->getOperand(OpNum
+ 1);
206 uint64_t Length
= MI
->getOperand(OpNum
+ 2).getImm();
207 printOperand(DispMO
, &MAI
, O
);
211 printRegName(O
, Base
);
216 void SystemZInstPrinterCommon::printBDRAddrOperand(const MCInst
*MI
, int OpNum
,
218 unsigned Base
= MI
->getOperand(OpNum
).getReg();
219 const MCOperand
&DispMO
= MI
->getOperand(OpNum
+ 1);
220 unsigned Length
= MI
->getOperand(OpNum
+ 2).getReg();
221 printOperand(DispMO
, &MAI
, O
);
223 printRegName(O
, Length
);
226 printRegName(O
, Base
);
231 void SystemZInstPrinterCommon::printBDVAddrOperand(const MCInst
*MI
, int OpNum
,
233 printAddress(&MAI
, MI
->getOperand(OpNum
).getReg(), MI
->getOperand(OpNum
+ 1),
234 MI
->getOperand(OpNum
+ 2).getReg(), O
);
237 void SystemZInstPrinterCommon::printCond4Operand(const MCInst
*MI
, int OpNum
,
239 static const char *const CondNames
[] = {"o", "h", "nle", "l", "nhe",
240 "lh", "ne", "e", "nlh", "he",
241 "nl", "le", "nh", "no"};
242 uint64_t Imm
= MI
->getOperand(OpNum
).getImm();
243 assert(Imm
> 0 && Imm
< 15 && "Invalid condition");
244 O
<< CondNames
[Imm
- 1];