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 "InstPrinter/BPFInstPrinter.h"
20 #include "llvm/CodeGen/AsmPrinter.h"
21 #include "llvm/CodeGen/MachineConstantPool.h"
22 #include "llvm/CodeGen/MachineFunctionPass.h"
23 #include "llvm/CodeGen/MachineInstr.h"
24 #include "llvm/CodeGen/MachineModuleInfo.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"
29 #include "llvm/Support/TargetRegistry.h"
30 #include "llvm/Support/raw_ostream.h"
33 #define DEBUG_TYPE "asm-printer"
36 class BPFAsmPrinter
: public AsmPrinter
{
38 explicit BPFAsmPrinter(TargetMachine
&TM
,
39 std::unique_ptr
<MCStreamer
> Streamer
)
40 : AsmPrinter(TM
, std::move(Streamer
)) {}
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 unsigned AsmVariant
, const char *ExtraCode
,
47 raw_ostream
&O
) override
;
48 bool PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNum
,
49 unsigned AsmVariant
, const char *ExtraCode
,
50 raw_ostream
&O
) override
;
52 void EmitInstruction(const MachineInstr
*MI
) override
;
56 bool BPFAsmPrinter::doInitialization(Module
&M
) {
57 AsmPrinter::doInitialization(M
);
59 if (MAI
->doesSupportDebugInformation()) {
60 Handlers
.push_back(HandlerInfo(new BTFDebug(this), "emit",
61 "Debug Info Emission", "BTF",
68 void BPFAsmPrinter::printOperand(const MachineInstr
*MI
, int OpNum
,
70 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
72 switch (MO
.getType()) {
73 case MachineOperand::MO_Register
:
74 O
<< BPFInstPrinter::getRegisterName(MO
.getReg());
77 case MachineOperand::MO_Immediate
:
81 case MachineOperand::MO_MachineBasicBlock
:
82 O
<< *MO
.getMBB()->getSymbol();
85 case MachineOperand::MO_GlobalAddress
:
86 O
<< *getSymbol(MO
.getGlobal());
89 case MachineOperand::MO_BlockAddress
: {
90 MCSymbol
*BA
= GetBlockAddressSymbol(MO
.getBlockAddress());
95 case MachineOperand::MO_ExternalSymbol
:
96 O
<< *GetExternalSymbolSymbol(MO
.getSymbolName());
99 case MachineOperand::MO_JumpTableIndex
:
100 case MachineOperand::MO_ConstantPoolIndex
:
102 llvm_unreachable("<unknown operand type>");
106 bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
107 unsigned /*AsmVariant*/,
108 const char *ExtraCode
, raw_ostream
&O
) {
109 if (ExtraCode
&& ExtraCode
[0])
110 return true; // BPF does not have special modifiers
112 printOperand(MI
, OpNo
, O
);
116 bool BPFAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
117 unsigned OpNum
, unsigned AsmVariant
,
118 const char *ExtraCode
,
120 assert(OpNum
+ 1 < MI
->getNumOperands() && "Insufficient operands");
121 const MachineOperand
&BaseMO
= MI
->getOperand(OpNum
);
122 const MachineOperand
&OffsetMO
= MI
->getOperand(OpNum
+ 1);
123 assert(BaseMO
.isReg() && "Unexpected base pointer for inline asm memory operand.");
124 assert(OffsetMO
.isImm() && "Unexpected offset for inline asm memory operand.");
125 int Offset
= OffsetMO
.getImm();
128 return true; // Unknown modifier.
131 O
<< "(" << BPFInstPrinter::getRegisterName(BaseMO
.getReg()) << " - " << -Offset
<< ")";
133 O
<< "(" << BPFInstPrinter::getRegisterName(BaseMO
.getReg()) << " + " << Offset
<< ")";
138 void BPFAsmPrinter::EmitInstruction(const MachineInstr
*MI
) {
140 BPFMCInstLower
MCInstLowering(OutContext
, *this);
143 MCInstLowering
.Lower(MI
, TmpInst
);
144 EmitToStreamer(*OutStreamer
, TmpInst
);
147 // Force static initialization.
148 extern "C" void LLVMInitializeBPFAsmPrinter() {
149 RegisterAsmPrinter
<BPFAsmPrinter
> X(getTheBPFleTarget());
150 RegisterAsmPrinter
<BPFAsmPrinter
> Y(getTheBPFbeTarget());
151 RegisterAsmPrinter
<BPFAsmPrinter
> Z(getTheBPFTarget());