X86AsmPrinter.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===//
  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. #ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
  9. #define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
  10. #include "llvm/CodeGen/AsmPrinter.h"
  11. #include "llvm/CodeGen/FaultMaps.h"
  12. #include "llvm/CodeGen/StackMaps.h"
  13. // Implemented in X86MCInstLower.cpp
  14. namespace {
  15. class X86MCInstLower;
  16. }
  17. namespace llvm {
  18. class MCCodeEmitter;
  19. class MCStreamer;
  20. class X86Subtarget;
  21. class TargetMachine;
  22. class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
  23. const X86Subtarget *Subtarget = nullptr;
  24. StackMaps SM;
  25. FaultMaps FM;
  26. std::unique_ptr<MCCodeEmitter> CodeEmitter;
  27. bool EmitFPOData = false;
  28. bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = false;
  29. // This utility class tracks the length of a stackmap instruction's 'shadow'.
  30. // It is used by the X86AsmPrinter to ensure that the stackmap shadow
  31. // invariants (i.e. no other stackmaps, patchpoints, or control flow within
  32. // the shadow) are met, while outputting a minimal number of NOPs for padding.
  33. //
  34. // To minimise the number of NOPs used, the shadow tracker counts the number
  35. // of instruction bytes output since the last stackmap. Only if there are too
  36. // few instruction bytes to cover the shadow are NOPs used for padding.
  37. class StackMapShadowTracker {
  38. public:
  39. void startFunction(MachineFunction &MF) {
  40. this->MF = &MF;
  41. }
  42. void count(MCInst &Inst, const MCSubtargetInfo &STI,
  43. MCCodeEmitter *CodeEmitter);
  44. // Called to signal the start of a shadow of RequiredSize bytes.
  45. void reset(unsigned RequiredSize) {
  46. RequiredShadowSize = RequiredSize;
  47. CurrentShadowSize = 0;
  48. InShadow = true;
  49. }
  50. // Called before every stackmap/patchpoint, and at the end of basic blocks,
  51. // to emit any necessary padding-NOPs.
  52. void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI);
  53. private:
  54. const MachineFunction *MF = nullptr;
  55. bool InShadow = false;
  56. // RequiredShadowSize holds the length of the shadow specified in the most
  57. // recently encountered STACKMAP instruction.
  58. // CurrentShadowSize counts the number of bytes encoded since the most
  59. // recently encountered STACKMAP, stopping when that number is greater than
  60. // or equal to RequiredShadowSize.
  61. unsigned RequiredShadowSize = 0, CurrentShadowSize = 0;
  62. };
  63. StackMapShadowTracker SMShadowTracker;
  64. // All instructions emitted by the X86AsmPrinter should use this helper
  65. // method.
  66. //
  67. // This helper function invokes the SMShadowTracker on each instruction before
  68. // outputting it to the OutStream. This allows the shadow tracker to minimise
  69. // the number of NOPs used for stackmap padding.
  70. void EmitAndCountInstruction(MCInst &Inst);
  71. void LowerSTACKMAP(const MachineInstr &MI);
  72. void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
  73. void LowerSTATEPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
  74. void LowerFAULTING_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
  75. void LowerPATCHABLE_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
  76. void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI);
  77. // XRay-specific lowering for X86.
  78. void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
  79. X86MCInstLower &MCIL);
  80. void LowerPATCHABLE_RET(const MachineInstr &MI, X86MCInstLower &MCIL);
  81. void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
  82. void LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
  83. void LowerPATCHABLE_TYPED_EVENT_CALL(const MachineInstr &MI,
  84. X86MCInstLower &MCIL);
  85. void LowerFENTRY_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
  86. // Address sanitizer specific lowering for X86.
  87. void LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI);
  88. // Choose between emitting .seh_ directives and .cv_fpo_ directives.
  89. void EmitSEHInstruction(const MachineInstr *MI);
  90. void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
  91. void PrintOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
  92. void PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
  93. raw_ostream &O, const char *Modifier);
  94. void PrintPCRelImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
  95. void PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
  96. raw_ostream &O, const char *Modifier);
  97. void PrintMemReference(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
  98. const char *Modifier);
  99. void PrintIntelMemReference(const MachineInstr *MI, unsigned OpNo,
  100. raw_ostream &O, const char *Modifier);
  101. public:
  102. X86AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
  103. StringRef getPassName() const override {
  104. return "X86 Assembly Printer";
  105. }
  106. const X86Subtarget &getSubtarget() const { return *Subtarget; }
  107. void emitStartOfAsmFile(Module &M) override;
  108. void emitEndOfAsmFile(Module &M) override;
  109. void emitInstruction(const MachineInstr *MI) override;
  110. void emitBasicBlockEnd(const MachineBasicBlock &MBB) override {
  111. AsmPrinter::emitBasicBlockEnd(MBB);
  112. SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
  113. }
  114. bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
  115. const char *ExtraCode, raw_ostream &O) override;
  116. bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
  117. const char *ExtraCode, raw_ostream &O) override;
  118. bool doInitialization(Module &M) override {
  119. SMShadowTracker.reset(0);
  120. SM.reset();
  121. FM.reset();
  122. return AsmPrinter::doInitialization(M);
  123. }
  124. bool runOnMachineFunction(MachineFunction &MF) override;
  125. void emitFunctionBodyStart() override;
  126. void emitFunctionBodyEnd() override;
  127. bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const override {
  128. return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
  129. }
  130. };
  131. } // end namespace llvm
  132. #endif