1//===-- BPFAsmPrinter.cpp - BPF LLVM assembly writer ----------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a printer that converts from our internal representation
11// of machine-dependent LLVM code to the BPF assembly language.
12//
13//===----------------------------------------------------------------------===//
14
15#include "BPF.h"
16#include "BPFInstrInfo.h"
17#include "BPFMCInstLower.h"
18#include "BPFTargetMachine.h"
19#include "InstPrinter/BPFInstPrinter.h"
20#include "llvm/CodeGen/AsmPrinter.h"
21#include "llvm/CodeGen/MachineModuleInfo.h"
22#include "llvm/CodeGen/MachineFunctionPass.h"
23#include "llvm/CodeGen/MachineConstantPool.h"
24#include "llvm/CodeGen/MachineInstr.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"
31using namespace llvm;
32
33#define DEBUG_TYPE "asm-printer"
34
35namespace {
36class BPFAsmPrinter : public AsmPrinter {
37public:
38  explicit BPFAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
39      : AsmPrinter(TM, std::move(Streamer)) {}
40
41  const char *getPassName() const override { return "BPF Assembly Printer"; }
42
43  void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
44                    const char *Modifier = nullptr);
45  void EmitInstruction(const MachineInstr *MI) override;
46};
47}
48
49void BPFAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
50                                 raw_ostream &O, const char *Modifier) {
51  const MachineOperand &MO = MI->getOperand(OpNum);
52
53  switch (MO.getType()) {
54  case MachineOperand::MO_Register:
55    O << BPFInstPrinter::getRegisterName(MO.getReg());
56    break;
57
58  case MachineOperand::MO_Immediate:
59    O << MO.getImm();
60    break;
61
62  case MachineOperand::MO_MachineBasicBlock:
63    O << *MO.getMBB()->getSymbol();
64    break;
65
66  case MachineOperand::MO_GlobalAddress:
67    O << *getSymbol(MO.getGlobal());
68    break;
69
70  default:
71    llvm_unreachable("<unknown operand type>");
72  }
73}
74
75void BPFAsmPrinter::EmitInstruction(const MachineInstr *MI) {
76
77  BPFMCInstLower MCInstLowering(OutContext, *this);
78
79  MCInst TmpInst;
80  MCInstLowering.Lower(MI, TmpInst);
81  EmitToStreamer(*OutStreamer, TmpInst);
82}
83
84// Force static initialization.
85extern "C" void LLVMInitializeBPFAsmPrinter() {
86  RegisterAsmPrinter<BPFAsmPrinter> X(TheBPFleTarget);
87  RegisterAsmPrinter<BPFAsmPrinter> Y(TheBPFbeTarget);
88  RegisterAsmPrinter<BPFAsmPrinter> Z(TheBPFTarget);
89}
90