35#define DEBUG_TYPE "wasm-disassembler"
39#include "WebAssemblyGenDisassemblerTables.inc"
45 std::unique_ptr<const MCInstrInfo> MCII;
57 std::unique_ptr<const MCInstrInfo> MCII)
65 std::unique_ptr<const MCInstrInfo> MCII(
T.createMCInstrInfo());
66 return new WebAssemblyDisassembler(STI, Ctx, std::move(MCII));
89 const char *
Error =
nullptr;
117 if (std::is_floating_point<T>::value) {
133 int64_t FunctionCount;
136 outs() <<
" # " << FunctionCount <<
" functions in section.";
139 int64_t BodySize, LocalEntryCount;
143 if (LocalEntryCount) {
144 outs() <<
" .local ";
145 for (int64_t
I = 0;
I < LocalEntryCount;
I++) {
150 for (int64_t J = 0; J <
Count; J++) {
153 outs() << WebAssembly::anyTypeToString(
Type);
163 MCInst &
MI, uint64_t &
Size, ArrayRef<uint8_t> Bytes, uint64_t ,
164 raw_ostream &CS)
const {
170 const auto *WasmInst = &InstructionTable0[
Opc];
172 if (WasmInst->ET == ET_Prefix) {
175 for (
const auto &[Prefix, Table] : PrefixTable) {
188 WasmInst += PrefixedOpc;
190 if (WasmInst->ET == ET_Unused)
193 assert(WasmInst->ET == ET_Instruction);
194 MI.setOpcode(WasmInst->Opcode);
196 for (uint8_t OPI = 0; OPI < WasmInst->NumOperands; OPI++) {
197 auto OT = OperandTable[WasmInst->OperandStart + OPI];
200 case WebAssembly::OPERAND_BASIC_BLOCK:
201 case WebAssembly::OPERAND_LOCAL:
202 case WebAssembly::OPERAND_GLOBAL:
203 case WebAssembly::OPERAND_FUNCTION32:
204 case WebAssembly::OPERAND_TABLE:
205 case WebAssembly::OPERAND_OFFSET32:
206 case WebAssembly::OPERAND_OFFSET64:
207 case WebAssembly::OPERAND_P2ALIGN:
208 case WebAssembly::OPERAND_TYPEINDEX:
209 case WebAssembly::OPERAND_TAG:
213 if (OT == WebAssembly::OPERAND_P2ALIGN) {
216 int64_t Val =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
219 MI.getOperand(
MI.getNumOperands() - 1)
223 uint8_t Order = Bytes[
Size++];
229 OperandTable[WasmInst->OperandStart + OPI - 1] ==
230 WebAssembly::OPERAND_MEMORDER &&
231 "P2ALIGN with memory order not preceded by MEMORDER");
234 MI.getOperand(
MI.getNumOperands() - 2)
237 MI.getOperand(
MI.getNumOperands() - 2)
244 case WebAssembly::OPERAND_I32IMM:
245 case WebAssembly::OPERAND_I64IMM: {
251 case WebAssembly::OPERAND_SIGNATURE: {
253 uint64_t PrevSize =
Size;
258 if (
Size != PrevSize + 1) {
267 auto *WasmSym =
static_cast<MCSymbolWasm *
>(Sym);
270 WasmSym, WebAssembly::S_TYPEINDEX,
getContext());
276 case WebAssembly::OPERAND_F32IMM: {
281 case WebAssembly::OPERAND_F64IMM: {
287 case WebAssembly::OPERAND_VEC_I8IMM: {
292 case WebAssembly::OPERAND_MEMORDER: {
294 if (OPI + 1 < WasmInst->NumOperands &&
295 OperandTable[WasmInst->OperandStart + OPI + 1] ==
296 WebAssembly::OPERAND_P2ALIGN) {
314 case WebAssembly::OPERAND_VEC_I16IMM: {
319 case WebAssembly::OPERAND_VEC_I32IMM: {
324 case WebAssembly::OPERAND_VEC_I64IMM: {
329 case WebAssembly::OPERAND_BRLIST: {
330 int64_t TargetTableLen;
333 for (int64_t
I = 0;
I < TargetTableLen;
I++) {
342 case WebAssembly::OPERAND_CATCH_LIST: {
345 int64_t NumCatches =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
346 for (int64_t
I = 0;
I < NumCatches;
I++) {
349 int64_t CatchOpcode =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
360 case WebAssembly::OPERAND_VALTYPE_LIST: {
367 int64_t NumTypes =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
368 for (int64_t
I = 0;
I < NumTypes;
I++) {
MCDisassembler::DecodeStatus DecodeStatus
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_EXTERNAL_VISIBILITY
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static constexpr int WebAssemblyInstructionTableSize
static int nextByte(ArrayRef< uint8_t > Bytes, uint64_t &Size)
static bool nextLEB(int64_t &Val, ArrayRef< uint8_t > Bytes, uint64_t &Size, bool Signed)
static MCDisassembler * createWebAssemblyDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeWebAssemblyDisassembler()
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
static bool parseLEBImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes, bool Signed)
This file contains the declaration of the WebAssemblyMCAsmInfo class.
This file contains the declaration of the WebAssembly-specific type parsing utility functions.
This file registers the WebAssembly target.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Context object for machine code objects.
Superclass for all disassemblers.
DecodeStatus
Ternary decode status.
Instances of this class represent a single low-level machine instruction.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
static MCOperand createDFPImm(uint64_t Val)
Generic base class for all target subtargets.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Target - Wrapper for Target specific information.
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.
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
@ WASM_SYMBOL_TYPE_SECTION
@ WASM_SYMBOL_TYPE_FUNCTION
@ WASM_MEM_ORDER_RMW_ACQ_REL
const unsigned WASM_MEMARG_HAS_MEM_ORDER
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Target & getTheWebAssemblyTarget32()
Target & getTheWebAssemblyTarget64()
To bit_cast(const From &from) noexcept
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.