blob: 73f20f52439ad7d70e36eba079309c36c5420419 [file] [log] [blame]
Evandro Menezes5cee6212012-04-12 17:55:53 +00001//===- HexagonInstPrinter.cpp - Convert Hexagon 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//
10// This class prints an Hexagon MCInst to a .s file.
11//
12//===----------------------------------------------------------------------===//
13
Evandro Menezes5cee6212012-04-12 17:55:53 +000014#include "HexagonAsmPrinter.h"
Jyotsna Verma7503a622013-02-20 16:13:27 +000015#include "Hexagon.h"
16#include "HexagonInstPrinter.h"
Colin LeMahieu1174fea2015-02-19 21:10:50 +000017#include "MCTargetDesc/HexagonMCInstrInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000018#include "llvm/ADT/StringExtras.h"
Evandro Menezes5cee6212012-04-12 17:55:53 +000019#include "llvm/MC/MCAsmInfo.h"
20#include "llvm/MC/MCExpr.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000021#include "llvm/MC/MCInst.h"
Evandro Menezes5cee6212012-04-12 17:55:53 +000022#include "llvm/Support/raw_ostream.h"
Evandro Menezes5cee6212012-04-12 17:55:53 +000023
24using namespace llvm;
25
Chandler Carruth84e68b22014-04-22 02:41:26 +000026#define DEBUG_TYPE "asm-printer"
27
Evandro Menezes5cee6212012-04-12 17:55:53 +000028#define GET_INSTRUCTION_NAME
29#include "HexagonGenAsmWriter.inc"
30
Colin LeMahieu68d967d2015-05-29 14:44:13 +000031HexagonAsmInstPrinter::HexagonAsmInstPrinter(MCInstPrinter *RawPrinter)
32 : MCInstPrinter(*RawPrinter), RawPrinter(RawPrinter) {}
33
34void HexagonAsmInstPrinter::printInst(MCInst const *MI, raw_ostream &O,
35 StringRef Annot,
36 MCSubtargetInfo const &STI) {
37 assert(HexagonMCInstrInfo::isBundle(*MI));
38 assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
39 std::string Buffer;
40 {
41 raw_string_ostream TempStream(Buffer);
42 RawPrinter->printInst(MI, TempStream, "", STI);
43 }
44 StringRef Contents(Buffer);
45 auto PacketBundle = Contents.rsplit('\n');
46 auto HeadTail = PacketBundle.first.split('\n');
47 auto Preamble = "\t{\n\t\t";
48 auto Separator = "";
49 while(!HeadTail.first.empty()) {
50 O << Separator;
51 StringRef Inst;
52 auto Duplex = HeadTail.first.split('\v');
53 if(!Duplex.second.empty()){
54 O << Duplex.first << "\n";
55 Inst = Duplex.second;
56 }
57 else
58 Inst = Duplex.first;
59 O << Preamble;
60 O << Inst;
61 HeadTail = HeadTail.second.split('\n');
62 Preamble = "";
63 Separator = "\n\t\t";
64 }
65 O << "\n\t}" << PacketBundle.second;
66}
67
68void HexagonAsmInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
69 RawPrinter->printRegName(O, RegNo);
70}
71
Sid Manning12cd21a2014-10-15 18:27:40 +000072// Return the minimum value that a constant extendable operand can have
73// without being extended.
74static int getMinValue(uint64_t TSFlags) {
75 unsigned isSigned =
76 (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
77 unsigned bits =
78 (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
79
80 if (isSigned)
81 return -1U << (bits - 1);
Sid Manningc374ac92014-10-20 13:08:19 +000082
83 return 0;
Sid Manning12cd21a2014-10-15 18:27:40 +000084}
85
86// Return the maximum value that a constant extendable operand can have
87// without being extended.
88static int getMaxValue(uint64_t TSFlags) {
89 unsigned isSigned =
90 (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
91 unsigned bits =
92 (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
93
94 if (isSigned)
95 return ~(-1U << (bits - 1));
Sid Manningc374ac92014-10-20 13:08:19 +000096
97 return ~(-1U << bits);
Sid Manning12cd21a2014-10-15 18:27:40 +000098}
99
100// Return true if the instruction must be extended.
101static bool isExtended(uint64_t TSFlags) {
102 return (TSFlags >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
103}
104
Sid Manning74cd0202014-10-15 19:24:14 +0000105// Currently just used in an assert statement
Sid Manninga0022962014-10-15 20:41:17 +0000106static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED;
Sid Manning12cd21a2014-10-15 18:27:40 +0000107// Return true if the instruction may be extended based on the operand value.
108static bool isExtendable(uint64_t TSFlags) {
109 return (TSFlags >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
110}
Jyotsna Verma7503a622013-02-20 16:13:27 +0000111
Evandro Menezes5cee6212012-04-12 17:55:53 +0000112StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
113 return MII.getName(Opcode);
114}
115
Krzysztof Parzyszekbadf3a62015-04-22 15:38:17 +0000116void HexagonInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
117 OS << getRegisterName(RegNo);
Evandro Menezes5cee6212012-04-12 17:55:53 +0000118}
119
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000120void HexagonInstPrinter::setExtender(MCInst const &MCI) {
121 HasExtender = HexagonMCInstrInfo::isImmext(MCI);
122}
123
124void HexagonInstPrinter::printInst(MCInst const *MI, raw_ostream &OS,
Akira Hatanakab46d0232015-03-27 20:36:02 +0000125 StringRef Annot,
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000126 MCSubtargetInfo const &STI) {
127 assert(HexagonMCInstrInfo::isBundle(*MI));
128 assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
129 HasExtender = false;
130 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
131 MCInst const &MCI = *I.getInst();
132 printInstruction(&MCI, OS);
133 setExtender(MCI);
134 OS << "\n";
Evandro Menezes5cee6212012-04-12 17:55:53 +0000135 }
136
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000137 auto Separator = "";
138 if (HexagonMCInstrInfo::isInnerLoop(*MI)) {
139 OS << Separator;
140 Separator = " ";
141 MCInst ME;
142 ME.setOpcode(Hexagon::ENDLOOP0);
143 printInstruction(&ME, OS);
144 }
145 if (HexagonMCInstrInfo::isOuterLoop(*MI)) {
146 OS << Separator;
147 Separator = " ";
148 MCInst ME;
149 ME.setOpcode(Hexagon::ENDLOOP1);
150 printInstruction(&ME, OS);
151 }
Evandro Menezes5cee6212012-04-12 17:55:53 +0000152}
153
154void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
155 raw_ostream &O) const {
156 const MCOperand& MO = MI->getOperand(OpNo);
157
158 if (MO.isReg()) {
Krzysztof Parzyszekbadf3a62015-04-22 15:38:17 +0000159 printRegName(O, MO.getReg());
Evandro Menezes5cee6212012-04-12 17:55:53 +0000160 } else if(MO.isExpr()) {
161 O << *MO.getExpr();
162 } else if(MO.isImm()) {
163 printImmOperand(MI, OpNo, O);
164 } else {
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000165 llvm_unreachable("Unknown operand");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000166 }
167}
168
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000169void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
170 raw_ostream &O) const {
Jyotsna Verma7503a622013-02-20 16:13:27 +0000171 const MCOperand& MO = MI->getOperand(OpNo);
172
173 if(MO.isExpr()) {
174 O << *MO.getExpr();
175 } else if(MO.isImm()) {
176 O << MI->getOperand(OpNo).getImm();
177 } else {
178 llvm_unreachable("Unknown operand");
179 }
Evandro Menezes5cee6212012-04-12 17:55:53 +0000180}
181
182void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000183 raw_ostream &O) const {
Sid Manning12cd21a2014-10-15 18:27:40 +0000184 const MCOperand &MO = MI->getOperand(OpNo);
185 const MCInstrDesc &MII = getMII().get(MI->getOpcode());
186
187 assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
188 "Expecting an extendable operand");
189
190 if (MO.isExpr() || isExtended(MII.TSFlags)) {
Jyotsna Verma7503a622013-02-20 16:13:27 +0000191 O << "#";
Sid Manning12cd21a2014-10-15 18:27:40 +0000192 } else if (MO.isImm()) {
193 int ImmValue = MO.getImm();
194 if (ImmValue < getMinValue(MII.TSFlags) ||
195 ImmValue > getMaxValue(MII.TSFlags))
196 O << "#";
197 }
Jyotsna Verma7503a622013-02-20 16:13:27 +0000198 printOperand(MI, OpNo, O);
Evandro Menezes5cee6212012-04-12 17:55:53 +0000199}
200
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000201void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI,
202 unsigned OpNo, raw_ostream &O) const {
Evandro Menezes5cee6212012-04-12 17:55:53 +0000203 O << MI->getOperand(OpNo).getImm();
204}
205
206void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo,
207 raw_ostream &O) const {
Brendon Cahoonf6b687e2012-05-14 19:35:42 +0000208 O << -MI->getOperand(OpNo).getImm();
Evandro Menezes5cee6212012-04-12 17:55:53 +0000209}
210
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000211void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo,
212 raw_ostream &O) const {
Evandro Menezes5cee6212012-04-12 17:55:53 +0000213 O << -1;
214}
215
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000216void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo,
217 raw_ostream &O) const {
Evandro Menezes5cee6212012-04-12 17:55:53 +0000218 const MCOperand& MO0 = MI->getOperand(OpNo);
219 const MCOperand& MO1 = MI->getOperand(OpNo + 1);
220
Krzysztof Parzyszekbadf3a62015-04-22 15:38:17 +0000221 printRegName(O, MO0.getReg());
Brendon Cahoonf6b687e2012-05-14 19:35:42 +0000222 O << " + #" << MO1.getImm();
Evandro Menezes5cee6212012-04-12 17:55:53 +0000223}
224
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000225void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
226 raw_ostream &O) const {
Evandro Menezes5cee6212012-04-12 17:55:53 +0000227 const MCOperand& MO0 = MI->getOperand(OpNo);
228 const MCOperand& MO1 = MI->getOperand(OpNo + 1);
229
Krzysztof Parzyszekbadf3a62015-04-22 15:38:17 +0000230 printRegName(O, MO0.getReg());
231 O << ", #" << MO1.getImm();
Evandro Menezes5cee6212012-04-12 17:55:53 +0000232}
233
234void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo,
235 raw_ostream &O) const {
NAKAMURA Takumidf3d5ea2012-04-21 11:24:55 +0000236 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000237
238 printOperand(MI, OpNo, O);
239}
240
241void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo,
242 raw_ostream &O) const {
NAKAMURA Takumidf3d5ea2012-04-21 11:24:55 +0000243 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000244
245 printOperand(MI, OpNo, O);
246}
247
248void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo,
249 raw_ostream &O) const {
NAKAMURA Takumidf3d5ea2012-04-21 11:24:55 +0000250 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000251
252 printOperand(MI, OpNo, O);
253}
254
255void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
256 raw_ostream &O) const {
257 // Branches can take an immediate operand. This is used by the branch
258 // selection pass to print $+8, an eight byte displacement from the PC.
Richard Trieud7fd95a2013-06-28 23:46:19 +0000259 llvm_unreachable("Unknown branch operand.");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000260}
261
262void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
263 raw_ostream &O) const {
264}
265
266void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo,
267 raw_ostream &O) const {
268}
269
270void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
271 raw_ostream &O) const {
272}
273
274void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
275 raw_ostream &O, bool hi) const {
Benjamin Kramer755bf4f2013-07-02 17:24:00 +0000276 assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000277
Benjamin Kramer755bf4f2013-07-02 17:24:00 +0000278 O << '#' << (hi ? "HI" : "LO") << "(#";
Richard Trieufab01e52013-07-01 23:06:23 +0000279 printOperand(MI, OpNo, O);
Evandro Menezes5cee6212012-04-12 17:55:53 +0000280 O << ')';
281}
Brendon Cahoon55bdeb72015-04-27 14:16:43 +0000282
283void HexagonInstPrinter::printExtBrtarget(const MCInst *MI, unsigned OpNo,
284 raw_ostream &O) const {
285 const MCOperand &MO = MI->getOperand(OpNo);
286 const MCInstrDesc &MII = getMII().get(MI->getOpcode());
287
288 assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
289 "Expecting an extendable operand");
290
291 if (MO.isExpr() || isExtended(MII.TSFlags)) {
292 O << "##";
293 }
294 printOperand(MI, OpNo, O);
295}