blob: 1207c7b327e879bb586a3a5182429a6cf0a209a7 [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"
Pete Cooper3de83e42015-05-15 21:58:42 +000012#include "llvm/MC/MCInst.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000013#include "llvm/MC/MCInstrInfo.h"
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +000014#include "llvm/MC/MCSymbol.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000015#include "llvm/Support/ErrorHandling.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000016#include "llvm/Support/raw_ostream.h"
17
18using namespace llvm;
19
Chandler Carruth84e68b22014-04-22 02:41:26 +000020#define DEBUG_TYPE "asm-printer"
21
Ulrich Weigand5f613df2013-05-06 16:15:19 +000022#include "SystemZGenAsmWriter.inc"
23
24void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp,
25 unsigned Index, raw_ostream &O) {
26 O << Disp;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000027 if (Base || Index) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +000028 O << '(';
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000029 if (Index) {
30 O << '%' << getRegisterName(Index);
31 if (Base)
32 O << ',';
33 }
34 if (Base)
35 O << '%' << getRegisterName(Base);
36 O << ')';
37 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +000038}
39
Matt Arsenault8b643552015-06-09 00:31:39 +000040void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI,
41 raw_ostream &O) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +000042 if (MO.isReg())
43 O << '%' << getRegisterName(MO.getReg());
44 else if (MO.isImm())
45 O << MO.getImm();
46 else if (MO.isExpr())
Matt Arsenault8b643552015-06-09 00:31:39 +000047 MO.getExpr()->print(O, MAI);
Ulrich Weigand5f613df2013-05-06 16:15:19 +000048 else
49 llvm_unreachable("Invalid operand");
50}
51
52void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
Akira Hatanakab46d0232015-03-27 20:36:02 +000053 StringRef Annot,
54 const MCSubtargetInfo &STI) {
Ulrich Weigand5f613df2013-05-06 16:15:19 +000055 printInstruction(MI, O);
56 printAnnotation(O, Annot);
57}
58
59void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
60 O << '%' << getRegisterName(RegNo);
61}
62
Benjamin Kramer039b1042015-10-28 13:54:36 +000063template <unsigned N>
64static void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000065 int64_t Value = MI->getOperand(OpNum).getImm();
66 assert(isUInt<N>(Value) && "Invalid uimm argument");
67 O << Value;
68}
69
Benjamin Kramer039b1042015-10-28 13:54:36 +000070template <unsigned N>
71static void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000072 int64_t Value = MI->getOperand(OpNum).getImm();
73 assert(isInt<N>(Value) && "Invalid simm argument");
74 O << Value;
75}
76
77void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,
78 raw_ostream &O) {
79 printUImmOperand<1>(MI, OpNum, O);
80}
81
82void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,
83 raw_ostream &O) {
84 printUImmOperand<2>(MI, OpNum, O);
85}
86
87void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,
88 raw_ostream &O) {
89 printUImmOperand<3>(MI, OpNum, O);
90}
91
Ulrich Weigand5f613df2013-05-06 16:15:19 +000092void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
93 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000094 printUImmOperand<4>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +000095}
96
97void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
98 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000099 printUImmOperand<6>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000100}
101
102void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
103 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000104 printSImmOperand<8>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000105}
106
107void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
108 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000109 printUImmOperand<8>(MI, OpNum, O);
110}
111
112void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,
113 raw_ostream &O) {
114 printUImmOperand<12>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000115}
116
117void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
118 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000119 printSImmOperand<16>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000120}
121
122void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
123 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000124 printUImmOperand<16>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000125}
126
127void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
128 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000129 printSImmOperand<32>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000130}
131
132void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
133 raw_ostream &O) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000134 printUImmOperand<32>(MI, OpNum, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000135}
136
Zhan Jun Liau4fbc3f42016-08-08 15:13:08 +0000137void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,
138 raw_ostream &O) {
139 printUImmOperand<48>(MI, OpNum, O);
140}
141
Richard Sandifordeb9af292013-05-14 10:17:52 +0000142void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
143 raw_ostream &O) {
144 const MCOperand &MO = MI->getOperand(OpNum);
145 if (MO.isImm()) {
146 O << "0x";
147 O.write_hex(MO.getImm());
148 } else
Matt Arsenault8b643552015-06-09 00:31:39 +0000149 MO.getExpr()->print(O, &MAI);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000150}
151
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000152void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum,
153 raw_ostream &O) {
154 // Output the PC-relative operand.
155 printPCRelOperand(MI, OpNum, O);
156
157 // Output the TLS marker if present.
158 if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
159 const MCOperand &MO = MI->getOperand(OpNum + 1);
160 const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
161 switch (refExp.getKind()) {
162 case MCSymbolRefExpr::VK_TLSGD:
163 O << ":tls_gdcall:";
164 break;
165 case MCSymbolRefExpr::VK_TLSLDM:
166 O << ":tls_ldcall:";
167 break;
168 default:
169 llvm_unreachable("Unexpected symbol kind");
170 }
171 O << refExp.getSymbol().getName();
172 }
173}
174
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000175void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
176 raw_ostream &O) {
Matt Arsenault8b643552015-06-09 00:31:39 +0000177 printOperand(MI->getOperand(OpNum), &MAI, O);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000178}
179
180void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
181 raw_ostream &O) {
182 printAddress(MI->getOperand(OpNum).getReg(),
183 MI->getOperand(OpNum + 1).getImm(), 0, O);
184}
185
186void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
187 raw_ostream &O) {
188 printAddress(MI->getOperand(OpNum).getReg(),
189 MI->getOperand(OpNum + 1).getImm(),
190 MI->getOperand(OpNum + 2).getReg(), O);
191}
192
Richard Sandiford1d959002013-07-02 14:56:45 +0000193void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
194 raw_ostream &O) {
195 unsigned Base = MI->getOperand(OpNum).getReg();
196 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
197 uint64_t Length = MI->getOperand(OpNum + 2).getImm();
198 O << Disp << '(' << Length;
199 if (Base)
200 O << ",%" << getRegisterName(Base);
201 O << ')';
202}
203
Ulrich Weigandec5d7792016-10-31 14:21:36 +0000204void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
205 raw_ostream &O) {
206 unsigned Base = MI->getOperand(OpNum).getReg();
207 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
208 unsigned Length = MI->getOperand(OpNum + 2).getReg();
209 O << Disp << "(%" << getRegisterName(Length);
210 if (Base)
211 O << ",%" << getRegisterName(Base);
212 O << ')';
213}
214
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000215void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
216 raw_ostream &O) {
217 printAddress(MI->getOperand(OpNum).getReg(),
218 MI->getOperand(OpNum + 1).getImm(),
219 MI->getOperand(OpNum + 2).getReg(), O);
220}
221
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000222void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
223 raw_ostream &O) {
224 static const char *const CondNames[] = {
225 "o", "h", "nle", "l", "nhe", "lh", "ne",
226 "e", "nlh", "he", "nl", "le", "nh", "no"
227 };
228 uint64_t Imm = MI->getOperand(OpNum).getImm();
229 assert(Imm > 0 && Imm < 15 && "Invalid condition");
230 O << CondNames[Imm - 1];
231}