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