123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- llvm/MC/MCAsmBackend.h - MC Asm Backend ------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_MC_MCASMBACKEND_H
- #define LLVM_MC_MCASMBACKEND_H
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/Optional.h"
- #include "llvm/MC/MCDirectives.h"
- #include "llvm/MC/MCFixup.h"
- #include "llvm/MC/MCFragment.h"
- #include "llvm/Support/Endian.h"
- #include <cstdint>
- namespace llvm {
- class MCAsmLayout;
- class MCAssembler;
- class MCCFIInstruction;
- struct MCFixupKindInfo;
- class MCInst;
- class MCObjectStreamer;
- class MCObjectTargetWriter;
- class MCObjectWriter;
- class MCSubtargetInfo;
- class MCValue;
- class raw_pwrite_stream;
- class StringRef;
- /// Generic interface to target specific assembler backends.
- class MCAsmBackend {
- protected: // Can only create subclasses.
- MCAsmBackend(support::endianness Endian);
- public:
- MCAsmBackend(const MCAsmBackend &) = delete;
- MCAsmBackend &operator=(const MCAsmBackend &) = delete;
- virtual ~MCAsmBackend();
- const support::endianness Endian;
- /// Return true if this target might automatically pad instructions and thus
- /// need to emit padding enable/disable directives around sensative code.
- virtual bool allowAutoPadding() const { return false; }
- /// Return true if this target allows an unrelaxable instruction to be
- /// emitted into RelaxableFragment and then we can increase its size in a
- /// tricky way for optimization.
- virtual bool allowEnhancedRelaxation() const { return false; }
- /// Give the target a chance to manipulate state related to instruction
- /// alignment (e.g. padding for optimization), instruction relaxablility, etc.
- /// before and after actually emitting the instruction.
- virtual void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst,
- const MCSubtargetInfo &STI) {}
- virtual void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) {}
- /// lifetime management
- virtual void reset() {}
- /// Create a new MCObjectWriter instance for use by the assembler backend to
- /// emit the final object file.
- std::unique_ptr<MCObjectWriter>
- createObjectWriter(raw_pwrite_stream &OS) const;
- /// Create an MCObjectWriter that writes two object files: a .o file which is
- /// linked into the final program and a .dwo file which is used by debuggers.
- /// This function is only supported with ELF targets.
- std::unique_ptr<MCObjectWriter>
- createDwoObjectWriter(raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS) const;
- virtual std::unique_ptr<MCObjectTargetWriter>
- createObjectTargetWriter() const = 0;
- /// \name Target Fixup Interfaces
- /// @{
- /// Get the number of target specific fixup kinds.
- virtual unsigned getNumFixupKinds() const = 0;
- /// Map a relocation name used in .reloc to a fixup kind.
- virtual Optional<MCFixupKind> getFixupKind(StringRef Name) const;
- /// Get information on a fixup kind.
- virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
- /// Hook to check if a relocation is needed for some target specific reason.
- virtual bool shouldForceRelocation(const MCAssembler &Asm,
- const MCFixup &Fixup,
- const MCValue &Target) {
- return false;
- }
- /// Hook to check if extra nop bytes must be inserted for alignment directive.
- /// For some targets this may be necessary in order to support linker
- /// relaxation. The number of bytes to insert are returned in Size.
- virtual bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF,
- unsigned &Size) {
- return false;
- }
- /// Hook which indicates if the target requires a fixup to be generated when
- /// handling an align directive in an executable section
- virtual bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
- const MCAsmLayout &Layout,
- MCAlignFragment &AF) {
- return false;
- }
- virtual bool evaluateTargetFixup(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFixup &Fixup, const MCFragment *DF,
- const MCValue &Target, uint64_t &Value,
- bool &WasForced) {
- llvm_unreachable("Need to implement hook if target has custom fixups");
- }
- /// Apply the \p Value for given \p Fixup into the provided data fragment, at
- /// the offset specified by the fixup and following the fixup kind as
- /// appropriate. Errors (such as an out of range fixup value) should be
- /// reported via \p Ctx.
- /// The \p STI is present only for fragments of type MCRelaxableFragment and
- /// MCDataFragment with hasInstructions() == true.
- virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target, MutableArrayRef<char> Data,
- uint64_t Value, bool IsResolved,
- const MCSubtargetInfo *STI) const = 0;
- /// @}
- /// \name Target Relaxation Interfaces
- /// @{
- /// Check whether the given instruction may need relaxation.
- ///
- /// \param Inst - The instruction to test.
- /// \param STI - The MCSubtargetInfo in effect when the instruction was
- /// encoded.
- virtual bool mayNeedRelaxation(const MCInst &Inst,
- const MCSubtargetInfo &STI) const {
- return false;
- }
- /// Target specific predicate for whether a given fixup requires the
- /// associated instruction to be relaxed.
- virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
- uint64_t Value,
- const MCRelaxableFragment *DF,
- const MCAsmLayout &Layout,
- const bool WasForced) const;
- /// Simple predicate for targets where !Resolved implies requiring relaxation
- virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
- const MCRelaxableFragment *DF,
- const MCAsmLayout &Layout) const = 0;
- /// Relax the instruction in the given fragment to the next wider instruction.
- ///
- /// \param [out] Inst The instruction to relax, which is also the relaxed
- /// instruction.
- /// \param STI the subtarget information for the associated instruction.
- virtual void relaxInstruction(MCInst &Inst,
- const MCSubtargetInfo &STI) const {};
- virtual bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF,
- MCAsmLayout &Layout, bool &WasRelaxed) const {
- return false;
- }
- virtual bool relaxDwarfCFA(MCDwarfCallFrameFragment &DF, MCAsmLayout &Layout,
- bool &WasRelaxed) const {
- return false;
- }
- /// @}
- /// Returns the minimum size of a nop in bytes on this target. The assembler
- /// will use this to emit excess padding in situations where the padding
- /// required for simple alignment would be less than the minimum nop size.
- ///
- virtual unsigned getMinimumNopSize() const { return 1; }
- /// Returns the maximum size of a nop in bytes on this target.
- ///
- virtual unsigned getMaximumNopSize(const MCSubtargetInfo &STI) const {
- return 0;
- }
- /// Write an (optimal) nop sequence of Count bytes to the given output. If the
- /// target cannot generate such a sequence, it should return an error.
- ///
- /// \return - True on success.
- virtual bool writeNopData(raw_ostream &OS, uint64_t Count,
- const MCSubtargetInfo *STI) const = 0;
- /// Give backend an opportunity to finish layout after relaxation
- virtual void finishLayout(MCAssembler const &Asm,
- MCAsmLayout &Layout) const {}
- /// Handle any target-specific assembler flags. By default, do nothing.
- virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
- /// Generate the compact unwind encoding for the CFI instructions.
- virtual uint32_t
- generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction>) const {
- return 0;
- }
- /// Check whether a given symbol has been flagged with MICROMIPS flag.
- virtual bool isMicroMips(const MCSymbol *Sym) const {
- return false;
- }
- };
- } // end namespace llvm
- #endif // LLVM_MC_MCASMBACKEND_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|