31#define DEBUG_TYPE "asm-printer"
33#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);
88 unsigned NumVariadicDefs = 0;
91 NumVariadicDefs =
MI->getOperand(0).getImm();
95 for (
auto I = Start,
E =
MI->getNumOperands();
I <
E; ++
I) {
96 if (
MI->getOpcode() == WebAssembly::CALL_INDIRECT &&
97 I - Start == NumVariadicDefs) {
115 unsigned Opc =
MI->getOpcode();
120 case WebAssembly::LOOP:
121 case WebAssembly::LOOP_S:
123 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter++,
true));
126 case WebAssembly::BLOCK:
127 case WebAssembly::BLOCK_S:
128 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter++,
false));
131 case WebAssembly::TRY:
132 case WebAssembly::TRY_S:
133 ControlFlowStack.
push_back(std::make_pair(ControlFlowCounter,
false));
134 TryStack.
push_back(ControlFlowCounter++);
138 case WebAssembly::END_LOOP:
139 case WebAssembly::END_LOOP_S:
140 if (ControlFlowStack.
empty()) {
147 case WebAssembly::END_BLOCK:
148 case WebAssembly::END_BLOCK_S:
149 if (ControlFlowStack.
empty()) {
153 OS,
"label" + utostr(ControlFlowStack.
pop_back_val().first) +
':');
157 case WebAssembly::END_TRY:
158 case WebAssembly::END_TRY_S:
159 if (ControlFlowStack.
empty() || EHInstStack.
empty()) {
163 OS,
"label" + utostr(ControlFlowStack.
pop_back_val().first) +
':');
168 case WebAssembly::CATCH:
169 case WebAssembly::CATCH_S:
170 case WebAssembly::CATCH_ALL:
171 case WebAssembly::CATCH_ALL_S:
174 if (EHInstStack.
empty()) {
176 }
else if (EHInstStack.
back() == CATCH_ALL) {
178 }
else if (EHInstStack.
back() == TRY) {
179 if (TryStack.
empty()) {
185 if (Opc == WebAssembly::CATCH || Opc == WebAssembly::CATCH_S) {
193 case WebAssembly::RETHROW:
194 case WebAssembly::RETHROW_S:
197 if (TryStack.
empty()) {
204 case WebAssembly::DELEGATE:
205 case WebAssembly::DELEGATE_S:
206 if (ControlFlowStack.
empty() || TryStack.
empty() || EHInstStack.
empty()) {
214 std::string Label =
"label/catch" +
221 Label +=
"to caller";
223 const auto &Pair = ControlFlowStack.
rbegin()[
Depth];
227 Label +=
"down to catch" + utostr(Pair.first);
238 for (
unsigned I = 0,
E =
MI->getNumOperands();
I <
E; ++
I) {
240 if (
I < NumFixedOperands) {
249 if (!
MI->getOperand(
I).isImm())
258 const auto &Pair = ControlFlowStack.
rbegin()[
Depth];
260 (Pair.second ?
"up" :
"down") +
" to label" +
272 APInt AI =
FP.bitcastToAPInt();
273 return std::string(AI.
isNegative() ?
"-" :
"") +
"nan:0x" +
276 : INT64_C(0x000fffffffffffff)),
281 static const size_t BufBytes = 128;
283 auto Written =
FP.convertToHexString(
287 assert(Written < BufBytes);
296 unsigned WAReg = Op.getReg();
299 else if (OpNo >= Desc.
getNumDefs() && !IsVariadicDef)
308 }
else if (Op.isImm()) {
310 }
else if (Op.isSFPImm()) {
312 }
else if (Op.isDFPImm()) {
315 assert(Op.isExpr() &&
"unknown operand kind in printOperand");
324 Op.getExpr()->print(O, &
MAI);
332 for (
unsigned I = OpNo,
E =
MI->getNumOperands();
I !=
E; ++
I) {
335 O <<
MI->getOperand(
I).getImm();
343 int64_t Imm =
MI->getOperand(OpNo).getImm();
346 O <<
":p2align=" << Imm;
354 auto Imm =
static_cast<unsigned>(Op.getImm());
358 auto Expr = cast<MCSymbolRefExpr>(Op.getExpr());
359 auto *
Sym = cast<MCSymbolWasm>(&Expr->getSymbol());
360 if (
Sym->getSignature()) {
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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 declares WebAssembly-specific per-machine-function information.
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 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 getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
unsigned short NumOperands
bool variadicOpsAreDefs() const
Return true if variadic operands of this instruction are definitions.
bool isVariadic() const
Return true if this instruction can have a variable number of operands.
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.
static const unsigned UnusedReg
static unsigned getWARegStackId(unsigned Reg)
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)
@ OPERAND_BASIC_BLOCK
Basic block label in a branch construct.
std::string signatureToString(const wasm::WasmSignature *Sig)
const char * anyTypeToString(unsigned Type)
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