diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 |
commit | 0b57cec536236d46e3dba9bd041533462f33dbb7 (patch) | |
tree | 56229dbdbbf76d18580f72f789003db17246c8d9 /contrib/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp | |
parent | 718ef55ec7785aae63f98f8ca05dc07ed399c16d (diff) |
Notes
Diffstat (limited to 'contrib/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp | 278 |
1 files changed, 0 insertions, 278 deletions
diff --git a/contrib/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp b/contrib/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp deleted file mode 100644 index f9bf3f85d30f..000000000000 --- a/contrib/llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp +++ /dev/null @@ -1,278 +0,0 @@ -//==- WebAssemblyDisassembler.cpp - Disassembler for WebAssembly -*- C++ -*-==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file is part of the WebAssembly Disassembler. -/// -/// It contains code to translate the data produced by the decoder into -/// MCInsts. -/// -//===----------------------------------------------------------------------===// - -#include "MCTargetDesc/WebAssemblyInstPrinter.h" -#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" -#include "TargetInfo/WebAssemblyTargetInfo.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/LEB128.h" -#include "llvm/Support/TargetRegistry.h" - -using namespace llvm; - -#define DEBUG_TYPE "wasm-disassembler" - -using DecodeStatus = MCDisassembler::DecodeStatus; - -#include "WebAssemblyGenDisassemblerTables.inc" - -namespace { -static constexpr int WebAssemblyInstructionTableSize = 256; - -class WebAssemblyDisassembler final : public MCDisassembler { - std::unique_ptr<const MCInstrInfo> MCII; - - DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, - ArrayRef<uint8_t> Bytes, uint64_t Address, - raw_ostream &VStream, - raw_ostream &CStream) const override; - DecodeStatus onSymbolStart(StringRef Name, uint64_t &Size, - ArrayRef<uint8_t> Bytes, uint64_t Address, - raw_ostream &VStream, - raw_ostream &CStream) const override; - -public: - WebAssemblyDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, - std::unique_ptr<const MCInstrInfo> MCII) - : MCDisassembler(STI, Ctx), MCII(std::move(MCII)) {} -}; -} // end anonymous namespace - -static MCDisassembler *createWebAssemblyDisassembler(const Target &T, - const MCSubtargetInfo &STI, - MCContext &Ctx) { - std::unique_ptr<const MCInstrInfo> MCII(T.createMCInstrInfo()); - return new WebAssemblyDisassembler(STI, Ctx, std::move(MCII)); -} - -extern "C" void LLVMInitializeWebAssemblyDisassembler() { - // Register the disassembler for each target. - TargetRegistry::RegisterMCDisassembler(getTheWebAssemblyTarget32(), - createWebAssemblyDisassembler); - TargetRegistry::RegisterMCDisassembler(getTheWebAssemblyTarget64(), - createWebAssemblyDisassembler); -} - -static int nextByte(ArrayRef<uint8_t> Bytes, uint64_t &Size) { - if (Size >= Bytes.size()) - return -1; - auto V = Bytes[Size]; - Size++; - return V; -} - -static bool nextLEB(int64_t &Val, ArrayRef<uint8_t> Bytes, uint64_t &Size, - bool Signed) { - unsigned N = 0; - const char *Error = nullptr; - Val = Signed ? decodeSLEB128(Bytes.data() + Size, &N, - Bytes.data() + Bytes.size(), &Error) - : static_cast<int64_t>(decodeULEB128(Bytes.data() + Size, &N, - Bytes.data() + Bytes.size(), - &Error)); - if (Error) - return false; - Size += N; - return true; -} - -static bool parseLEBImmediate(MCInst &MI, uint64_t &Size, - ArrayRef<uint8_t> Bytes, bool Signed) { - int64_t Val; - if (!nextLEB(Val, Bytes, Size, Signed)) - return false; - MI.addOperand(MCOperand::createImm(Val)); - return true; -} - -template <typename T> -bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes) { - if (Size + sizeof(T) > Bytes.size()) - return false; - T Val = support::endian::read<T, support::endianness::little, 1>( - Bytes.data() + Size); - Size += sizeof(T); - if (std::is_floating_point<T>::value) { - MI.addOperand(MCOperand::createFPImm(static_cast<double>(Val))); - } else { - MI.addOperand(MCOperand::createImm(static_cast<int64_t>(Val))); - } - return true; -} - -MCDisassembler::DecodeStatus WebAssemblyDisassembler::onSymbolStart( - StringRef Name, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, - raw_ostream &VStream, raw_ostream &CStream) const { - Size = 0; - if (Address == 0) { - // Start of a code section: we're parsing only the function count. - int64_t FunctionCount; - if (!nextLEB(FunctionCount, Bytes, Size, false)) - return MCDisassembler::Fail; - outs() << " # " << FunctionCount << " functions in section."; - } else { - // Parse the start of a single function. - int64_t BodySize, LocalEntryCount; - if (!nextLEB(BodySize, Bytes, Size, false) || - !nextLEB(LocalEntryCount, Bytes, Size, false)) - return MCDisassembler::Fail; - if (LocalEntryCount) { - outs() << " .local "; - for (int64_t I = 0; I < LocalEntryCount; I++) { - int64_t Count, Type; - if (!nextLEB(Count, Bytes, Size, false) || - !nextLEB(Type, Bytes, Size, false)) - return MCDisassembler::Fail; - for (int64_t J = 0; J < Count; J++) { - if (I || J) - outs() << ", "; - outs() << WebAssembly::anyTypeToString(Type); - } - } - } - } - outs() << "\n"; - return MCDisassembler::Success; -} - -MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction( - MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t /*Address*/, - raw_ostream & /*OS*/, raw_ostream &CS) const { - CommentStream = &CS; - Size = 0; - int Opc = nextByte(Bytes, Size); - if (Opc < 0) - return MCDisassembler::Fail; - const auto *WasmInst = &InstructionTable0[Opc]; - // If this is a prefix byte, indirect to another table. - if (WasmInst->ET == ET_Prefix) { - WasmInst = nullptr; - // Linear search, so far only 2 entries. - for (auto PT = PrefixTable; PT->Table; PT++) { - if (PT->Prefix == Opc) { - WasmInst = PT->Table; - break; - } - } - if (!WasmInst) - return MCDisassembler::Fail; - int64_t PrefixedOpc; - if (!nextLEB(PrefixedOpc, Bytes, Size, false)) - return MCDisassembler::Fail; - if (PrefixedOpc < 0 || PrefixedOpc >= WebAssemblyInstructionTableSize) - return MCDisassembler::Fail; - WasmInst += PrefixedOpc; - } - if (WasmInst->ET == ET_Unused) - return MCDisassembler::Fail; - // At this point we must have a valid instruction to decode. - assert(WasmInst->ET == ET_Instruction); - MI.setOpcode(WasmInst->Opcode); - // Parse any operands. - for (uint8_t OPI = 0; OPI < WasmInst->NumOperands; OPI++) { - auto OT = OperandTable[WasmInst->OperandStart + OPI]; - switch (OT) { - // ULEB operands: - case WebAssembly::OPERAND_BASIC_BLOCK: - case WebAssembly::OPERAND_LOCAL: - case WebAssembly::OPERAND_GLOBAL: - case WebAssembly::OPERAND_FUNCTION32: - case WebAssembly::OPERAND_OFFSET32: - case WebAssembly::OPERAND_P2ALIGN: - case WebAssembly::OPERAND_TYPEINDEX: - case WebAssembly::OPERAND_EVENT: - case MCOI::OPERAND_IMMEDIATE: { - if (!parseLEBImmediate(MI, Size, Bytes, false)) - return MCDisassembler::Fail; - break; - } - // SLEB operands: - case WebAssembly::OPERAND_I32IMM: - case WebAssembly::OPERAND_I64IMM: { - if (!parseLEBImmediate(MI, Size, Bytes, true)) - return MCDisassembler::Fail; - break; - } - // block_type operands (uint8_t). - case WebAssembly::OPERAND_SIGNATURE: { - if (!parseImmediate<uint8_t>(MI, Size, Bytes)) - return MCDisassembler::Fail; - break; - } - // FP operands. - case WebAssembly::OPERAND_F32IMM: { - if (!parseImmediate<float>(MI, Size, Bytes)) - return MCDisassembler::Fail; - break; - } - case WebAssembly::OPERAND_F64IMM: { - if (!parseImmediate<double>(MI, Size, Bytes)) - return MCDisassembler::Fail; - break; - } - // Vector lane operands (not LEB encoded). - case WebAssembly::OPERAND_VEC_I8IMM: { - if (!parseImmediate<uint8_t>(MI, Size, Bytes)) - return MCDisassembler::Fail; - break; - } - case WebAssembly::OPERAND_VEC_I16IMM: { - if (!parseImmediate<uint16_t>(MI, Size, Bytes)) - return MCDisassembler::Fail; - break; - } - case WebAssembly::OPERAND_VEC_I32IMM: { - if (!parseImmediate<uint32_t>(MI, Size, Bytes)) - return MCDisassembler::Fail; - break; - } - case WebAssembly::OPERAND_VEC_I64IMM: { - if (!parseImmediate<uint64_t>(MI, Size, Bytes)) - return MCDisassembler::Fail; - break; - } - case WebAssembly::OPERAND_BRLIST: { - int64_t TargetTableLen; - if (!nextLEB(TargetTableLen, Bytes, Size, false)) - return MCDisassembler::Fail; - for (int64_t I = 0; I < TargetTableLen; I++) { - if (!parseLEBImmediate(MI, Size, Bytes, false)) - return MCDisassembler::Fail; - } - // Default case. - if (!parseLEBImmediate(MI, Size, Bytes, false)) - return MCDisassembler::Fail; - break; - } - case MCOI::OPERAND_REGISTER: - // The tablegen header currently does not have any register operands since - // we use only the stack (_S) instructions. - // If you hit this that probably means a bad instruction definition in - // tablegen. - llvm_unreachable("Register operand in WebAssemblyDisassembler"); - default: - llvm_unreachable("Unknown operand type in WebAssemblyDisassembler"); - } - } - return MCDisassembler::Success; -} |