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