0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 //===-- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax ===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 // The LLVM Compiler Infrastructure
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 #include "SystemZInstPrinter.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 #include "llvm/MC/MCExpr.h"
|
95
|
12 #include "llvm/MC/MCInst.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13 #include "llvm/MC/MCInstrInfo.h"
|
95
|
14 #include "llvm/MC/MCSymbol.h"
|
|
15 #include "llvm/Support/ErrorHandling.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16 #include "llvm/Support/raw_ostream.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 using namespace llvm;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19
|
77
|
20 #define DEBUG_TYPE "asm-printer"
|
|
21
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 #include "SystemZGenAsmWriter.inc"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
23
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 unsigned Index, raw_ostream &O) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26 O << Disp;
|
95
|
27 if (Base || Index) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
28 O << '(';
|
95
|
29 if (Index) {
|
|
30 O << '%' << getRegisterName(Index);
|
|
31 if (Base)
|
|
32 O << ',';
|
|
33 }
|
|
34 if (Base)
|
|
35 O << '%' << getRegisterName(Base);
|
|
36 O << ')';
|
|
37 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
38 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
39
|
95
|
40 void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI,
|
|
41 raw_ostream &O) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
42 if (MO.isReg())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
43 O << '%' << getRegisterName(MO.getReg());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
44 else if (MO.isImm())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
45 O << MO.getImm();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
46 else if (MO.isExpr())
|
95
|
47 MO.getExpr()->print(O, MAI);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
48 else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
49 llvm_unreachable("Invalid operand");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
50 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
51
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
52 void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
95
|
53 StringRef Annot,
|
|
54 const MCSubtargetInfo &STI) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
55 printInstruction(MI, O);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
56 printAnnotation(O, Annot);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
57 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
58
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
59 void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
60 O << '%' << getRegisterName(RegNo);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
61 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
62
|
100
|
63 template <unsigned N>
|
|
64 static void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
|
95
|
65 int64_t Value = MI->getOperand(OpNum).getImm();
|
|
66 assert(isUInt<N>(Value) && "Invalid uimm argument");
|
|
67 O << Value;
|
|
68 }
|
|
69
|
100
|
70 template <unsigned N>
|
|
71 static void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
|
95
|
72 int64_t Value = MI->getOperand(OpNum).getImm();
|
|
73 assert(isInt<N>(Value) && "Invalid simm argument");
|
|
74 O << Value;
|
|
75 }
|
|
76
|
|
77 void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
|
|
78 raw_ostream &O) {
|
|
79 printUImmOperand<1>(MI, OpNum, O);
|
|
80 }
|
|
81
|
|
82 void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
|
|
83 raw_ostream &O) {
|
|
84 printUImmOperand<2>(MI, OpNum, O);
|
|
85 }
|
|
86
|
|
87 void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
|
|
88 raw_ostream &O) {
|
|
89 printUImmOperand<3>(MI, OpNum, O);
|
|
90 }
|
|
91
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
92 void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
93 raw_ostream &O) {
|
95
|
94 printUImmOperand<4>(MI, OpNum, O);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
95 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
96
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
97 void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
98 raw_ostream &O) {
|
95
|
99 printUImmOperand<6>(MI, OpNum, O);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
100 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
101
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
102 void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
103 raw_ostream &O) {
|
95
|
104 printSImmOperand<8>(MI, OpNum, O);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
105 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
106
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
107 void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
108 raw_ostream &O) {
|
95
|
109 printUImmOperand<8>(MI, OpNum, O);
|
|
110 }
|
|
111
|
|
112 void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
|
|
113 raw_ostream &O) {
|
|
114 printUImmOperand<12>(MI, OpNum, O);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
115 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
116
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
117 void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
118 raw_ostream &O) {
|
95
|
119 printSImmOperand<16>(MI, OpNum, O);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
120 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
121
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
122 void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
123 raw_ostream &O) {
|
95
|
124 printUImmOperand<16>(MI, OpNum, O);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
125 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
126
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
127 void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
128 raw_ostream &O) {
|
95
|
129 printSImmOperand<32>(MI, OpNum, O);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
130 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
131
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
132 void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
133 raw_ostream &O) {
|
95
|
134 printUImmOperand<32>(MI, OpNum, O);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
135 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
136
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
137 void SystemZInstPrinter::printAccessRegOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
138 raw_ostream &O) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
139 uint64_t Value = MI->getOperand(OpNum).getImm();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
140 assert(Value < 16 && "Invalid access register number");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
141 O << "%a" << (unsigned int)Value;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
142 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
143
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
144 void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
145 raw_ostream &O) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
146 const MCOperand &MO = MI->getOperand(OpNum);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
147 if (MO.isImm()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
148 O << "0x";
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
149 O.write_hex(MO.getImm());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
150 } else
|
95
|
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 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
175 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
176
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
177 void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
178 raw_ostream &O) {
|
95
|
179 printOperand(MI->getOperand(OpNum), &MAI, O);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
180 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
181
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
182 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
183 raw_ostream &O) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
184 printAddress(MI->getOperand(OpNum).getReg(),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
185 MI->getOperand(OpNum + 1).getImm(), 0, O);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
186 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
187
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
188 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
189 raw_ostream &O) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
190 printAddress(MI->getOperand(OpNum).getReg(),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
191 MI->getOperand(OpNum + 1).getImm(),
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
192 MI->getOperand(OpNum + 2).getReg(), O);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
193 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
194
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
195 void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
196 raw_ostream &O) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
197 unsigned Base = MI->getOperand(OpNum).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
198 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
199 uint64_t Length = MI->getOperand(OpNum + 2).getImm();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
200 O << Disp << '(' << Length;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
201 if (Base)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
202 O << ",%" << getRegisterName(Base);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
203 O << ')';
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
204 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
205
|
95
|
206 void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
|
|
207 raw_ostream &O) {
|
|
208 printAddress(MI->getOperand(OpNum).getReg(),
|
|
209 MI->getOperand(OpNum + 1).getImm(),
|
|
210 MI->getOperand(OpNum + 2).getReg(), O);
|
|
211 }
|
|
212
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
213 void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
214 raw_ostream &O) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
215 static const char *const CondNames[] = {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
216 "o", "h", "nle", "l", "nhe", "lh", "ne",
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
217 "e", "nlh", "he", "nl", "le", "nh", "no"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
218 };
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
219 uint64_t Imm = MI->getOperand(OpNum).getImm();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
220 assert(Imm > 0 && Imm < 15 && "Invalid condition");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
221 O << CondNames[Imm - 1];
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
222 }
|