1 //===- MCInstPrinter.h - MCInst to target assembly syntax -------*- 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_MCINSTPRINTER_H 10 #define LLVM_MC_MCINSTPRINTER_H 11 12 #include "llvm/Support/Compiler.h" 13 #include "llvm/Support/Format.h" 14 #include <cstdint> 15 16 namespace llvm { 17 18 class MCAsmInfo; 19 class MCInst; 20 class MCInstrAnalysis; 21 class MCInstrInfo; 22 class MCOperand; 23 class MCRegister; 24 class MCRegisterInfo; 25 class MCSubtargetInfo; 26 class StringRef; 27 class raw_ostream; 28 29 /// Convert `Bytes' to a hex string and output to `OS' 30 void dumpBytes(ArrayRef<uint8_t> Bytes, raw_ostream &OS); 31 32 namespace HexStyle { 33 34 enum Style { 35 C, ///< 0xff 36 Asm ///< 0ffh 37 }; 38 39 } // end namespace HexStyle 40 41 struct AliasMatchingData; 42 43 /// This is an instance of a target assembly language printer that 44 /// converts an MCInst to valid target assembly syntax. 45 class MCInstPrinter { 46 protected: 47 /// A stream that comments can be emitted to if desired. Each comment 48 /// must end with a newline. This will be null if verbose assembly emission 49 /// is disabled. 50 raw_ostream *CommentStream = nullptr; 51 const MCAsmInfo &MAI; 52 const MCInstrInfo &MII; 53 const MCRegisterInfo &MRI; 54 const MCInstrAnalysis *MIA = nullptr; 55 56 /// True if we are printing marked up assembly. 57 bool UseMarkup = false; 58 59 /// True if we are printing colored assembly. 60 bool UseColor = false; 61 62 /// True if we prefer aliases (e.g. nop) to raw mnemonics. 63 bool PrintAliases = true; 64 65 /// True if we are printing immediates as hex. 66 bool PrintImmHex = false; 67 68 /// Which style to use for printing hexadecimal values. 69 HexStyle::Style PrintHexStyle = HexStyle::C; 70 71 /// If true, a branch immediate (e.g. bl 4) will be printed as a hexadecimal 72 /// address (e.g. bl 0x20004). This is useful for a stream disassembler 73 /// (llvm-objdump -d). 74 bool PrintBranchImmAsAddress = false; 75 76 /// If true, symbolize branch target and memory reference operands. 77 bool SymbolizeOperands = false; 78 79 /// Utility function for printing annotations. 80 void printAnnotation(raw_ostream &OS, StringRef Annot); 81 82 /// Helper for matching MCInsts to alias patterns when printing instructions. 83 const char *matchAliasPatterns(const MCInst *MI, const MCSubtargetInfo *STI, 84 const AliasMatchingData &M); 85 86 public: 87 MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, 88 const MCRegisterInfo &mri) : MAI(mai), MII(mii), MRI(mri) {} 89 90 virtual ~MCInstPrinter(); 91 92 enum class Markup { 93 Immediate, 94 Register, 95 Target, 96 Memory, 97 }; 98 99 class WithMarkup { 100 public: 101 LLVM_CTOR_NODISCARD WithMarkup(raw_ostream &OS, Markup M, bool EnableMarkup, 102 bool EnableColor); 103 ~WithMarkup(); 104 105 template <typename T> WithMarkup &operator<<(T &O) { 106 OS << O; 107 return *this; 108 } 109 110 template <typename T> WithMarkup &operator<<(const T &O) { 111 OS << O; 112 return *this; 113 } 114 115 private: 116 raw_ostream &OS; 117 bool EnableMarkup; 118 bool EnableColor; 119 }; 120 121 /// Customize the printer according to a command line option. 122 /// @return true if the option is recognized and applied. 123 virtual bool applyTargetSpecificCLOption(StringRef Opt) { return false; } 124 125 /// Specify a stream to emit comments to. 126 void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } 127 128 /// Returns a pair containing the mnemonic for \p MI and the number of bits 129 /// left for further processing by printInstruction (generated by tablegen). 130 virtual std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) = 0; 131 132 /// Print the specified MCInst to the specified raw_ostream. 133 /// 134 /// \p Address the address of current instruction on most targets, used to 135 /// print a PC relative immediate as the target address. On targets where a PC 136 /// relative immediate is relative to the next instruction and the length of a 137 /// MCInst is difficult to measure (e.g. x86), this is the address of the next 138 /// instruction. If Address is 0, the immediate will be printed. 139 virtual void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, 140 const MCSubtargetInfo &STI, raw_ostream &OS) = 0; 141 142 /// Return the name of the specified opcode enum (e.g. "MOV32ri") or 143 /// empty if we can't resolve it. 144 StringRef getOpcodeName(unsigned Opcode) const; 145 146 /// Print the assembler register name. 147 virtual void printRegName(raw_ostream &OS, MCRegister Reg) const; 148 149 bool getUseMarkup() const { return UseMarkup; } 150 void setUseMarkup(bool Value) { UseMarkup = Value; } 151 152 bool getUseColor() const { return UseColor; } 153 void setUseColor(bool Value) { UseColor = Value; } 154 155 WithMarkup markup(raw_ostream &OS, Markup M) const; 156 157 bool getPrintImmHex() const { return PrintImmHex; } 158 void setPrintImmHex(bool Value) { PrintImmHex = Value; } 159 160 void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; } 161 162 void setPrintBranchImmAsAddress(bool Value) { 163 PrintBranchImmAsAddress = Value; 164 } 165 166 void setSymbolizeOperands(bool Value) { SymbolizeOperands = Value; } 167 void setMCInstrAnalysis(const MCInstrAnalysis *Value) { MIA = Value; } 168 169 /// Utility function to print immediates in decimal or hex. 170 format_object<int64_t> formatImm(int64_t Value) const { 171 return PrintImmHex ? formatHex(Value) : formatDec(Value); 172 } 173 174 /// Utility functions to print decimal/hexadecimal values. 175 format_object<int64_t> formatDec(int64_t Value) const; 176 format_object<int64_t> formatHex(int64_t Value) const; 177 format_object<uint64_t> formatHex(uint64_t Value) const; 178 }; 179 180 /// Map from opcode to pattern list by binary search. 181 struct PatternsForOpcode { 182 uint32_t Opcode; 183 uint16_t PatternStart; 184 uint16_t NumPatterns; 185 }; 186 187 /// Data for each alias pattern. Includes feature bits, string, number of 188 /// operands, and a variadic list of conditions to check. 189 struct AliasPattern { 190 uint32_t AsmStrOffset; 191 uint32_t AliasCondStart; 192 uint8_t NumOperands; 193 uint8_t NumConds; 194 }; 195 196 struct AliasPatternCond { 197 enum CondKind : uint8_t { 198 K_Feature, // Match only if a feature is enabled. 199 K_NegFeature, // Match only if a feature is disabled. 200 K_OrFeature, // Match only if one of a set of features is enabled. 201 K_OrNegFeature, // Match only if one of a set of features is disabled. 202 K_EndOrFeatures, // Note end of list of K_Or(Neg)?Features. 203 K_Ignore, // Match any operand. 204 K_Reg, // Match a specific register. 205 K_TiedReg, // Match another already matched register. 206 K_Imm, // Match a specific immediate. 207 K_RegClass, // Match registers in a class. 208 K_Custom, // Call custom matcher by index. 209 }; 210 211 CondKind Kind; 212 uint32_t Value; 213 }; 214 215 /// Tablegenerated data structures needed to match alias patterns. 216 struct AliasMatchingData { 217 ArrayRef<PatternsForOpcode> OpToPatterns; 218 ArrayRef<AliasPattern> Patterns; 219 ArrayRef<AliasPatternCond> PatternConds; 220 StringRef AsmStrings; 221 bool (*ValidateMCOperand)(const MCOperand &MCOp, const MCSubtargetInfo &STI, 222 unsigned PredicateIndex); 223 }; 224 225 } // end namespace llvm 226 227 #endif // LLVM_MC_MCINSTPRINTER_H 228