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