1 //===-- BPFAsmPrinter.cpp - BPF LLVM assembly writer ----------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains a printer that converts from our internal representation
10 // of machine-dependent LLVM code to the BPF assembly language.
12 //===----------------------------------------------------------------------===//
15 #include "BPFInstrInfo.h"
16 #include "BPFMCInstLower.h"
17 #include "BPFTargetMachine.h"
19 #include "MCTargetDesc/BPFInstPrinter.h"
20 #include "TargetInfo/BPFTargetInfo.h"
21 #include "llvm/CodeGen/AsmPrinter.h"
22 #include "llvm/CodeGen/MachineConstantPool.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstr.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h"
26 #include "llvm/MC/MCAsmInfo.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/Support/TargetRegistry.h"
31 #include "llvm/Support/raw_ostream.h"
34 #define DEBUG_TYPE "asm-printer"
37 class BPFAsmPrinter
: public AsmPrinter
{
39 explicit BPFAsmPrinter(TargetMachine
&TM
,
40 std::unique_ptr
<MCStreamer
> Streamer
)
41 : AsmPrinter(TM
, std::move(Streamer
)), BTF(nullptr) {}
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
;
51 void EmitInstruction(const MachineInstr
*MI
) override
;
58 bool BPFAsmPrinter::doInitialization(Module
&M
) {
59 AsmPrinter::doInitialization(M
);
61 // Only emit BTF when debuginfo available.
62 if (MAI
->doesSupportDebugInformation() && !M
.debug_compile_units().empty()) {
63 BTF
= new BTFDebug(this);
64 Handlers
.push_back(HandlerInfo(std::unique_ptr
<BTFDebug
>(BTF
), "emit",
65 "Debug Info Emission", "BTF",
72 void BPFAsmPrinter::printOperand(const MachineInstr
*MI
, int OpNum
,
74 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
76 switch (MO
.getType()) {
77 case MachineOperand::MO_Register
:
78 O
<< BPFInstPrinter::getRegisterName(MO
.getReg());
81 case MachineOperand::MO_Immediate
:
85 case MachineOperand::MO_MachineBasicBlock
:
86 O
<< *MO
.getMBB()->getSymbol();
89 case MachineOperand::MO_GlobalAddress
:
90 O
<< *getSymbol(MO
.getGlobal());
93 case MachineOperand::MO_BlockAddress
: {
94 MCSymbol
*BA
= GetBlockAddressSymbol(MO
.getBlockAddress());
99 case MachineOperand::MO_ExternalSymbol
:
100 O
<< *GetExternalSymbolSymbol(MO
.getSymbolName());
103 case MachineOperand::MO_JumpTableIndex
:
104 case MachineOperand::MO_ConstantPoolIndex
:
106 llvm_unreachable("<unknown operand type>");
110 bool 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
);
115 printOperand(MI
, OpNo
, O
);
119 bool BPFAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
120 unsigned OpNum
, const char *ExtraCode
,
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();
130 return true; // Unknown modifier.
133 O
<< "(" << BPFInstPrinter::getRegisterName(BaseMO
.getReg()) << " - " << -Offset
<< ")";
135 O
<< "(" << BPFInstPrinter::getRegisterName(BaseMO
.getReg()) << " + " << Offset
<< ")";
140 void BPFAsmPrinter::EmitInstruction(const MachineInstr
*MI
) {
143 if (!BTF
|| !BTF
->InstLower(MI
, TmpInst
)) {
144 BPFMCInstLower
MCInstLowering(OutContext
, *this);
145 MCInstLowering
.Lower(MI
, TmpInst
);
147 EmitToStreamer(*OutStreamer
, TmpInst
);
150 // Force static initialization.
151 extern "C" void LLVMInitializeBPFAsmPrinter() {
152 RegisterAsmPrinter
<BPFAsmPrinter
> X(getTheBPFleTarget());
153 RegisterAsmPrinter
<BPFAsmPrinter
> Y(getTheBPFbeTarget());
154 RegisterAsmPrinter
<BPFAsmPrinter
> Z(getTheBPFTarget());