blob: e0d0dc68d478469126294972bf6339eef12daef5 [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
Sid Manning12cd21a2014-10-15 18:27:40 +000031// Return the minimum value that a constant extendable operand can have
32// without being extended.
33static int getMinValue(uint64_t TSFlags) {
34 unsigned isSigned =
35 (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
36 unsigned bits =
37 (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
38
39 if (isSigned)
40 return -1U << (bits - 1);
Sid Manningc374ac92014-10-20 13:08:19 +000041
42 return 0;
Sid Manning12cd21a2014-10-15 18:27:40 +000043}
44
45// Return the maximum value that a constant extendable operand can have
46// without being extended.
47static int getMaxValue(uint64_t TSFlags) {
48 unsigned isSigned =
49 (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
50 unsigned bits =
51 (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
52
53 if (isSigned)
54 return ~(-1U << (bits - 1));
Sid Manningc374ac92014-10-20 13:08:19 +000055
56 return ~(-1U << bits);
Sid Manning12cd21a2014-10-15 18:27:40 +000057}
58
59// Return true if the instruction must be extended.
60static bool isExtended(uint64_t TSFlags) {
61 return (TSFlags >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
62}
63
Sid Manning74cd0202014-10-15 19:24:14 +000064// Currently just used in an assert statement
Sid Manninga0022962014-10-15 20:41:17 +000065static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED;
Sid Manning12cd21a2014-10-15 18:27:40 +000066// Return true if the instruction may be extended based on the operand value.
67static bool isExtendable(uint64_t TSFlags) {
68 return (TSFlags >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
69}
Jyotsna Verma7503a622013-02-20 16:13:27 +000070
Evandro Menezes5cee6212012-04-12 17:55:53 +000071StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
72 return MII.getName(Opcode);
73}
74
Krzysztof Parzyszekbadf3a62015-04-22 15:38:17 +000075void HexagonInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
76 OS << getRegisterName(RegNo);
Evandro Menezes5cee6212012-04-12 17:55:53 +000077}
78
Colin LeMahieu68d967d2015-05-29 14:44:13 +000079void HexagonInstPrinter::setExtender(MCInst const &MCI) {
80 HasExtender = HexagonMCInstrInfo::isImmext(MCI);
81}
82
83void HexagonInstPrinter::printInst(MCInst const *MI, raw_ostream &OS,
Akira Hatanakab46d0232015-03-27 20:36:02 +000084 StringRef Annot,
Colin LeMahieu68d967d2015-05-29 14:44:13 +000085 MCSubtargetInfo const &STI) {
86 assert(HexagonMCInstrInfo::isBundle(*MI));
87 assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
88 HasExtender = false;
89 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
90 MCInst const &MCI = *I.getInst();
Colin LeMahieube8c4532015-06-05 16:00:11 +000091 if (HexagonMCInstrInfo::isDuplex(MII, MCI)) {
92 printInstruction(MCI.getOperand(1).getInst(), OS);
93 OS << '\v';
94 HasExtender = false;
95 printInstruction(MCI.getOperand(0).getInst(), OS);
96 } else
97 printInstruction(&MCI, OS);
Colin LeMahieu68d967d2015-05-29 14:44:13 +000098 setExtender(MCI);
99 OS << "\n";
Evandro Menezes5cee6212012-04-12 17:55:53 +0000100 }
101
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000102 auto Separator = "";
103 if (HexagonMCInstrInfo::isInnerLoop(*MI)) {
104 OS << Separator;
105 Separator = " ";
106 MCInst ME;
107 ME.setOpcode(Hexagon::ENDLOOP0);
108 printInstruction(&ME, OS);
109 }
110 if (HexagonMCInstrInfo::isOuterLoop(*MI)) {
111 OS << Separator;
112 Separator = " ";
113 MCInst ME;
114 ME.setOpcode(Hexagon::ENDLOOP1);
115 printInstruction(&ME, OS);
116 }
Evandro Menezes5cee6212012-04-12 17:55:53 +0000117}
118
119void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
120 raw_ostream &O) const {
121 const MCOperand& MO = MI->getOperand(OpNo);
122
123 if (MO.isReg()) {
Krzysztof Parzyszekbadf3a62015-04-22 15:38:17 +0000124 printRegName(O, MO.getReg());
Evandro Menezes5cee6212012-04-12 17:55:53 +0000125 } else if(MO.isExpr()) {
Matt Arsenault8b643552015-06-09 00:31:39 +0000126 MO.getExpr()->print(O, &MAI);
Evandro Menezes5cee6212012-04-12 17:55:53 +0000127 } else if(MO.isImm()) {
128 printImmOperand(MI, OpNo, O);
129 } else {
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000130 llvm_unreachable("Unknown operand");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000131 }
132}
133
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000134void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
135 raw_ostream &O) const {
Jyotsna Verma7503a622013-02-20 16:13:27 +0000136 const MCOperand& MO = MI->getOperand(OpNo);
137
138 if(MO.isExpr()) {
Matt Arsenault8b643552015-06-09 00:31:39 +0000139 MO.getExpr()->print(O, &MAI);
Jyotsna Verma7503a622013-02-20 16:13:27 +0000140 } else if(MO.isImm()) {
141 O << MI->getOperand(OpNo).getImm();
142 } else {
143 llvm_unreachable("Unknown operand");
144 }
Evandro Menezes5cee6212012-04-12 17:55:53 +0000145}
146
147void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000148 raw_ostream &O) const {
Sid Manning12cd21a2014-10-15 18:27:40 +0000149 const MCOperand &MO = MI->getOperand(OpNo);
150 const MCInstrDesc &MII = getMII().get(MI->getOpcode());
151
152 assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
153 "Expecting an extendable operand");
154
155 if (MO.isExpr() || isExtended(MII.TSFlags)) {
Jyotsna Verma7503a622013-02-20 16:13:27 +0000156 O << "#";
Sid Manning12cd21a2014-10-15 18:27:40 +0000157 } else if (MO.isImm()) {
158 int ImmValue = MO.getImm();
159 if (ImmValue < getMinValue(MII.TSFlags) ||
160 ImmValue > getMaxValue(MII.TSFlags))
161 O << "#";
162 }
Jyotsna Verma7503a622013-02-20 16:13:27 +0000163 printOperand(MI, OpNo, O);
Evandro Menezes5cee6212012-04-12 17:55:53 +0000164}
165
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000166void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI,
167 unsigned OpNo, raw_ostream &O) const {
Evandro Menezes5cee6212012-04-12 17:55:53 +0000168 O << MI->getOperand(OpNo).getImm();
169}
170
171void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo,
172 raw_ostream &O) const {
Brendon Cahoonf6b687e2012-05-14 19:35:42 +0000173 O << -MI->getOperand(OpNo).getImm();
Evandro Menezes5cee6212012-04-12 17:55:53 +0000174}
175
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000176void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo,
177 raw_ostream &O) const {
Evandro Menezes5cee6212012-04-12 17:55:53 +0000178 O << -1;
179}
180
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000181void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo,
182 raw_ostream &O) const {
Evandro Menezes5cee6212012-04-12 17:55:53 +0000183 const MCOperand& MO0 = MI->getOperand(OpNo);
184 const MCOperand& MO1 = MI->getOperand(OpNo + 1);
185
Krzysztof Parzyszekbadf3a62015-04-22 15:38:17 +0000186 printRegName(O, MO0.getReg());
Brendon Cahoonf6b687e2012-05-14 19:35:42 +0000187 O << " + #" << MO1.getImm();
Evandro Menezes5cee6212012-04-12 17:55:53 +0000188}
189
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000190void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
191 raw_ostream &O) const {
Evandro Menezes5cee6212012-04-12 17:55:53 +0000192 const MCOperand& MO0 = MI->getOperand(OpNo);
193 const MCOperand& MO1 = MI->getOperand(OpNo + 1);
194
Krzysztof Parzyszekbadf3a62015-04-22 15:38:17 +0000195 printRegName(O, MO0.getReg());
196 O << ", #" << MO1.getImm();
Evandro Menezes5cee6212012-04-12 17:55:53 +0000197}
198
199void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo,
200 raw_ostream &O) const {
NAKAMURA Takumidf3d5ea2012-04-21 11:24:55 +0000201 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000202
203 printOperand(MI, OpNo, O);
204}
205
206void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo,
207 raw_ostream &O) const {
NAKAMURA Takumidf3d5ea2012-04-21 11:24:55 +0000208 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000209
210 printOperand(MI, OpNo, O);
211}
212
213void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo,
214 raw_ostream &O) const {
NAKAMURA Takumidf3d5ea2012-04-21 11:24:55 +0000215 assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000216
217 printOperand(MI, OpNo, O);
218}
219
220void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo,
221 raw_ostream &O) const {
222 // Branches can take an immediate operand. This is used by the branch
223 // selection pass to print $+8, an eight byte displacement from the PC.
Richard Trieud7fd95a2013-06-28 23:46:19 +0000224 llvm_unreachable("Unknown branch operand.");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000225}
226
227void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
228 raw_ostream &O) const {
229}
230
231void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo,
232 raw_ostream &O) const {
233}
234
235void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
236 raw_ostream &O) const {
237}
238
239void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
240 raw_ostream &O, bool hi) const {
Benjamin Kramer755bf4f2013-07-02 17:24:00 +0000241 assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
Evandro Menezes5cee6212012-04-12 17:55:53 +0000242
Benjamin Kramer755bf4f2013-07-02 17:24:00 +0000243 O << '#' << (hi ? "HI" : "LO") << "(#";
Richard Trieufab01e52013-07-01 23:06:23 +0000244 printOperand(MI, OpNo, O);
Evandro Menezes5cee6212012-04-12 17:55:53 +0000245 O << ')';
246}
Brendon Cahoon55bdeb72015-04-27 14:16:43 +0000247
248void HexagonInstPrinter::printExtBrtarget(const MCInst *MI, unsigned OpNo,
249 raw_ostream &O) const {
250 const MCOperand &MO = MI->getOperand(OpNo);
251 const MCInstrDesc &MII = getMII().get(MI->getOpcode());
252
253 assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
254 "Expecting an extendable operand");
255
256 if (MO.isExpr() || isExtended(MII.TSFlags)) {
257 O << "##";
258 }
259 printOperand(MI, OpNo, O);
260}