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