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 "BPFInstPrinter.h" 15 #include "BPF.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 << 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