LLVM 20.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"
31using namespace llvm;
32
33#define DEBUG_TYPE "asm-printer"
34
35namespace {
36class BPFAsmPrinter : public AsmPrinter {
37public:
38 explicit BPFAsmPrinter(TargetMachine &TM,
39 std::unique_ptr<MCStreamer> Streamer)
40 : AsmPrinter(TM, std::move(Streamer)), BTF(nullptr) {}
41
42 StringRef getPassName() const override { return "BPF Assembly Printer"; }
43 bool doInitialization(Module &M) override;
44 void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
45 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
46 const char *ExtraCode, raw_ostream &O) override;
47 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
48 const char *ExtraCode, raw_ostream &O) override;
49
50 void emitInstruction(const MachineInstr *MI) override;
51
52private:
53 BTFDebug *BTF;
54};
55} // namespace
56
57bool BPFAsmPrinter::doInitialization(Module &M) {
59
60 // Only emit BTF when debuginfo available.
61 if (MAI->doesSupportDebugInformation() && !M.debug_compile_units().empty()) {
62 BTF = new BTFDebug(this);
63 DebugHandlers.push_back(std::unique_ptr<BTFDebug>(BTF));
64 }
65
66 return false;
67}
68
69void BPFAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
70 raw_ostream &O) {
71 const MachineOperand &MO = MI->getOperand(OpNum);
72
73 switch (MO.getType()) {
76 break;
77
79 O << MO.getImm();
80 break;
81
83 O << *MO.getMBB()->getSymbol();
84 break;
85
87 O << *getSymbol(MO.getGlobal());
88 break;
89
91 MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress());
92 O << BA->getName();
93 break;
94 }
95
97 O << *GetExternalSymbolSymbol(MO.getSymbolName());
98 break;
99
102 default:
103 llvm_unreachable("<unknown operand type>");
104 }
105}
106
107bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
108 const char *ExtraCode, raw_ostream &O) {
109 if (ExtraCode && ExtraCode[0])
110 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
111
112 printOperand(MI, OpNo, O);
113 return false;
114}
115
116bool BPFAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
117 unsigned OpNum, const char *ExtraCode,
118 raw_ostream &O) {
119 assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
120 const MachineOperand &BaseMO = MI->getOperand(OpNum);
121 const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
122 assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
123 assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
124 int Offset = OffsetMO.getImm();
125
126 if (ExtraCode)
127 return true; // Unknown modifier.
128
129 if (Offset < 0)
130 O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " - " << -Offset << ")";
131 else
132 O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " + " << Offset << ")";
133
134 return false;
135}
136
137void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
138 BPF_MC::verifyInstructionPredicates(MI->getOpcode(),
139 getSubtargetInfo().getFeatureBits());
140
141 MCInst TmpInst;
142
143 if (!BTF || !BTF->InstLower(MI, TmpInst)) {
144 BPFMCInstLower MCInstLowering(OutContext, *this);
145 MCInstLowering.Lower(MI, TmpInst);
146 }
147 EmitToStreamer(*OutStreamer, TmpInst);
148}
149
150// Force static initialization.
155}
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFAsmPrinter()
This file contains support for writing BTF debug info.
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:128
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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 ...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:86
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
Definition: AsmPrinter.h:561
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
Definition: AsmPrinter.cpp:459
virtual bool PrintAsmMemoryOperand(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 as...
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
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
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:65
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
Target & getTheBPFleTarget()
Target & getTheBPFbeTarget()
Target & getTheBPFTarget()
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...