xref: /aosp_15_r20/external/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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