1283625Sdim//===-- BPFAsmPrinter.cpp - BPF LLVM assembly writer ----------------------===// 2283625Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6283625Sdim// 7283625Sdim//===----------------------------------------------------------------------===// 8283625Sdim// 9283625Sdim// This file contains a printer that converts from our internal representation 10283625Sdim// of machine-dependent LLVM code to the BPF assembly language. 11283625Sdim// 12283625Sdim//===----------------------------------------------------------------------===// 13283625Sdim 14283625Sdim#include "BPF.h" 15283625Sdim#include "BPFInstrInfo.h" 16283625Sdim#include "BPFMCInstLower.h" 17283625Sdim#include "BPFTargetMachine.h" 18344779Sdim#include "BTFDebug.h" 19353358Sdim#include "MCTargetDesc/BPFInstPrinter.h" 20353358Sdim#include "TargetInfo/BPFTargetInfo.h" 21283625Sdim#include "llvm/CodeGen/AsmPrinter.h" 22321369Sdim#include "llvm/CodeGen/MachineConstantPool.h" 23283625Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 24283625Sdim#include "llvm/CodeGen/MachineInstr.h" 25321369Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 26283625Sdim#include "llvm/MC/MCAsmInfo.h" 27283625Sdim#include "llvm/MC/MCInst.h" 28283625Sdim#include "llvm/MC/MCStreamer.h" 29283625Sdim#include "llvm/MC/MCSymbol.h" 30283625Sdim#include "llvm/Support/TargetRegistry.h" 31283625Sdim#include "llvm/Support/raw_ostream.h" 32283625Sdimusing namespace llvm; 33283625Sdim 34283625Sdim#define DEBUG_TYPE "asm-printer" 35283625Sdim 36283625Sdimnamespace { 37283625Sdimclass BPFAsmPrinter : public AsmPrinter { 38283625Sdimpublic: 39321369Sdim explicit BPFAsmPrinter(TargetMachine &TM, 40321369Sdim std::unique_ptr<MCStreamer> Streamer) 41353358Sdim : AsmPrinter(TM, std::move(Streamer)), BTF(nullptr) {} 42283625Sdim 43314564Sdim StringRef getPassName() const override { return "BPF Assembly Printer"; } 44344779Sdim bool doInitialization(Module &M) override; 45327952Sdim void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O); 46327952Sdim bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 47353358Sdim const char *ExtraCode, raw_ostream &O) override; 48327952Sdim bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, 49353358Sdim const char *ExtraCode, raw_ostream &O) override; 50283625Sdim 51283625Sdim void EmitInstruction(const MachineInstr *MI) override; 52353358Sdim 53353358Sdimprivate: 54353358Sdim BTFDebug *BTF; 55283625Sdim}; 56321369Sdim} // namespace 57283625Sdim 58344779Sdimbool BPFAsmPrinter::doInitialization(Module &M) { 59344779Sdim AsmPrinter::doInitialization(M); 60344779Sdim 61353358Sdim // Only emit BTF when debuginfo available. 62360784Sdim if (MAI->doesSupportDebugInformation() && !M.debug_compile_units().empty()) { 63353358Sdim BTF = new BTFDebug(this); 64353358Sdim Handlers.push_back(HandlerInfo(std::unique_ptr<BTFDebug>(BTF), "emit", 65344779Sdim "Debug Info Emission", "BTF", 66344779Sdim "BTF Emission")); 67344779Sdim } 68344779Sdim 69344779Sdim return false; 70344779Sdim} 71344779Sdim 72327952Sdimvoid BPFAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 73327952Sdim raw_ostream &O) { 74327952Sdim const MachineOperand &MO = MI->getOperand(OpNum); 75327952Sdim 76327952Sdim switch (MO.getType()) { 77327952Sdim case MachineOperand::MO_Register: 78327952Sdim O << BPFInstPrinter::getRegisterName(MO.getReg()); 79327952Sdim break; 80327952Sdim 81327952Sdim case MachineOperand::MO_Immediate: 82327952Sdim O << MO.getImm(); 83327952Sdim break; 84327952Sdim 85327952Sdim case MachineOperand::MO_MachineBasicBlock: 86327952Sdim O << *MO.getMBB()->getSymbol(); 87327952Sdim break; 88327952Sdim 89327952Sdim case MachineOperand::MO_GlobalAddress: 90327952Sdim O << *getSymbol(MO.getGlobal()); 91327952Sdim break; 92327952Sdim 93327952Sdim case MachineOperand::MO_BlockAddress: { 94327952Sdim MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); 95327952Sdim O << BA->getName(); 96327952Sdim break; 97327952Sdim } 98327952Sdim 99327952Sdim case MachineOperand::MO_ExternalSymbol: 100327952Sdim O << *GetExternalSymbolSymbol(MO.getSymbolName()); 101327952Sdim break; 102327952Sdim 103327952Sdim case MachineOperand::MO_JumpTableIndex: 104327952Sdim case MachineOperand::MO_ConstantPoolIndex: 105327952Sdim default: 106327952Sdim llvm_unreachable("<unknown operand type>"); 107327952Sdim } 108327952Sdim} 109327952Sdim 110327952Sdimbool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 111327952Sdim const char *ExtraCode, raw_ostream &O) { 112327952Sdim if (ExtraCode && ExtraCode[0]) 113353358Sdim return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); 114327952Sdim 115327952Sdim printOperand(MI, OpNo, O); 116327952Sdim return false; 117327952Sdim} 118327952Sdim 119327952Sdimbool BPFAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 120353358Sdim unsigned OpNum, const char *ExtraCode, 121327952Sdim raw_ostream &O) { 122327952Sdim assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands"); 123327952Sdim const MachineOperand &BaseMO = MI->getOperand(OpNum); 124327952Sdim const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1); 125327952Sdim assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand."); 126327952Sdim assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand."); 127327952Sdim int Offset = OffsetMO.getImm(); 128327952Sdim 129327952Sdim if (ExtraCode) 130327952Sdim return true; // Unknown modifier. 131327952Sdim 132327952Sdim if (Offset < 0) 133327952Sdim O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " - " << -Offset << ")"; 134327952Sdim else 135327952Sdim O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " + " << Offset << ")"; 136327952Sdim 137327952Sdim return false; 138327952Sdim} 139327952Sdim 140283625Sdimvoid BPFAsmPrinter::EmitInstruction(const MachineInstr *MI) { 141353358Sdim MCInst TmpInst; 142283625Sdim 143353358Sdim if (!BTF || !BTF->InstLower(MI, TmpInst)) { 144353358Sdim BPFMCInstLower MCInstLowering(OutContext, *this); 145353358Sdim MCInstLowering.Lower(MI, TmpInst); 146353358Sdim } 147283625Sdim EmitToStreamer(*OutStreamer, TmpInst); 148283625Sdim} 149283625Sdim 150283625Sdim// Force static initialization. 151360784Sdimextern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFAsmPrinter() { 152314564Sdim RegisterAsmPrinter<BPFAsmPrinter> X(getTheBPFleTarget()); 153314564Sdim RegisterAsmPrinter<BPFAsmPrinter> Y(getTheBPFbeTarget()); 154314564Sdim RegisterAsmPrinter<BPFAsmPrinter> Z(getTheBPFTarget()); 155283625Sdim} 156