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