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 "llvm/MC/MCAsmInfo.h" 16 #include "llvm/MC/MCExpr.h" 17 #include "llvm/MC/MCInst.h" 18 #include "llvm/MC/MCSymbol.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, raw_ostream &O, 29 StringRef Annot, const MCSubtargetInfo &STI) { 30 printInstruction(MI, 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