1*88ebb9e2SColin LeMahieu //===-- HexagonDisassembler.cpp - Disassembler for Hexagon ISA ------------===// 2*88ebb9e2SColin LeMahieu // 3*88ebb9e2SColin LeMahieu // The LLVM Compiler Infrastructure 4*88ebb9e2SColin LeMahieu // 5*88ebb9e2SColin LeMahieu // This file is distributed under the University of Illinois Open Source 6*88ebb9e2SColin LeMahieu // License. See LICENSE.TXT for details. 7*88ebb9e2SColin LeMahieu // 8*88ebb9e2SColin LeMahieu //===----------------------------------------------------------------------===// 9*88ebb9e2SColin LeMahieu 10*88ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonBaseInfo.h" 11*88ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonMCTargetDesc.h" 12*88ebb9e2SColin LeMahieu 13*88ebb9e2SColin LeMahieu #include "llvm/MC/MCContext.h" 14*88ebb9e2SColin LeMahieu #include "llvm/MC/MCDisassembler.h" 15*88ebb9e2SColin LeMahieu #include "llvm/MC/MCExpr.h" 16*88ebb9e2SColin LeMahieu #include "llvm/MC/MCFixedLenDisassembler.h" 17*88ebb9e2SColin LeMahieu #include "llvm/MC/MCInst.h" 18*88ebb9e2SColin LeMahieu #include "llvm/MC/MCInstrDesc.h" 19*88ebb9e2SColin LeMahieu #include "llvm/MC/MCSubtargetInfo.h" 20*88ebb9e2SColin LeMahieu #include "llvm/Support/Debug.h" 21*88ebb9e2SColin LeMahieu #include "llvm/Support/ErrorHandling.h" 22*88ebb9e2SColin LeMahieu #include "llvm/Support/LEB128.h" 23*88ebb9e2SColin LeMahieu #include "llvm/Support/MemoryObject.h" 24*88ebb9e2SColin LeMahieu #include "llvm/Support/raw_ostream.h" 25*88ebb9e2SColin LeMahieu #include "llvm/Support/TargetRegistry.h" 26*88ebb9e2SColin LeMahieu #include "llvm/Support/Endian.h" 27*88ebb9e2SColin LeMahieu 28*88ebb9e2SColin LeMahieu #include <vector> 29*88ebb9e2SColin LeMahieu #include <array> 30*88ebb9e2SColin LeMahieu 31*88ebb9e2SColin LeMahieu using namespace llvm; 32*88ebb9e2SColin LeMahieu 33*88ebb9e2SColin LeMahieu #define DEBUG_TYPE "hexagon-disassembler" 34*88ebb9e2SColin LeMahieu 35*88ebb9e2SColin LeMahieu using DecodeStatus = MCDisassembler::DecodeStatus; 36*88ebb9e2SColin LeMahieu 37*88ebb9e2SColin LeMahieu namespace { 38*88ebb9e2SColin LeMahieu /// \brief Hexagon disassembler for all Hexagon platforms. 39*88ebb9e2SColin LeMahieu class HexagonDisassembler : public MCDisassembler { 40*88ebb9e2SColin LeMahieu public: 41*88ebb9e2SColin LeMahieu HexagonDisassembler(MCSubtargetInfo const &STI, MCContext &Ctx) 42*88ebb9e2SColin LeMahieu : MCDisassembler(STI, Ctx) {} 43*88ebb9e2SColin LeMahieu 44*88ebb9e2SColin LeMahieu DecodeStatus getInstruction(MCInst &instr, uint64_t &size, 45*88ebb9e2SColin LeMahieu MemoryObject const ®ion, uint64_t address, 46*88ebb9e2SColin LeMahieu raw_ostream &vStream, raw_ostream &cStream) const override; 47*88ebb9e2SColin LeMahieu }; 48*88ebb9e2SColin LeMahieu } 49*88ebb9e2SColin LeMahieu 50*88ebb9e2SColin LeMahieu static const uint16_t IntRegDecoderTable[] = { 51*88ebb9e2SColin LeMahieu Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, 52*88ebb9e2SColin LeMahieu Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, 53*88ebb9e2SColin LeMahieu Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, 54*88ebb9e2SColin LeMahieu Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 55*88ebb9e2SColin LeMahieu Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, 56*88ebb9e2SColin LeMahieu Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29, 57*88ebb9e2SColin LeMahieu Hexagon::R30, Hexagon::R31}; 58*88ebb9e2SColin LeMahieu 59*88ebb9e2SColin LeMahieu static const uint16_t DoubleRegDecoderTable[] = { 60*88ebb9e2SColin LeMahieu Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3, 61*88ebb9e2SColin LeMahieu Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7, 62*88ebb9e2SColin LeMahieu Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11, 63*88ebb9e2SColin LeMahieu Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15}; 64*88ebb9e2SColin LeMahieu 65*88ebb9e2SColin LeMahieu static const uint16_t PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1, 66*88ebb9e2SColin LeMahieu Hexagon::P2, Hexagon::P3}; 67*88ebb9e2SColin LeMahieu 68*88ebb9e2SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, 69*88ebb9e2SColin LeMahieu uint64_t /*Address*/, 70*88ebb9e2SColin LeMahieu void const *Decoder) { 71*88ebb9e2SColin LeMahieu if (RegNo > 31) 72*88ebb9e2SColin LeMahieu return MCDisassembler::Fail; 73*88ebb9e2SColin LeMahieu 74*88ebb9e2SColin LeMahieu unsigned Register = IntRegDecoderTable[RegNo]; 75*88ebb9e2SColin LeMahieu Inst.addOperand(MCOperand::CreateReg(Register)); 76*88ebb9e2SColin LeMahieu return MCDisassembler::Success; 77*88ebb9e2SColin LeMahieu } 78*88ebb9e2SColin LeMahieu 79*88ebb9e2SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, 80*88ebb9e2SColin LeMahieu uint64_t /*Address*/, 81*88ebb9e2SColin LeMahieu void const *Decoder) { 82*88ebb9e2SColin LeMahieu if (RegNo > 15) 83*88ebb9e2SColin LeMahieu return MCDisassembler::Fail; 84*88ebb9e2SColin LeMahieu 85*88ebb9e2SColin LeMahieu unsigned Register = DoubleRegDecoderTable[RegNo]; 86*88ebb9e2SColin LeMahieu Inst.addOperand(MCOperand::CreateReg(Register)); 87*88ebb9e2SColin LeMahieu return MCDisassembler::Success; 88*88ebb9e2SColin LeMahieu } 89*88ebb9e2SColin LeMahieu 90*88ebb9e2SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 91*88ebb9e2SColin LeMahieu uint64_t /*Address*/, 92*88ebb9e2SColin LeMahieu void const *Decoder) { 93*88ebb9e2SColin LeMahieu if (RegNo > 3) 94*88ebb9e2SColin LeMahieu return MCDisassembler::Fail; 95*88ebb9e2SColin LeMahieu 96*88ebb9e2SColin LeMahieu unsigned Register = PredRegDecoderTable[RegNo]; 97*88ebb9e2SColin LeMahieu Inst.addOperand(MCOperand::CreateReg(Register)); 98*88ebb9e2SColin LeMahieu return MCDisassembler::Success; 99*88ebb9e2SColin LeMahieu } 100*88ebb9e2SColin LeMahieu 101*88ebb9e2SColin LeMahieu #include "HexagonGenDisassemblerTables.inc" 102*88ebb9e2SColin LeMahieu 103*88ebb9e2SColin LeMahieu static MCDisassembler *createHexagonDisassembler(Target const &T, 104*88ebb9e2SColin LeMahieu MCSubtargetInfo const &STI, 105*88ebb9e2SColin LeMahieu MCContext &Ctx) { 106*88ebb9e2SColin LeMahieu return new HexagonDisassembler(STI, Ctx); 107*88ebb9e2SColin LeMahieu } 108*88ebb9e2SColin LeMahieu 109*88ebb9e2SColin LeMahieu extern "C" void LLVMInitializeHexagonDisassembler() { 110*88ebb9e2SColin LeMahieu TargetRegistry::RegisterMCDisassembler(TheHexagonTarget, 111*88ebb9e2SColin LeMahieu createHexagonDisassembler); 112*88ebb9e2SColin LeMahieu } 113*88ebb9e2SColin LeMahieu 114*88ebb9e2SColin LeMahieu DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 115*88ebb9e2SColin LeMahieu MemoryObject const &Region, 116*88ebb9e2SColin LeMahieu uint64_t Address, 117*88ebb9e2SColin LeMahieu raw_ostream &os, 118*88ebb9e2SColin LeMahieu raw_ostream &cs) const { 119*88ebb9e2SColin LeMahieu std::array<uint8_t, 4> Bytes; 120*88ebb9e2SColin LeMahieu Size = 4; 121*88ebb9e2SColin LeMahieu if (Region.readBytes(Address, Bytes.size(), Bytes.data()) == -1) { 122*88ebb9e2SColin LeMahieu return MCDisassembler::Fail; 123*88ebb9e2SColin LeMahieu } 124*88ebb9e2SColin LeMahieu uint32_t insn = 125*88ebb9e2SColin LeMahieu llvm::support::endian::read<uint32_t, llvm::support::little, 126*88ebb9e2SColin LeMahieu llvm::support::unaligned>(Bytes.data()); 127*88ebb9e2SColin LeMahieu 128*88ebb9e2SColin LeMahieu // Remove parse bits. 129*88ebb9e2SColin LeMahieu insn &= ~static_cast<uint32_t>(HexagonII::InstParseBits::INST_PARSE_MASK); 130*88ebb9e2SColin LeMahieu return decodeInstruction(DecoderTable32, MI, insn, Address, this, STI); 131*88ebb9e2SColin LeMahieu } 132