xref: /aosp_15_r20/external/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- LanaiInstPrinter.cpp - Convert Lanai MCInst to asm 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 Lanai 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 "LanaiInstPrinter.h"
15*9880d681SAndroid Build Coastguard Worker #include "Lanai.h"
16*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/LanaiMCExpr.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FormattedStream.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 // Include the auto-generated portion of the assembly writer.
29*9880d681SAndroid Build Coastguard Worker #define PRINT_ALIAS_INSTR
30*9880d681SAndroid Build Coastguard Worker #include "LanaiGenAsmWriter.inc"
31*9880d681SAndroid Build Coastguard Worker 
printRegName(raw_ostream & OS,unsigned RegNo) const32*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
33*9880d681SAndroid Build Coastguard Worker   OS << StringRef(getRegisterName(RegNo)).lower();
34*9880d681SAndroid Build Coastguard Worker }
35*9880d681SAndroid Build Coastguard Worker 
printInst(const MCInst * MI,raw_ostream & OS,StringRef Alias,unsigned OpNo0,unsigned OpNo1)36*9880d681SAndroid Build Coastguard Worker bool LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
37*9880d681SAndroid Build Coastguard Worker                                  StringRef Alias, unsigned OpNo0,
38*9880d681SAndroid Build Coastguard Worker                                  unsigned OpNo1) {
39*9880d681SAndroid Build Coastguard Worker   OS << "\t" << Alias << " ";
40*9880d681SAndroid Build Coastguard Worker   printOperand(MI, OpNo0, OS);
41*9880d681SAndroid Build Coastguard Worker   OS << ", ";
42*9880d681SAndroid Build Coastguard Worker   printOperand(MI, OpNo1, OS);
43*9880d681SAndroid Build Coastguard Worker   return true;
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker 
usesGivenOffset(const MCInst * MI,int AddOffset)46*9880d681SAndroid Build Coastguard Worker static bool usesGivenOffset(const MCInst *MI, int AddOffset) {
47*9880d681SAndroid Build Coastguard Worker   unsigned AluCode = MI->getOperand(3).getImm();
48*9880d681SAndroid Build Coastguard Worker   return LPAC::encodeLanaiAluCode(AluCode) == LPAC::ADD &&
49*9880d681SAndroid Build Coastguard Worker          (MI->getOperand(2).getImm() == AddOffset ||
50*9880d681SAndroid Build Coastguard Worker           MI->getOperand(2).getImm() == -AddOffset);
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker 
isPreIncrementForm(const MCInst * MI,int AddOffset)53*9880d681SAndroid Build Coastguard Worker static bool isPreIncrementForm(const MCInst *MI, int AddOffset) {
54*9880d681SAndroid Build Coastguard Worker   unsigned AluCode = MI->getOperand(3).getImm();
55*9880d681SAndroid Build Coastguard Worker   return LPAC::isPreOp(AluCode) && usesGivenOffset(MI, AddOffset);
56*9880d681SAndroid Build Coastguard Worker }
57*9880d681SAndroid Build Coastguard Worker 
isPostIncrementForm(const MCInst * MI,int AddOffset)58*9880d681SAndroid Build Coastguard Worker static bool isPostIncrementForm(const MCInst *MI, int AddOffset) {
59*9880d681SAndroid Build Coastguard Worker   unsigned AluCode = MI->getOperand(3).getImm();
60*9880d681SAndroid Build Coastguard Worker   return LPAC::isPostOp(AluCode) && usesGivenOffset(MI, AddOffset);
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker 
decIncOperator(const MCInst * MI)63*9880d681SAndroid Build Coastguard Worker static StringRef decIncOperator(const MCInst *MI) {
64*9880d681SAndroid Build Coastguard Worker   if (MI->getOperand(2).getImm() < 0)
65*9880d681SAndroid Build Coastguard Worker     return "--";
66*9880d681SAndroid Build Coastguard Worker   return "++";
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker 
printMemoryLoadIncrement(const MCInst * MI,raw_ostream & OS,StringRef Opcode,int AddOffset)69*9880d681SAndroid Build Coastguard Worker bool LanaiInstPrinter::printMemoryLoadIncrement(const MCInst *MI,
70*9880d681SAndroid Build Coastguard Worker                                                 raw_ostream &OS,
71*9880d681SAndroid Build Coastguard Worker                                                 StringRef Opcode,
72*9880d681SAndroid Build Coastguard Worker                                                 int AddOffset) {
73*9880d681SAndroid Build Coastguard Worker   if (isPreIncrementForm(MI, AddOffset)) {
74*9880d681SAndroid Build Coastguard Worker     OS << "\t" << Opcode << "\t[" << decIncOperator(MI) << "%"
75*9880d681SAndroid Build Coastguard Worker        << getRegisterName(MI->getOperand(1).getReg()) << "], %"
76*9880d681SAndroid Build Coastguard Worker        << getRegisterName(MI->getOperand(0).getReg());
77*9880d681SAndroid Build Coastguard Worker     return true;
78*9880d681SAndroid Build Coastguard Worker   }
79*9880d681SAndroid Build Coastguard Worker   if (isPostIncrementForm(MI, AddOffset)) {
80*9880d681SAndroid Build Coastguard Worker     OS << "\t" << Opcode << "\t[%"
81*9880d681SAndroid Build Coastguard Worker        << getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI)
82*9880d681SAndroid Build Coastguard Worker        << "], %" << getRegisterName(MI->getOperand(0).getReg());
83*9880d681SAndroid Build Coastguard Worker     return true;
84*9880d681SAndroid Build Coastguard Worker   }
85*9880d681SAndroid Build Coastguard Worker   return false;
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker 
printMemoryStoreIncrement(const MCInst * MI,raw_ostream & OS,StringRef Opcode,int AddOffset)88*9880d681SAndroid Build Coastguard Worker bool LanaiInstPrinter::printMemoryStoreIncrement(const MCInst *MI,
89*9880d681SAndroid Build Coastguard Worker                                                  raw_ostream &OS,
90*9880d681SAndroid Build Coastguard Worker                                                  StringRef Opcode,
91*9880d681SAndroid Build Coastguard Worker                                                  int AddOffset) {
92*9880d681SAndroid Build Coastguard Worker   if (isPreIncrementForm(MI, AddOffset)) {
93*9880d681SAndroid Build Coastguard Worker     OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
94*9880d681SAndroid Build Coastguard Worker        << ", [" << decIncOperator(MI) << "%"
95*9880d681SAndroid Build Coastguard Worker        << getRegisterName(MI->getOperand(1).getReg()) << "]";
96*9880d681SAndroid Build Coastguard Worker     return true;
97*9880d681SAndroid Build Coastguard Worker   }
98*9880d681SAndroid Build Coastguard Worker   if (isPostIncrementForm(MI, AddOffset)) {
99*9880d681SAndroid Build Coastguard Worker     OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
100*9880d681SAndroid Build Coastguard Worker        << ", [%" << getRegisterName(MI->getOperand(1).getReg())
101*9880d681SAndroid Build Coastguard Worker        << decIncOperator(MI) << "]";
102*9880d681SAndroid Build Coastguard Worker     return true;
103*9880d681SAndroid Build Coastguard Worker   }
104*9880d681SAndroid Build Coastguard Worker   return false;
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker 
printAlias(const MCInst * MI,raw_ostream & OS)107*9880d681SAndroid Build Coastguard Worker bool LanaiInstPrinter::printAlias(const MCInst *MI, raw_ostream &OS) {
108*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
109*9880d681SAndroid Build Coastguard Worker   case Lanai::LDW_RI:
110*9880d681SAndroid Build Coastguard Worker     // ld 4[*%rN], %rX => ld [++imm], %rX
111*9880d681SAndroid Build Coastguard Worker     // ld -4[*%rN], %rX => ld [--imm], %rX
112*9880d681SAndroid Build Coastguard Worker     // ld 4[%rN*], %rX => ld [imm++], %rX
113*9880d681SAndroid Build Coastguard Worker     // ld -4[%rN*], %rX => ld [imm--], %rX
114*9880d681SAndroid Build Coastguard Worker     return printMemoryLoadIncrement(MI, OS, "ld", 4);
115*9880d681SAndroid Build Coastguard Worker   case Lanai::LDHs_RI:
116*9880d681SAndroid Build Coastguard Worker     return printMemoryLoadIncrement(MI, OS, "ld.h", 2);
117*9880d681SAndroid Build Coastguard Worker   case Lanai::LDHz_RI:
118*9880d681SAndroid Build Coastguard Worker     return printMemoryLoadIncrement(MI, OS, "uld.h", 2);
119*9880d681SAndroid Build Coastguard Worker   case Lanai::LDBs_RI:
120*9880d681SAndroid Build Coastguard Worker     return printMemoryLoadIncrement(MI, OS, "ld.b", 1);
121*9880d681SAndroid Build Coastguard Worker   case Lanai::LDBz_RI:
122*9880d681SAndroid Build Coastguard Worker     return printMemoryLoadIncrement(MI, OS, "uld.b", 1);
123*9880d681SAndroid Build Coastguard Worker   case Lanai::SW_RI:
124*9880d681SAndroid Build Coastguard Worker     // st %rX, 4[*%rN] => st %rX, [++imm]
125*9880d681SAndroid Build Coastguard Worker     // st %rX, -4[*%rN] => st %rX, [--imm]
126*9880d681SAndroid Build Coastguard Worker     // st %rX, 4[%rN*] => st %rX, [imm++]
127*9880d681SAndroid Build Coastguard Worker     // st %rX, -4[%rN*] => st %rX, [imm--]
128*9880d681SAndroid Build Coastguard Worker     return printMemoryStoreIncrement(MI, OS, "st", 4);
129*9880d681SAndroid Build Coastguard Worker   case Lanai::STH_RI:
130*9880d681SAndroid Build Coastguard Worker     return printMemoryStoreIncrement(MI, OS, "st.h", 2);
131*9880d681SAndroid Build Coastguard Worker   case Lanai::STB_RI:
132*9880d681SAndroid Build Coastguard Worker     return printMemoryStoreIncrement(MI, OS, "st.b", 1);
133*9880d681SAndroid Build Coastguard Worker   default:
134*9880d681SAndroid Build Coastguard Worker     return false;
135*9880d681SAndroid Build Coastguard Worker   }
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker 
printInst(const MCInst * MI,raw_ostream & OS,StringRef Annotation,const MCSubtargetInfo & STI)138*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
139*9880d681SAndroid Build Coastguard Worker                                  StringRef Annotation,
140*9880d681SAndroid Build Coastguard Worker                                  const MCSubtargetInfo &STI) {
141*9880d681SAndroid Build Coastguard Worker   if (!printAlias(MI, OS) && !printAliasInstr(MI, OS))
142*9880d681SAndroid Build Coastguard Worker     printInstruction(MI, OS);
143*9880d681SAndroid Build Coastguard Worker   printAnnotation(OS, Annotation);
144*9880d681SAndroid Build Coastguard Worker }
145*9880d681SAndroid Build Coastguard Worker 
printOperand(const MCInst * MI,unsigned OpNo,raw_ostream & OS,const char * Modifier)146*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
147*9880d681SAndroid Build Coastguard Worker                                     raw_ostream &OS, const char *Modifier) {
148*9880d681SAndroid Build Coastguard Worker   assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
149*9880d681SAndroid Build Coastguard Worker   const MCOperand &Op = MI->getOperand(OpNo);
150*9880d681SAndroid Build Coastguard Worker   if (Op.isReg())
151*9880d681SAndroid Build Coastguard Worker     OS << "%" << getRegisterName(Op.getReg());
152*9880d681SAndroid Build Coastguard Worker   else if (Op.isImm())
153*9880d681SAndroid Build Coastguard Worker     OS << formatHex(Op.getImm());
154*9880d681SAndroid Build Coastguard Worker   else {
155*9880d681SAndroid Build Coastguard Worker     assert(Op.isExpr() && "Expected an expression");
156*9880d681SAndroid Build Coastguard Worker     Op.getExpr()->print(OS, &MAI);
157*9880d681SAndroid Build Coastguard Worker   }
158*9880d681SAndroid Build Coastguard Worker }
159*9880d681SAndroid Build Coastguard Worker 
printMemImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & OS)160*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printMemImmOperand(const MCInst *MI, unsigned OpNo,
161*9880d681SAndroid Build Coastguard Worker                                           raw_ostream &OS) {
162*9880d681SAndroid Build Coastguard Worker   const MCOperand &Op = MI->getOperand(OpNo);
163*9880d681SAndroid Build Coastguard Worker   if (Op.isImm()) {
164*9880d681SAndroid Build Coastguard Worker     OS << '[' << formatHex(Op.getImm()) << ']';
165*9880d681SAndroid Build Coastguard Worker   } else {
166*9880d681SAndroid Build Coastguard Worker     // Symbolic operand will be lowered to immediate value by linker
167*9880d681SAndroid Build Coastguard Worker     assert(Op.isExpr() && "Expected an expression");
168*9880d681SAndroid Build Coastguard Worker     OS << '[';
169*9880d681SAndroid Build Coastguard Worker     Op.getExpr()->print(OS, &MAI);
170*9880d681SAndroid Build Coastguard Worker     OS << ']';
171*9880d681SAndroid Build Coastguard Worker   }
172*9880d681SAndroid Build Coastguard Worker }
173*9880d681SAndroid Build Coastguard Worker 
printHi16ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & OS)174*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printHi16ImmOperand(const MCInst *MI, unsigned OpNo,
175*9880d681SAndroid Build Coastguard Worker                                            raw_ostream &OS) {
176*9880d681SAndroid Build Coastguard Worker   const MCOperand &Op = MI->getOperand(OpNo);
177*9880d681SAndroid Build Coastguard Worker   if (Op.isImm()) {
178*9880d681SAndroid Build Coastguard Worker     OS << formatHex(Op.getImm() << 16);
179*9880d681SAndroid Build Coastguard Worker   } else {
180*9880d681SAndroid Build Coastguard Worker     // Symbolic operand will be lowered to immediate value by linker
181*9880d681SAndroid Build Coastguard Worker     assert(Op.isExpr() && "Expected an expression");
182*9880d681SAndroid Build Coastguard Worker     Op.getExpr()->print(OS, &MAI);
183*9880d681SAndroid Build Coastguard Worker   }
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker 
printHi16AndImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & OS)186*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printHi16AndImmOperand(const MCInst *MI, unsigned OpNo,
187*9880d681SAndroid Build Coastguard Worker                                               raw_ostream &OS) {
188*9880d681SAndroid Build Coastguard Worker   const MCOperand &Op = MI->getOperand(OpNo);
189*9880d681SAndroid Build Coastguard Worker   if (Op.isImm()) {
190*9880d681SAndroid Build Coastguard Worker     OS << formatHex((Op.getImm() << 16) | 0xffff);
191*9880d681SAndroid Build Coastguard Worker   } else {
192*9880d681SAndroid Build Coastguard Worker     // Symbolic operand will be lowered to immediate value by linker
193*9880d681SAndroid Build Coastguard Worker     assert(Op.isExpr() && "Expected an expression");
194*9880d681SAndroid Build Coastguard Worker     Op.getExpr()->print(OS, &MAI);
195*9880d681SAndroid Build Coastguard Worker   }
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker 
printLo16AndImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & OS)198*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printLo16AndImmOperand(const MCInst *MI, unsigned OpNo,
199*9880d681SAndroid Build Coastguard Worker                                               raw_ostream &OS) {
200*9880d681SAndroid Build Coastguard Worker   const MCOperand &Op = MI->getOperand(OpNo);
201*9880d681SAndroid Build Coastguard Worker   if (Op.isImm()) {
202*9880d681SAndroid Build Coastguard Worker     OS << formatHex(0xffff0000 | Op.getImm());
203*9880d681SAndroid Build Coastguard Worker   } else {
204*9880d681SAndroid Build Coastguard Worker     // Symbolic operand will be lowered to immediate value by linker
205*9880d681SAndroid Build Coastguard Worker     assert(Op.isExpr() && "Expected an expression");
206*9880d681SAndroid Build Coastguard Worker     Op.getExpr()->print(OS, &MAI);
207*9880d681SAndroid Build Coastguard Worker   }
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker 
printMemoryBaseRegister(raw_ostream & OS,const unsigned AluCode,const MCOperand & RegOp)210*9880d681SAndroid Build Coastguard Worker static void printMemoryBaseRegister(raw_ostream &OS, const unsigned AluCode,
211*9880d681SAndroid Build Coastguard Worker                                     const MCOperand &RegOp) {
212*9880d681SAndroid Build Coastguard Worker   assert(RegOp.isReg() && "Register operand expected");
213*9880d681SAndroid Build Coastguard Worker   OS << "[";
214*9880d681SAndroid Build Coastguard Worker   if (LPAC::isPreOp(AluCode))
215*9880d681SAndroid Build Coastguard Worker     OS << "*";
216*9880d681SAndroid Build Coastguard Worker   OS << "%" << LanaiInstPrinter::getRegisterName(RegOp.getReg());
217*9880d681SAndroid Build Coastguard Worker   if (LPAC::isPostOp(AluCode))
218*9880d681SAndroid Build Coastguard Worker     OS << "*";
219*9880d681SAndroid Build Coastguard Worker   OS << "]";
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker 
222*9880d681SAndroid Build Coastguard Worker template <unsigned SizeInBits>
printMemoryImmediateOffset(const MCAsmInfo & MAI,const MCOperand & OffsetOp,raw_ostream & OS)223*9880d681SAndroid Build Coastguard Worker static void printMemoryImmediateOffset(const MCAsmInfo &MAI,
224*9880d681SAndroid Build Coastguard Worker                                        const MCOperand &OffsetOp,
225*9880d681SAndroid Build Coastguard Worker                                        raw_ostream &OS) {
226*9880d681SAndroid Build Coastguard Worker   assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected");
227*9880d681SAndroid Build Coastguard Worker   if (OffsetOp.isImm()) {
228*9880d681SAndroid Build Coastguard Worker     assert(isInt<SizeInBits>(OffsetOp.getImm()) && "Constant value truncated");
229*9880d681SAndroid Build Coastguard Worker     OS << OffsetOp.getImm();
230*9880d681SAndroid Build Coastguard Worker   } else
231*9880d681SAndroid Build Coastguard Worker     OffsetOp.getExpr()->print(OS, &MAI);
232*9880d681SAndroid Build Coastguard Worker }
233*9880d681SAndroid Build Coastguard Worker 
printMemRiOperand(const MCInst * MI,int OpNo,raw_ostream & OS,const char * Modifier)234*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printMemRiOperand(const MCInst *MI, int OpNo,
235*9880d681SAndroid Build Coastguard Worker                                          raw_ostream &OS,
236*9880d681SAndroid Build Coastguard Worker                                          const char *Modifier) {
237*9880d681SAndroid Build Coastguard Worker   const MCOperand &RegOp = MI->getOperand(OpNo);
238*9880d681SAndroid Build Coastguard Worker   const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
239*9880d681SAndroid Build Coastguard Worker   const MCOperand &AluOp = MI->getOperand(OpNo + 2);
240*9880d681SAndroid Build Coastguard Worker   const unsigned AluCode = AluOp.getImm();
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker   // Offset
243*9880d681SAndroid Build Coastguard Worker   printMemoryImmediateOffset<16>(MAI, OffsetOp, OS);
244*9880d681SAndroid Build Coastguard Worker 
245*9880d681SAndroid Build Coastguard Worker   // Register
246*9880d681SAndroid Build Coastguard Worker   printMemoryBaseRegister(OS, AluCode, RegOp);
247*9880d681SAndroid Build Coastguard Worker }
248*9880d681SAndroid Build Coastguard Worker 
printMemRrOperand(const MCInst * MI,int OpNo,raw_ostream & OS,const char * Modifier)249*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printMemRrOperand(const MCInst *MI, int OpNo,
250*9880d681SAndroid Build Coastguard Worker                                          raw_ostream &OS,
251*9880d681SAndroid Build Coastguard Worker                                          const char *Modifier) {
252*9880d681SAndroid Build Coastguard Worker   const MCOperand &RegOp = MI->getOperand(OpNo);
253*9880d681SAndroid Build Coastguard Worker   const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
254*9880d681SAndroid Build Coastguard Worker   const MCOperand &AluOp = MI->getOperand(OpNo + 2);
255*9880d681SAndroid Build Coastguard Worker   const unsigned AluCode = AluOp.getImm();
256*9880d681SAndroid Build Coastguard Worker   assert(OffsetOp.isReg() && RegOp.isReg() && "Registers expected.");
257*9880d681SAndroid Build Coastguard Worker 
258*9880d681SAndroid Build Coastguard Worker   // [ Base OP Offset ]
259*9880d681SAndroid Build Coastguard Worker   OS << "[";
260*9880d681SAndroid Build Coastguard Worker   if (LPAC::isPreOp(AluCode))
261*9880d681SAndroid Build Coastguard Worker     OS << "*";
262*9880d681SAndroid Build Coastguard Worker   OS << "%" << getRegisterName(RegOp.getReg());
263*9880d681SAndroid Build Coastguard Worker   if (LPAC::isPostOp(AluCode))
264*9880d681SAndroid Build Coastguard Worker     OS << "*";
265*9880d681SAndroid Build Coastguard Worker   OS << " " << LPAC::lanaiAluCodeToString(AluCode) << " ";
266*9880d681SAndroid Build Coastguard Worker   OS << "%" << getRegisterName(OffsetOp.getReg());
267*9880d681SAndroid Build Coastguard Worker   OS << "]";
268*9880d681SAndroid Build Coastguard Worker }
269*9880d681SAndroid Build Coastguard Worker 
printMemSplsOperand(const MCInst * MI,int OpNo,raw_ostream & OS,const char * Modifier)270*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printMemSplsOperand(const MCInst *MI, int OpNo,
271*9880d681SAndroid Build Coastguard Worker                                            raw_ostream &OS,
272*9880d681SAndroid Build Coastguard Worker                                            const char *Modifier) {
273*9880d681SAndroid Build Coastguard Worker   const MCOperand &RegOp = MI->getOperand(OpNo);
274*9880d681SAndroid Build Coastguard Worker   const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
275*9880d681SAndroid Build Coastguard Worker   const MCOperand &AluOp = MI->getOperand(OpNo + 2);
276*9880d681SAndroid Build Coastguard Worker   const unsigned AluCode = AluOp.getImm();
277*9880d681SAndroid Build Coastguard Worker 
278*9880d681SAndroid Build Coastguard Worker   // Offset
279*9880d681SAndroid Build Coastguard Worker   printMemoryImmediateOffset<10>(MAI, OffsetOp, OS);
280*9880d681SAndroid Build Coastguard Worker 
281*9880d681SAndroid Build Coastguard Worker   // Register
282*9880d681SAndroid Build Coastguard Worker   printMemoryBaseRegister(OS, AluCode, RegOp);
283*9880d681SAndroid Build Coastguard Worker }
284*9880d681SAndroid Build Coastguard Worker 
printCCOperand(const MCInst * MI,int OpNo,raw_ostream & OS)285*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printCCOperand(const MCInst *MI, int OpNo,
286*9880d681SAndroid Build Coastguard Worker                                       raw_ostream &OS) {
287*9880d681SAndroid Build Coastguard Worker   LPCC::CondCode CC =
288*9880d681SAndroid Build Coastguard Worker       static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
289*9880d681SAndroid Build Coastguard Worker   // Handle the undefined value here for printing so we don't abort().
290*9880d681SAndroid Build Coastguard Worker   if (CC >= LPCC::UNKNOWN)
291*9880d681SAndroid Build Coastguard Worker     OS << "<und>";
292*9880d681SAndroid Build Coastguard Worker   else
293*9880d681SAndroid Build Coastguard Worker     OS << lanaiCondCodeToString(CC);
294*9880d681SAndroid Build Coastguard Worker }
295*9880d681SAndroid Build Coastguard Worker 
printPredicateOperand(const MCInst * MI,unsigned OpNo,raw_ostream & OS)296*9880d681SAndroid Build Coastguard Worker void LanaiInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
297*9880d681SAndroid Build Coastguard Worker                                              raw_ostream &OS) {
298*9880d681SAndroid Build Coastguard Worker   LPCC::CondCode CC =
299*9880d681SAndroid Build Coastguard Worker       static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
300*9880d681SAndroid Build Coastguard Worker   // Handle the undefined value here for printing so we don't abort().
301*9880d681SAndroid Build Coastguard Worker   if (CC >= LPCC::UNKNOWN)
302*9880d681SAndroid Build Coastguard Worker     OS << "<und>";
303*9880d681SAndroid Build Coastguard Worker   else if (CC != LPCC::ICC_T)
304*9880d681SAndroid Build Coastguard Worker     OS << "." << lanaiCondCodeToString(CC);
305*9880d681SAndroid Build Coastguard Worker }
306