xref: /openbsd-src/gnu/llvm/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
1*d415bd75Srobert //===- XtensaInstPrinter.cpp - Convert Xtensa MCInst to asm syntax --------===//
2*d415bd75Srobert //
3*d415bd75Srobert //                     The LLVM Compiler Infrastructure
4*d415bd75Srobert //
5*d415bd75Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6*d415bd75Srobert // See https://llvm.org/LICENSE.txt for license information.
7*d415bd75Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8*d415bd75Srobert //
9*d415bd75Srobert //===----------------------------------------------------------------------===//
10*d415bd75Srobert //
11*d415bd75Srobert // This class prints an Xtensa MCInst to a .s file.
12*d415bd75Srobert //
13*d415bd75Srobert //===----------------------------------------------------------------------===//
14*d415bd75Srobert 
15*d415bd75Srobert #include "XtensaInstPrinter.h"
16*d415bd75Srobert #include "llvm/CodeGen/MachineOperand.h"
17*d415bd75Srobert #include "llvm/MC/MCExpr.h"
18*d415bd75Srobert #include "llvm/MC/MCInstrInfo.h"
19*d415bd75Srobert #include "llvm/MC/MCRegister.h"
20*d415bd75Srobert #include "llvm/MC/MCSymbol.h"
21*d415bd75Srobert #include "llvm/Support/Casting.h"
22*d415bd75Srobert #include "llvm/Support/raw_ostream.h"
23*d415bd75Srobert 
24*d415bd75Srobert using namespace llvm;
25*d415bd75Srobert 
26*d415bd75Srobert #define DEBUG_TYPE "asm-printer"
27*d415bd75Srobert 
28*d415bd75Srobert #include "XtensaGenAsmWriter.inc"
29*d415bd75Srobert 
printExpr(const MCExpr * Expr,raw_ostream & OS)30*d415bd75Srobert static void printExpr(const MCExpr *Expr, raw_ostream &OS) {
31*d415bd75Srobert   int Offset = 0;
32*d415bd75Srobert   const MCSymbolRefExpr *SRE;
33*d415bd75Srobert 
34*d415bd75Srobert   if (!(SRE = cast<MCSymbolRefExpr>(Expr)))
35*d415bd75Srobert     assert(false && "Unexpected MCExpr type.");
36*d415bd75Srobert 
37*d415bd75Srobert   MCSymbolRefExpr::VariantKind Kind = SRE->getKind();
38*d415bd75Srobert 
39*d415bd75Srobert   switch (Kind) {
40*d415bd75Srobert   case MCSymbolRefExpr::VK_None:
41*d415bd75Srobert     break;
42*d415bd75Srobert   // TODO
43*d415bd75Srobert   default:
44*d415bd75Srobert     report_fatal_error("Invalid kind!");
45*d415bd75Srobert   }
46*d415bd75Srobert 
47*d415bd75Srobert   OS << SRE->getSymbol();
48*d415bd75Srobert 
49*d415bd75Srobert   if (Offset) {
50*d415bd75Srobert     if (Offset > 0)
51*d415bd75Srobert       OS << '+';
52*d415bd75Srobert     OS << Offset;
53*d415bd75Srobert   }
54*d415bd75Srobert 
55*d415bd75Srobert   if (Kind != MCSymbolRefExpr::VK_None)
56*d415bd75Srobert     OS << ')';
57*d415bd75Srobert }
58*d415bd75Srobert 
printOperand(const MCOperand & MC,raw_ostream & O)59*d415bd75Srobert void XtensaInstPrinter::printOperand(const MCOperand &MC, raw_ostream &O) {
60*d415bd75Srobert   if (MC.isReg())
61*d415bd75Srobert     O << getRegisterName(MC.getReg());
62*d415bd75Srobert   else if (MC.isImm())
63*d415bd75Srobert     O << MC.getImm();
64*d415bd75Srobert   else if (MC.isExpr())
65*d415bd75Srobert     printExpr(MC.getExpr(), O);
66*d415bd75Srobert   else
67*d415bd75Srobert     report_fatal_error("Invalid operand");
68*d415bd75Srobert }
69*d415bd75Srobert 
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & O)70*d415bd75Srobert void XtensaInstPrinter::printInst(const MCInst *MI, uint64_t Address,
71*d415bd75Srobert                                   StringRef Annot, const MCSubtargetInfo &STI,
72*d415bd75Srobert                                   raw_ostream &O) {
73*d415bd75Srobert   printInstruction(MI, Address, O);
74*d415bd75Srobert   printAnnotation(O, Annot);
75*d415bd75Srobert }
76*d415bd75Srobert 
printRegName(raw_ostream & O,MCRegister Reg) const77*d415bd75Srobert void XtensaInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {
78*d415bd75Srobert   O << getRegisterName(Reg);
79*d415bd75Srobert }
80*d415bd75Srobert 
printOperand(const MCInst * MI,int OpNum,raw_ostream & O)81*d415bd75Srobert void XtensaInstPrinter::printOperand(const MCInst *MI, int OpNum,
82*d415bd75Srobert                                      raw_ostream &O) {
83*d415bd75Srobert   printOperand(MI->getOperand(OpNum), O);
84*d415bd75Srobert }
85*d415bd75Srobert 
printMemOperand(const MCInst * MI,int OpNum,raw_ostream & OS)86*d415bd75Srobert void XtensaInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
87*d415bd75Srobert                                         raw_ostream &OS) {
88*d415bd75Srobert   OS << getRegisterName(MI->getOperand(OpNum).getReg());
89*d415bd75Srobert   OS << ", ";
90*d415bd75Srobert   printOperand(MI, OpNum + 1, OS);
91*d415bd75Srobert }
92*d415bd75Srobert 
printBranchTarget(const MCInst * MI,int OpNum,raw_ostream & OS)93*d415bd75Srobert void XtensaInstPrinter::printBranchTarget(const MCInst *MI, int OpNum,
94*d415bd75Srobert                                           raw_ostream &OS) {
95*d415bd75Srobert   const MCOperand &MC = MI->getOperand(OpNum);
96*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
97*d415bd75Srobert     int64_t Val = MC.getImm() + 4;
98*d415bd75Srobert     OS << ". ";
99*d415bd75Srobert     if (Val > 0)
100*d415bd75Srobert       OS << '+';
101*d415bd75Srobert     OS << Val;
102*d415bd75Srobert   } else if (MC.isExpr())
103*d415bd75Srobert     MC.getExpr()->print(OS, &MAI, true);
104*d415bd75Srobert   else
105*d415bd75Srobert     llvm_unreachable("Invalid operand");
106*d415bd75Srobert }
107*d415bd75Srobert 
printJumpTarget(const MCInst * MI,int OpNum,raw_ostream & OS)108*d415bd75Srobert void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
109*d415bd75Srobert                                         raw_ostream &OS) {
110*d415bd75Srobert   const MCOperand &MC = MI->getOperand(OpNum);
111*d415bd75Srobert   if (MC.isImm()) {
112*d415bd75Srobert     int64_t Val = MC.getImm() + 4;
113*d415bd75Srobert     OS << ". ";
114*d415bd75Srobert     if (Val > 0)
115*d415bd75Srobert       OS << '+';
116*d415bd75Srobert     OS << Val;
117*d415bd75Srobert   } else if (MC.isExpr())
118*d415bd75Srobert     MC.getExpr()->print(OS, &MAI, true);
119*d415bd75Srobert   else
120*d415bd75Srobert     llvm_unreachable("Invalid operand");
121*d415bd75Srobert   ;
122*d415bd75Srobert }
123*d415bd75Srobert 
printCallOperand(const MCInst * MI,int OpNum,raw_ostream & OS)124*d415bd75Srobert void XtensaInstPrinter::printCallOperand(const MCInst *MI, int OpNum,
125*d415bd75Srobert                                          raw_ostream &OS) {
126*d415bd75Srobert   const MCOperand &MC = MI->getOperand(OpNum);
127*d415bd75Srobert   if (MC.isImm()) {
128*d415bd75Srobert     int64_t Val = MC.getImm() + 4;
129*d415bd75Srobert     OS << ". ";
130*d415bd75Srobert     if (Val > 0)
131*d415bd75Srobert       OS << '+';
132*d415bd75Srobert     OS << Val;
133*d415bd75Srobert   } else if (MC.isExpr())
134*d415bd75Srobert     MC.getExpr()->print(OS, &MAI, true);
135*d415bd75Srobert   else
136*d415bd75Srobert     llvm_unreachable("Invalid operand");
137*d415bd75Srobert }
138*d415bd75Srobert 
printL32RTarget(const MCInst * MI,int OpNum,raw_ostream & O)139*d415bd75Srobert void XtensaInstPrinter::printL32RTarget(const MCInst *MI, int OpNum,
140*d415bd75Srobert                                         raw_ostream &O) {
141*d415bd75Srobert   const MCOperand &MC = MI->getOperand(OpNum);
142*d415bd75Srobert   if (MC.isImm()) {
143*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
144*d415bd75Srobert     int64_t InstrOff = Value & 0x3;
145*d415bd75Srobert     Value -= InstrOff;
146*d415bd75Srobert     assert((Value >= -262144 && Value <= -4) &&
147*d415bd75Srobert            "Invalid argument, value must be in ranges [-262144,-4]");
148*d415bd75Srobert     Value += ((InstrOff + 0x3) & 0x4) - InstrOff;
149*d415bd75Srobert     O << ". ";
150*d415bd75Srobert     O << Value;
151*d415bd75Srobert   } else if (MC.isExpr())
152*d415bd75Srobert     MC.getExpr()->print(O, &MAI, true);
153*d415bd75Srobert   else
154*d415bd75Srobert     llvm_unreachable("Invalid operand");
155*d415bd75Srobert }
156*d415bd75Srobert 
printImm8_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)157*d415bd75Srobert void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum,
158*d415bd75Srobert                                              raw_ostream &O) {
159*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
160*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
161*d415bd75Srobert     assert(isInt<8>(Value) &&
162*d415bd75Srobert            "Invalid argument, value must be in ranges [-128,127]");
163*d415bd75Srobert     O << Value;
164*d415bd75Srobert   } else {
165*d415bd75Srobert     printOperand(MI, OpNum, O);
166*d415bd75Srobert   }
167*d415bd75Srobert }
168*d415bd75Srobert 
printImm8_sh8_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)169*d415bd75Srobert void XtensaInstPrinter::printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum,
170*d415bd75Srobert                                                  raw_ostream &O) {
171*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
172*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
173*d415bd75Srobert     assert((isInt<16>(Value) && ((Value & 0xFF) == 0)) &&
174*d415bd75Srobert            "Invalid argument, value must be multiples of 256 in range "
175*d415bd75Srobert            "[-32768,32512]");
176*d415bd75Srobert     O << Value;
177*d415bd75Srobert   } else
178*d415bd75Srobert     printOperand(MI, OpNum, O);
179*d415bd75Srobert }
180*d415bd75Srobert 
printImm12_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)181*d415bd75Srobert void XtensaInstPrinter::printImm12_AsmOperand(const MCInst *MI, int OpNum,
182*d415bd75Srobert                                               raw_ostream &O) {
183*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
184*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
185*d415bd75Srobert     assert((Value >= -2048 && Value <= 2047) &&
186*d415bd75Srobert            "Invalid argument, value must be in ranges [-2048,2047]");
187*d415bd75Srobert     O << Value;
188*d415bd75Srobert   } else
189*d415bd75Srobert     printOperand(MI, OpNum, O);
190*d415bd75Srobert }
191*d415bd75Srobert 
printImm12m_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)192*d415bd75Srobert void XtensaInstPrinter::printImm12m_AsmOperand(const MCInst *MI, int OpNum,
193*d415bd75Srobert                                                raw_ostream &O) {
194*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
195*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
196*d415bd75Srobert     assert((Value >= -2048 && Value <= 2047) &&
197*d415bd75Srobert            "Invalid argument, value must be in ranges [-2048,2047]");
198*d415bd75Srobert     O << Value;
199*d415bd75Srobert   } else
200*d415bd75Srobert     printOperand(MI, OpNum, O);
201*d415bd75Srobert }
202*d415bd75Srobert 
printUimm4_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)203*d415bd75Srobert void XtensaInstPrinter::printUimm4_AsmOperand(const MCInst *MI, int OpNum,
204*d415bd75Srobert                                               raw_ostream &O) {
205*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
206*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
207*d415bd75Srobert     assert((Value >= 0 && Value <= 15) && "Invalid argument");
208*d415bd75Srobert     O << Value;
209*d415bd75Srobert   } else
210*d415bd75Srobert     printOperand(MI, OpNum, O);
211*d415bd75Srobert }
212*d415bd75Srobert 
printUimm5_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)213*d415bd75Srobert void XtensaInstPrinter::printUimm5_AsmOperand(const MCInst *MI, int OpNum,
214*d415bd75Srobert                                               raw_ostream &O) {
215*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
216*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
217*d415bd75Srobert     assert((Value >= 0 && Value <= 31) && "Invalid argument");
218*d415bd75Srobert     O << Value;
219*d415bd75Srobert   } else
220*d415bd75Srobert     printOperand(MI, OpNum, O);
221*d415bd75Srobert }
222*d415bd75Srobert 
printShimm1_31_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)223*d415bd75Srobert void XtensaInstPrinter::printShimm1_31_AsmOperand(const MCInst *MI, int OpNum,
224*d415bd75Srobert                                                   raw_ostream &O) {
225*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
226*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
227*d415bd75Srobert     assert((Value >= 1 && Value <= 31) &&
228*d415bd75Srobert            "Invalid argument, value must be in range [1,31]");
229*d415bd75Srobert     O << Value;
230*d415bd75Srobert   } else
231*d415bd75Srobert     printOperand(MI, OpNum, O);
232*d415bd75Srobert }
233*d415bd75Srobert 
printImm1_16_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)234*d415bd75Srobert void XtensaInstPrinter::printImm1_16_AsmOperand(const MCInst *MI, int OpNum,
235*d415bd75Srobert                                                 raw_ostream &O) {
236*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
237*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
238*d415bd75Srobert     assert((Value >= 1 && Value <= 16) &&
239*d415bd75Srobert            "Invalid argument, value must be in range [1,16]");
240*d415bd75Srobert     O << Value;
241*d415bd75Srobert   } else
242*d415bd75Srobert     printOperand(MI, OpNum, O);
243*d415bd75Srobert }
244*d415bd75Srobert 
printOffset8m8_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)245*d415bd75Srobert void XtensaInstPrinter::printOffset8m8_AsmOperand(const MCInst *MI, int OpNum,
246*d415bd75Srobert                                                   raw_ostream &O) {
247*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
248*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
249*d415bd75Srobert     assert((Value >= 0 && Value <= 255) &&
250*d415bd75Srobert            "Invalid argument, value must be in range [0,255]");
251*d415bd75Srobert     O << Value;
252*d415bd75Srobert   } else
253*d415bd75Srobert     printOperand(MI, OpNum, O);
254*d415bd75Srobert }
255*d415bd75Srobert 
printOffset8m16_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)256*d415bd75Srobert void XtensaInstPrinter::printOffset8m16_AsmOperand(const MCInst *MI, int OpNum,
257*d415bd75Srobert                                                    raw_ostream &O) {
258*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
259*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
260*d415bd75Srobert     assert((Value >= 0 && Value <= 510 && ((Value & 0x1) == 0)) &&
261*d415bd75Srobert            "Invalid argument, value must be multiples of two in range [0,510]");
262*d415bd75Srobert     O << Value;
263*d415bd75Srobert   } else
264*d415bd75Srobert     printOperand(MI, OpNum, O);
265*d415bd75Srobert }
266*d415bd75Srobert 
printOffset8m32_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)267*d415bd75Srobert void XtensaInstPrinter::printOffset8m32_AsmOperand(const MCInst *MI, int OpNum,
268*d415bd75Srobert                                                    raw_ostream &O) {
269*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
270*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
271*d415bd75Srobert     assert(
272*d415bd75Srobert         (Value >= 0 && Value <= 1020 && ((Value & 0x3) == 0)) &&
273*d415bd75Srobert         "Invalid argument, value must be multiples of four in range [0,1020]");
274*d415bd75Srobert     O << Value;
275*d415bd75Srobert   } else
276*d415bd75Srobert     printOperand(MI, OpNum, O);
277*d415bd75Srobert }
278*d415bd75Srobert 
printOffset4m32_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)279*d415bd75Srobert void XtensaInstPrinter::printOffset4m32_AsmOperand(const MCInst *MI, int OpNum,
280*d415bd75Srobert                                                    raw_ostream &O) {
281*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
282*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
283*d415bd75Srobert     assert((Value >= 0 && Value <= 60 && ((Value & 0x3) == 0)) &&
284*d415bd75Srobert            "Invalid argument, value must be multiples of four in range [0,60]");
285*d415bd75Srobert     O << Value;
286*d415bd75Srobert   } else
287*d415bd75Srobert     printOperand(MI, OpNum, O);
288*d415bd75Srobert }
289*d415bd75Srobert 
printB4const_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)290*d415bd75Srobert void XtensaInstPrinter::printB4const_AsmOperand(const MCInst *MI, int OpNum,
291*d415bd75Srobert                                                 raw_ostream &O) {
292*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
293*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
294*d415bd75Srobert 
295*d415bd75Srobert     switch (Value) {
296*d415bd75Srobert     case -1:
297*d415bd75Srobert     case 1:
298*d415bd75Srobert     case 2:
299*d415bd75Srobert     case 3:
300*d415bd75Srobert     case 4:
301*d415bd75Srobert     case 5:
302*d415bd75Srobert     case 6:
303*d415bd75Srobert     case 7:
304*d415bd75Srobert     case 8:
305*d415bd75Srobert     case 10:
306*d415bd75Srobert     case 12:
307*d415bd75Srobert     case 16:
308*d415bd75Srobert     case 32:
309*d415bd75Srobert     case 64:
310*d415bd75Srobert     case 128:
311*d415bd75Srobert     case 256:
312*d415bd75Srobert       break;
313*d415bd75Srobert     default:
314*d415bd75Srobert       assert((0) && "Invalid B4const argument");
315*d415bd75Srobert     }
316*d415bd75Srobert     O << Value;
317*d415bd75Srobert   } else
318*d415bd75Srobert     printOperand(MI, OpNum, O);
319*d415bd75Srobert }
320*d415bd75Srobert 
printB4constu_AsmOperand(const MCInst * MI,int OpNum,raw_ostream & O)321*d415bd75Srobert void XtensaInstPrinter::printB4constu_AsmOperand(const MCInst *MI, int OpNum,
322*d415bd75Srobert                                                  raw_ostream &O) {
323*d415bd75Srobert   if (MI->getOperand(OpNum).isImm()) {
324*d415bd75Srobert     int64_t Value = MI->getOperand(OpNum).getImm();
325*d415bd75Srobert 
326*d415bd75Srobert     switch (Value) {
327*d415bd75Srobert     case 32768:
328*d415bd75Srobert     case 65536:
329*d415bd75Srobert     case 2:
330*d415bd75Srobert     case 3:
331*d415bd75Srobert     case 4:
332*d415bd75Srobert     case 5:
333*d415bd75Srobert     case 6:
334*d415bd75Srobert     case 7:
335*d415bd75Srobert     case 8:
336*d415bd75Srobert     case 10:
337*d415bd75Srobert     case 12:
338*d415bd75Srobert     case 16:
339*d415bd75Srobert     case 32:
340*d415bd75Srobert     case 64:
341*d415bd75Srobert     case 128:
342*d415bd75Srobert     case 256:
343*d415bd75Srobert       break;
344*d415bd75Srobert     default:
345*d415bd75Srobert       assert((0) && "Invalid B4constu argument");
346*d415bd75Srobert     }
347*d415bd75Srobert     O << Value;
348*d415bd75Srobert   } else
349*d415bd75Srobert     printOperand(MI, OpNum, O);
350*d415bd75Srobert }
351