32#define DEBUG_TYPE "asm-printer"
34#include "WebAssemblyGenAsmWriter.inc"
45 OS <<
"$" << Reg.id();
52 switch (
MI->getOpcode()) {
53 case WebAssembly::CALL_INDIRECT_S:
54 case WebAssembly::RET_CALL_INDIRECT_S: {
65 const unsigned TypeOperand = 0;
66 const unsigned TableOperand = 1;
67 if (
MI->getOperand(TableOperand).isExpr()) {
71 assert(
MI->getOperand(TableOperand).getImm() == 0);
84 if (
Desc.isVariadic()) {
85 if ((
Desc.getNumOperands() == 0 &&
MI->getNumOperands() > 0) ||
86 Desc.variadicOpsAreDefs())
88 unsigned Start =
Desc.getNumOperands();
89 unsigned NumVariadicDefs = 0;
90 if (
Desc.variadicOpsAreDefs()) {
92 NumVariadicDefs =
MI->getOperand(0).getImm();
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) {
116 unsigned Opc =
MI->getOpcode();
121 case WebAssembly::LOOP:
122 case WebAssembly::LOOP_S:
124 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter++,
true));
127 case WebAssembly::BLOCK:
128 case WebAssembly::BLOCK_S:
129 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter++,
false));
132 case WebAssembly::TRY:
133 case WebAssembly::TRY_S:
134 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter,
false));
135 TryStack.
push_back(ControlFlowCounter++);
139 case WebAssembly::END_LOOP:
140 case WebAssembly::END_LOOP_S:
141 if (ControlFlowStack.
empty()) {
148 case WebAssembly::END_BLOCK:
149 case WebAssembly::END_BLOCK_S:
150 if (ControlFlowStack.
empty()) {
154 OS,
"label" + utostr(ControlFlowStack.
pop_back_val().first) +
':');
158 case WebAssembly::END_TRY:
159 case WebAssembly::END_TRY_S:
160 if (ControlFlowStack.
empty() || EHInstStack.
empty()) {
164 OS,
"label" + utostr(ControlFlowStack.
pop_back_val().first) +
':');
169 case WebAssembly::CATCH:
170 case WebAssembly::CATCH_S:
171 case WebAssembly::CATCH_ALL:
172 case WebAssembly::CATCH_ALL_S:
175 if (EHInstStack.
empty()) {
177 }
else if (EHInstStack.
back() == CATCH_ALL) {
179 }
else if (EHInstStack.
back() == TRY) {
180 if (TryStack.
empty()) {
186 if (Opc == WebAssembly::CATCH || Opc == WebAssembly::CATCH_S) {
194 case WebAssembly::RETHROW:
195 case WebAssembly::RETHROW_S:
198 if (TryStack.
empty()) {
205 case WebAssembly::DELEGATE:
206 case WebAssembly::DELEGATE_S:
207 if (ControlFlowStack.
empty() || TryStack.
empty() || EHInstStack.
empty()) {
215 std::string Label =
"label/catch" +
222 Label +=
"to caller";
224 const auto &Pair = ControlFlowStack.
rbegin()[
Depth];
228 Label +=
"down to catch" + utostr(Pair.first);
237 unsigned NumFixedOperands =
Desc.NumOperands;
239 for (
unsigned I = 0, E =
MI->getNumOperands();
I < E; ++
I) {
241 if (
I < NumFixedOperands) {
250 if (!
MI->getOperand(
I).isImm())
259 const auto &Pair = ControlFlowStack.
rbegin()[
Depth];
261 (Pair.second ?
"up" :
"down") +
" to label" +
273 APInt AI =
FP.bitcastToAPInt();
274 return std::string(AI.
isNegative() ?
"-" :
"") +
"nan:0x" +
277 : INT64_C(0x000fffffffffffff)),
282 static const size_t BufBytes = 128;
284 auto Written =
FP.convertToHexString(
288 assert(Written < BufBytes);
297 unsigned WAReg =
Op.getReg();
300 else if (OpNo >=
Desc.getNumDefs() && !IsVariadicDef)
309 }
else if (
Op.isImm()) {
311 }
else if (
Op.isSFPImm()) {
313 }
else if (
Op.isDFPImm()) {
316 assert(
Op.isExpr() &&
"unknown operand kind in printOperand");
333 for (
unsigned I = OpNo, E =
MI->getNumOperands();
I != E; ++
I) {
336 O <<
MI->getOperand(
I).getImm();
344 int64_t Imm =
MI->getOperand(OpNo).getImm();
347 O <<
":p2align=" << Imm;
355 auto Imm =
static_cast<unsigned>(
Op.getImm());
359 auto Expr = cast<MCSymbolRefExpr>(
Op.getExpr());
360 auto *
Sym = cast<MCSymbolWasm>(&Expr->getSymbol());
361 if (
Sym->getSignature()) {
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.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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) const 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) 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 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)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEdouble() LLVM_READNONE
Description of the encoding of one expression Op.