xref: /freebsd/contrib/llvm-project/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.cpp (revision 6966ac055c3b7a39266fb982493330df7a097997)
1 //===-- BPFInstPrinter.cpp - Convert BPF MCInst to asm syntax -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class prints an BPF MCInst to a .s file.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MCTargetDesc/BPFInstPrinter.h"
14 #include "llvm/MC/MCAsmInfo.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCSymbol.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Support/FormattedStream.h"
20 using namespace llvm;
21 
22 #define DEBUG_TYPE "asm-printer"
23 
24 // Include the auto-generated portion of the assembly writer.
25 #include "BPFGenAsmWriter.inc"
26 
27 void BPFInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
28                                StringRef Annot, const MCSubtargetInfo &STI) {
29   printInstruction(MI, O);
30   printAnnotation(O, Annot);
31 }
32 
33 static void printExpr(const MCExpr *Expr, raw_ostream &O) {
34 #ifndef NDEBUG
35   const MCSymbolRefExpr *SRE;
36 
37   if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr))
38     SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
39   else
40     SRE = dyn_cast<MCSymbolRefExpr>(Expr);
41   assert(SRE && "Unexpected MCExpr type.");
42 
43   MCSymbolRefExpr::VariantKind Kind = SRE->getKind();
44 
45   assert(Kind == MCSymbolRefExpr::VK_None);
46 #endif
47   O << *Expr;
48 }
49 
50 void BPFInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
51                                   raw_ostream &O, const char *Modifier) {
52   assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
53   const MCOperand &Op = MI->getOperand(OpNo);
54   if (Op.isReg()) {
55     O << getRegisterName(Op.getReg());
56   } else if (Op.isImm()) {
57     O << formatImm((int32_t)Op.getImm());
58   } else {
59     assert(Op.isExpr() && "Expected an expression");
60     printExpr(Op.getExpr(), O);
61   }
62 }
63 
64 void BPFInstPrinter::printMemOperand(const MCInst *MI, int OpNo, raw_ostream &O,
65                                      const char *Modifier) {
66   const MCOperand &RegOp = MI->getOperand(OpNo);
67   const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
68 
69   // register
70   assert(RegOp.isReg() && "Register operand not a register");
71   O << getRegisterName(RegOp.getReg());
72 
73   // offset
74   if (OffsetOp.isImm()) {
75     auto Imm = OffsetOp.getImm();
76     if (Imm >= 0)
77       O << " + " << formatImm(Imm);
78     else
79       O << " - " << formatImm(-Imm);
80   } else {
81     assert(0 && "Expected an immediate");
82   }
83 }
84 
85 void BPFInstPrinter::printImm64Operand(const MCInst *MI, unsigned OpNo,
86                                        raw_ostream &O) {
87   const MCOperand &Op = MI->getOperand(OpNo);
88   if (Op.isImm())
89     O << formatImm(Op.getImm());
90   else if (Op.isExpr())
91     printExpr(Op.getExpr(), O);
92   else
93     O << Op;
94 }
95 
96 void BPFInstPrinter::printBrTargetOperand(const MCInst *MI, unsigned OpNo,
97                                        raw_ostream &O) {
98   const MCOperand &Op = MI->getOperand(OpNo);
99   if (Op.isImm()) {
100     int16_t Imm = Op.getImm();
101     O << ((Imm >= 0) ? "+" : "") << formatImm(Imm);
102   } else if (Op.isExpr()) {
103     printExpr(Op.getExpr(), O);
104   } else {
105     O << Op;
106   }
107 }
108