blob: 6cd12e13e220c02c51d85c5c5e3a17a77fc2faa1 [file] [log] [blame]
Eugene Zelenko06869c02017-02-03 23:39:06 +00001//===- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax -===//
Ulrich Weigand5f613df2013-05-06 16:15:19 +00002//
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"
Pete Cooper3de83e42015-05-15 21:58:42 +000012#include "llvm/MC/MCInst.h"
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +000013#include "llvm/MC/MCSymbol.h"
Eugene Zelenko06869c02017-02-03 23:39:06 +000014#include "llvm/Support/Casting.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000015#include "llvm/Support/ErrorHandling.h"
Eugene Zelenko06869c02017-02-03 23:39:06 +000016#include "llvm/Support/MathExtras.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000017#include "llvm/Support/raw_ostream.h"
Eugene Zelenko06869c02017-02-03 23:39:06 +000018#include <cassert>
19#include <cstdint>
Ulrich Weigand5f613df2013-05-06 16:15:19 +000020
21using namespace llvm;
22
Chandler Carruth84e68b22014-04-22 02:41:26 +000023#define DEBUG_TYPE "asm-printer"
24
Ulrich Weigand5f613df2013-05-06 16:15:19 +000025#include "SystemZGenAsmWriter.inc"
26
27void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp,
28 unsigned Index, raw_ostream &O) {
29 O << Disp;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000030 if (Base || Index) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +000031 O << '(';
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000032 if (Index) {
33 O << '%' << getRegisterName(Index);
34 if (Base)
35 O << ',';
36 }
37 if (Base)
38 O << '%' << getRegisterName(Base);
39 O << ')';
40 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +000041}
42
Matt Arsenault8b643552015-06-09 00:31:39 +000043void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI,
44 raw_ostream &O) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +000045 if (MO.isReg())
46 O << '%' << getRegisterName(MO.getReg());
47 else if (MO.isImm())
48 O << MO.getImm();
49 else if (MO.isExpr())
Matt Arsenault8b643552015-06-09 00:31:39 +000050 MO.getExpr()->print(O, MAI);
Ulrich Weigand5f613df2013-05-06 16:15:19 +000051 else
52 llvm_unreachable("Invalid operand");
53}
54
55void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
Akira Hatanakab46d0232015-03-27 20:36:02 +000056 StringRef Annot,
57 const MCSubtargetInfo &STI) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +000058 printInstruction(MI, O);
59 printAnnotation(O, Annot);
60}
61
62void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
63 O << '%' << getRegisterName(RegNo);
64}
65
Benjamin Kramer039b1042015-10-28 13:54:36 +000066template <unsigned N>
67static void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000068 int64_t Value = MI->getOperand(OpNum).getImm();
69 assert(isUInt<N>(Value) && "Invalid uimm argument");
70 O << Value;
71}
72
Benjamin Kramer039b1042015-10-28 13:54:36 +000073template <unsigned N>
74static void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000075 int64_t Value = MI->getOperand(OpNum).getImm();
76 assert(isInt<N>(Value) && "Invalid simm argument");
77 O << Value;
78}
79
80void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
81 raw_ostream &O) {
82 printUImmOperand<1>(MI, OpNum, O);
83}
84
85void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
86 raw_ostream &O) {
87 printUImmOperand<2>(MI, OpNum, O);
88}
89
90void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
91 raw_ostream &O) {
92 printUImmOperand<3>(MI, OpNum, O);
93}
94
Ulrich Weigand5f613df2013-05-06 16:15:19 +000095void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
96 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000097 printUImmOperand<4>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +000098}
99
100void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
101 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000102 printUImmOperand<6>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000103}
104
105void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
106 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000107 printSImmOperand<8>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000108}
109
110void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
111 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000112 printUImmOperand<8>(MI, OpNum, O);
113}
114
115void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
116 raw_ostream &O) {
117 printUImmOperand<12>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000118}
119
120void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
121 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000122 printSImmOperand<16>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000123}
124
125void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
126 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000127 printUImmOperand<16>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000128}
129
130void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
131 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000132 printSImmOperand<32>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000133}
134
135void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
136 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000137 printUImmOperand<32>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000138}
139
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000140void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,
141 raw_ostream &O) {
142 printUImmOperand<48>(MI, OpNum, O);
143}
144
Richard Sandifordeb9af292013-05-14 10:17:52 +0000145void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
146 raw_ostream &O) {
147 const MCOperand &MO = MI->getOperand(OpNum);
148 if (MO.isImm()) {
149 O << "0x";
150 O.write_hex(MO.getImm());
151 } else
Matt Arsenault8b643552015-06-09 00:31:39 +0000152 MO.getExpr()->print(O, &MAI);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000153}
154
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000155void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum,
156 raw_ostream &O) {
157 // Output the PC-relative operand.
158 printPCRelOperand(MI, OpNum, O);
159
160 // Output the TLS marker if present.
161 if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
162 const MCOperand &MO = MI->getOperand(OpNum + 1);
163 const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
164 switch (refExp.getKind()) {
165 case MCSymbolRefExpr::VK_TLSGD:
166 O << ":tls_gdcall:";
167 break;
168 case MCSymbolRefExpr::VK_TLSLDM:
169 O << ":tls_ldcall:";
170 break;
171 default:
172 llvm_unreachable("Unexpected symbol kind");
173 }
174 O << refExp.getSymbol().getName();
175 }
176}
177
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000178void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
179 raw_ostream &O) {
Matt Arsenault8b643552015-06-09 00:31:39 +0000180 printOperand(MI->getOperand(OpNum), &MAI, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000181}
182
183void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
184 raw_ostream &O) {
185 printAddress(MI->getOperand(OpNum).getReg(),
186 MI->getOperand(OpNum + 1).getImm(), 0, O);
187}
188
189void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
190 raw_ostream &O) {
191 printAddress(MI->getOperand(OpNum).getReg(),
192 MI->getOperand(OpNum + 1).getImm(),
193 MI->getOperand(OpNum + 2).getReg(), O);
194}
195
Richard Sandiford1d959002013-07-02 14:56:45 +0000196void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
197 raw_ostream &O) {
198 unsigned Base = MI->getOperand(OpNum).getReg();
199 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
200 uint64_t Length = MI->getOperand(OpNum + 2).getImm();
201 O << Disp << '(' << Length;
202 if (Base)
203 O << ",%" << getRegisterName(Base);
204 O << ')';
205}
206
Ulrich Weigandec5d7792016-10-31 14:21:36 +0000207void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
208 raw_ostream &O) {
209 unsigned Base = MI->getOperand(OpNum).getReg();
210 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
211 unsigned Length = MI->getOperand(OpNum + 2).getReg();
212 O << Disp << "(%" << getRegisterName(Length);
213 if (Base)
214 O << ",%" << getRegisterName(Base);
215 O << ')';
216}
217
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000218void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
219 raw_ostream &O) {
220 printAddress(MI->getOperand(OpNum).getReg(),
221 MI->getOperand(OpNum + 1).getImm(),
222 MI->getOperand(OpNum + 2).getReg(), O);
223}
224
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000225void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
226 raw_ostream &O) {
227 static const char *const CondNames[] = {
228 "o", "h", "nle", "l", "nhe", "lh", "ne",
229 "e", "nlh", "he", "nl", "le", "nh", "no"
230 };
231 uint64_t Imm = MI->getOperand(OpNum).getImm();
232 assert(Imm > 0 && Imm < 15 && "Invalid condition");
233 O << CondNames[Imm - 1];
234}