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)
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++);
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()) {
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) +
':');
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()) {
218 if (
Opc == WebAssembly::CATCH_LEGACY ||
219 Opc == WebAssembly::CATCH_LEGACY_S) {
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()) {
248 std::string Label =
"label/catch" +
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)
332 }
else if (
Op.isImm()) {
334 }
else if (
Op.isSFPImm()) {
336 }
else if (
Op.isDFPImm()) {
339 assert(
Op.isExpr() &&
"unknown operand kind in printOperand");
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());
382 auto Expr = cast<MCSymbolRefExpr>(
Op.getExpr());
384 if (
Sym->getSignature()) {
395 unsigned OpIdx = OpNo;
397 unsigned NumCatches =
Op.getImm();
403 TagExpr = cast<MCSymbolRefExpr>(
Op.getExpr());
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)
unsigned const MachineRegisterInfo * MRI
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 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.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
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
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...
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 LLVM_ABI const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
Description of the encoding of one expression Op.