32#define DEBUG_TYPE "asm-printer"
34#include "WebAssemblyGenAsmWriter.inc"
44 OS <<
"$" << Reg.id();
51 unsigned TypeOperand = 0;
52 unsigned TableOperand = 1;
53 switch (
MI->getOpcode()) {
54 case WebAssembly::CALL_INDIRECT: {
55 unsigned NumDefs =
MI->getOperand(0).getImm();
56 TypeOperand = NumDefs + 1;
57 TableOperand = NumDefs + 2;
60 case WebAssembly::RET_CALL_INDIRECT:
61 case WebAssembly::CALL_INDIRECT_S:
62 case WebAssembly::RET_CALL_INDIRECT_S: {
71 if (
MI->getOperand(TableOperand).isExpr()) {
75 assert(
MI->getOperand(TableOperand).getImm() == 0);
78 if (
MI->getOpcode() == WebAssembly::CALL_INDIRECT)
90 if (
Desc.isVariadic()) {
91 if ((
Desc.getNumOperands() == 0 &&
MI->getNumOperands() > 0) ||
92 Desc.variadicOpsAreDefs())
94 unsigned Start =
Desc.getNumOperands();
95 unsigned NumVariadicDefs = 0;
96 if (
Desc.variadicOpsAreDefs()) {
98 NumVariadicDefs =
MI->getOperand(0).getImm();
101 bool NeedsComma =
Desc.getNumOperands() > 0 && !
Desc.variadicOpsAreDefs();
102 for (
auto I = Start, E =
MI->getNumOperands();
I < E; ++
I) {
103 if (
MI->getOpcode() == WebAssembly::CALL_INDIRECT &&
104 I - Start == NumVariadicDefs) {
119 auto PrintBranchAnnotation = [&](
const MCOperand &
Op,
122 if (!Printed.insert(
Depth).second)
124 if (
Depth >= ControlFlowStack.size()) {
127 const auto &Pair = ControlFlowStack.rbegin()[
Depth];
129 " to label" +
utostr(Pair.first));
136 unsigned Opc =
MI->getOpcode();
141 case WebAssembly::LOOP:
142 case WebAssembly::LOOP_S:
144 ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++,
true));
147 case WebAssembly::BLOCK:
148 case WebAssembly::BLOCK_S:
149 ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++,
false));
152 case WebAssembly::TRY:
153 case WebAssembly::TRY_S:
154 ControlFlowStack.push_back(std::make_pair(ControlFlowCounter,
false));
155 TryStack.push_back(ControlFlowCounter++);
156 EHInstStack.push_back(TRY);
159 case WebAssembly::TRY_TABLE:
160 case WebAssembly::TRY_TABLE_S: {
164 unsigned NumCatches =
Op.getImm();
165 for (
unsigned I = 0;
I < NumCatches;
I++) {
166 int64_t CatchOpcode =
MI->getOperand(
OpIdx++).getImm();
170 PrintBranchAnnotation(
MI->getOperand(
OpIdx++), Printed);
172 ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++,
false));
176 case WebAssembly::SELECT_T:
177 case WebAssembly::SELECT_T_S:
182 case WebAssembly::END_LOOP:
183 case WebAssembly::END_LOOP_S:
184 if (ControlFlowStack.empty()) {
187 ControlFlowStack.pop_back();
191 case WebAssembly::END_BLOCK:
192 case WebAssembly::END_BLOCK_S:
193 case WebAssembly::END_TRY_TABLE:
194 case WebAssembly::END_TRY_TABLE_S:
195 if (ControlFlowStack.empty()) {
199 OS,
"label" +
utostr(ControlFlowStack.pop_back_val().first) +
':');
203 case WebAssembly::END_TRY:
204 case WebAssembly::END_TRY_S:
205 if (ControlFlowStack.empty() || EHInstStack.empty()) {
209 OS,
"label" +
utostr(ControlFlowStack.pop_back_val().first) +
':');
210 EHInstStack.pop_back();
214 case WebAssembly::CATCH_LEGACY:
215 case WebAssembly::CATCH_LEGACY_S:
216 case WebAssembly::CATCH_ALL_LEGACY:
217 case WebAssembly::CATCH_ALL_LEGACY_S:
220 if (EHInstStack.empty()) {
222 }
else if (EHInstStack.back() == CATCH_ALL_LEGACY) {
224 }
else if (EHInstStack.back() == TRY) {
225 if (TryStack.empty()) {
230 EHInstStack.pop_back();
231 if (
Opc == WebAssembly::CATCH_LEGACY ||
232 Opc == WebAssembly::CATCH_LEGACY_S) {
233 EHInstStack.push_back(CATCH_LEGACY);
235 EHInstStack.push_back(CATCH_ALL_LEGACY);
240 case WebAssembly::RETHROW:
241 case WebAssembly::RETHROW_S:
244 if (TryStack.empty()) {
251 case WebAssembly::DELEGATE:
252 case WebAssembly::DELEGATE_S:
253 if (ControlFlowStack.empty() || TryStack.empty() || EHInstStack.empty()) {
260 assert(ControlFlowStack.back().first == TryStack.back());
261 std::string Label =
"label/catch" +
262 utostr(ControlFlowStack.pop_back_val().first) +
265 EHInstStack.pop_back();
267 if (
Depth >= ControlFlowStack.size()) {
268 Label +=
"to caller";
270 const auto &Pair = ControlFlowStack.rbegin()[
Depth];
274 Label +=
"down to catch" +
utostr(Pair.first);
283 unsigned NumFixedOperands =
Desc.NumOperands;
285 for (
unsigned I = 0, E =
MI->getNumOperands();
I < E; ++
I) {
287 if (
I < NumFixedOperands) {
296 if (!
MI->getOperand(
I).isImm())
299 PrintBranchAnnotation(
MI->getOperand(
I), Printed);
309 APInt AI =
FP.bitcastToAPInt();
310 return std::string(AI.
isNegative() ?
"-" :
"") +
"nan:0x" +
313 : INT64_C(0x000fffffffffffff)),
318 static const size_t BufBytes = 128;
320 auto Written =
FP.convertToHexString(
324 assert(Written < BufBytes);
335 if (
int(WAReg.
id()) >= 0)
337 else if (OpNo >=
Desc.getNumDefs() && !IsVariadicDef)
344 if (OpNo <
MII.get(
MI->getOpcode()).getNumDefs() || IsVariadicDef)
346 }
else if (
Op.isImm()) {
348 }
else if (
Op.isSFPImm()) {
350 }
else if (
Op.isDFPImm()) {
353 assert(
Op.isExpr() &&
"unknown operand kind in printOperand");
359 auto &Sym =
static_cast<const MCSymbolWasm &
>(SRE->getSymbol());
362 MAI.printExpr(O, *
Op.getExpr());
371 for (
unsigned I = OpNo, E =
MI->getNumOperands();
I != E; ++
I) {
374 O <<
MI->getOperand(
I).getImm();
382 int64_t Imm =
MI->getOperand(OpNo).getImm();
385 O <<
":p2align=" << Imm;
391 int64_t Imm =
MI->getOperand(OpNo).getImm();
412 auto Imm =
static_cast<unsigned>(
Op.getImm());
417 auto *Sym =
static_cast<const MCSymbolWasm *
>(&Expr->getSymbol());
418 if (Sym->getSignature()) {
430 unsigned OpIdx = OpNo;
432 unsigned NumCatches =
Op.getImm();
444 O <<
Op.getImm() <<
" ";
448 for (
unsigned I = 0;
I < NumCatches;
I++) {
451 switch (
Op.getImm()) {
454 PrintTagOp(
MI->getOperand(
OpIdx++));
458 PrintTagOp(
MI->getOperand(
OpIdx++));
464 O <<
"catch_all_ref ";
467 O <<
MI->getOperand(
OpIdx++).getImm();
469 if (
I < NumCatches - 1)
477 unsigned OpIdx = OpNo;
480 if (NumTypes > Remaining)
481 NumTypes = Remaining;
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.
constexpr unsigned id() const
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
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...
Represent a constant reference to a string, i.e.
void printCatchList(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O, bool IsVariadicDef=false)
void printWebAssemblyMemOrderOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegName(raw_ostream &OS, MCRegister Reg) override
Print the assembler register name.
void printWebAssemblyP2AlignOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, 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 printBrList(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void printTypeList(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
void printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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)
unsigned getWARegStackId(MCRegister Reg)
const char * anyTypeToString(unsigned Type)
@ WASM_OPCODE_CATCH_ALL_REF
@ WASM_MEM_ORDER_RMW_ACQ_REL
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.