BPFAsmPrinter.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. #include "BPF.h"
  14. #include "BPFInstrInfo.h"
  15. #include "BPFMCInstLower.h"
  16. #include "BPFTargetMachine.h"
  17. #include "BTFDebug.h"
  18. #include "MCTargetDesc/BPFInstPrinter.h"
  19. #include "TargetInfo/BPFTargetInfo.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/MC/TargetRegistry.h"
  30. #include "llvm/Support/raw_ostream.h"
  31. using namespace llvm;
  32. #define DEBUG_TYPE "asm-printer"
  33. namespace {
  34. class BPFAsmPrinter : public AsmPrinter {
  35. public:
  36. explicit BPFAsmPrinter(TargetMachine &TM,
  37. std::unique_ptr<MCStreamer> Streamer)
  38. : AsmPrinter(TM, std::move(Streamer)), BTF(nullptr) {}
  39. StringRef getPassName() const override { return "BPF Assembly Printer"; }
  40. bool doInitialization(Module &M) override;
  41. void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
  42. bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
  43. const char *ExtraCode, raw_ostream &O) override;
  44. bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
  45. const char *ExtraCode, raw_ostream &O) override;
  46. void emitInstruction(const MachineInstr *MI) override;
  47. private:
  48. BTFDebug *BTF;
  49. };
  50. } // namespace
  51. bool BPFAsmPrinter::doInitialization(Module &M) {
  52. AsmPrinter::doInitialization(M);
  53. // Only emit BTF when debuginfo available.
  54. if (MAI->doesSupportDebugInformation() && !M.debug_compile_units().empty()) {
  55. BTF = new BTFDebug(this);
  56. Handlers.push_back(HandlerInfo(std::unique_ptr<BTFDebug>(BTF), "emit",
  57. "Debug Info Emission", "BTF",
  58. "BTF Emission"));
  59. }
  60. return false;
  61. }
  62. void BPFAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
  63. raw_ostream &O) {
  64. const MachineOperand &MO = MI->getOperand(OpNum);
  65. switch (MO.getType()) {
  66. case MachineOperand::MO_Register:
  67. O << BPFInstPrinter::getRegisterName(MO.getReg());
  68. break;
  69. case MachineOperand::MO_Immediate:
  70. O << MO.getImm();
  71. break;
  72. case MachineOperand::MO_MachineBasicBlock:
  73. O << *MO.getMBB()->getSymbol();
  74. break;
  75. case MachineOperand::MO_GlobalAddress:
  76. O << *getSymbol(MO.getGlobal());
  77. break;
  78. case MachineOperand::MO_BlockAddress: {
  79. MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress());
  80. O << BA->getName();
  81. break;
  82. }
  83. case MachineOperand::MO_ExternalSymbol:
  84. O << *GetExternalSymbolSymbol(MO.getSymbolName());
  85. break;
  86. case MachineOperand::MO_JumpTableIndex:
  87. case MachineOperand::MO_ConstantPoolIndex:
  88. default:
  89. llvm_unreachable("<unknown operand type>");
  90. }
  91. }
  92. bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
  93. const char *ExtraCode, raw_ostream &O) {
  94. if (ExtraCode && ExtraCode[0])
  95. return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
  96. printOperand(MI, OpNo, O);
  97. return false;
  98. }
  99. bool BPFAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
  100. unsigned OpNum, const char *ExtraCode,
  101. raw_ostream &O) {
  102. assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
  103. const MachineOperand &BaseMO = MI->getOperand(OpNum);
  104. const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
  105. assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
  106. assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
  107. int Offset = OffsetMO.getImm();
  108. if (ExtraCode)
  109. return true; // Unknown modifier.
  110. if (Offset < 0)
  111. O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " - " << -Offset << ")";
  112. else
  113. O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " + " << Offset << ")";
  114. return false;
  115. }
  116. void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
  117. BPF_MC::verifyInstructionPredicates(MI->getOpcode(),
  118. getSubtargetInfo().getFeatureBits());
  119. MCInst TmpInst;
  120. if (!BTF || !BTF->InstLower(MI, TmpInst)) {
  121. BPFMCInstLower MCInstLowering(OutContext, *this);
  122. MCInstLowering.Lower(MI, TmpInst);
  123. }
  124. EmitToStreamer(*OutStreamer, TmpInst);
  125. }
  126. // Force static initialization.
  127. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeBPFAsmPrinter() {
  128. RegisterAsmPrinter<BPFAsmPrinter> X(getTheBPFleTarget());
  129. RegisterAsmPrinter<BPFAsmPrinter> Y(getTheBPFbeTarget());
  130. RegisterAsmPrinter<BPFAsmPrinter> Z(getTheBPFTarget());
  131. }