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