BPFInstPrinter.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. //===-- BPFInstPrinter.cpp - Convert BPF MCInst to asm syntax -------------===//
  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 class prints an BPF MCInst to a .s file.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "MCTargetDesc/BPFInstPrinter.h"
  13. #include "llvm/MC/MCAsmInfo.h"
  14. #include "llvm/MC/MCExpr.h"
  15. #include "llvm/MC/MCInst.h"
  16. #include "llvm/MC/MCRegister.h"
  17. #include "llvm/MC/MCSymbol.h"
  18. #include "llvm/Support/Casting.h"
  19. #include "llvm/Support/ErrorHandling.h"
  20. #include "llvm/Support/FormattedStream.h"
  21. using namespace llvm;
  22. #define DEBUG_TYPE "asm-printer"
  23. // Include the auto-generated portion of the assembly writer.
  24. #include "BPFGenAsmWriter.inc"
  25. void BPFInstPrinter::printInst(const MCInst *MI, uint64_t Address,
  26. StringRef Annot, const MCSubtargetInfo &STI,
  27. raw_ostream &O) {
  28. printInstruction(MI, Address, O);
  29. printAnnotation(O, Annot);
  30. }
  31. static void printExpr(const MCExpr *Expr, raw_ostream &O) {
  32. #ifndef NDEBUG
  33. const MCSymbolRefExpr *SRE;
  34. if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr))
  35. SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
  36. else
  37. SRE = dyn_cast<MCSymbolRefExpr>(Expr);
  38. assert(SRE && "Unexpected MCExpr type.");
  39. MCSymbolRefExpr::VariantKind Kind = SRE->getKind();
  40. assert(Kind == MCSymbolRefExpr::VK_None);
  41. #endif
  42. O << *Expr;
  43. }
  44. void BPFInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
  45. raw_ostream &O, const char *Modifier) {
  46. assert((Modifier == nullptr || Modifier[0] == 0) && "No modifiers supported");
  47. const MCOperand &Op = MI->getOperand(OpNo);
  48. if (Op.isReg()) {
  49. O << getRegisterName(Op.getReg());
  50. } else if (Op.isImm()) {
  51. O << formatImm((int32_t)Op.getImm());
  52. } else {
  53. assert(Op.isExpr() && "Expected an expression");
  54. printExpr(Op.getExpr(), O);
  55. }
  56. }
  57. void BPFInstPrinter::printMemOperand(const MCInst *MI, int OpNo, raw_ostream &O,
  58. const char *Modifier) {
  59. const MCOperand &RegOp = MI->getOperand(OpNo);
  60. const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
  61. // register
  62. assert(RegOp.isReg() && "Register operand not a register");
  63. O << getRegisterName(RegOp.getReg());
  64. // offset
  65. if (OffsetOp.isImm()) {
  66. auto Imm = OffsetOp.getImm();
  67. if (Imm >= 0)
  68. O << " + " << formatImm(Imm);
  69. else
  70. O << " - " << formatImm(-Imm);
  71. } else {
  72. assert(0 && "Expected an immediate");
  73. }
  74. }
  75. void BPFInstPrinter::printImm64Operand(const MCInst *MI, unsigned OpNo,
  76. raw_ostream &O) {
  77. const MCOperand &Op = MI->getOperand(OpNo);
  78. if (Op.isImm())
  79. O << formatImm(Op.getImm());
  80. else if (Op.isExpr())
  81. printExpr(Op.getExpr(), O);
  82. else
  83. O << Op;
  84. }
  85. void BPFInstPrinter::printBrTargetOperand(const MCInst *MI, unsigned OpNo,
  86. raw_ostream &O) {
  87. const MCOperand &Op = MI->getOperand(OpNo);
  88. if (Op.isImm()) {
  89. int16_t Imm = Op.getImm();
  90. O << ((Imm >= 0) ? "+" : "") << formatImm(Imm);
  91. } else if (Op.isExpr()) {
  92. printExpr(Op.getExpr(), O);
  93. } else {
  94. O << Op;
  95. }
  96. }