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