32#define DEBUG_TYPE "asm-printer" 
   34#include "WebAssemblyGenAsmWriter.inc" 
   44  OS << 
"$" << Reg.id();
 
 
   51  switch (
MI->getOpcode()) {
 
   52  case WebAssembly::CALL_INDIRECT_S:
 
   53  case WebAssembly::RET_CALL_INDIRECT_S: {
 
   64    const unsigned TypeOperand = 0;
 
   65    const unsigned TableOperand = 1;
 
   66    if (
MI->getOperand(TableOperand).isExpr()) {
 
   70      assert(
MI->getOperand(TableOperand).getImm() == 0);
 
   83  if (
Desc.isVariadic()) {
 
   84    if ((
Desc.getNumOperands() == 0 && 
MI->getNumOperands() > 0) ||
 
   85        Desc.variadicOpsAreDefs())
 
   87    unsigned Start = 
Desc.getNumOperands();
 
   88    unsigned NumVariadicDefs = 0;
 
   89    if (
Desc.variadicOpsAreDefs()) {
 
   91      NumVariadicDefs = 
MI->getOperand(0).getImm();
 
   94    bool NeedsComma = 
Desc.getNumOperands() > 0 && !
Desc.variadicOpsAreDefs();
 
   95    for (
auto I = Start, E = 
MI->getNumOperands(); 
I < E; ++
I) {
 
   96      if (
MI->getOpcode() == WebAssembly::CALL_INDIRECT &&
 
   97          I - Start == NumVariadicDefs) {
 
  112  auto PrintBranchAnnotation = [&](
const MCOperand &
Op,
 
  115    if (!Printed.insert(
Depth).second)
 
  117    if (
Depth >= ControlFlowStack.size()) {
 
  120      const auto &Pair = ControlFlowStack.rbegin()[
Depth];
 
  122                              " to label" + 
utostr(Pair.first));
 
  129    unsigned Opc = 
MI->getOpcode();
 
  134    case WebAssembly::LOOP:
 
  135    case WebAssembly::LOOP_S:
 
  137      ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, 
true));
 
  140    case WebAssembly::BLOCK:
 
  141    case WebAssembly::BLOCK_S:
 
  142      ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, 
false));
 
  145    case WebAssembly::TRY:
 
  146    case WebAssembly::TRY_S:
 
  147      ControlFlowStack.push_back(std::make_pair(ControlFlowCounter, 
false));
 
  148      TryStack.push_back(ControlFlowCounter++);
 
  149      EHInstStack.push_back(TRY);
 
  152    case WebAssembly::TRY_TABLE:
 
  153    case WebAssembly::TRY_TABLE_S: {
 
  157      unsigned NumCatches = 
Op.getImm();
 
  158      for (
unsigned I = 0; 
I < NumCatches; 
I++) {
 
  159        int64_t CatchOpcode = 
MI->getOperand(
OpIdx++).getImm();
 
  163        PrintBranchAnnotation(
MI->getOperand(
OpIdx++), Printed);
 
  165      ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, 
false));
 
  169    case WebAssembly::END_LOOP:
 
  170    case WebAssembly::END_LOOP_S:
 
  171      if (ControlFlowStack.empty()) {
 
  174        ControlFlowStack.pop_back();
 
  178    case WebAssembly::END_BLOCK:
 
  179    case WebAssembly::END_BLOCK_S:
 
  180    case WebAssembly::END_TRY_TABLE:
 
  181    case WebAssembly::END_TRY_TABLE_S:
 
  182      if (ControlFlowStack.empty()) {
 
  186            OS, 
"label" + 
utostr(ControlFlowStack.pop_back_val().first) + 
':');
 
  190    case WebAssembly::END_TRY:
 
  191    case WebAssembly::END_TRY_S:
 
  192      if (ControlFlowStack.empty() || EHInstStack.empty()) {
 
  196            OS, 
"label" + 
utostr(ControlFlowStack.pop_back_val().first) + 
':');
 
  197        EHInstStack.pop_back();
 
  201    case WebAssembly::CATCH_LEGACY:
 
  202    case WebAssembly::CATCH_LEGACY_S:
 
  203    case WebAssembly::CATCH_ALL_LEGACY:
 
  204    case WebAssembly::CATCH_ALL_LEGACY_S:
 
  207      if (EHInstStack.empty()) {
 
  209      } 
else if (EHInstStack.back() == CATCH_ALL_LEGACY) {
 
  211      } 
else if (EHInstStack.back() == TRY) {
 
  212        if (TryStack.empty()) {
 
  217        EHInstStack.pop_back();
 
  218        if (
Opc == WebAssembly::CATCH_LEGACY ||
 
  219            Opc == WebAssembly::CATCH_LEGACY_S) {
 
  220          EHInstStack.push_back(CATCH_LEGACY);
 
  222          EHInstStack.push_back(CATCH_ALL_LEGACY);
 
  227    case WebAssembly::RETHROW:
 
  228    case WebAssembly::RETHROW_S:
 
  231      if (TryStack.empty()) {
 
  238    case WebAssembly::DELEGATE:
 
  239    case WebAssembly::DELEGATE_S:
 
  240      if (ControlFlowStack.empty() || TryStack.empty() || EHInstStack.empty()) {
 
  247        assert(ControlFlowStack.back().first == TryStack.back());
 
  248        std::string Label = 
"label/catch" +
 
  249                            utostr(ControlFlowStack.pop_back_val().first) +
 
  252        EHInstStack.pop_back();
 
  254        if (
Depth >= ControlFlowStack.size()) {
 
  255          Label += 
"to caller";
 
  257          const auto &Pair = ControlFlowStack.rbegin()[
Depth];
 
  261            Label += 
"down to catch" + 
utostr(Pair.first);
 
  270    unsigned NumFixedOperands = 
Desc.NumOperands;
 
  272    for (
unsigned I = 0, E = 
MI->getNumOperands(); 
I < E; ++
I) {
 
  274      if (
I < NumFixedOperands) {
 
  283        if (!
MI->getOperand(
I).isImm())
 
  286      PrintBranchAnnotation(
MI->getOperand(
I), Printed);
 
 
  296    APInt AI = 
FP.bitcastToAPInt();
 
  297    return std::string(AI.
isNegative() ? 
"-" : 
"") + 
"nan:0x" +
 
  300                                                 : INT64_C(0x000fffffffffffff)),
 
  305  static const size_t BufBytes = 128;
 
  307  auto Written = 
FP.convertToHexString(
 
  311  assert(Written < BufBytes);
 
 
  320    unsigned WAReg = 
Op.getReg();
 
  323    else if (OpNo >= 
Desc.getNumDefs() && !IsVariadicDef)
 
  330    if (OpNo < 
MII.get(
MI->getOpcode()).getNumDefs() || IsVariadicDef)
 
  332  } 
else if (
Op.isImm()) {
 
  334  } 
else if (
Op.isSFPImm()) {
 
  336  } 
else if (
Op.isDFPImm()) {
 
  339    assert(
Op.isExpr() && 
"unknown operand kind in printOperand");
 
  345      auto &Sym = 
static_cast<const MCSymbolWasm &
>(SRE->getSymbol());
 
  348      MAI.printExpr(O, *
Op.getExpr());
 
 
  356  for (
unsigned I = OpNo, E = 
MI->getNumOperands(); 
I != E; ++
I) {
 
  359    O << 
MI->getOperand(
I).getImm();
 
 
  367  int64_t Imm = 
MI->getOperand(OpNo).getImm();
 
  370  O << 
":p2align=" << Imm;
 
 
  378    auto Imm = 
static_cast<unsigned>(
Op.getImm());
 
  383    auto *Sym = 
static_cast<const MCSymbolWasm *
>(&Expr->getSymbol());
 
  384    if (Sym->getSignature()) {
 
 
  395  unsigned OpIdx = OpNo;
 
  397  unsigned NumCatches = 
Op.getImm();
 
  409      O << 
Op.getImm() << 
" ";
 
  413  for (
unsigned I = 0; 
I < NumCatches; 
I++) {
 
  416    switch (
Op.getImm()) {
 
  419      PrintTagOp(
MI->getOperand(
OpIdx++));
 
  423      PrintTagOp(
MI->getOperand(
OpIdx++));
 
  429      O << 
"catch_all_ref ";
 
  432    O << 
MI->getOperand(
OpIdx++).getImm(); 
 
  434    if (
I < NumCatches - 1)
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
This file declares a class to represent arbitrary precision floating point values and provide a varie...
 
MachineInstr unsigned OpIdx
 
This file defines the SmallSet class.
 
This class prints an WebAssembly MCInst to wasm file syntax.
 
This file contains the declaration of the WebAssemblyMCAsmInfo class.
 
This file provides WebAssembly-specific target descriptions.
 
This file contains the declaration of the WebAssembly-specific type parsing utility functions.
 
static const fltSemantics & IEEEsingle()
 
static const fltSemantics & IEEEdouble()
 
static constexpr roundingMode rmNearestTiesToEven
 
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
 
Class for arbitrary precision integers.
 
uint64_t getZExtValue() const
Get zero extended value.
 
unsigned getBitWidth() const
Return the number of bits in the APInt.
 
bool isNegative() const
Determine sign of this APInt.
 
This class is intended to be used as a base class for asm properties and features specific to the tar...
 
raw_ostream * CommentStream
A stream that comments can be emitted to if desired.
 
const MCRegisterInfo & MRI
 
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
 
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri)
 
Instances of this class represent a single low-level machine instruction.
 
Describe properties that are true of each instruction in the target description file.
 
Interface to description of machine instruction set.
 
Instances of this class represent operands of the MCInst class.
 
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.
 
Generic base class for all target subtargets.
 
Represent a reference to a symbol from inside an expression.
 
const MCSymbol & getSymbol() const
 
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
 
StringRef getName() const
getName - Get the symbol name.
 
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
 
StringRef - Represent a constant reference to a string, i.e.
 
void printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
 
void printRegName(raw_ostream &OS, MCRegister Reg) override
Print the assembler register name.
 
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O)
 
std::pair< const char *, uint64_t > getMnemonic(const MCInst &MI) const override
Returns a pair containing the mnemonic for MI and the number of bits left for further processing by p...
 
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.
 
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool IsVariadicDef=false)
 
void printBrList(const MCInst *MI, unsigned OpNo, raw_ostream &O)
 
void printCatchList(const MCInst *MI, unsigned OpNo, raw_ostream &O)
 
void printWebAssemblyP2AlignOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
 
WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
 
This class implements an extremely fast bulk output stream that can only output to a stream.
 
unsigned GetDefaultP2Align(unsigned Opc)
 
static const unsigned UnusedReg
 
@ OPERAND_BASIC_BLOCK
Basic block label in a branch construct.
 
std::string signatureToString(const wasm::WasmSignature *Sig)
 
const char * anyTypeToString(unsigned Type)
 
unsigned getWARegStackId(unsigned Reg)
 
@ WASM_OPCODE_CATCH_ALL_REF
 
This is an optimization pass for GlobalISel generic memory operations.
 
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
 
std::string utostr(uint64_t X, bool isNeg=false)
 
DWARFExpression::Operation Op
 
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.