[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / SystemZ / MCTargetDesc / SystemZInstPrinter.cpp
blobf3f3f096da33945eb8c5f4c3fc03207681e15f67
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 //===----------------------------------------------------------------------===//
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"
17 #include <cassert>
18 #include <cstdint>
20 using namespace llvm;
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,
28 raw_ostream &O) {
29 O << Disp;
30 if (Base || Index) {
31 O << '(';
32 if (Index) {
33 printFormattedRegName(MAI, Index, O);
34 if (Base)
35 O << ',';
37 if (Base)
38 printFormattedRegName(MAI, Base, O);
39 O << ')';
43 void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI,
44 raw_ostream &O) {
45 if (MO.isReg()) {
46 if (!MO.getReg())
47 O << '0';
48 else
49 printFormattedRegName(MAI, MO.getReg(), O);
51 else if (MO.isImm())
52 O << MO.getImm();
53 else if (MO.isExpr())
54 MO.getExpr()->print(O, MAI);
55 else
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]));
65 O << (RegName + 1);
66 } else
67 O << '%' << RegName;
70 void SystemZInstPrinter::printInst(const MCInst *MI, uint64_t Address,
71 StringRef Annot, const MCSubtargetInfo &STI,
72 raw_ostream &O) {
73 printInstruction(MI, Address, O);
74 printAnnotation(O, Annot);
77 template <unsigned N>
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");
81 O << Value;
84 template <unsigned N>
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");
88 O << Value;
91 void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
92 raw_ostream &O) {
93 printUImmOperand<1>(MI, OpNum, O);
96 void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
97 raw_ostream &O) {
98 printUImmOperand<2>(MI, OpNum, O);
101 void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
102 raw_ostream &O) {
103 printUImmOperand<3>(MI, OpNum, O);
106 void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
107 raw_ostream &O) {
108 printUImmOperand<4>(MI, OpNum, O);
111 void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
112 raw_ostream &O) {
113 printUImmOperand<6>(MI, OpNum, O);
116 void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
117 raw_ostream &O) {
118 printSImmOperand<8>(MI, OpNum, O);
121 void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
122 raw_ostream &O) {
123 printUImmOperand<8>(MI, OpNum, O);
126 void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
127 raw_ostream &O) {
128 printUImmOperand<12>(MI, OpNum, O);
131 void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
132 raw_ostream &O) {
133 printSImmOperand<16>(MI, OpNum, O);
136 void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
137 raw_ostream &O) {
138 printUImmOperand<16>(MI, OpNum, O);
141 void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
142 raw_ostream &O) {
143 printSImmOperand<32>(MI, OpNum, O);
146 void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
147 raw_ostream &O) {
148 printUImmOperand<32>(MI, OpNum, O);
151 void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,
152 raw_ostream &O) {
153 printUImmOperand<48>(MI, OpNum, O);
156 void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
157 raw_ostream &O) {
158 const MCOperand &MO = MI->getOperand(OpNum);
159 if (MO.isImm()) {
160 O << "0x";
161 O.write_hex(MO.getImm());
162 } else
163 MO.getExpr()->print(O, &MAI);
166 void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI,
167 uint64_t Address, int OpNum,
168 raw_ostream &O) {
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:
178 O << ":tls_gdcall:";
179 break;
180 case MCSymbolRefExpr::VK_TLSLDM:
181 O << ":tls_ldcall:";
182 break;
183 default:
184 llvm_unreachable("Unexpected symbol kind");
186 O << refExp.getSymbol().getName();
190 void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
191 raw_ostream &O) {
192 printOperand(MI->getOperand(OpNum), &MAI, O);
195 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
196 raw_ostream &O) {
197 printAddress(&MAI, MI->getOperand(OpNum).getReg(),
198 MI->getOperand(OpNum + 1).getImm(), 0, O);
201 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
202 raw_ostream &O) {
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,
209 raw_ostream &O) {
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;
214 if (Base) {
215 O << ",";
216 printRegName(O, Base);
218 O << ')';
221 void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
222 raw_ostream &O) {
223 unsigned Base = MI->getOperand(OpNum).getReg();
224 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
225 unsigned Length = MI->getOperand(OpNum + 2).getReg();
226 O << Disp << "(";
227 printRegName(O, Length);
228 if (Base) {
229 O << ",";
230 printRegName(O, Base);
232 O << ')';
235 void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
236 raw_ostream &O) {
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,
243 raw_ostream &O) {
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];