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/Casting.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/Support/FormattedStream.h" 21 using namespace llvm; 22 23 #define DEBUG_TYPE "asm-printer" 24 25 // Include the auto-generated portion of the assembly writer. 26 #include "BPFGenAsmWriter.inc" 27 28 void BPFInstPrinter::printInst(const MCInst *MI, uint64_t Address, 29 StringRef Annot, const MCSubtargetInfo &STI, 30 raw_ostream &O) { 31 printInstruction(MI, Address, O); 32 printAnnotation(O, Annot); 33 } 34 35 static void printExpr(const MCExpr *Expr, raw_ostream &O) { 36 #ifndef NDEBUG 37 const MCSymbolRefExpr *SRE; 38 39 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) 40 SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS()); 41 else 42 SRE = dyn_cast<MCSymbolRefExpr>(Expr); 43 assert(SRE && "Unexpected MCExpr type."); 44 45 MCSymbolRefExpr::VariantKind Kind = SRE->getKind(); 46 47 assert(Kind == MCSymbolRefExpr::VK_None); 48 #endif 49 O << *Expr; 50 } 51 52 void BPFInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 53 raw_ostream &O, const char *Modifier) { 54 assert((Modifier == nullptr || Modifier[0] == 0) && "No modifiers supported"); 55 const MCOperand &Op = MI->getOperand(OpNo); 56 if (Op.isReg()) { 57 O << getRegisterName(Op.getReg()); 58 } else if (Op.isImm()) { 59 O << formatImm((int32_t)Op.getImm()); 60 } else { 61 assert(Op.isExpr() && "Expected an expression"); 62 printExpr(Op.getExpr(), O); 63 } 64 } 65 66 void BPFInstPrinter::printMemOperand(const MCInst *MI, int OpNo, raw_ostream &O, 67 const char *Modifier) { 68 const MCOperand &RegOp = MI->getOperand(OpNo); 69 const MCOperand &OffsetOp = MI->getOperand(OpNo + 1); 70 71 // register 72 assert(RegOp.isReg() && "Register operand not a register"); 73 O << getRegisterName(RegOp.getReg()); 74 75 // offset 76 if (OffsetOp.isImm()) { 77 auto Imm = OffsetOp.getImm(); 78 if (Imm >= 0) 79 O << " + " << formatImm(Imm); 80 else 81 O << " - " << formatImm(-Imm); 82 } else { 83 assert(0 && "Expected an immediate"); 84 } 85 } 86 87 void BPFInstPrinter::printImm64Operand(const MCInst *MI, unsigned OpNo, 88 raw_ostream &O) { 89 const MCOperand &Op = MI->getOperand(OpNo); 90 if (Op.isImm()) 91 O << formatImm(Op.getImm()); 92 else if (Op.isExpr()) 93 printExpr(Op.getExpr(), O); 94 else 95 O << Op; 96 } 97 98 void BPFInstPrinter::printBrTargetOperand(const MCInst *MI, unsigned OpNo, 99 raw_ostream &O) { 100 const MCOperand &Op = MI->getOperand(OpNo); 101 if (Op.isImm()) { 102 int16_t Imm = Op.getImm(); 103 O << ((Imm >= 0) ? "+" : "") << formatImm(Imm); 104 } else if (Op.isExpr()) { 105 printExpr(Op.getExpr(), O); 106 } else { 107 O << Op; 108 } 109 } 110