1*9880d681SAndroid Build Coastguard Worker //===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This class prints an Hexagon MCInst to a .s file.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "HexagonAsmPrinter.h"
15*9880d681SAndroid Build Coastguard Worker #include "HexagonInstPrinter.h"
16*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/HexagonBaseInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/HexagonMCInstrInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "asm-printer"
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker #define GET_INSTRUCTION_NAME
29*9880d681SAndroid Build Coastguard Worker #include "HexagonGenAsmWriter.inc"
30*9880d681SAndroid Build Coastguard Worker
HexagonInstPrinter(MCAsmInfo const & MAI,MCInstrInfo const & MII,MCRegisterInfo const & MRI)31*9880d681SAndroid Build Coastguard Worker HexagonInstPrinter::HexagonInstPrinter(MCAsmInfo const &MAI,
32*9880d681SAndroid Build Coastguard Worker MCInstrInfo const &MII,
33*9880d681SAndroid Build Coastguard Worker MCRegisterInfo const &MRI)
34*9880d681SAndroid Build Coastguard Worker : MCInstPrinter(MAI, MII, MRI), MII(MII), HasExtender(false) {
35*9880d681SAndroid Build Coastguard Worker }
36*9880d681SAndroid Build Coastguard Worker
getOpcodeName(unsigned Opcode) const37*9880d681SAndroid Build Coastguard Worker StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
38*9880d681SAndroid Build Coastguard Worker return MII.getName(Opcode);
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker
printRegName(raw_ostream & O,unsigned RegNo) const41*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
42*9880d681SAndroid Build Coastguard Worker O << getRegName(RegNo);
43*9880d681SAndroid Build Coastguard Worker }
44*9880d681SAndroid Build Coastguard Worker
getRegName(unsigned RegNo) const45*9880d681SAndroid Build Coastguard Worker StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
46*9880d681SAndroid Build Coastguard Worker return getRegisterName(RegNo);
47*9880d681SAndroid Build Coastguard Worker }
48*9880d681SAndroid Build Coastguard Worker
setExtender(MCInst const & MCI)49*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::setExtender(MCInst const &MCI) {
50*9880d681SAndroid Build Coastguard Worker HasExtender = HexagonMCInstrInfo::isImmext(MCI);
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker
printInst(const MCInst * MI,raw_ostream & OS,StringRef Annot,const MCSubtargetInfo & STI)53*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
54*9880d681SAndroid Build Coastguard Worker StringRef Annot, const MCSubtargetInfo &STI) {
55*9880d681SAndroid Build Coastguard Worker assert(HexagonMCInstrInfo::isBundle(*MI));
56*9880d681SAndroid Build Coastguard Worker assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
57*9880d681SAndroid Build Coastguard Worker assert(HexagonMCInstrInfo::bundleSize(*MI) > 0);
58*9880d681SAndroid Build Coastguard Worker HasExtender = false;
59*9880d681SAndroid Build Coastguard Worker for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
60*9880d681SAndroid Build Coastguard Worker MCInst const &MCI = *I.getInst();
61*9880d681SAndroid Build Coastguard Worker if (HexagonMCInstrInfo::isDuplex(MII, MCI)) {
62*9880d681SAndroid Build Coastguard Worker printInstruction(MCI.getOperand(1).getInst(), OS);
63*9880d681SAndroid Build Coastguard Worker OS << '\v';
64*9880d681SAndroid Build Coastguard Worker HasExtender = false;
65*9880d681SAndroid Build Coastguard Worker printInstruction(MCI.getOperand(0).getInst(), OS);
66*9880d681SAndroid Build Coastguard Worker } else
67*9880d681SAndroid Build Coastguard Worker printInstruction(&MCI, OS);
68*9880d681SAndroid Build Coastguard Worker setExtender(MCI);
69*9880d681SAndroid Build Coastguard Worker OS << "\n";
70*9880d681SAndroid Build Coastguard Worker }
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker auto Separator = "";
73*9880d681SAndroid Build Coastguard Worker if (HexagonMCInstrInfo::isInnerLoop(*MI)) {
74*9880d681SAndroid Build Coastguard Worker OS << Separator;
75*9880d681SAndroid Build Coastguard Worker Separator = " ";
76*9880d681SAndroid Build Coastguard Worker MCInst ME;
77*9880d681SAndroid Build Coastguard Worker ME.setOpcode(Hexagon::ENDLOOP0);
78*9880d681SAndroid Build Coastguard Worker printInstruction(&ME, OS);
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker if (HexagonMCInstrInfo::isOuterLoop(*MI)) {
81*9880d681SAndroid Build Coastguard Worker OS << Separator;
82*9880d681SAndroid Build Coastguard Worker MCInst ME;
83*9880d681SAndroid Build Coastguard Worker ME.setOpcode(Hexagon::ENDLOOP1);
84*9880d681SAndroid Build Coastguard Worker printInstruction(&ME, OS);
85*9880d681SAndroid Build Coastguard Worker }
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker
printOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const88*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo,
89*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
90*9880d681SAndroid Build Coastguard Worker if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo &&
91*9880d681SAndroid Build Coastguard Worker (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)))
92*9880d681SAndroid Build Coastguard Worker O << "#";
93*9880d681SAndroid Build Coastguard Worker MCOperand const &MO = MI->getOperand(OpNo);
94*9880d681SAndroid Build Coastguard Worker if (MO.isReg()) {
95*9880d681SAndroid Build Coastguard Worker O << getRegisterName(MO.getReg());
96*9880d681SAndroid Build Coastguard Worker } else if (MO.isExpr()) {
97*9880d681SAndroid Build Coastguard Worker int64_t Value;
98*9880d681SAndroid Build Coastguard Worker if (MO.getExpr()->evaluateAsAbsolute(Value))
99*9880d681SAndroid Build Coastguard Worker O << formatImm(Value);
100*9880d681SAndroid Build Coastguard Worker else
101*9880d681SAndroid Build Coastguard Worker O << *MO.getExpr();
102*9880d681SAndroid Build Coastguard Worker } else {
103*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown operand");
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker
printExtOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const107*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo,
108*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
109*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNo, O);
110*9880d681SAndroid Build Coastguard Worker }
111*9880d681SAndroid Build Coastguard Worker
printUnsignedImmOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const112*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI,
113*9880d681SAndroid Build Coastguard Worker unsigned OpNo,
114*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
115*9880d681SAndroid Build Coastguard Worker O << MI->getOperand(OpNo).getImm();
116*9880d681SAndroid Build Coastguard Worker }
117*9880d681SAndroid Build Coastguard Worker
printNegImmOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const118*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned OpNo,
119*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
120*9880d681SAndroid Build Coastguard Worker O << -MI->getOperand(OpNo).getImm();
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker
printNOneImmOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const123*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned OpNo,
124*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
125*9880d681SAndroid Build Coastguard Worker O << -1;
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker
prints3_6ImmOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const128*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::prints3_6ImmOperand(MCInst const *MI, unsigned OpNo,
129*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
130*9880d681SAndroid Build Coastguard Worker int64_t Imm;
131*9880d681SAndroid Build Coastguard Worker bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
132*9880d681SAndroid Build Coastguard Worker Imm = SignExtend64<9>(Imm);
133*9880d681SAndroid Build Coastguard Worker assert(Success); (void)Success;
134*9880d681SAndroid Build Coastguard Worker assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
135*9880d681SAndroid Build Coastguard Worker O << formatImm(Imm/64);
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker
prints3_7ImmOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const138*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::prints3_7ImmOperand(MCInst const *MI, unsigned OpNo,
139*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
140*9880d681SAndroid Build Coastguard Worker int64_t Imm;
141*9880d681SAndroid Build Coastguard Worker bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
142*9880d681SAndroid Build Coastguard Worker Imm = SignExtend64<10>(Imm);
143*9880d681SAndroid Build Coastguard Worker assert(Success); (void)Success;
144*9880d681SAndroid Build Coastguard Worker assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
145*9880d681SAndroid Build Coastguard Worker O << formatImm(Imm/128);
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker
prints4_6ImmOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const148*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::prints4_6ImmOperand(MCInst const *MI, unsigned OpNo,
149*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
150*9880d681SAndroid Build Coastguard Worker int64_t Imm;
151*9880d681SAndroid Build Coastguard Worker bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
152*9880d681SAndroid Build Coastguard Worker Imm = SignExtend64<10>(Imm);
153*9880d681SAndroid Build Coastguard Worker assert(Success); (void)Success;
154*9880d681SAndroid Build Coastguard Worker assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
155*9880d681SAndroid Build Coastguard Worker O << formatImm(Imm/64);
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker
prints4_7ImmOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const158*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::prints4_7ImmOperand(MCInst const *MI, unsigned OpNo,
159*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
160*9880d681SAndroid Build Coastguard Worker int64_t Imm;
161*9880d681SAndroid Build Coastguard Worker bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
162*9880d681SAndroid Build Coastguard Worker Imm = SignExtend64<11>(Imm);
163*9880d681SAndroid Build Coastguard Worker assert(Success); (void)Success;
164*9880d681SAndroid Build Coastguard Worker assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
165*9880d681SAndroid Build Coastguard Worker O << formatImm(Imm/128);
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker
printGlobalOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const168*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned OpNo,
169*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
170*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNo, O);
171*9880d681SAndroid Build Coastguard Worker }
172*9880d681SAndroid Build Coastguard Worker
printJumpTable(MCInst const * MI,unsigned OpNo,raw_ostream & O) const173*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printJumpTable(MCInst const *MI, unsigned OpNo,
174*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
175*9880d681SAndroid Build Coastguard Worker assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNo, O);
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
printConstantPool(MCInst const * MI,unsigned OpNo,raw_ostream & O) const180*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printConstantPool(MCInst const *MI, unsigned OpNo,
181*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
182*9880d681SAndroid Build Coastguard Worker assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNo, O);
185*9880d681SAndroid Build Coastguard Worker }
186*9880d681SAndroid Build Coastguard Worker
printBranchOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const187*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printBranchOperand(MCInst const *MI, unsigned OpNo,
188*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
189*9880d681SAndroid Build Coastguard Worker // Branches can take an immediate operand. This is used by the branch
190*9880d681SAndroid Build Coastguard Worker // selection pass to print $+8, an eight byte displacement from the PC.
191*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown branch operand.");
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker
printCallOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const194*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo,
195*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {}
196*9880d681SAndroid Build Coastguard Worker
printAbsAddrOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const197*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned OpNo,
198*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {}
199*9880d681SAndroid Build Coastguard Worker
printPredicateOperand(MCInst const * MI,unsigned OpNo,raw_ostream & O) const200*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned OpNo,
201*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {}
202*9880d681SAndroid Build Coastguard Worker
printSymbol(MCInst const * MI,unsigned OpNo,raw_ostream & O,bool hi) const203*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printSymbol(MCInst const *MI, unsigned OpNo,
204*9880d681SAndroid Build Coastguard Worker raw_ostream &O, bool hi) const {
205*9880d681SAndroid Build Coastguard Worker assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker O << '#' << (hi ? "HI" : "LO") << '(';
208*9880d681SAndroid Build Coastguard Worker O << '#';
209*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNo, O);
210*9880d681SAndroid Build Coastguard Worker O << ')';
211*9880d681SAndroid Build Coastguard Worker }
212*9880d681SAndroid Build Coastguard Worker
printBrtarget(MCInst const * MI,unsigned OpNo,raw_ostream & O) const213*9880d681SAndroid Build Coastguard Worker void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo,
214*9880d681SAndroid Build Coastguard Worker raw_ostream &O) const {
215*9880d681SAndroid Build Coastguard Worker MCOperand const &MO = MI->getOperand(OpNo);
216*9880d681SAndroid Build Coastguard Worker assert (MO.isExpr());
217*9880d681SAndroid Build Coastguard Worker MCExpr const &Expr = *MO.getExpr();
218*9880d681SAndroid Build Coastguard Worker int64_t Value;
219*9880d681SAndroid Build Coastguard Worker if (Expr.evaluateAsAbsolute(Value))
220*9880d681SAndroid Build Coastguard Worker O << format("0x%" PRIx64, Value);
221*9880d681SAndroid Build Coastguard Worker else {
222*9880d681SAndroid Build Coastguard Worker if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))
223*9880d681SAndroid Build Coastguard Worker if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo)
224*9880d681SAndroid Build Coastguard Worker O << "##";
225*9880d681SAndroid Build Coastguard Worker O << Expr;
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker }
228