1 //===-- HexagonDisassembler.cpp - Disassembler for Hexagon ISA ------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/HexagonBaseInfo.h" 11 #include "MCTargetDesc/HexagonMCInst.h" 12 #include "MCTargetDesc/HexagonMCTargetDesc.h" 13 #include "llvm/MC/MCContext.h" 14 #include "llvm/MC/MCDisassembler.h" 15 #include "llvm/MC/MCExpr.h" 16 #include "llvm/MC/MCFixedLenDisassembler.h" 17 #include "llvm/MC/MCInst.h" 18 #include "llvm/MC/MCInstrDesc.h" 19 #include "llvm/MC/MCSubtargetInfo.h" 20 #include "llvm/Support/Debug.h" 21 #include "llvm/Support/Endian.h" 22 #include "llvm/Support/ErrorHandling.h" 23 #include "llvm/Support/LEB128.h" 24 #include "llvm/Support/TargetRegistry.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include <array> 27 #include <vector> 28 29 using namespace llvm; 30 31 #define DEBUG_TYPE "hexagon-disassembler" 32 33 // Pull DecodeStatus and its enum values into the global namespace. 34 typedef llvm::MCDisassembler::DecodeStatus DecodeStatus; 35 36 namespace { 37 /// \brief Hexagon disassembler for all Hexagon platforms. 38 class HexagonDisassembler : public MCDisassembler { 39 public: 40 HexagonDisassembler(MCSubtargetInfo const &STI, MCContext &Ctx) 41 : MCDisassembler(STI, Ctx) {} 42 43 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 44 ArrayRef<uint8_t> Bytes, uint64_t Address, 45 raw_ostream &VStream, 46 raw_ostream &CStream) const override; 47 }; 48 } 49 50 static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, 51 uint64_t Address, const void *Decoder); 52 static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, 53 uint64_t Address, const void *Decoder); 54 55 static const uint16_t IntRegDecoderTable[] = { 56 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, 57 Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, 58 Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, 59 Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 60 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, 61 Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29, 62 Hexagon::R30, Hexagon::R31 }; 63 64 static const uint16_t PredRegDecoderTable[] = { Hexagon::P0, Hexagon::P1, 65 Hexagon::P2, Hexagon::P3 }; 66 67 static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo, 68 const uint16_t Table[], size_t Size) { 69 if (RegNo < Size) { 70 Inst.addOperand(MCOperand::CreateReg(Table[RegNo])); 71 return MCDisassembler::Success; 72 } 73 else 74 return MCDisassembler::Fail; 75 } 76 77 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, 78 uint64_t /*Address*/, 79 void const *Decoder) { 80 if (RegNo > 31) 81 return MCDisassembler::Fail; 82 83 unsigned Register = IntRegDecoderTable[RegNo]; 84 Inst.addOperand(MCOperand::CreateReg(Register)); 85 return MCDisassembler::Success; 86 } 87 88 static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, 89 uint64_t /*Address*/, const void *Decoder) { 90 static const uint16_t CtrlRegDecoderTable[] = { 91 Hexagon::SA0, Hexagon::LC0, Hexagon::SA1, Hexagon::LC1, 92 Hexagon::P3_0, Hexagon::NoRegister, Hexagon::C6, Hexagon::C7, 93 Hexagon::USR, Hexagon::PC, Hexagon::UGP, Hexagon::GP, 94 Hexagon::CS0, Hexagon::CS1, Hexagon::UPCL, Hexagon::UPCH 95 }; 96 97 if (RegNo >= sizeof(CtrlRegDecoderTable) / sizeof(CtrlRegDecoderTable[0])) 98 return MCDisassembler::Fail; 99 100 if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister) 101 return MCDisassembler::Fail; 102 103 unsigned Register = CtrlRegDecoderTable[RegNo]; 104 Inst.addOperand(MCOperand::CreateReg(Register)); 105 return MCDisassembler::Success; 106 } 107 108 static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, 109 uint64_t /*Address*/, const void *Decoder) { 110 unsigned Register = 0; 111 switch (RegNo) { 112 case 0: 113 Register = Hexagon::M0; 114 break; 115 case 1: 116 Register = Hexagon::M1; 117 break; 118 default: 119 return MCDisassembler::Fail; 120 } 121 Inst.addOperand(MCOperand::CreateReg(Register)); 122 return MCDisassembler::Success; 123 } 124 125 static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, 126 uint64_t /*Address*/, const void *Decoder) { 127 static const uint16_t DoubleRegDecoderTable[] = { 128 Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3, 129 Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7, 130 Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11, 131 Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15 132 }; 133 134 return (DecodeRegisterClass(Inst, RegNo >> 1, 135 DoubleRegDecoderTable, 136 sizeof (DoubleRegDecoderTable))); 137 } 138 139 static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 140 uint64_t /*Address*/, 141 void const *Decoder) { 142 if (RegNo > 3) 143 return MCDisassembler::Fail; 144 145 unsigned Register = PredRegDecoderTable[RegNo]; 146 Inst.addOperand(MCOperand::CreateReg(Register)); 147 return MCDisassembler::Success; 148 } 149 150 #include "HexagonGenDisassemblerTables.inc" 151 152 static MCDisassembler *createHexagonDisassembler(Target const &T, 153 MCSubtargetInfo const &STI, 154 MCContext &Ctx) { 155 return new HexagonDisassembler(STI, Ctx); 156 } 157 158 extern "C" void LLVMInitializeHexagonDisassembler() { 159 TargetRegistry::RegisterMCDisassembler(TheHexagonTarget, 160 createHexagonDisassembler); 161 } 162 163 DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 164 ArrayRef<uint8_t> Bytes, 165 uint64_t Address, 166 raw_ostream &os, 167 raw_ostream &cs) const { 168 Size = 4; 169 if (Bytes.size() < 4) 170 return MCDisassembler::Fail; 171 172 uint32_t insn = 173 llvm::support::endian::read<uint32_t, llvm::support::little, 174 llvm::support::unaligned>(Bytes.data()); 175 176 // Remove parse bits. 177 insn &= ~static_cast<uint32_t>(HexagonII::InstParseBits::INST_PARSE_MASK); 178 DecodeStatus Result = decodeInstruction(DecoderTable32, MI, insn, Address, this, STI); 179 HexagonMCInst::AppendImplicitOperands(MI); 180 return Result; 181 } 182