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 * = 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: |
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. |
128 | virtual bool applyTargetSpecificCLOption(StringRef Opt) { return false; } |
129 | |
130 | /// Specify a stream to emit comments to. |
131 | void (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 | |
155 | bool getUseMarkup() const { return UseMarkup; } |
156 | void setUseMarkup(bool Value) { UseMarkup = Value; } |
157 | |
158 | bool getUseColor() const { return UseColor; } |
159 | void setUseColor(bool Value) { UseColor = Value; } |
160 | |
161 | WithMarkup markup(raw_ostream &OS, Markup M); |
162 | |
163 | bool getPrintImmHex() const { return PrintImmHex; } |
164 | void setPrintImmHex(bool Value) { PrintImmHex = Value; } |
165 | |
166 | void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; } |
167 | |
168 | void setPrintBranchImmAsAddress(bool Value) { |
169 | PrintBranchImmAsAddress = Value; |
170 | } |
171 | |
172 | void setSymbolizeOperands(bool Value) { SymbolizeOperands = Value; } |
173 | void setMCInstrAnalysis(const MCInstrAnalysis *Value) { MIA = Value; } |
174 | |
175 | /// Utility function to print immediates in decimal or hex. |
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 | |