blob: 02bd47d07f726a74e4b1a47f2c22771a036b18cf [file] [log] [blame]
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001//===-- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax ===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Ulrich Weigand5f613df2013-05-06 16:15:19 +000010#include "SystemZInstPrinter.h"
11#include "llvm/MC/MCExpr.h"
12#include "llvm/MC/MCInstrInfo.h"
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +000013#include "llvm/MC/MCSymbol.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000014#include "llvm/Support/raw_ostream.h"
15
16using namespace llvm;
17
Chandler Carruth84e68b22014-04-22 02:41:26 +000018#define DEBUG_TYPE "asm-printer"
19
Ulrich Weigand5f613df2013-05-06 16:15:19 +000020#include "SystemZGenAsmWriter.inc"
21
22void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp,
23 unsigned Index, raw_ostream &O) {
24 O << Disp;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000025 if (Base || Index) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +000026 O << '(';
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000027 if (Index) {
28 O << '%' << getRegisterName(Index);
29 if (Base)
30 O << ',';
31 }
32 if (Base)
33 O << '%' << getRegisterName(Base);
34 O << ')';
35 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +000036}
37
38void SystemZInstPrinter::printOperand(const MCOperand &MO, raw_ostream &O) {
39 if (MO.isReg())
40 O << '%' << getRegisterName(MO.getReg());
41 else if (MO.isImm())
42 O << MO.getImm();
43 else if (MO.isExpr())
44 O << *MO.getExpr();
45 else
46 llvm_unreachable("Invalid operand");
47}
48
49void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
Akira Hatanakab46d0232015-03-27 20:36:02 +000050 StringRef Annot,
51 const MCSubtargetInfo &STI) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +000052 printInstruction(MI, O);
53 printAnnotation(O, Annot);
54}
55
56void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
57 O << '%' << getRegisterName(RegNo);
58}
59
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000060template<unsigned N>
61void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
62 int64_t Value = MI->getOperand(OpNum).getImm();
63 assert(isUInt<N>(Value) && "Invalid uimm argument");
64 O << Value;
65}
66
67template<unsigned N>
68void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
69 int64_t Value = MI->getOperand(OpNum).getImm();
70 assert(isInt<N>(Value) && "Invalid simm argument");
71 O << Value;
72}
73
74void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
75 raw_ostream &O) {
76 printUImmOperand<1>(MI, OpNum, O);
77}
78
79void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
80 raw_ostream &O) {
81 printUImmOperand<2>(MI, OpNum, O);
82}
83
84void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
85 raw_ostream &O) {
86 printUImmOperand<3>(MI, OpNum, O);
87}
88
Ulrich Weigand5f613df2013-05-06 16:15:19 +000089void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
90 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000091 printUImmOperand<4>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +000092}
93
94void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
95 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000096 printUImmOperand<6>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +000097}
98
99void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
100 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000101 printSImmOperand<8>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000102}
103
104void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
105 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000106 printUImmOperand<8>(MI, OpNum, O);
107}
108
109void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
110 raw_ostream &O) {
111 printUImmOperand<12>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000112}
113
114void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
115 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000116 printSImmOperand<16>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000117}
118
119void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
120 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000121 printUImmOperand<16>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000122}
123
124void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
125 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000126 printSImmOperand<32>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000127}
128
129void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
130 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000131 printUImmOperand<32>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000132}
133
134void SystemZInstPrinter::printAccessRegOperand(const MCInst *MI, int OpNum,
135 raw_ostream &O) {
136 uint64_t Value = MI->getOperand(OpNum).getImm();
137 assert(Value < 16 && "Invalid access register number");
138 O << "%a" << (unsigned int)Value;
139}
140
Richard Sandifordeb9af292013-05-14 10:17:52 +0000141void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
142 raw_ostream &O) {
143 const MCOperand &MO = MI->getOperand(OpNum);
144 if (MO.isImm()) {
145 O << "0x";
146 O.write_hex(MO.getImm());
147 } else
148 O << *MO.getExpr();
149}
150
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000151void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum,
152 raw_ostream &O) {
153 // Output the PC-relative operand.
154 printPCRelOperand(MI, OpNum, O);
155
156 // Output the TLS marker if present.
157 if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
158 const MCOperand &MO = MI->getOperand(OpNum + 1);
159 const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
160 switch (refExp.getKind()) {
161 case MCSymbolRefExpr::VK_TLSGD:
162 O << ":tls_gdcall:";
163 break;
164 case MCSymbolRefExpr::VK_TLSLDM:
165 O << ":tls_ldcall:";
166 break;
167 default:
168 llvm_unreachable("Unexpected symbol kind");
169 }
170 O << refExp.getSymbol().getName();
171 }
172}
173
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000174void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
175 raw_ostream &O) {
176 printOperand(MI->getOperand(OpNum), O);
177}
178
179void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
180 raw_ostream &O) {
181 printAddress(MI->getOperand(OpNum).getReg(),
182 MI->getOperand(OpNum + 1).getImm(), 0, O);
183}
184
185void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
186 raw_ostream &O) {
187 printAddress(MI->getOperand(OpNum).getReg(),
188 MI->getOperand(OpNum + 1).getImm(),
189 MI->getOperand(OpNum + 2).getReg(), O);
190}
191
Richard Sandiford1d959002013-07-02 14:56:45 +0000192void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
193 raw_ostream &O) {
194 unsigned Base = MI->getOperand(OpNum).getReg();
195 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
196 uint64_t Length = MI->getOperand(OpNum + 2).getImm();
197 O << Disp << '(' << Length;
198 if (Base)
199 O << ",%" << getRegisterName(Base);
200 O << ')';
201}
202
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000203void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
204 raw_ostream &O) {
205 printAddress(MI->getOperand(OpNum).getReg(),
206 MI->getOperand(OpNum + 1).getImm(),
207 MI->getOperand(OpNum + 2).getReg(), O);
208}
209
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000210void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
211 raw_ostream &O) {
212 static const char *const CondNames[] = {
213 "o", "h", "nle", "l", "nhe", "lh", "ne",
214 "e", "nlh", "he", "nl", "le", "nh", "no"
215 };
216 uint64_t Imm = MI->getOperand(OpNum).getImm();
217 assert(Imm > 0 && Imm < 15 && "Invalid condition");
218 O << CondNames[Imm - 1];
219}