LLVM  15.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"
15 #include "llvm/MC/MCRegisterInfo.h"
18 #include "llvm/Support/Format.h"
20 #include <cinttypes>
21 #include <cstdint>
22 
23 using 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.
42 StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const {
43  return MII.getName(Opcode);
44 }
45 
46 void MCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
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 
63 static 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.
69  if (C.Kind == AliasPatternCond::K_Feature)
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  }
80  if (C.Kind == AliasPatternCond::K_OrNegFeature) {
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) {
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) {
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:
227  if (needsLeadingZero(Value))
228  return format("0%" PRIx64 "h", Value);
229  else
230  return format("%" PRIx64 "h", Value);
231  }
232  llvm_unreachable("unsupported print style");
233 }
i
i
Definition: README.txt:29
llvm::MCInstPrinter::formatDec
format_object< int64_t > formatDec(int64_t Value) const
Utility functions to print decimal/hexadecimal values.
Definition: MCInstPrinter.cpp:194
llvm::MCInstPrinter::MII
const MCInstrInfo & MII
Definition: MCInstPrinter.h:50
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::MCAsmInfo::getCommentString
StringRef getCommentString() const
Definition: MCAsmInfo.h:653
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::MCOperand::isReg
bool isReg() const
Definition: MCInst.h:61
llvm::lower_bound
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:1724
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
matchAliasCondition
static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI, const MCRegisterInfo &MRI, unsigned &OpIdx, const AliasMatchingData &M, const AliasPatternCond &C, bool &OrPredicateResult)
Definition: MCInstPrinter.cpp:63
llvm::AliasPatternCond::K_Imm
@ K_Imm
Definition: MCInstPrinter.h:170
ErrorHandling.h
llvm::MCInstPrinter::getUseMarkup
bool getUseMarkup() const
Definition: MCInstPrinter.h:115
llvm::AliasPatternCond::K_Feature
@ K_Feature
Definition: MCInstPrinter.h:162
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Format.h
llvm::AliasMatchingData
Tablegenerated data structures needed to match alias patterns.
Definition: MCInstPrinter.h:180
llvm::MCInstPrinter::MRI
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:51
llvm::TargetRegisterClass::contains
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
Definition: TargetRegisterInfo.h:94
llvm::all_of
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:1605
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::AliasPatternCond::K_OrFeature
@ K_OrFeature
Definition: MCInstPrinter.h:164
MCInstrInfo.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
MCInst.h
First
into llvm powi allowing the code generator to produce balanced multiplication trees First
Definition: README.txt:54
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:112
llvm::PatternsForOpcode
Map from opcode to pattern list by binary search.
Definition: MCInstPrinter.h:145
llvm::MCInstPrinter::matchAliasPatterns
const char * matchAliasPatterns(const MCInst *MI, const MCSubtargetInfo *STI, const AliasMatchingData &M)
Helper for matching MCInsts to alias patterns when printing instructions.
Definition: MCInstPrinter.cpp:124
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::MCInstPrinter::CommentStream
raw_ostream * CommentStream
A stream that comments can be emitted to if desired.
Definition: MCInstPrinter.h:48
llvm::AliasPatternCond::K_OrNegFeature
@ K_OrNegFeature
Definition: MCInstPrinter.h:165
llvm::AliasPatternCond
Definition: MCInstPrinter.h:160
MCInstPrinter.h
llvm::MCInstPrinter::printAnnotation
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
Definition: MCInstPrinter.cpp:50
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:642
llvm::AliasPatternCond::K_EndOrFeatures
@ K_EndOrFeatures
Definition: MCInstPrinter.h:166
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::MCInstPrinter::printRegName
virtual void printRegName(raw_ostream &OS, unsigned RegNo) const
Print the assembler register name.
Definition: MCInstPrinter.cpp:46
uint64_t
llvm::dumpBytes
void dumpBytes(ArrayRef< uint8_t > Bytes, raw_ostream &OS)
Convert ‘Bytes’ to a hex string and output to ‘OS’.
Definition: MCInstPrinter.cpp:25
s
multiplies can be turned into SHL s
Definition: README.txt:370
llvm::MCInstPrinter::formatHex
format_object< int64_t > formatHex(int64_t Value) const
Definition: MCInstPrinter.cpp:198
MCRegisterInfo.h
ArrayRef.h
llvm::MCInstPrinter::PrintHexStyle
HexStyle::Style PrintHexStyle
Which style to use for printing hexadecimal values.
Definition: MCInstPrinter.h:64
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MCInstrInfo::getName
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition: MCInstrInfo.h:69
llvm::ArrayRef< uint8_t >
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
MCAsmInfo.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
uint32_t
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::AliasPatternCond::K_Ignore
@ K_Ignore
Definition: MCInstPrinter.h:167
llvm::HexStyle::C
@ C
0xff
Definition: MCInstPrinter.h:33
needsLeadingZero
static bool needsLeadingZero(uint64_t Value)
Definition: MCInstPrinter.cpp:182
llvm::MCInstPrinter::getOpcodeName
StringRef getOpcodeName(unsigned Opcode) const
Return the name of the specified opcode enum (e.g.
Definition: MCInstPrinter.cpp:42
llvm::MCInstPrinter::markup
StringRef markup(StringRef s) const
Utility functions to make adding mark ups simpler.
Definition: MCInstPrinter.cpp:174
llvm::AliasPattern
Data for each alias pattern.
Definition: MCInstPrinter.h:153
llvm::FeatureBitset::test
constexpr bool test(unsigned I) const
Definition: SubtargetFeature.h:90
llvm::MCInstPrinter::MAI
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:49
llvm::AliasPatternCond::K_TiedReg
@ K_TiedReg
Definition: MCInstPrinter.h:169
llvm::AliasPatternCond::K_RegClass
@ K_RegClass
Definition: MCInstPrinter.h:171
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::format_object
Definition: Format.h:90
llvm::AliasPatternCond::K_Reg
@ K_Reg
Definition: MCInstPrinter.h:168
raw_ostream.h
llvm::AliasPatternCond::K_NegFeature
@ K_NegFeature
Definition: MCInstPrinter.h:163
llvm::MCInstPrinter::~MCInstPrinter
virtual ~MCInstPrinter()
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::AliasPatternCond::K_Custom
@ K_Custom
Definition: MCInstPrinter.h:172
llvm::MCOperand::getReg
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69