1 //===-- BPFInstPrinter.cpp - Convert BPF MCInst to asm syntax -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This class prints an BPF MCInst to a .s file. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "BPF.h" 15 #include "BPFInstPrinter.h" 16 #include "llvm/MC/MCAsmInfo.h" 17 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCSymbol.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, raw_ostream &O, 30 StringRef Annot, const MCSubtargetInfo &STI) { 31 printInstruction(MI, 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 == 0 || 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 << (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 // offset 71 if (OffsetOp.isImm()) 72 O << formatDec(OffsetOp.getImm()); 73 else 74 assert(0 && "Expected an immediate"); 75 76 // register 77 assert(RegOp.isReg() && "Register operand not a register"); 78 O << '(' << getRegisterName(RegOp.getReg()) << ')'; 79 } 80 81 void BPFInstPrinter::printImm64Operand(const MCInst *MI, unsigned OpNo, 82 raw_ostream &O) { 83 const MCOperand &Op = MI->getOperand(OpNo); 84 if (Op.isImm()) 85 O << (uint64_t)Op.getImm(); 86 else 87 O << Op; 88 } 89