xref: /freebsd/contrib/llvm-project/llvm/include/llvm/MC/MCInstPrinter.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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