Index: lib/Target/WebAssembly/CMakeLists.txt =================================================================== --- lib/Target/WebAssembly/CMakeLists.txt +++ lib/Target/WebAssembly/CMakeLists.txt @@ -3,6 +3,7 @@ tablegen(LLVM WebAssemblyGenAsmMatcher.inc -gen-asm-matcher) tablegen(LLVM WebAssemblyGenAsmWriter.inc -gen-asm-writer) tablegen(LLVM WebAssemblyGenDAGISel.inc -gen-dag-isel) +tablegen(LLVM WebAssemblyGenDisassemblerTables.inc -gen-disassembler) tablegen(LLVM WebAssemblyGenFastISel.inc -gen-fast-isel) tablegen(LLVM WebAssemblyGenInstrInfo.inc -gen-instr-info) tablegen(LLVM WebAssemblyGenMCCodeEmitter.inc -gen-emitter) Index: lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp =================================================================== --- lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp +++ lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp @@ -19,16 +19,22 @@ #include "WebAssembly.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/MC/MCFixedLenDisassembler.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/Endian.h" #include "llvm/Support/TargetRegistry.h" + using namespace llvm; #define DEBUG_TYPE "wasm-disassembler" +using DecodeStatus = MCDisassembler::DecodeStatus; + +#include "WebAssemblyGenDisassemblerTables.inc" + namespace { class WebAssemblyDisassembler final : public MCDisassembler { std::unique_ptr MCII; @@ -61,10 +67,23 @@ } MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction( - MCInst &MI, uint64_t &Size, ArrayRef Bytes, uint64_t /*Address*/, + MCInst &MI, uint64_t &Size, ArrayRef Bytes, uint64_t Address, raw_ostream &OS, raw_ostream &CS) const { - - // TODO: Implement disassembly. + CommentStream = &CS; + // We want to read at least 1 byte of data. + if (Bytes.size() < 1) { + Size = 0; + return MCDisassembler::Fail; + } + uint32_t Insn = Bytes[0]; + Size = 1; // FIXME + // Calling the auto-generated decoder function. + DecodeStatus Result = + decodeInstruction(DecoderTable8, MI, Insn, Address, this, STI); + if (Result != MCDisassembler::Fail) { + return checkDecodedInstruction(MI, Size, Address, OS, CS, Insn, Result); + } return MCDisassembler::Fail; } + Index: lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h =================================================================== --- lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h +++ lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h @@ -37,14 +37,18 @@ const MCSubtargetInfo &STI) override; // Used by tblegen code. - void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, + raw_ostream &O); void printWebAssemblyP2AlignOperand(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); void printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); // Autogenerated by tblgen. - void printInstruction(const MCInst *MI, raw_ostream &O); + void printInstruction(const MCInst *MI, const MCSubtargetInfo &STI, + raw_ostream &O); static const char *getRegisterName(unsigned RegNo); }; Index: lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp =================================================================== --- lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp +++ lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp @@ -46,9 +46,9 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, - const MCSubtargetInfo & /*STI*/) { + const MCSubtargetInfo &STI) { // Print the instruction (this uses the AsmStrings from the .td files). - printInstruction(MI, OS); + printInstruction(MI, STI, OS); // Print any additional variadic operands. const MCInstrDesc &Desc = MII.get(MI->getOpcode()); @@ -61,7 +61,7 @@ (MI->getOpcode() != WebAssembly::CALL_INDIRECT_VOID || i != Desc.getNumOperands())) OS << ", "; - printOperand(MI, i, OS); + printOperand(MI, i, STI, OS); } // Print any added annotation. @@ -138,6 +138,7 @@ } void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &/*STI*/, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); if (Op.isReg()) { @@ -197,6 +198,8 @@ void WebAssemblyInstPrinter::printWebAssemblyP2AlignOperand(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo & + STI, raw_ostream &O) { int64_t Imm = MI->getOperand(OpNo).getImm(); if (Imm == WebAssembly::GetDefaultP2Align(MI->getOpcode())) @@ -207,6 +210,8 @@ void WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo & + STI, raw_ostream &O) { int64_t Imm = MI->getOperand(OpNo).getImm(); switch (WebAssembly::ExprType(Imm)) { Index: lib/Target/WebAssembly/WebAssembly.td =================================================================== --- lib/Target/WebAssembly/WebAssembly.td +++ lib/Target/WebAssembly/WebAssembly.td @@ -82,7 +82,15 @@ let ShouldEmitMatchRegisterName = 0; } +def WebAssemblyAsmWriter : AsmWriter { + string AsmWriterClassName = "InstPrinter"; + int PassSubtarget = 1; + int Variant = 0; + bit isMCAsmWriter = 1; +} + def WebAssembly : Target { let InstructionSet = WebAssemblyInstrInfo; let AssemblyParsers = [WebAssemblyAsmParser]; + let AssemblyWriters = [WebAssemblyAsmWriter]; } Index: lib/Target/WebAssembly/WebAssemblyInstrFormats.td =================================================================== --- lib/Target/WebAssembly/WebAssemblyInstrFormats.td +++ lib/Target/WebAssembly/WebAssemblyInstrFormats.td @@ -15,6 +15,8 @@ // WebAssembly Instruction Format. class WebAssemblyInst inst, string asmstr> : Instruction { field bits<32> Inst = inst; // Instruction encoding. + field bits<32> SoftFail = 0; // Needed for disassembler? + let Size = 1; // Needed for disassembler? let Namespace = "WebAssembly"; let Pattern = []; let AsmString = asmstr;