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