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