30#define DEBUG_TYPE "asm-printer"
32#include "WebAssemblyGenAsmWriter.inc"
42 OS <<
"$" << Reg.id();
49 switch (
MI->getOpcode()) {
50 case WebAssembly::CALL_INDIRECT_S:
51 case WebAssembly::RET_CALL_INDIRECT_S: {
62 const unsigned TypeOperand = 0;
63 const unsigned TableOperand = 1;
64 if (
MI->getOperand(TableOperand).isExpr()) {
68 assert(
MI->getOperand(TableOperand).getImm() == 0);
81 if (
Desc.isVariadic()) {
82 if ((
Desc.getNumOperands() == 0 &&
MI->getNumOperands() > 0) ||
83 Desc.variadicOpsAreDefs())
85 unsigned Start =
Desc.getNumOperands();
86 unsigned NumVariadicDefs = 0;
87 if (
Desc.variadicOpsAreDefs()) {
89 NumVariadicDefs =
MI->getOperand(0).getImm();
92 bool NeedsComma =
Desc.getNumOperands() > 0 && !
Desc.variadicOpsAreDefs();
93 for (
auto I = Start, E =
MI->getNumOperands();
I < E; ++
I) {
94 if (
MI->getOpcode() == WebAssembly::CALL_INDIRECT &&
95 I - Start == NumVariadicDefs) {
110 auto PrintBranchAnnotation = [&](
const MCOperand &
Op,
113 if (!Printed.insert(
Depth).second)
118 const auto &Pair = ControlFlowStack.
rbegin()[
Depth];
120 " to label" + utostr(Pair.first));
127 unsigned Opc =
MI->getOpcode();
132 case WebAssembly::LOOP:
133 case WebAssembly::LOOP_S:
135 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter++,
true));
138 case WebAssembly::BLOCK:
139 case WebAssembly::BLOCK_S:
140 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter++,
false));
143 case WebAssembly::TRY:
144 case WebAssembly::TRY_S:
145 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter,
false));
146 TryStack.
push_back(ControlFlowCounter++);
150 case WebAssembly::TRY_TABLE:
151 case WebAssembly::TRY_TABLE_S: {
155 unsigned NumCatches =
Op.getImm();
156 for (
unsigned I = 0;
I < NumCatches;
I++) {
157 int64_t CatchOpcode =
MI->getOperand(OpIdx++).getImm();
161 PrintBranchAnnotation(
MI->getOperand(OpIdx++), Printed);
163 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter++,
false));
167 case WebAssembly::END_LOOP:
168 case WebAssembly::END_LOOP_S:
169 if (ControlFlowStack.
empty()) {
176 case WebAssembly::END_BLOCK:
177 case WebAssembly::END_BLOCK_S:
178 case WebAssembly::END_TRY_TABLE:
179 case WebAssembly::END_TRY_TABLE_S:
180 if (ControlFlowStack.
empty()) {
184 OS,
"label" + utostr(ControlFlowStack.
pop_back_val().first) +
':');
188 case WebAssembly::END_TRY:
189 case WebAssembly::END_TRY_S:
190 if (ControlFlowStack.
empty() || EHInstStack.
empty()) {
194 OS,
"label" + utostr(ControlFlowStack.
pop_back_val().first) +
':');
199 case WebAssembly::CATCH_LEGACY:
200 case WebAssembly::CATCH_LEGACY_S:
201 case WebAssembly::CATCH_ALL_LEGACY:
202 case WebAssembly::CATCH_ALL_LEGACY_S:
205 if (EHInstStack.
empty()) {
207 }
else if (EHInstStack.
back() == CATCH_ALL_LEGACY) {
209 }
else if (EHInstStack.
back() == TRY) {
210 if (TryStack.
empty()) {
216 if (Opc == WebAssembly::CATCH_LEGACY ||
217 Opc == WebAssembly::CATCH_LEGACY_S) {
225 case WebAssembly::RETHROW:
226 case WebAssembly::RETHROW_S:
229 if (TryStack.
empty()) {
236 case WebAssembly::DELEGATE:
237 case WebAssembly::DELEGATE_S:
238 if (ControlFlowStack.
empty() || TryStack.
empty() || EHInstStack.
empty()) {
246 std::string Label =
"label/catch" +
253 Label +=
"to caller";
255 const auto &Pair = ControlFlowStack.
rbegin()[
Depth];
259 Label +=
"down to catch" + utostr(Pair.first);
268 unsigned NumFixedOperands =
Desc.NumOperands;
270 for (
unsigned I = 0, E =
MI->getNumOperands();
I < E; ++
I) {
272 if (
I < NumFixedOperands) {
281 if (!
MI->getOperand(
I).isImm())
284 PrintBranchAnnotation(
MI->getOperand(
I), Printed);
294 APInt AI =
FP.bitcastToAPInt();
295 return std::string(AI.
isNegative() ?
"-" :
"") +
"nan:0x" +
298 : INT64_C(0x000fffffffffffff)),
303 static const size_t BufBytes = 128;
305 auto Written =
FP.convertToHexString(
309 assert(Written < BufBytes);
318 unsigned WAReg =
Op.getReg();
321 else if (OpNo >=
Desc.getNumDefs() && !IsVariadicDef)
330 }
else if (
Op.isImm()) {
332 }
else if (
Op.isSFPImm()) {
334 }
else if (
Op.isDFPImm()) {
337 assert(
Op.isExpr() &&
"unknown operand kind in printOperand");
354 for (
unsigned I = OpNo, E =
MI->getNumOperands();
I != E; ++
I) {
357 O <<
MI->getOperand(
I).getImm();
365 int64_t Imm =
MI->getOperand(OpNo).getImm();
368 O <<
":p2align=" << Imm;
376 auto Imm =
static_cast<unsigned>(
Op.getImm());
380 auto Expr = cast<MCSymbolRefExpr>(
Op.getExpr());
381 auto *
Sym = cast<MCSymbolWasm>(&Expr->getSymbol());
382 if (
Sym->getSignature()) {
393 unsigned OpIdx = OpNo;
395 unsigned NumCatches =
Op.getImm();
401 TagExpr = cast<MCSymbolRefExpr>(
Op.getExpr());
402 TagSym = cast<MCSymbolWasm>(&TagExpr->
getSymbol());
407 O <<
Op.getImm() <<
" ";
411 for (
unsigned I = 0;
I < NumCatches;
I++) {
414 switch (
Op.getImm()) {
417 PrintTagOp(
MI->getOperand(OpIdx++));
421 PrintTagOp(
MI->getOperand(OpIdx++));
427 O <<
"catch_all_ref ";
430 O <<
MI->getOperand(OpIdx++).getImm();
432 if (
I < NumCatches - 1)
unsigned const MachineRegisterInfo * MRI
This file declares a class to represent arbitrary precision floating point values and provide a varie...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This class prints an WebAssembly MCInst to wasm file syntax.
This file provides WebAssembly-specific target descriptions.
This file contains the declaration of the WebAssembly-specific type parsing utility functions.
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 represents an Operation in the Expression.
bool print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, DWARFUnit *U) const
This class is intended to be used as a base class for asm properties and features specific to the tar...
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
raw_ostream * CommentStream
A stream that comments can be emitted to if desired.
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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
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...
void push_back(const T &Elt)
reverse_iterator rbegin()
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.
DWARFExpression::Operation Op
const char * toString(DWARFSectionKind Kind)
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEdouble() LLVM_READNONE
Description of the encoding of one expression Op.