LLVM 22.0.0git
BPFAsmPrinter.cpp
Go to the documentation of this file.
1//===-- BPFAsmPrinter.cpp - BPF LLVM assembly writer ----------------------===//
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 file contains a printer that converts from our internal representation
10// of machine-dependent LLVM code to the BPF assembly language.
11//
12//===----------------------------------------------------------------------===//
13
14#include "BPF.h"
15#include "BPFInstrInfo.h"
16#include "BPFMCInstLower.h"
17#include "BTFDebug.h"
24#include "llvm/IR/Module.h"
25#include "llvm/MC/MCAsmInfo.h"
26#include "llvm/MC/MCInst.h"
27#include "llvm/MC/MCStreamer.h"
28#include "llvm/MC/MCSymbol.h"
32using namespace llvm;
33
34#define DEBUG_TYPE "asm-printer"
35
36namespace {
37class BPFAsmPrinter : public AsmPrinter {
38public:
39 explicit BPFAsmPrinter(TargetMachine &TM,
40 std::unique_ptr<MCStreamer> Streamer)
41 : AsmPrinter(TM, std::move(Streamer), ID), BTF(nullptr) {}
42
43 StringRef getPassName() const override { return "BPF Assembly Printer"; }
44 bool doInitialization(Module &M) override;
45 void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
46 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
47 const char *ExtraCode, raw_ostream &O) override;
48 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
49 const char *ExtraCode, raw_ostream &O) override;
50
51 void emitInstruction(const MachineInstr *MI) override;
52
53 static char ID;
54
55private:
57};
58} // namespace
59
60bool BPFAsmPrinter::doInitialization(Module &M) {
62
63 // Only emit BTF when debuginfo available.
64 if (MAI->doesSupportDebugInformation() && !M.debug_compile_units().empty()) {
65 BTF = new BTFDebug(this);
66 Handlers.push_back(std::unique_ptr<BTFDebug>(BTF));
67 }
68
69 return false;
70}
71
72void BPFAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
73 raw_ostream &O) {
74 const MachineOperand &MO = MI->getOperand(OpNum);
75
76 switch (MO.getType()) {
79 break;
80
82 O << MO.getImm();
83 break;
84
86 O << *MO.getMBB()->getSymbol();
87 break;
88
90 O << *getSymbol(MO.getGlobal());
91 break;
92
94 MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress());
95 O << BA->getName();
96 break;
97 }
98
100 O << *GetExternalSymbolSymbol(MO.getSymbolName());
101 break;
102
105 default:
106 llvm_unreachable("<unknown operand type>");
107 }
108}
109
110bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
111 const char *ExtraCode, raw_ostream &O) {
112 if (ExtraCode && ExtraCode[0])
113 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
114
115 printOperand(MI, OpNo, O);
116 return false;
117}
118
119bool BPFAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
120 unsigned OpNum, const char *ExtraCode,
121 raw_ostream &O) {
122 assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
123 const MachineOperand &BaseMO = MI->getOperand(OpNum);
124 const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
125 assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
126 assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
127 int Offset = OffsetMO.getImm();
128
129 if (ExtraCode)
130 return true; // Unknown modifier.
131
132 if (Offset < 0)
133 O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " - " << -Offset << ")";
134 else
135 O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " + " << Offset << ")";
136
137 return false;
138}
139
140void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
141 BPF_MC::verifyInstructionPredicates(MI->getOpcode(),
142 getSubtargetInfo().getFeatureBits());
143
144 MCInst TmpInst;
145
146 if (!BTF || !BTF->InstLower(MI, TmpInst)) {
147 BPFMCInstLower MCInstLowering(OutContext, *this);
148 MCInstLowering.Lower(MI, TmpInst);
149 }
150 EmitToStreamer(*OutStreamer, TmpInst);
151}
152
153char BPFAsmPrinter::ID = 0;
154
155INITIALIZE_PASS(BPFAsmPrinter, "bpf-asm-printer", "BPF Assembly Printer", false,
156 false)
157
158// Force static initialization.
160LLVMInitializeBPFAsmPrinter() {
164}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains support for writing BTF debug info.
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This class is intended to be used as a driving class for all asm writers.
Definition AsmPrinter.h:90
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
static const char * getRegisterName(MCRegister Reg)
Collect and emit BTF information.
Definition BTFDebug.h:289
bool InstLower(const MachineInstr *MI, MCInst &OutMI)
Emit proper patchable instructions.
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Representation of each machine instruction.
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const BlockAddress * getBlockAddress() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Primary interface to the complete machine description for the target machine.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
Target & getTheBPFleTarget()
Target & getTheBPFbeTarget()
Target & getTheBPFTarget()
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...