blob: 81f26321b99e1c2bf79e0ea24fd034645ad144c5 [file] [log] [blame]
NAKAMURA Takumi729be142014-10-27 12:37:26 +00001//===-- 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
Colin LeMahieu68d967d2015-05-29 14:44:13 +000010#include "Hexagon.h"
NAKAMURA Takumi729be142014-10-27 12:37:26 +000011#include "MCTargetDesc/HexagonBaseInfo.h"
Colin LeMahieu1174fea2015-02-19 21:10:50 +000012#include "MCTargetDesc/HexagonMCInstrInfo.h"
NAKAMURA Takumi729be142014-10-27 12:37:26 +000013#include "MCTargetDesc/HexagonMCTargetDesc.h"
Colin LeMahieu68d967d2015-05-29 14:44:13 +000014
NAKAMURA Takumi729be142014-10-27 12:37:26 +000015#include "llvm/MC/MCContext.h"
16#include "llvm/MC/MCDisassembler.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCFixedLenDisassembler.h"
19#include "llvm/MC/MCInst.h"
20#include "llvm/MC/MCInstrDesc.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/Support/Debug.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000023#include "llvm/Support/Endian.h"
NAKAMURA Takumi729be142014-10-27 12:37:26 +000024#include "llvm/Support/ErrorHandling.h"
25#include "llvm/Support/LEB128.h"
NAKAMURA Takumi729be142014-10-27 12:37:26 +000026#include "llvm/Support/TargetRegistry.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000027#include "llvm/Support/raw_ostream.h"
NAKAMURA Takumi729be142014-10-27 12:37:26 +000028#include <array>
Chandler Carruthd9903882015-01-14 11:23:27 +000029#include <vector>
NAKAMURA Takumi729be142014-10-27 12:37:26 +000030
31using namespace llvm;
Colin LeMahieu68d967d2015-05-29 14:44:13 +000032using namespace Hexagon;
NAKAMURA Takumi729be142014-10-27 12:37:26 +000033
34#define DEBUG_TYPE "hexagon-disassembler"
35
36// Pull DecodeStatus and its enum values into the global namespace.
37typedef llvm::MCDisassembler::DecodeStatus DecodeStatus;
38
39namespace {
40/// \brief Hexagon disassembler for all Hexagon platforms.
41class HexagonDisassembler : public MCDisassembler {
42public:
Colin LeMahieu68d967d2015-05-29 14:44:13 +000043 std::unique_ptr<MCInst *> CurrentBundle;
NAKAMURA Takumi729be142014-10-27 12:37:26 +000044 HexagonDisassembler(MCSubtargetInfo const &STI, MCContext &Ctx)
Colin LeMahieu68d967d2015-05-29 14:44:13 +000045 : MCDisassembler(STI, Ctx), CurrentBundle(new MCInst *) {}
NAKAMURA Takumi729be142014-10-27 12:37:26 +000046
Colin LeMahieu68d967d2015-05-29 14:44:13 +000047 DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
48 ArrayRef<uint8_t> Bytes, uint64_t Address,
49 raw_ostream &VStream, raw_ostream &CStream,
50 bool &Complete) const;
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000051 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000052 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000053 raw_ostream &VStream,
54 raw_ostream &CStream) const override;
NAKAMURA Takumi729be142014-10-27 12:37:26 +000055};
56}
57
Colin LeMahieuff370ed2014-12-26 20:30:58 +000058static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +000059 uint64_t Address, const void *Decoder);
Colin LeMahieuf3db8842014-12-19 19:06:32 +000060static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +000061 uint64_t Address, const void *Decoder);
Colin LeMahieu404d5b22015-02-10 16:59:36 +000062static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +000063 uint64_t Address, void const *Decoder);
Colin LeMahieuf3db8842014-12-19 19:06:32 +000064
Colin LeMahieuefa74e02014-11-18 20:28:11 +000065static const uint16_t IntRegDecoderTable[] = {
Colin LeMahieuc40be852015-06-04 21:32:42 +000066 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
67 Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9,
68 Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
69 Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
70 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
71 Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
72 Hexagon::R30, Hexagon::R31 };
Colin LeMahieuefa74e02014-11-18 20:28:11 +000073
Colin LeMahieuc40be852015-06-04 21:32:42 +000074static const uint16_t PredRegDecoderTable[] = { Hexagon::P0, Hexagon::P1,
75Hexagon::P2, Hexagon::P3 };
Colin LeMahieuefa74e02014-11-18 20:28:11 +000076
Colin LeMahieu383c36e2014-12-05 18:24:06 +000077static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +000078 const uint16_t Table[], size_t Size) {
Colin LeMahieu383c36e2014-12-05 18:24:06 +000079 if (RegNo < Size) {
Jim Grosbache9119e42015-05-13 18:37:00 +000080 Inst.addOperand(MCOperand::createReg(Table[RegNo]));
Colin LeMahieu383c36e2014-12-05 18:24:06 +000081 return MCDisassembler::Success;
Colin LeMahieuc40be852015-06-04 21:32:42 +000082 }
83 else
Colin LeMahieu383c36e2014-12-05 18:24:06 +000084 return MCDisassembler::Fail;
85}
86
Colin LeMahieuefa74e02014-11-18 20:28:11 +000087static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +000088 uint64_t /*Address*/,
89 void const *Decoder) {
Colin LeMahieuefa74e02014-11-18 20:28:11 +000090 if (RegNo > 31)
91 return MCDisassembler::Fail;
92
93 unsigned Register = IntRegDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +000094 Inst.addOperand(MCOperand::createReg(Register));
Colin LeMahieuefa74e02014-11-18 20:28:11 +000095 return MCDisassembler::Success;
96}
97
Colin LeMahieuf3db8842014-12-19 19:06:32 +000098static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +000099 uint64_t /*Address*/, const void *Decoder) {
Colin LeMahieuf3db8842014-12-19 19:06:32 +0000100 static const uint16_t CtrlRegDecoderTable[] = {
Colin LeMahieuc40be852015-06-04 21:32:42 +0000101 Hexagon::SA0, Hexagon::LC0, Hexagon::SA1, Hexagon::LC1,
102 Hexagon::P3_0, Hexagon::NoRegister, Hexagon::C6, Hexagon::C7,
103 Hexagon::USR, Hexagon::PC, Hexagon::UGP, Hexagon::GP,
104 Hexagon::CS0, Hexagon::CS1, Hexagon::UPCL, Hexagon::UPCH
105 };
Colin LeMahieuf3db8842014-12-19 19:06:32 +0000106
107 if (RegNo >= sizeof(CtrlRegDecoderTable) / sizeof(CtrlRegDecoderTable[0]))
108 return MCDisassembler::Fail;
109
110 if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister)
111 return MCDisassembler::Fail;
112
113 unsigned Register = CtrlRegDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000114 Inst.addOperand(MCOperand::createReg(Register));
Colin LeMahieuf3db8842014-12-19 19:06:32 +0000115 return MCDisassembler::Success;
116}
117
Colin LeMahieu404d5b22015-02-10 16:59:36 +0000118static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +0000119 uint64_t /*Address*/, void const *Decoder) {
Colin LeMahieu404d5b22015-02-10 16:59:36 +0000120 static const uint16_t CtrlReg64DecoderTable[] = {
Colin LeMahieuc40be852015-06-04 21:32:42 +0000121 Hexagon::C1_0, Hexagon::NoRegister,
122 Hexagon::C3_2, Hexagon::NoRegister,
123 Hexagon::NoRegister, Hexagon::NoRegister,
124 Hexagon::C7_6, Hexagon::NoRegister,
125 Hexagon::C9_8, Hexagon::NoRegister,
126 Hexagon::C11_10, Hexagon::NoRegister,
127 Hexagon::CS, Hexagon::NoRegister,
128 Hexagon::UPC, Hexagon::NoRegister
129 };
Colin LeMahieu404d5b22015-02-10 16:59:36 +0000130
131 if (RegNo >= sizeof(CtrlReg64DecoderTable) / sizeof(CtrlReg64DecoderTable[0]))
132 return MCDisassembler::Fail;
133
134 if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister)
135 return MCDisassembler::Fail;
136
137 unsigned Register = CtrlReg64DecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000138 Inst.addOperand(MCOperand::createReg(Register));
Colin LeMahieu404d5b22015-02-10 16:59:36 +0000139 return MCDisassembler::Success;
140}
141
Colin LeMahieuff370ed2014-12-26 20:30:58 +0000142static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +0000143 uint64_t /*Address*/, const void *Decoder) {
Colin LeMahieuff370ed2014-12-26 20:30:58 +0000144 unsigned Register = 0;
145 switch (RegNo) {
146 case 0:
147 Register = Hexagon::M0;
148 break;
149 case 1:
150 Register = Hexagon::M1;
151 break;
152 default:
153 return MCDisassembler::Fail;
154 }
Jim Grosbache9119e42015-05-13 18:37:00 +0000155 Inst.addOperand(MCOperand::createReg(Register));
Colin LeMahieuff370ed2014-12-26 20:30:58 +0000156 return MCDisassembler::Success;
157}
158
Colin LeMahieu383c36e2014-12-05 18:24:06 +0000159static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +0000160 uint64_t /*Address*/, const void *Decoder) {
Colin LeMahieu383c36e2014-12-05 18:24:06 +0000161 static const uint16_t DoubleRegDecoderTable[] = {
Colin LeMahieuc40be852015-06-04 21:32:42 +0000162 Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3,
163 Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7,
164 Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11,
165 Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15
166 };
Colin LeMahieu383c36e2014-12-05 18:24:06 +0000167
Colin LeMahieuc40be852015-06-04 21:32:42 +0000168 return (DecodeRegisterClass(Inst, RegNo >> 1,
169 DoubleRegDecoderTable,
170 sizeof (DoubleRegDecoderTable)));
Colin LeMahieu383c36e2014-12-05 18:24:06 +0000171}
172
Colin LeMahieuefa74e02014-11-18 20:28:11 +0000173static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
Colin LeMahieuc40be852015-06-04 21:32:42 +0000174 uint64_t /*Address*/,
175 void const *Decoder) {
Colin LeMahieuefa74e02014-11-18 20:28:11 +0000176 if (RegNo > 3)
177 return MCDisassembler::Fail;
178
179 unsigned Register = PredRegDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000180 Inst.addOperand(MCOperand::createReg(Register));
Colin LeMahieuefa74e02014-11-18 20:28:11 +0000181 return MCDisassembler::Success;
182}
183
NAKAMURA Takumi729be142014-10-27 12:37:26 +0000184#include "HexagonGenDisassemblerTables.inc"
185
186static MCDisassembler *createHexagonDisassembler(Target const &T,
187 MCSubtargetInfo const &STI,
188 MCContext &Ctx) {
189 return new HexagonDisassembler(STI, Ctx);
190}
191
192extern "C" void LLVMInitializeHexagonDisassembler() {
193 TargetRegistry::RegisterMCDisassembler(TheHexagonTarget,
194 createHexagonDisassembler);
195}
196
197DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000198 ArrayRef<uint8_t> Bytes,
NAKAMURA Takumi729be142014-10-27 12:37:26 +0000199 uint64_t Address,
200 raw_ostream &os,
201 raw_ostream &cs) const {
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000202 DecodeStatus Result = DecodeStatus::Success;
203 bool Complete = false;
204 Size = 0;
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000205
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000206 *CurrentBundle = &MI;
207 MI.setOpcode(Hexagon::BUNDLE);
208 MI.addOperand(MCOperand::createImm(0));
Colin LeMahieuc40be852015-06-04 21:32:42 +0000209 while (Result == Success && Complete == false)
210 {
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000211 if (Bytes.size() < HEXAGON_INSTR_SIZE)
212 return MCDisassembler::Fail;
Colin LeMahieuc40be852015-06-04 21:32:42 +0000213 MCInst * Inst = new (getContext()) MCInst;
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000214 Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete);
215 MI.addOperand(MCOperand::createInst(Inst));
216 Size += HEXAGON_INSTR_SIZE;
217 Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
218 }
219 return Result;
220}
221
222DecodeStatus HexagonDisassembler::getSingleInstruction(
223 MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
224 raw_ostream &os, raw_ostream &cs, bool &Complete) const {
225 assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
226
227 uint32_t Instruction =
NAKAMURA Takumi729be142014-10-27 12:37:26 +0000228 llvm::support::endian::read<uint32_t, llvm::support::little,
229 llvm::support::unaligned>(Bytes.data());
230
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000231 auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
232 if ((Instruction & HexagonII::INST_PARSE_MASK) ==
233 HexagonII::INST_PARSE_LOOP_END) {
234 if (BundleSize == 0)
235 HexagonMCInstrInfo::setInnerLoop(MCB);
236 else if (BundleSize == 1)
237 HexagonMCInstrInfo::setOuterLoop(MCB);
238 else
239 return DecodeStatus::Fail;
240 }
241
242 DecodeStatus Result = DecodeStatus::Success;
243 if ((Instruction & HexagonII::INST_PARSE_MASK) ==
Colin LeMahieuc40be852015-06-04 21:32:42 +0000244 HexagonII::INST_PARSE_PACKET_END)
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000245 Complete = true;
Colin LeMahieuc40be852015-06-04 21:32:42 +0000246 // Calling the auto-generated decoder function.
247 Result =
248 decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI);
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000249
Colin LeMahieu5d6f03b2014-12-04 03:41:21 +0000250 return Result;
NAKAMURA Takumi729be142014-10-27 12:37:26 +0000251}