xref: /llvm-project/llvm/include/llvm/MC/MCInstPrinter.h (revision eeb987f6f35aa614ed7a555be33d67c5cb1be230)
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 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 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:
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 WithMarkup(MCInstPrinter &IP, raw_ostream &OS, Markup M,
105                                    bool EnableMarkup, bool EnableColor);
106     ~WithMarkup();
107 
108     template <typename T> WithMarkup &operator<<(T &O) {
109       OS << O;
110       return *this;
111     }
112 
113     template <typename T> WithMarkup &operator<<(const T &O) {
114       OS << O;
115       return *this;
116     }
117 
118   private:
119     MCInstPrinter &IP;
120     raw_ostream &OS;
121     bool EnableMarkup;
122     bool EnableColor;
123   };
124 
125   /// Customize the printer according to a command line option.
126   /// @return true if the option is recognized and applied.
127   virtual bool applyTargetSpecificCLOption(StringRef Opt) { return false; }
128 
129   /// Specify a stream to emit comments to.
130   void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
131 
132   /// Returns a pair containing the mnemonic for \p MI and the number of bits
133   /// left for further processing by printInstruction (generated by tablegen).
134   virtual std::pair<const char *, uint64_t>
135   getMnemonic(const MCInst &MI) const = 0;
136 
137   /// Print the specified MCInst to the specified raw_ostream.
138   ///
139   /// \p Address the address of current instruction on most targets, used to
140   /// print a PC relative immediate as the target address. On targets where a PC
141   /// relative immediate is relative to the next instruction and the length of a
142   /// MCInst is difficult to measure (e.g. x86), this is the address of the next
143   /// instruction. If Address is 0, the immediate will be printed.
144   virtual void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
145                          const MCSubtargetInfo &STI, raw_ostream &OS) = 0;
146 
147   /// Return the name of the specified opcode enum (e.g. "MOV32ri") or
148   /// empty if we can't resolve it.
149   StringRef getOpcodeName(unsigned Opcode) const;
150 
151   /// Print the assembler register name.
152   virtual void printRegName(raw_ostream &OS, MCRegister Reg);
153 
154   bool getUseMarkup() const { return UseMarkup; }
155   void setUseMarkup(bool Value) { UseMarkup = Value; }
156 
157   bool getUseColor() const { return UseColor; }
158   void setUseColor(bool Value) { UseColor = Value; }
159 
160   WithMarkup markup(raw_ostream &OS, Markup M);
161 
162   bool getPrintImmHex() const { return PrintImmHex; }
163   void setPrintImmHex(bool Value) { PrintImmHex = Value; }
164 
165   void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; }
166 
167   void setPrintBranchImmAsAddress(bool Value) {
168     PrintBranchImmAsAddress = Value;
169   }
170 
171   void setSymbolizeOperands(bool Value) { SymbolizeOperands = Value; }
172   void setMCInstrAnalysis(const MCInstrAnalysis *Value) { MIA = Value; }
173 
174   /// Utility function to print immediates in decimal or hex.
175   format_object<int64_t> formatImm(int64_t Value) const {
176     return PrintImmHex ? formatHex(Value) : formatDec(Value);
177   }
178 
179   /// Utility functions to print decimal/hexadecimal values.
180   format_object<int64_t> formatDec(int64_t Value) const;
181   format_object<int64_t> formatHex(int64_t Value) const;
182   format_object<uint64_t> formatHex(uint64_t Value) const;
183 };
184 
185 /// Map from opcode to pattern list by binary search.
186 struct PatternsForOpcode {
187   uint32_t Opcode;
188   uint16_t PatternStart;
189   uint16_t NumPatterns;
190 };
191 
192 /// Data for each alias pattern. Includes feature bits, string, number of
193 /// operands, and a variadic list of conditions to check.
194 struct AliasPattern {
195   uint32_t AsmStrOffset;
196   uint32_t AliasCondStart;
197   uint8_t NumOperands;
198   uint8_t NumConds;
199 };
200 
201 struct AliasPatternCond {
202   enum CondKind : uint8_t {
203     K_Feature,       // Match only if a feature is enabled.
204     K_NegFeature,    // Match only if a feature is disabled.
205     K_OrFeature,     // Match only if one of a set of features is enabled.
206     K_OrNegFeature,  // Match only if one of a set of features is disabled.
207     K_EndOrFeatures, // Note end of list of K_Or(Neg)?Features.
208     K_Ignore,        // Match any operand.
209     K_Reg,           // Match a specific register.
210     K_TiedReg,       // Match another already matched register.
211     K_Imm,           // Match a specific immediate.
212     K_RegClass,      // Match registers in a class.
213     K_Custom,        // Call custom matcher by index.
214   };
215 
216   CondKind Kind;
217   uint32_t Value;
218 };
219 
220 /// Tablegenerated data structures needed to match alias patterns.
221 struct AliasMatchingData {
222   ArrayRef<PatternsForOpcode> OpToPatterns;
223   ArrayRef<AliasPattern> Patterns;
224   ArrayRef<AliasPatternCond> PatternConds;
225   StringRef AsmStrings;
226   bool (*ValidateMCOperand)(const MCOperand &MCOp, const MCSubtargetInfo &STI,
227                             unsigned PredicateIndex);
228 };
229 
230 } // end namespace llvm
231 
232 #endif // LLVM_MC_MCINSTPRINTER_H
233