LLVM  14.0.0git
WebAssemblyInstPrinter.cpp
Go to the documentation of this file.
1 //=- WebAssemblyInstPrinter.cpp - WebAssembly assembly instruction printing -=//
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 /// \file
10 /// Print MCInst instructions to wasm format.
11 ///
12 //===----------------------------------------------------------------------===//
13 
18 #include "WebAssembly.h"
20 #include "llvm/ADT/SmallSet.h"
21 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrInfo.h"
27 #include "llvm/MC/MCSymbol.h"
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "asm-printer"
33 
34 #include "WebAssemblyGenAsmWriter.inc"
35 
37  const MCInstrInfo &MII,
38  const MCRegisterInfo &MRI)
39  : MCInstPrinter(MAI, MII, MRI) {}
40 
42  unsigned RegNo) const {
44  // Note that there's an implicit local.get/local.set here!
45  OS << "$" << RegNo;
46 }
47 
49  StringRef Annot,
50  const MCSubtargetInfo &STI,
51  raw_ostream &OS) {
52  switch (MI->getOpcode()) {
53  case WebAssembly::CALL_INDIRECT_S:
54  case WebAssembly::RET_CALL_INDIRECT_S: {
55  // A special case for call_indirect (and ret_call_indirect), if the table
56  // operand is a symbol: the order of the type and table operands is inverted
57  // in the text format relative to the binary format. Otherwise if table the
58  // operand isn't a symbol, then we have an MVP compilation unit, and the
59  // table shouldn't appear in the output.
60  OS << "\t";
61  OS << getMnemonic(MI).first;
62  OS << " ";
63 
64  assert(MI->getNumOperands() == 2);
65  const unsigned TypeOperand = 0;
66  const unsigned TableOperand = 1;
67  if (MI->getOperand(TableOperand).isExpr()) {
68  printOperand(MI, TableOperand, OS);
69  OS << ", ";
70  } else {
71  assert(MI->getOperand(TableOperand).getImm() == 0);
72  }
73  printOperand(MI, TypeOperand, OS);
74  break;
75  }
76  default:
77  // Print the instruction (this uses the AsmStrings from the .td files).
79  break;
80  }
81 
82  // Print any additional variadic operands.
83  const MCInstrDesc &Desc = MII.get(MI->getOpcode());
84  if (Desc.isVariadic()) {
85  if ((Desc.getNumOperands() == 0 && MI->getNumOperands() > 0) ||
86  Desc.variadicOpsAreDefs())
87  OS << "\t";
88  unsigned Start = Desc.getNumOperands();
89  unsigned NumVariadicDefs = 0;
90  if (Desc.variadicOpsAreDefs()) {
91  // The number of variadic defs is encoded in an immediate by MCInstLower
92  NumVariadicDefs = MI->getOperand(0).getImm();
93  Start = 1;
94  }
95  bool NeedsComma = Desc.getNumOperands() > 0 && !Desc.variadicOpsAreDefs();
96  for (auto I = Start, E = MI->getNumOperands(); I < E; ++I) {
97  if (MI->getOpcode() == WebAssembly::CALL_INDIRECT &&
98  I - Start == NumVariadicDefs) {
99  // Skip type and table arguments when printing for tests.
100  ++I;
101  continue;
102  }
103  if (NeedsComma)
104  OS << ", ";
105  printOperand(MI, I, OS, I - Start < NumVariadicDefs);
106  NeedsComma = true;
107  }
108  }
109 
110  // Print any added annotation.
111  printAnnotation(OS, Annot);
112 
113  if (CommentStream) {
114  // Observe any effects on the control flow stack, for use in annotating
115  // control flow label references.
116  unsigned Opc = MI->getOpcode();
117  switch (Opc) {
118  default:
119  break;
120 
121  case WebAssembly::LOOP:
122  case WebAssembly::LOOP_S:
123  printAnnotation(OS, "label" + utostr(ControlFlowCounter) + ':');
124  ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, true));
125  return;
126 
127  case WebAssembly::BLOCK:
128  case WebAssembly::BLOCK_S:
129  ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false));
130  return;
131 
132  case WebAssembly::TRY:
133  case WebAssembly::TRY_S:
134  ControlFlowStack.push_back(std::make_pair(ControlFlowCounter, false));
135  TryStack.push_back(ControlFlowCounter++);
136  EHInstStack.push_back(TRY);
137  return;
138 
139  case WebAssembly::END_LOOP:
140  case WebAssembly::END_LOOP_S:
141  if (ControlFlowStack.empty()) {
142  printAnnotation(OS, "End marker mismatch!");
143  } else {
144  ControlFlowStack.pop_back();
145  }
146  return;
147 
149  case WebAssembly::END_BLOCK_S:
150  if (ControlFlowStack.empty()) {
151  printAnnotation(OS, "End marker mismatch!");
152  } else {
154  OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
155  }
156  return;
157 
158  case WebAssembly::END_TRY:
159  case WebAssembly::END_TRY_S:
160  if (ControlFlowStack.empty() || EHInstStack.empty()) {
161  printAnnotation(OS, "End marker mismatch!");
162  } else {
164  OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
165  EHInstStack.pop_back();
166  }
167  return;
168 
169  case WebAssembly::CATCH:
170  case WebAssembly::CATCH_S:
171  case WebAssembly::CATCH_ALL:
172  case WebAssembly::CATCH_ALL_S:
173  // There can be multiple catch instructions for one try instruction, so
174  // we print a label only for the first 'catch' label.
175  if (EHInstStack.empty()) {
176  printAnnotation(OS, "try-catch mismatch!");
177  } else if (EHInstStack.back() == CATCH_ALL) {
178  printAnnotation(OS, "catch/catch_all cannot occur after catch_all");
179  } else if (EHInstStack.back() == TRY) {
180  if (TryStack.empty()) {
181  printAnnotation(OS, "try-catch mismatch!");
182  } else {
183  printAnnotation(OS, "catch" + utostr(TryStack.pop_back_val()) + ':');
184  }
185  EHInstStack.pop_back();
186  if (Opc == WebAssembly::CATCH || Opc == WebAssembly::CATCH_S) {
187  EHInstStack.push_back(CATCH);
188  } else {
189  EHInstStack.push_back(CATCH_ALL);
190  }
191  }
192  return;
193 
194  case WebAssembly::RETHROW:
195  case WebAssembly::RETHROW_S:
196  // 'rethrow' rethrows to the nearest enclosing catch scope, if any. If
197  // there's no enclosing catch scope, it throws up to the caller.
198  if (TryStack.empty()) {
199  printAnnotation(OS, "to caller");
200  } else {
201  printAnnotation(OS, "down to catch" + utostr(TryStack.back()));
202  }
203  return;
204 
206  case WebAssembly::DELEGATE_S:
207  if (ControlFlowStack.empty() || TryStack.empty() || EHInstStack.empty()) {
208  printAnnotation(OS, "try-delegate mismatch!");
209  } else {
210  // 'delegate' is
211  // 1. A marker for the end of block label
212  // 2. A destination for throwing instructions
213  // 3. An instruction that itself rethrows to another 'catch'
214  assert(ControlFlowStack.back().first == TryStack.back());
215  std::string Label = "label/catch" +
216  utostr(ControlFlowStack.pop_back_val().first) +
217  ": ";
218  TryStack.pop_back();
219  EHInstStack.pop_back();
220  uint64_t Depth = MI->getOperand(0).getImm();
221  if (Depth >= ControlFlowStack.size()) {
222  Label += "to caller";
223  } else {
224  const auto &Pair = ControlFlowStack.rbegin()[Depth];
225  if (Pair.second)
226  printAnnotation(OS, "delegate cannot target a loop");
227  else
228  Label += "down to catch" + utostr(Pair.first);
229  }
230  printAnnotation(OS, Label);
231  }
232  return;
233  }
234 
235  // Annotate any control flow label references.
236 
237  unsigned NumFixedOperands = Desc.NumOperands;
238  SmallSet<uint64_t, 8> Printed;
239  for (unsigned I = 0, E = MI->getNumOperands(); I < E; ++I) {
240  // See if this operand denotes a basic block target.
241  if (I < NumFixedOperands) {
242  // A non-variable_ops operand, check its type.
244  continue;
245  } else {
246  // A variable_ops operand, which currently can be immediates (used in
247  // br_table) which are basic block targets, or for call instructions
248  // when using -wasm-keep-registers (in which case they are registers,
249  // and should not be processed).
250  if (!MI->getOperand(I).isImm())
251  continue;
252  }
253  uint64_t Depth = MI->getOperand(I).getImm();
254  if (!Printed.insert(Depth).second)
255  continue;
256  if (Depth >= ControlFlowStack.size()) {
257  printAnnotation(OS, "Invalid depth argument!");
258  } else {
259  const auto &Pair = ControlFlowStack.rbegin()[Depth];
260  printAnnotation(OS, utostr(Depth) + ": " +
261  (Pair.second ? "up" : "down") + " to label" +
262  utostr(Pair.first));
263  }
264  }
265  }
266 }
267 
268 static std::string toString(const APFloat &FP) {
269  // Print NaNs with custom payloads specially.
270  if (FP.isNaN() && !FP.bitwiseIsEqual(APFloat::getQNaN(FP.getSemantics())) &&
271  !FP.bitwiseIsEqual(
272  APFloat::getQNaN(FP.getSemantics(), /*Negative=*/true))) {
273  APInt AI = FP.bitcastToAPInt();
274  return std::string(AI.isNegative() ? "-" : "") + "nan:0x" +
275  utohexstr(AI.getZExtValue() &
276  (AI.getBitWidth() == 32 ? INT64_C(0x007fffff)
277  : INT64_C(0x000fffffffffffff)),
278  /*LowerCase=*/true);
279  }
280 
281  // Use C99's hexadecimal floating-point representation.
282  static const size_t BufBytes = 128;
283  char Buf[BufBytes];
284  auto Written = FP.convertToHexString(
285  Buf, /*HexDigits=*/0, /*UpperCase=*/false, APFloat::rmNearestTiesToEven);
286  (void)Written;
287  assert(Written != 0);
288  assert(Written < BufBytes);
289  return Buf;
290 }
291 
292 void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
293  raw_ostream &O, bool IsVariadicDef) {
294  const MCOperand &Op = MI->getOperand(OpNo);
295  if (Op.isReg()) {
296  const MCInstrDesc &Desc = MII.get(MI->getOpcode());
297  unsigned WAReg = Op.getReg();
298  if (int(WAReg) >= 0)
299  printRegName(O, WAReg);
300  else if (OpNo >= Desc.getNumDefs() && !IsVariadicDef)
301  O << "$pop" << WebAssemblyFunctionInfo::getWARegStackId(WAReg);
302  else if (WAReg != WebAssemblyFunctionInfo::UnusedReg)
303  O << "$push" << WebAssemblyFunctionInfo::getWARegStackId(WAReg);
304  else
305  O << "$drop";
306  // Add a '=' suffix if this is a def.
307  if (OpNo < MII.get(MI->getOpcode()).getNumDefs() || IsVariadicDef)
308  O << '=';
309  } else if (Op.isImm()) {
310  O << Op.getImm();
311  } else if (Op.isSFPImm()) {
312  O << ::toString(APFloat(APFloat::IEEEsingle(), APInt(32, Op.getSFPImm())));
313  } else if (Op.isDFPImm()) {
314  O << ::toString(APFloat(APFloat::IEEEdouble(), APInt(64, Op.getDFPImm())));
315  } else {
316  assert(Op.isExpr() && "unknown operand kind in printOperand");
317  // call_indirect instructions have a TYPEINDEX operand that we print
318  // as a signature here, such that the assembler can recover this
319  // information.
320  auto SRE = static_cast<const MCSymbolRefExpr *>(Op.getExpr());
321  if (SRE->getKind() == MCSymbolRefExpr::VK_WASM_TYPEINDEX) {
322  auto &Sym = static_cast<const MCSymbolWasm &>(SRE->getSymbol());
323  O << WebAssembly::signatureToString(Sym.getSignature());
324  } else {
325  Op.getExpr()->print(O, &MAI);
326  }
327  }
328 }
329 
330 void WebAssemblyInstPrinter::printBrList(const MCInst *MI, unsigned OpNo,
331  raw_ostream &O) {
332  O << "{";
333  for (unsigned I = OpNo, E = MI->getNumOperands(); I != E; ++I) {
334  if (I != OpNo)
335  O << ", ";
336  O << MI->getOperand(I).getImm();
337  }
338  O << "}";
339 }
340 
342  unsigned OpNo,
343  raw_ostream &O) {
344  int64_t Imm = MI->getOperand(OpNo).getImm();
345  if (Imm == WebAssembly::GetDefaultP2Align(MI->getOpcode()))
346  return;
347  O << ":p2align=" << Imm;
348 }
349 
351  unsigned OpNo,
352  raw_ostream &O) {
353  const MCOperand &Op = MI->getOperand(OpNo);
354  if (Op.isImm()) {
355  auto Imm = static_cast<unsigned>(Op.getImm());
356  if (Imm != wasm::WASM_TYPE_NORESULT)
358  } else {
359  auto Expr = cast<MCSymbolRefExpr>(Op.getExpr());
360  auto *Sym = cast<MCSymbolWasm>(&Expr->getSymbol());
361  if (Sym->getSignature()) {
362  O << WebAssembly::signatureToString(Sym->getSignature());
363  } else {
364  // Disassembler does not currently produce a signature
365  O << "unknown_type";
366  }
367  }
368 }
369 
371  unsigned OpNo,
372  raw_ostream &O) {
373  const MCOperand &Op = MI->getOperand(OpNo);
374  if (Op.isImm()) {
375  switch (Op.getImm()) {
376  case long(wasm::ValType::EXTERNREF):
377  O << "extern";
378  break;
379  case long(wasm::ValType::FUNCREF):
380  O << "func";
381  break;
382  default:
383  O << "unsupported_heap_type_value";
384  break;
385  }
386  } else {
387  // Typed function references and other subtypes of funcref and externref
388  // currently unimplemented.
389  O << "unsupported_heap_type_operand";
390  }
391 }
llvm::lltok::APFloat
@ APFloat
Definition: LLToken.h:495
llvm::MCInstrDesc::getNumDefs
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Definition: MCInstrDesc.h:243
CmpMode::FP
@ FP
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
WebAssembly.h
llvm::APFloatBase::IEEEsingle
static const fltSemantics & IEEEsingle() LLVM_READNONE
Definition: APFloat.cpp:170
llvm::MCAsmInfo
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
llvm::toString
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:1020
ErrorHandling.h
llvm::WebAssemblyInstPrinter::printWebAssemblyHeapTypeOperand
void printWebAssemblyHeapTypeOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
Definition: WebAssemblyInstPrinter.cpp:370
llvm::WebAssemblyInstPrinter::printOperand
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool IsVariadicDef=false)
Definition: WebAssemblyInstPrinter.cpp:292
llvm::WebAssembly::signatureToString
std::string signatureToString(const wasm::WasmSignature *Sig)
Definition: WebAssemblyTypeUtilities.cpp:122
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::APInt::getBitWidth
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1399
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::wasm::WASM_TYPE_NORESULT
@ WASM_TYPE_NORESULT
Definition: Wasm.h:261
FormattedStream.h
llvm::WebAssemblyInstPrinter::printRegName
void printRegName(raw_ostream &OS, unsigned RegNo) const override
Print the assembler register name.
Definition: WebAssemblyInstPrinter.cpp:41
llvm::APInt::isNegative
bool isNegative() const
Determine sign of this APInt.
Definition: APInt.h:312
llvm::WebAssemblyInstPrinter::printBrList
void printBrList(const MCInst *MI, unsigned OpNo, raw_ostream &O)
Definition: WebAssemblyInstPrinter.cpp:330
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::WebAssemblyInstPrinter::printInst
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &OS) override
Print the specified MCInst to the specified raw_ostream.
Definition: WebAssemblyInstPrinter.cpp:48
MCInstrInfo.h
MCSymbol.h
llvm::bitc::END_BLOCK
@ END_BLOCK
Definition: BitCodes.h:47
MCInst.h
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:195
MCSubtargetInfo.h
WebAssemblyTypeUtilities.h
llvm::APInt::getZExtValue
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1449
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::AMDGPUISD::LOOP
@ LOOP
Definition: AMDGPUISelLowering.h:352
llvm::MCInstPrinter::printAnnotation
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
Definition: MCInstPrinter.cpp:49
WebAssemblyUtilities.h
WebAssemblyMCTargetDesc.h
llvm::APFloat::getQNaN
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
Definition: APFloat.h:916
llvm::WebAssemblyFunctionInfo::UnusedReg
static const unsigned UnusedReg
Definition: WebAssemblyMachineFunctionInfo.h:122
llvm::APFloat
Definition: APFloat.h:701
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:197
llvm::MCInstrDesc::NumOperands
unsigned short NumOperands
Definition: MCInstrDesc.h:198
uint64_t
llvm::MCInstPrinter
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:43
llvm::wasm::ValType::EXTERNREF
@ EXTERNREF
llvm::MCSymbolWasm
Definition: MCSymbolWasm.h:16
llvm::MCOperandInfo::OperandType
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:95
llvm::wasm::ValType::FUNCREF
@ FUNCREF
WebAssemblyInstPrinter.h
I
#define I(x, y, z)
Definition: MD5.cpp:59
StringExtras.h
llvm::WebAssemblyInstPrinter::printInstruction
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O)
llvm::HighlightColor::Address
@ Address
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MCInstrDesc::OpInfo
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:206
llvm::WebAssemblyInstPrinter::WebAssemblyInstPrinter
WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
Definition: WebAssemblyInstPrinter.cpp:36
llvm::MCSymbolRefExpr
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
WebAssemblyMachineFunctionInfo.h
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
llvm::APFloatBase::IEEEdouble
static const fltSemantics & IEEEdouble() LLVM_READNONE
Definition: APFloat.cpp:173
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MCInstrDesc::variadicOpsAreDefs
bool variadicOpsAreDefs() const
Return true if variadic operands of this instruction are definitions.
Definition: MCInstrDesc.h:409
llvm::SmallSet::insert
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:180
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::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:25
DELEGATE
#define DELEGATE(CLASS_TO_VISIT)
Definition: InstVisitor.h:28
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:324
llvm::MCSymbolRefExpr::VK_WASM_TYPEINDEX
@ VK_WASM_TYPEINDEX
Definition: MCExpr.h:327
llvm::MCInstrDesc::isVariadic
bool isVariadic() const
Return true if this instruction can have a variable number of operands.
Definition: MCInstrDesc.h:256
llvm::WebAssemblyInstPrinter::getMnemonic
std::pair< const char *, uint64_t > getMnemonic(const MCInst *MI) override
Returns a pair containing the mnemonic for MI and the number of bits left for further processing by p...
llvm::MCInstPrinter::MAI
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:49
llvm::APFloatBase::rmNearestTiesToEven
static constexpr roundingMode rmNearestTiesToEven
Definition: APFloat.h:190
llvm::WebAssemblyInstPrinter::printWebAssemblySignatureOperand
void printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
Definition: WebAssemblyInstPrinter.cpp:350
llvm::WebAssemblyInstPrinter::printWebAssemblyP2AlignOperand
void printWebAssemblyP2AlignOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
Definition: WebAssemblyInstPrinter.cpp:341
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::WebAssembly::anyTypeToString
const char * anyTypeToString(unsigned Type)
Definition: WebAssemblyTypeUtilities.cpp:83
llvm::MCInstrInfo::get
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:62
MCExpr.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::WebAssembly::GetDefaultP2Align
unsigned GetDefaultP2Align(unsigned Opc)
Definition: WebAssemblyMCTargetDesc.h:269
llvm::MCInstrDesc::getNumOperands
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:228
TargetRegisterInfo.h
llvm::WebAssemblyFunctionInfo::getWARegStackId
static unsigned getWARegStackId(unsigned Reg)
Definition: WebAssemblyMachineFunctionInfo.h:157
llvm::WebAssembly::OPERAND_BASIC_BLOCK
@ OPERAND_BASIC_BLOCK
Basic block label in a branch construct.
Definition: WebAssemblyMCTargetDesc.h:42
SmallSet.h