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
18namespace llvm {
19
20class MCAsmInfo;
21class MCInst;
22class MCInstrAnalysis;
23class MCInstrInfo;
24class MCOperand;
25class MCRegister;
26class MCRegisterInfo;
27class MCSubtargetInfo;
28class StringRef;
29
30/// Convert `Bytes' to a hex string and output to `OS'
31LLVM_ABI void dumpBytes(ArrayRef<uint8_t> Bytes, raw_ostream &OS);
32
33namespace HexStyle {
34
35enum Style {
36 C, ///< 0xff
37 Asm ///< 0ffh
38};
39
40} // end namespace HexStyle
41
42struct AliasMatchingData;
43
44/// This is an instance of a target assembly language printer that
45/// converts an MCInst to valid target assembly syntax.
46class LLVM_ABI MCInstPrinter {
47protected:
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
89public:
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 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
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.
187struct 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.
195struct AliasPattern {
196 uint32_t AsmStrOffset;
197 uint32_t AliasCondStart;
198 uint8_t NumOperands;
199 uint8_t NumConds;
200};
201
202struct 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.
222struct 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