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 "BPF.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/Casting.h" 20 #include "llvm/Support/ErrorHandling.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, uint64_t Address, 29 StringRef Annot, const MCSubtargetInfo &STI, 30 raw_ostream &O) { 31 printInstruction(MI, Address, O); 32 printAnnotation(O, Annot); 33 } 34 35 void BPFInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 36 raw_ostream &O) { 37 const MCOperand &Op = MI->getOperand(OpNo); 38 if (Op.isReg()) { 39 O << getRegisterName(Op.getReg()); 40 } else if (Op.isImm()) { 41 O << formatImm((int32_t)Op.getImm()); 42 } else { 43 assert(Op.isExpr() && "Expected an expression"); 44 MAI.printExpr(O, *Op.getExpr()); 45 } 46 } 47 48 void BPFInstPrinter::printMemOperand(const MCInst *MI, int OpNo, 49 raw_ostream &O) { 50 const MCOperand &RegOp = MI->getOperand(OpNo); 51 const MCOperand &OffsetOp = MI->getOperand(OpNo + 1); 52 53 // register 54 assert(RegOp.isReg() && "Register operand not a register"); 55 O << getRegisterName(RegOp.getReg()); 56 57 // offset 58 if (OffsetOp.isImm()) { 59 auto Imm = OffsetOp.getImm(); 60 if (Imm >= 0) 61 O << " + " << formatImm(Imm); 62 else 63 O << " - " << formatImm(-Imm); 64 } else { 65 assert(0 && "Expected an immediate"); 66 } 67 } 68 69 void BPFInstPrinter::printImm64Operand(const MCInst *MI, unsigned OpNo, 70 raw_ostream &O) { 71 const MCOperand &Op = MI->getOperand(OpNo); 72 if (Op.isImm()) 73 O << formatImm(Op.getImm()); 74 else if (Op.isExpr()) 75 MAI.printExpr(O, *Op.getExpr()); 76 else 77 O << Op; 78 } 79 80 void BPFInstPrinter::printBrTargetOperand(const MCInst *MI, unsigned OpNo, 81 raw_ostream &O) { 82 const MCOperand &Op = MI->getOperand(OpNo); 83 if (Op.isImm()) { 84 if (MI->getOpcode() == BPF::JMPL) { 85 int32_t Imm = Op.getImm(); 86 O << ((Imm >= 0) ? "+" : "") << formatImm(Imm); 87 } else { 88 int16_t Imm = Op.getImm(); 89 O << ((Imm >= 0) ? "+" : "") << formatImm(Imm); 90 } 91 } else if (Op.isExpr()) { 92 MAI.printExpr(O, *Op.getExpr()); 93 } else { 94 O << Op; 95 } 96 } 97