]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp
MFC r355070:
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / SystemZ / MCTargetDesc / SystemZInstPrinter.cpp
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 //===----------------------------------------------------------------------===//
8
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>
19
20 using namespace llvm;
21
22 #define DEBUG_TYPE "asm-printer"
23
24 #include "SystemZGenAsmWriter.inc"
25
26 void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp,
27                                       unsigned Index, raw_ostream &O) {
28   O << Disp;
29   if (Base || Index) {
30     O << '(';
31     if (Index) {
32       O << '%' << getRegisterName(Index);
33       if (Base)
34         O << ',';
35     }
36     if (Base)
37       O << '%' << getRegisterName(Base);
38     O << ')';
39   }
40 }
41
42 void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI,
43                                       raw_ostream &O) {
44   if (MO.isReg())
45     O << '%' << getRegisterName(MO.getReg());
46   else if (MO.isImm())
47     O << MO.getImm();
48   else if (MO.isExpr())
49     MO.getExpr()->print(O, MAI);
50   else
51     llvm_unreachable("Invalid operand");
52 }
53
54 void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
55                                    StringRef Annot,
56                                    const MCSubtargetInfo &STI) {
57   printInstruction(MI, O);
58   printAnnotation(O, Annot);
59 }
60
61 void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
62   O << '%' << getRegisterName(RegNo);
63 }
64
65 template <unsigned N>
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");
69   O << Value;
70 }
71
72 template <unsigned N>
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");
76   O << Value;
77 }
78
79 void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
80                                            raw_ostream &O) {
81   printUImmOperand<1>(MI, OpNum, O);
82 }
83
84 void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
85                                            raw_ostream &O) {
86   printUImmOperand<2>(MI, OpNum, O);
87 }
88
89 void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
90                                            raw_ostream &O) {
91   printUImmOperand<3>(MI, OpNum, O);
92 }
93
94 void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
95                                            raw_ostream &O) {
96   printUImmOperand<4>(MI, OpNum, O);
97 }
98
99 void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
100                                            raw_ostream &O) {
101   printUImmOperand<6>(MI, OpNum, O);
102 }
103
104 void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
105                                            raw_ostream &O) {
106   printSImmOperand<8>(MI, OpNum, O);
107 }
108
109 void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
110                                            raw_ostream &O) {
111   printUImmOperand<8>(MI, OpNum, O);
112 }
113
114 void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
115                                             raw_ostream &O) {
116   printUImmOperand<12>(MI, OpNum, O);
117 }
118
119 void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
120                                             raw_ostream &O) {
121   printSImmOperand<16>(MI, OpNum, O);
122 }
123
124 void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
125                                             raw_ostream &O) {
126   printUImmOperand<16>(MI, OpNum, O);
127 }
128
129 void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
130                                             raw_ostream &O) {
131   printSImmOperand<32>(MI, OpNum, O);
132 }
133
134 void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
135                                             raw_ostream &O) {
136   printUImmOperand<32>(MI, OpNum, O);
137 }
138
139 void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,
140                                             raw_ostream &O) {
141   printUImmOperand<48>(MI, OpNum, O);
142 }
143
144 void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
145                                            raw_ostream &O) {
146   const MCOperand &MO = MI->getOperand(OpNum);
147   if (MO.isImm()) {
148     O << "0x";
149     O.write_hex(MO.getImm());
150   } else
151     MO.getExpr()->print(O, &MAI);
152 }
153
154 void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum,
155                                               raw_ostream &O) {
156   // Output the PC-relative operand.
157   printPCRelOperand(MI, OpNum, O);
158
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:
165         O << ":tls_gdcall:";
166         break;
167       case MCSymbolRefExpr::VK_TLSLDM:
168         O << ":tls_ldcall:";
169         break;
170       default:
171         llvm_unreachable("Unexpected symbol kind");
172     }
173     O << refExp.getSymbol().getName();
174   }
175 }
176
177 void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
178                                       raw_ostream &O) {
179   printOperand(MI->getOperand(OpNum), &MAI, O);
180 }
181
182 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
183                                             raw_ostream &O) {
184   printAddress(MI->getOperand(OpNum).getReg(),
185                MI->getOperand(OpNum + 1).getImm(), 0, O);
186 }
187
188 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
189                                              raw_ostream &O) {
190   printAddress(MI->getOperand(OpNum).getReg(),
191                MI->getOperand(OpNum + 1).getImm(),
192                MI->getOperand(OpNum + 2).getReg(), O);
193 }
194
195 void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
196                                              raw_ostream &O) {
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;
201   if (Base)
202     O << ",%" << getRegisterName(Base);
203   O << ')';
204 }
205
206 void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
207                                              raw_ostream &O) {
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);
212   if (Base)
213     O << ",%" << getRegisterName(Base);
214   O << ')';
215 }
216
217 void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
218                                              raw_ostream &O) {
219   printAddress(MI->getOperand(OpNum).getReg(),
220                MI->getOperand(OpNum + 1).getImm(),
221                MI->getOperand(OpNum + 2).getReg(), O);
222 }
223
224 void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
225                                            raw_ostream &O) {
226   static const char *const CondNames[] = {
227     "o", "h", "nle", "l", "nhe", "lh", "ne",
228     "e", "nlh", "he", "nl", "le", "nh", "no"
229   };
230   uint64_t Imm = MI->getOperand(OpNum).getImm();
231   assert(Imm > 0 && Imm < 15 && "Invalid condition");
232   O << CondNames[Imm - 1];
233 }