blob: 996a49288480d971a6d8715c58e08ffb917bd4cc [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;
25 if (Base) {
26 O << '(';
27 if (Index)
28 O << '%' << getRegisterName(Index) << ',';
29 O << '%' << getRegisterName(Base) << ')';
30 } else
31 assert(!Index && "Shouldn't have an index without a base");
32}
33
34void SystemZInstPrinter::printOperand(const MCOperand &MO, raw_ostream &O) {
35 if (MO.isReg())
36 O << '%' << getRegisterName(MO.getReg());
37 else if (MO.isImm())
38 O << MO.getImm();
39 else if (MO.isExpr())
40 O << *MO.getExpr();
41 else
42 llvm_unreachable("Invalid operand");
43}
44
45void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
46 StringRef Annot) {
47 printInstruction(MI, O);
48 printAnnotation(O, Annot);
49}
50
51void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
52 O << '%' << getRegisterName(RegNo);
53}
54
55void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,
56 raw_ostream &O) {
57 int64_t Value = MI->getOperand(OpNum).getImm();
58 assert(isUInt<4>(Value) && "Invalid u4imm argument");
59 O << Value;
60}
61
62void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum,
63 raw_ostream &O) {
64 int64_t Value = MI->getOperand(OpNum).getImm();
65 assert(isUInt<6>(Value) && "Invalid u6imm argument");
66 O << Value;
67}
68
69void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,
70 raw_ostream &O) {
71 int64_t Value = MI->getOperand(OpNum).getImm();
72 assert(isInt<8>(Value) && "Invalid s8imm argument");
73 O << Value;
74}
75
76void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,
77 raw_ostream &O) {
78 int64_t Value = MI->getOperand(OpNum).getImm();
79 assert(isUInt<8>(Value) && "Invalid u8imm argument");
80 O << Value;
81}
82
83void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,
84 raw_ostream &O) {
85 int64_t Value = MI->getOperand(OpNum).getImm();
86 assert(isInt<16>(Value) && "Invalid s16imm argument");
87 O << Value;
88}
89
90void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,
91 raw_ostream &O) {
92 int64_t Value = MI->getOperand(OpNum).getImm();
93 assert(isUInt<16>(Value) && "Invalid u16imm argument");
94 O << Value;
95}
96
97void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,
98 raw_ostream &O) {
99 int64_t Value = MI->getOperand(OpNum).getImm();
100 assert(isInt<32>(Value) && "Invalid s32imm argument");
101 O << Value;
102}
103
104void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,
105 raw_ostream &O) {
106 int64_t Value = MI->getOperand(OpNum).getImm();
107 assert(isUInt<32>(Value) && "Invalid u32imm argument");
108 O << Value;
109}
110
111void SystemZInstPrinter::printAccessRegOperand(const MCInst *MI, int OpNum,
112 raw_ostream &O) {
113 uint64_t Value = MI->getOperand(OpNum).getImm();
114 assert(Value < 16 && "Invalid access register number");
115 O << "%a" << (unsigned int)Value;
116}
117
Richard Sandifordeb9af292013-05-14 10:17:52 +0000118void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
119 raw_ostream &O) {
120 const MCOperand &MO = MI->getOperand(OpNum);
121 if (MO.isImm()) {
122 O << "0x";
123 O.write_hex(MO.getImm());
124 } else
125 O << *MO.getExpr();
126}
127
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000128void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum,
129 raw_ostream &O) {
130 // Output the PC-relative operand.
131 printPCRelOperand(MI, OpNum, O);
132
133 // Output the TLS marker if present.
134 if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
135 const MCOperand &MO = MI->getOperand(OpNum + 1);
136 const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
137 switch (refExp.getKind()) {
138 case MCSymbolRefExpr::VK_TLSGD:
139 O << ":tls_gdcall:";
140 break;
141 case MCSymbolRefExpr::VK_TLSLDM:
142 O << ":tls_ldcall:";
143 break;
144 default:
145 llvm_unreachable("Unexpected symbol kind");
146 }
147 O << refExp.getSymbol().getName();
148 }
149}
150
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000151void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
152 raw_ostream &O) {
153 printOperand(MI->getOperand(OpNum), O);
154}
155
156void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
157 raw_ostream &O) {
158 printAddress(MI->getOperand(OpNum).getReg(),
159 MI->getOperand(OpNum + 1).getImm(), 0, O);
160}
161
162void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
163 raw_ostream &O) {
164 printAddress(MI->getOperand(OpNum).getReg(),
165 MI->getOperand(OpNum + 1).getImm(),
166 MI->getOperand(OpNum + 2).getReg(), O);
167}
168
Richard Sandiford1d959002013-07-02 14:56:45 +0000169void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
170 raw_ostream &O) {
171 unsigned Base = MI->getOperand(OpNum).getReg();
172 uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
173 uint64_t Length = MI->getOperand(OpNum + 2).getImm();
174 O << Disp << '(' << Length;
175 if (Base)
176 O << ",%" << getRegisterName(Base);
177 O << ')';
178}
179
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000180void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,
181 raw_ostream &O) {
182 static const char *const CondNames[] = {
183 "o", "h", "nle", "l", "nhe", "lh", "ne",
184 "e", "nlh", "he", "nl", "le", "nh", "no"
185 };
186 uint64_t Imm = MI->getOperand(OpNum).getImm();
187 assert(Imm > 0 && Imm < 15 && "Invalid condition");
188 O << CondNames[Imm - 1];
189}