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
18namespace llvm {
19
20class MCAlignFragment;
21class MCDwarfCallFrameFragment;
22class MCDwarfLineAddrFragment;
23class MCFragment;
24class MCLEBFragment;
25class MCRelaxableFragment;
26class MCSymbol;
27class MCAssembler;
28class MCContext;
29struct MCDwarfFrameInfo;
30struct MCFixupKindInfo;
31class MCInst;
32class MCObjectStreamer;
33class MCObjectTargetWriter;
34class MCObjectWriter;
35class MCSubtargetInfo;
36class MCValue;
37class raw_pwrite_stream;
38class StringRef;
39class raw_ostream;
40
41/// Generic interface to target specific assembler backends.
42class MCAsmBackend {
43protected: // Can only create subclasses.
44 MCAsmBackend(llvm::endianness Endian, unsigned RelaxFixupKind = MaxFixupKind);
45
46public:
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 shouldInsertExtraNopBytesForCodeAlign(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