LLVM  14.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"
17 #include "llvm/Support/Format.h"
19 #include <cinttypes>
20 #include <cstdint>
21 
22 using namespace llvm;
23 
25  static const char hex_rep[] = "0123456789abcdef";
26  bool First = true;
27  for (char i: bytes) {
28  if (First)
29  First = false;
30  else
31  OS << ' ';
32  OS << hex_rep[(i & 0xF0) >> 4];
33  OS << hex_rep[i & 0xF];
34  }
35 }
36 
38 
39 /// getOpcodeName - Return the name of the specified opcode enum (e.g.
40 /// "MOV32ri") or empty if we can't resolve it.
41 StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const {
42  return MII.getName(Opcode);
43 }
44 
45 void MCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
46  llvm_unreachable("Target should implement this");
47 }
48 
50  if (!Annot.empty()) {
51  if (CommentStream) {
52  (*CommentStream) << Annot;
53  // By definition (see MCInstPrinter.h), CommentStream must end with
54  // a newline after each comment.
55  if (Annot.back() != '\n')
56  (*CommentStream) << '\n';
57  } else
58  OS << " " << MAI.getCommentString() << " " << Annot;
59  }
60 }
61 
62 static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI,
63  const MCRegisterInfo &MRI, unsigned &OpIdx,
64  const AliasMatchingData &M,
65  const AliasPatternCond &C,
66  bool &OrPredicateResult) {
67  // Feature tests are special, they don't consume operands.
68  if (C.Kind == AliasPatternCond::K_Feature)
69  return STI->getFeatureBits().test(C.Value);
71  return !STI->getFeatureBits().test(C.Value);
72  // For feature tests where just one feature is required in a list, set the
73  // predicate result bit to whether the expression will return true, and only
74  // return the real result at the end of list marker.
75  if (C.Kind == AliasPatternCond::K_OrFeature) {
76  OrPredicateResult |= STI->getFeatureBits().test(C.Value);
77  return true;
78  }
79  if (C.Kind == AliasPatternCond::K_OrNegFeature) {
80  OrPredicateResult |= !(STI->getFeatureBits().test(C.Value));
81  return true;
82  }
84  bool Res = OrPredicateResult;
85  OrPredicateResult = false;
86  return Res;
87  }
88 
89  // Get and consume an operand.
90  const MCOperand &Opnd = MI.getOperand(OpIdx);
91  ++OpIdx;
92 
93  // Check the specific condition for the operand.
94  switch (C.Kind) {
96  // Operand must be a specific immediate.
97  return Opnd.isImm() && Opnd.getImm() == int32_t(C.Value);
99  // Operand must be a specific register.
100  return Opnd.isReg() && Opnd.getReg() == C.Value;
102  // Operand must match the register of another operand.
103  return Opnd.isReg() && Opnd.getReg() == MI.getOperand(C.Value).getReg();
105  // Operand must be a register in this class. Value is a register class id.
106  return Opnd.isReg() && MRI.getRegClass(C.Value).contains(Opnd.getReg());
108  // Operand must match some custom criteria.
109  return M.ValidateMCOperand(Opnd, *STI, C.Value);
111  // Operand can be anything.
112  return true;
118  llvm_unreachable("handled earlier");
119  }
120  llvm_unreachable("invalid kind");
121 }
122 
124  const MCSubtargetInfo *STI,
125  const AliasMatchingData &M) {
126  // Binary search by opcode. Return false if there are no aliases for this
127  // opcode.
128  auto It = lower_bound(M.OpToPatterns, MI->getOpcode(),
129  [](const PatternsForOpcode &L, unsigned Opcode) {
130  return L.Opcode < Opcode;
131  });
132  if (It == M.OpToPatterns.end() || It->Opcode != MI->getOpcode())
133  return nullptr;
134 
135  // Try all patterns for this opcode.
136  uint32_t AsmStrOffset = ~0U;
137  ArrayRef<AliasPattern> Patterns =
138  M.Patterns.slice(It->PatternStart, It->NumPatterns);
139  for (const AliasPattern &P : Patterns) {
140  // Check operand count first.
141  if (MI->getNumOperands() != P.NumOperands)
142  return nullptr;
143 
144  // Test all conditions for this pattern.
146  M.PatternConds.slice(P.AliasCondStart, P.NumConds);
147  unsigned OpIdx = 0;
148  bool OrPredicateResult = false;
149  if (llvm::all_of(Conds, [&](const AliasPatternCond &C) {
150  return matchAliasCondition(*MI, STI, MRI, OpIdx, M, C,
151  OrPredicateResult);
152  })) {
153  // If all conditions matched, use this asm string.
154  AsmStrOffset = P.AsmStrOffset;
155  break;
156  }
157  }
158 
159  // If no alias matched, don't print an alias.
160  if (AsmStrOffset == ~0U)
161  return nullptr;
162 
163  // Go to offset AsmStrOffset and use the null terminated string there. The
164  // offset should point to the beginning of an alias string, so it should
165  // either be zero or be preceded by a null byte.
166  assert(AsmStrOffset < M.AsmStrings.size() &&
167  (AsmStrOffset == 0 || M.AsmStrings[AsmStrOffset - 1] == '\0') &&
168  "bad asm string offset");
169  return M.AsmStrings.data() + AsmStrOffset;
170 }
171 
172 /// Utility functions to make adding mark ups simpler.
174  if (getUseMarkup())
175  return s;
176  else
177  return "";
178 }
179 
180 // For asm-style hex (e.g. 0ffh) the first digit always has to be a number.
182 {
183  while (Value)
184  {
185  uint64_t digit = (Value >> 60) & 0xf;
186  if (digit != 0)
187  return (digit >= 0xa);
188  Value <<= 4;
189  }
190  return false;
191 }
192 
194  return format("%" PRId64, Value);
195 }
196 
198  switch (PrintHexStyle) {
199  case HexStyle::C:
200  if (Value < 0) {
202  return format<int64_t>("-0x8000000000000000", Value);
203  return format("-0x%" PRIx64, -Value);
204  }
205  return format("0x%" PRIx64, Value);
206  case HexStyle::Asm:
207  if (Value < 0) {
209  return format<int64_t>("-8000000000000000h", Value);
211  return format("-0%" PRIx64 "h", -Value);
212  return format("-%" PRIx64 "h", -Value);
213  }
215  return format("0%" PRIx64 "h", Value);
216  return format("%" PRIx64 "h", Value);
217  }
218  llvm_unreachable("unsupported print style");
219 }
220 
222  switch(PrintHexStyle) {
223  case HexStyle::C:
224  return format("0x%" PRIx64, Value);
225  case HexStyle::Asm:
226  if (needsLeadingZero(Value))
227  return format("0%" PRIx64 "h", Value);
228  else
229  return format("%" PRIx64 "h", Value);
230  }
231  llvm_unreachable("unsupported print style");
232 }
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:193
llvm::MCInstPrinter::MII
const MCInstrInfo & MII
Definition: MCInstPrinter.h:50
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::MCAsmInfo::getCommentString
StringRef getCommentString() const
Definition: MCAsmInfo.h:641
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::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
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:1661
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:62
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:93
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:1551
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:111
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:123
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
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:49
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:634
llvm::AliasPatternCond::K_EndOrFeatures
@ K_EndOrFeatures
Definition: MCInstPrinter.h:166
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
llvm::MCInstPrinter::printRegName
virtual void printRegName(raw_ostream &OS, unsigned RegNo) const
Print the assembler register name.
Definition: MCInstPrinter.cpp:45
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:24
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:197
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:68
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:134
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:181
llvm::MCInstPrinter::getOpcodeName
StringRef getOpcodeName(unsigned Opcode) const
Return the name of the specified opcode enum (e.g.
Definition: MCInstPrinter.cpp:41
llvm::MCInstPrinter::markup
StringRef markup(StringRef s) const
Utility functions to make adding mark ups simpler.
Definition: MCInstPrinter.cpp:173
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:75
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