LLVM  14.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 "BPFTargetMachine.h"
18 #include "BTFDebug.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"
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "asm-printer"
35 
36 namespace {
37 class BPFAsmPrinter : public AsmPrinter {
38 public:
39  explicit BPFAsmPrinter(TargetMachine &TM,
40  std::unique_ptr<MCStreamer> Streamer)
41  : AsmPrinter(TM, std::move(Streamer)), 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 private:
54  BTFDebug *BTF;
55 };
56 } // namespace
57 
58 bool BPFAsmPrinter::doInitialization(Module &M) {
60 
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",
66  "BTF Emission"));
67  }
68 
69  return false;
70 }
71 
72 void 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 
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);
114 
115  printOperand(MI, OpNo, O);
116  return false;
117 }
118 
119 bool 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 
140 void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
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 }
AsmPrinter.h
llvm::getTheBPFleTarget
Target & getTheBPFleTarget()
Definition: BPFTargetInfo.cpp:14
llvm::MachineOperand::MO_BlockAddress
@ MO_BlockAddress
Address of a basic block.
Definition: MachineOperand.h:63
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
MachineInstr.h
llvm::MachineOperand::MO_Immediate
@ MO_Immediate
Immediate operand.
Definition: MachineOperand.h:53
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::MachineOperand::getGlobal
const GlobalValue * getGlobal() const
Definition: MachineOperand.h:563
llvm::MachineOperand::getBlockAddress
const BlockAddress * getBlockAddress() const
Definition: MachineOperand.h:568
printOperand
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
Definition: SelectionDAGDumper.cpp:946
BPFMCInstLower.h
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
BPF.h
llvm::MachineOperand::MO_Register
@ MO_Register
Register operand.
Definition: MachineOperand.h:52
BPFTargetInfo.h
llvm::MachineBasicBlock::getSymbol
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Definition: MachineBasicBlock.cpp:60
llvm::MachineOperand::MO_GlobalAddress
@ MO_GlobalAddress
Address of a global value.
Definition: MachineOperand.h:62
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:537
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
llvm::BPFInstPrinter::getRegisterName
static const char * getRegisterName(unsigned RegNo)
MCSymbol.h
MCInst.h
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::MCSymbol::getName
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:198
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::BTFDebug
Collect and emit BTF information.
Definition: BTFDebug.h:263
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:192
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
MachineConstantPool.h
llvm::MachineOperand::getType
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Definition: MachineOperand.h:219
BTFDebug.h
MachineFunctionPass.h
LLVMInitializeBPFAsmPrinter
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFAsmPrinter()
Definition: BPFAsmPrinter.cpp:151
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:79
llvm::getTheBPFbeTarget
Target & getTheBPFbeTarget()
Definition: BPFTargetInfo.cpp:18
MachineModuleInfo.h
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::MachineOperand::MO_JumpTableIndex
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
Definition: MachineOperand.h:60
llvm::MachineOperand::getMBB
MachineBasicBlock * getMBB() const
Definition: MachineOperand.h:552
MCAsmInfo.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::MachineOperand::MO_MachineBasicBlock
@ MO_MachineBasicBlock
MachineBasicBlock reference.
Definition: MachineOperand.h:56
llvm::MachineOperand::MO_ExternalSymbol
@ MO_ExternalSymbol
Name of external global symbol.
Definition: MachineOperand.h:61
llvm::AsmPrinter
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:82
llvm::BPFMCInstLower
Definition: BPFMCInstLower.h:24
llvm::MachineOperand::isImm
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Definition: MachineOperand.h:323
BPFInstPrinter.h
llvm::getTheBPFTarget
Target & getTheBPFTarget()
Definition: BPFTargetInfo.cpp:22
llvm::MachineOperand::getSymbolName
const char * getSymbolName() const
Definition: MachineOperand.h:608
MCStreamer.h
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::RegisterAsmPrinter
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
Definition: TargetRegistry.h:1338
raw_ostream.h
TargetRegistry.h
llvm::AsmPrinter::PrintAsmOperand
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.
Definition: AsmPrinterInlineAsm.cpp:599
BPFInstrInfo.h
llvm::MachineOperand::MO_ConstantPoolIndex
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
Definition: MachineOperand.h:58
llvm::AsmPrinter::doInitialization
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
Definition: AsmPrinter.cpp:267
BPFTargetMachine.h