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