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