Home | History | Annotate | Line # | Download | only in MC
      1 //===- llvm/MC/MCAsmBackend.h - MC Asm Backend ------------------*- 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 
      9 #ifndef LLVM_MC_MCASMBACKEND_H
     10 #define LLVM_MC_MCASMBACKEND_H
     11 
     12 #include "llvm/ADT/ArrayRef.h"
     13 #include "llvm/ADT/Optional.h"
     14 #include "llvm/MC/MCDirectives.h"
     15 #include "llvm/MC/MCFixup.h"
     16 #include "llvm/MC/MCFragment.h"
     17 #include "llvm/Support/Endian.h"
     18 #include <cstdint>
     19 
     20 namespace llvm {
     21 
     22 class MCAsmLayout;
     23 class MCAssembler;
     24 class MCCFIInstruction;
     25 struct MCFixupKindInfo;
     26 class MCInst;
     27 class MCObjectStreamer;
     28 class MCObjectTargetWriter;
     29 class MCObjectWriter;
     30 class MCSubtargetInfo;
     31 class MCValue;
     32 class raw_pwrite_stream;
     33 class StringRef;
     34 
     35 /// Generic interface to target specific assembler backends.
     36 class MCAsmBackend {
     37 protected: // Can only create subclasses.
     38   MCAsmBackend(support::endianness Endian);
     39 
     40 public:
     41   MCAsmBackend(const MCAsmBackend &) = delete;
     42   MCAsmBackend &operator=(const MCAsmBackend &) = delete;
     43   virtual ~MCAsmBackend();
     44 
     45   const support::endianness Endian;
     46 
     47   /// Return true if this target might automatically pad instructions and thus
     48   /// need to emit padding enable/disable directives around sensative code.
     49   virtual bool allowAutoPadding() const { return false; }
     50   /// Return true if this target allows an unrelaxable instruction to be
     51   /// emitted into RelaxableFragment and then we can increase its size in a
     52   /// tricky way for optimization.
     53   virtual bool allowEnhancedRelaxation() const { return false; }
     54 
     55   /// Give the target a chance to manipulate state related to instruction
     56   /// alignment (e.g. padding for optimization), instruction relaxablility, etc.
     57   /// before and after actually emitting the instruction.
     58   virtual void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst) {}
     59   virtual void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) {}
     60 
     61   /// lifetime management
     62   virtual void reset() {}
     63 
     64   /// Create a new MCObjectWriter instance for use by the assembler backend to
     65   /// emit the final object file.
     66   std::unique_ptr<MCObjectWriter>
     67   createObjectWriter(raw_pwrite_stream &OS) const;
     68 
     69   /// Create an MCObjectWriter that writes two object files: a .o file which is
     70   /// linked into the final program and a .dwo file which is used by debuggers.
     71   /// This function is only supported with ELF targets.
     72   std::unique_ptr<MCObjectWriter>
     73   createDwoObjectWriter(raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS) const;
     74 
     75   virtual std::unique_ptr<MCObjectTargetWriter>
     76   createObjectTargetWriter() const = 0;
     77 
     78   /// \name Target Fixup Interfaces
     79   /// @{
     80 
     81   /// Get the number of target specific fixup kinds.
     82   virtual unsigned getNumFixupKinds() const = 0;
     83 
     84   /// Map a relocation name used in .reloc to a fixup kind.
     85   virtual Optional<MCFixupKind> getFixupKind(StringRef Name) const;
     86 
     87   /// Get information on a fixup kind.
     88   virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
     89 
     90   /// Hook to check if a relocation is needed for some target specific reason.
     91   virtual bool shouldForceRelocation(const MCAssembler &Asm,
     92                                      const MCFixup &Fixup,
     93                                      const MCValue &Target) {
     94     return false;
     95   }
     96 
     97   /// Hook to check if extra nop bytes must be inserted for alignment directive.
     98   /// For some targets this may be necessary in order to support linker
     99   /// relaxation. The number of bytes to insert are returned in Size.
    100   virtual bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF,
    101                                                      unsigned &Size) {
    102     return false;
    103   }
    104 
    105   /// Hook which indicates if the target requires a fixup to be generated when
    106   /// handling an align directive in an executable section
    107   virtual bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
    108                                              const MCAsmLayout &Layout,
    109                                              MCAlignFragment &AF) {
    110     return false;
    111   }
    112 
    113   virtual bool evaluateTargetFixup(const MCAssembler &Asm,
    114                                    const MCAsmLayout &Layout,
    115                                    const MCFixup &Fixup, const MCFragment *DF,
    116                                    const MCValue &Target, uint64_t &Value,
    117                                    bool &WasForced) {
    118     llvm_unreachable("Need to implement hook if target has custom fixups");
    119   }
    120 
    121   /// Apply the \p Value for given \p Fixup into the provided data fragment, at
    122   /// the offset specified by the fixup and following the fixup kind as
    123   /// appropriate. Errors (such as an out of range fixup value) should be
    124   /// reported via \p Ctx.
    125   /// The  \p STI is present only for fragments of type MCRelaxableFragment and
    126   /// MCDataFragment with hasInstructions() == true.
    127   virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
    128                           const MCValue &Target, MutableArrayRef<char> Data,
    129                           uint64_t Value, bool IsResolved,
    130                           const MCSubtargetInfo *STI) const = 0;
    131 
    132   /// Check whether the given target requires emitting differences of two
    133   /// symbols as a set of relocations.
    134   virtual bool requiresDiffExpressionRelocations() const { return false; }
    135 
    136   /// @}
    137 
    138   /// \name Target Relaxation Interfaces
    139   /// @{
    140 
    141   /// Check whether the given instruction may need relaxation.
    142   ///
    143   /// \param Inst - The instruction to test.
    144   /// \param STI - The MCSubtargetInfo in effect when the instruction was
    145   /// encoded.
    146   virtual bool mayNeedRelaxation(const MCInst &Inst,
    147                                  const MCSubtargetInfo &STI) const {
    148     return false;
    149   }
    150 
    151   /// Target specific predicate for whether a given fixup requires the
    152   /// associated instruction to be relaxed.
    153   virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
    154                                             uint64_t Value,
    155                                             const MCRelaxableFragment *DF,
    156                                             const MCAsmLayout &Layout,
    157                                             const bool WasForced) const;
    158 
    159   /// Simple predicate for targets where !Resolved implies requiring relaxation
    160   virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
    161                                     const MCRelaxableFragment *DF,
    162                                     const MCAsmLayout &Layout) const = 0;
    163 
    164   /// Relax the instruction in the given fragment to the next wider instruction.
    165   ///
    166   /// \param [out] Inst The instruction to relax, which is also the relaxed
    167   /// instruction.
    168   /// \param STI the subtarget information for the associated instruction.
    169   virtual void relaxInstruction(MCInst &Inst,
    170                                 const MCSubtargetInfo &STI) const {};
    171 
    172   /// @}
    173 
    174   /// Returns the minimum size of a nop in bytes on this target. The assembler
    175   /// will use this to emit excess padding in situations where the padding
    176   /// required for simple alignment would be less than the minimum nop size.
    177   ///
    178   virtual unsigned getMinimumNopSize() const { return 1; }
    179 
    180   /// Returns the maximum size of a nop in bytes on this target.
    181   ///
    182   virtual unsigned getMaximumNopSize() const { return 0; }
    183 
    184   /// Write an (optimal) nop sequence of Count bytes to the given output. If the
    185   /// target cannot generate such a sequence, it should return an error.
    186   ///
    187   /// \return - True on success.
    188   virtual bool writeNopData(raw_ostream &OS, uint64_t Count) const = 0;
    189 
    190   /// Give backend an opportunity to finish layout after relaxation
    191   virtual void finishLayout(MCAssembler const &Asm,
    192                             MCAsmLayout &Layout) const {}
    193 
    194   /// Handle any target-specific assembler flags. By default, do nothing.
    195   virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
    196 
    197   /// Generate the compact unwind encoding for the CFI instructions.
    198   virtual uint32_t
    199       generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction>) const {
    200     return 0;
    201   }
    202 
    203   /// Check whether a given symbol has been flagged with MICROMIPS flag.
    204   virtual bool isMicroMips(const MCSymbol *Sym) const {
    205     return false;
    206   }
    207 };
    208 
    209 } // end namespace llvm
    210 
    211 #endif // LLVM_MC_MCASMBACKEND_H
    212