LLVM 17.0.0git
MCInstPrinter.cpp
Go to the documentation of this file.
1//===- MCInstPrinter.cpp - Convert an MCInst to target assembly syntax ----===//
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
10#include "llvm/ADT/ArrayRef.h"
11#include "llvm/ADT/StringRef.h"
12#include "llvm/MC/MCAsmInfo.h"
13#include "llvm/MC/MCInst.h"
14#include "llvm/MC/MCInstrInfo.h"
18#include "llvm/Support/Format.h"
20#include <cinttypes>
21#include <cstdint>
22
23using namespace llvm;
24
26 static const char hex_rep[] = "0123456789abcdef";
27 bool First = true;
28 for (char i: bytes) {
29 if (First)
30 First = false;
31 else
32 OS << ' ';
33 OS << hex_rep[(i & 0xF0) >> 4];
34 OS << hex_rep[i & 0xF];
35 }
36}
37
39
40/// getOpcodeName - Return the name of the specified opcode enum (e.g.
41/// "MOV32ri") or empty if we can't resolve it.
43 return MII.getName(Opcode);
44}
45
47 llvm_unreachable("Target should implement this");
48}
49
51 if (!Annot.empty()) {
52 if (CommentStream) {
53 (*CommentStream) << Annot;
54 // By definition (see MCInstPrinter.h), CommentStream must end with
55 // a newline after each comment.
56 if (Annot.back() != '\n')
57 (*CommentStream) << '\n';
58 } else
59 OS << " " << MAI.getCommentString() << " " << Annot;
60 }
61}
62
63static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI,
64 const MCRegisterInfo &MRI, unsigned &OpIdx,
65 const AliasMatchingData &M,
66 const AliasPatternCond &C,
67 bool &OrPredicateResult) {
68 // Feature tests are special, they don't consume operands.
70 return STI->getFeatureBits().test(C.Value);
72 return !STI->getFeatureBits().test(C.Value);
73 // For feature tests where just one feature is required in a list, set the
74 // predicate result bit to whether the expression will return true, and only
75 // return the real result at the end of list marker.
76 if (C.Kind == AliasPatternCond::K_OrFeature) {
77 OrPredicateResult |= STI->getFeatureBits().test(C.Value);
78 return true;
79 }
81 OrPredicateResult |= !(STI->getFeatureBits().test(C.Value));
82 return true;
83 }
85 bool Res = OrPredicateResult;
86 OrPredicateResult = false;
87 return Res;
88 }
89
90 // Get and consume an operand.
91 const MCOperand &Opnd = MI.getOperand(OpIdx);
92 ++OpIdx;
93
94 // Check the specific condition for the operand.
95 switch (C.Kind) {
97 // Operand must be a specific immediate.
98 return Opnd.isImm() && Opnd.getImm() == int32_t(C.Value);
100 // Operand must be a specific register.
101 return Opnd.isReg() && Opnd.getReg() == C.Value;
103 // Operand must match the register of another operand.
104 return Opnd.isReg() && Opnd.getReg() == MI.getOperand(C.Value).getReg();
106 // Operand must be a register in this class. Value is a register class id.
107 return Opnd.isReg() && MRI.getRegClass(C.Value).contains(Opnd.getReg());
109 // Operand must match some custom criteria.
110 return M.ValidateMCOperand(Opnd, *STI, C.Value);
112 // Operand can be anything.
113 return true;
119 llvm_unreachable("handled earlier");
120 }
121 llvm_unreachable("invalid kind");
122}
123
125 const MCSubtargetInfo *STI,
126 const AliasMatchingData &M) {
127 // Binary search by opcode. Return false if there are no aliases for this
128 // opcode.
129 auto It = lower_bound(M.OpToPatterns, MI->getOpcode(),
130 [](const PatternsForOpcode &L, unsigned Opcode) {
131 return L.Opcode < Opcode;
132 });
133 if (It == M.OpToPatterns.end() || It->Opcode != MI->getOpcode())
134 return nullptr;
135
136 // Try all patterns for this opcode.
137 uint32_t AsmStrOffset = ~0U;
138 ArrayRef<AliasPattern> Patterns =
139 M.Patterns.slice(It->PatternStart, It->NumPatterns);
140 for (const AliasPattern &P : Patterns) {
141 // Check operand count first.
142 if (MI->getNumOperands() != P.NumOperands)
143 return nullptr;
144
145 // Test all conditions for this pattern.
147 M.PatternConds.slice(P.AliasCondStart, P.NumConds);
148 unsigned OpIdx = 0;
149 bool OrPredicateResult = false;
150 if (llvm::all_of(Conds, [&](const AliasPatternCond &C) {
151 return matchAliasCondition(*MI, STI, MRI, OpIdx, M, C,
152 OrPredicateResult);
153 })) {
154 // If all conditions matched, use this asm string.
155 AsmStrOffset = P.AsmStrOffset;
156 break;
157 }
158 }
159
160 // If no alias matched, don't print an alias.
161 if (AsmStrOffset == ~0U)
162 return nullptr;
163
164 // Go to offset AsmStrOffset and use the null terminated string there. The
165 // offset should point to the beginning of an alias string, so it should
166 // either be zero or be preceded by a null byte.
167 assert(AsmStrOffset < M.AsmStrings.size() &&
168 (AsmStrOffset == 0 || M.AsmStrings[AsmStrOffset - 1] == '\0') &&
169 "bad asm string offset");
170 return M.AsmStrings.data() + AsmStrOffset;
171}
172
173/// Utility functions to make adding mark ups simpler.
175 if (getUseMarkup())
176 return s;
177 else
178 return "";
179}
180
181// For asm-style hex (e.g. 0ffh) the first digit always has to be a number.
183{
184 while (Value)
185 {
186 uint64_t digit = (Value >> 60) & 0xf;
187 if (digit != 0)
188 return (digit >= 0xa);
189 Value <<= 4;
190 }
191 return false;
192}
193
195 return format("%" PRId64, Value);
196}
197
199 switch (PrintHexStyle) {
200 case HexStyle::C:
201 if (Value < 0) {
202 if (Value == std::numeric_limits<int64_t>::min())
203 return format<int64_t>("-0x8000000000000000", Value);
204 return format("-0x%" PRIx64, -Value);
205 }
206 return format("0x%" PRIx64, Value);
207 case HexStyle::Asm:
208 if (Value < 0) {
209 if (Value == std::numeric_limits<int64_t>::min())
210 return format<int64_t>("-8000000000000000h", Value);
212 return format("-0%" PRIx64 "h", -Value);
213 return format("-%" PRIx64 "h", -Value);
214 }
216 return format("0%" PRIx64 "h", Value);
217 return format("%" PRIx64 "h", Value);
218 }
219 llvm_unreachable("unsupported print style");
220}
221
223 switch(PrintHexStyle) {
224 case HexStyle::C:
225 return format("0x%" PRIx64, Value);
226 case HexStyle::Asm:
228 return format("0%" PRIx64 "h", Value);
229 else
230 return format("%" PRIx64 "h", Value);
231 }
232 llvm_unreachable("unsupported print style");
233}
unsigned const MachineRegisterInfo * MRI
IRTranslator LLVM IR MI
static bool needsLeadingZero(uint64_t Value)
static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI, const MCRegisterInfo &MRI, unsigned &OpIdx, const AliasMatchingData &M, const AliasPatternCond &C, bool &OrPredicateResult)
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
constexpr bool test(unsigned I) const
StringRef getCommentString() const
Definition: MCAsmInfo.h:655
format_object< int64_t > formatHex(int64_t Value) const
const MCInstrInfo & MII
Definition: MCInstPrinter.h:51
raw_ostream * CommentStream
A stream that comments can be emitted to if desired.
Definition: MCInstPrinter.h:49
virtual ~MCInstPrinter()
virtual void printRegName(raw_ostream &OS, MCRegister Reg) const
Print the assembler register name.
StringRef getOpcodeName(unsigned Opcode) const
Return the name of the specified opcode enum (e.g.
StringRef markup(StringRef s) const
Utility functions to make adding mark ups simpler.
format_object< int64_t > formatDec(int64_t Value) const
Utility functions to print decimal/hexadecimal values.
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:52
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:50
bool getUseMarkup() const
const char * matchAliasPatterns(const MCInst *MI, const MCSubtargetInfo *STI, const AliasMatchingData &M)
Helper for matching MCInsts to alias patterns when printing instructions.
HexStyle::Style PrintHexStyle
Which style to use for printing hexadecimal values.
Definition: MCInstPrinter.h:65
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition: MCInstrInfo.h:70
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
int64_t getImm() const
Definition: MCInst.h:80
bool isImm() const
Definition: MCInst.h:62
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69
bool isReg() const
Definition: MCInst.h:61
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1819
void dumpBytes(ArrayRef< uint8_t > Bytes, raw_ostream &OS)
Convert ‘Bytes’ to a hex string and output to ‘OS’.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:2038
Tablegenerated data structures needed to match alias patterns.
Data for each alias pattern.
Map from opcode to pattern list by binary search.