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. allowAutoPadding()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. allowEnhancedRelaxation()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. emitInstructionBegin(MCObjectStreamer & OS,const MCInst & Inst,const MCSubtargetInfo & STI)68 virtual void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst, 69 const MCSubtargetInfo &STI) {} emitInstructionEnd(MCObjectStreamer & OS,const MCInst & Inst)70 virtual void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) {} 71 72 /// lifetime management reset()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. shouldForceRelocation(const MCAssembler & Asm,const MCFixup & Fixup,const MCValue & Target,const MCSubtargetInfo * STI)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. shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment & AF,unsigned & Size)112 virtual bool shouldInsertExtraNopBytesForCodeAlign(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 shouldInsertFixupForCodeAlign(MCAssembler & Asm,const MCAsmLayout & Layout,MCAlignFragment & AF)119 virtual bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, 120 const MCAsmLayout &Layout, 121 MCAlignFragment &AF) { 122 return false; 123 } 124 evaluateTargetFixup(const MCAssembler & Asm,const MCAsmLayout & Layout,const MCFixup & Fixup,const MCFragment * DF,const MCValue & Target,const MCSubtargetInfo * STI,uint64_t & Value,bool & WasForced)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 handleAddSubRelocations(const MCAsmLayout & Layout,const MCFragment & F,const MCFixup & Fixup,const MCValue & Target,uint64_t & FixedValue)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. mayNeedRelaxation(const MCInst & Inst,const MCSubtargetInfo & STI)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. relaxInstruction(MCInst & Inst,const MCSubtargetInfo & STI)186 virtual void relaxInstruction(MCInst &Inst, 187 const MCSubtargetInfo &STI) const {}; 188 relaxDwarfLineAddr(MCDwarfLineAddrFragment & DF,MCAsmLayout & Layout,bool & WasRelaxed)189 virtual bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF, 190 MCAsmLayout &Layout, bool &WasRelaxed) const { 191 return false; 192 } 193 relaxDwarfCFA(MCDwarfCallFrameFragment & DF,MCAsmLayout & Layout,bool & WasRelaxed)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> relaxLEB128(MCLEBFragment & LF,MCAsmLayout & Layout,int64_t & Value)202 relaxLEB128(MCLEBFragment &LF, MCAsmLayout &Layout, int64_t &Value) const { 203 return std::make_pair(false, 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 /// getMinimumNopSize()212 virtual unsigned getMinimumNopSize() const { return 1; } 213 214 /// Returns the maximum size of a nop in bytes on this target. 215 /// getMaximumNopSize(const MCSubtargetInfo & STI)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 finishLayout(MCAssembler const & Asm,MCAsmLayout & Layout)228 virtual void finishLayout(MCAssembler const &Asm, 229 MCAsmLayout &Layout) const {} 230 231 /// Handle any target-specific assembler flags. By default, do nothing. handleAssemblerFlag(MCAssemblerFlag Flag)232 virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {} 233 234 /// Generate the compact unwind encoding for the CFI instructions. generateCompactUnwindEncoding(const MCDwarfFrameInfo * FI,const MCContext * Ctxt)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. isMicroMips(const MCSymbol * Sym)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