1*0b57cec5SDimitry Andric //===- ARCDisassembler.cpp - Disassembler for ARC ---------------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric ///
9*0b57cec5SDimitry Andric /// \file
10*0b57cec5SDimitry Andric /// This file is part of the ARC Disassembler.
11*0b57cec5SDimitry Andric ///
12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13*0b57cec5SDimitry Andric
14*0b57cec5SDimitry Andric #include "ARC.h"
15*0b57cec5SDimitry Andric #include "ARCRegisterInfo.h"
16*0b57cec5SDimitry Andric #include "MCTargetDesc/ARCMCTargetDesc.h"
17*0b57cec5SDimitry Andric #include "TargetInfo/ARCTargetInfo.h"
18*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
19*0b57cec5SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
20*0b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
21*0b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
22*0b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
23*0b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
24*0b57cec5SDimitry Andric #include "llvm/MC/TargetRegistry.h"
25*0b57cec5SDimitry Andric
26*0b57cec5SDimitry Andric using namespace llvm;
27*0b57cec5SDimitry Andric
28*0b57cec5SDimitry Andric #define DEBUG_TYPE "arc-disassembler"
29*0b57cec5SDimitry Andric
30*0b57cec5SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
31*0b57cec5SDimitry Andric
32*0b57cec5SDimitry Andric namespace {
33*0b57cec5SDimitry Andric
34*0b57cec5SDimitry Andric /// A disassembler class for ARC.
35*0b57cec5SDimitry Andric class ARCDisassembler : public MCDisassembler {
36*0b57cec5SDimitry Andric public:
37*0b57cec5SDimitry Andric std::unique_ptr<MCInstrInfo const> const MCII;
38*0b57cec5SDimitry Andric
ARCDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)39*0b57cec5SDimitry Andric ARCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
40*0b57cec5SDimitry Andric MCInstrInfo const *MCII)
41*0b57cec5SDimitry Andric : MCDisassembler(STI, Ctx), MCII(MCII) {}
42*0b57cec5SDimitry Andric
43*0b57cec5SDimitry Andric DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
44*0b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
45*0b57cec5SDimitry Andric raw_ostream &CStream) const override;
46*0b57cec5SDimitry Andric };
47*0b57cec5SDimitry Andric
48*0b57cec5SDimitry Andric } // end anonymous namespace
49*0b57cec5SDimitry Andric
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn)50*0b57cec5SDimitry Andric static bool readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
51*0b57cec5SDimitry Andric uint64_t &Size, uint32_t &Insn) {
52*0b57cec5SDimitry Andric Size = 4;
53*0b57cec5SDimitry Andric // Read 2 16-bit values, but swap hi/lo parts.
54*0b57cec5SDimitry Andric Insn =
55*0b57cec5SDimitry Andric (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
56*0b57cec5SDimitry Andric return true;
57*0b57cec5SDimitry Andric }
58*0b57cec5SDimitry Andric
readInstruction64(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint64_t & Insn)59*0b57cec5SDimitry Andric static bool readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address,
60*0b57cec5SDimitry Andric uint64_t &Size, uint64_t &Insn) {
61*0b57cec5SDimitry Andric Size = 8;
62*0b57cec5SDimitry Andric Insn = ((uint64_t)Bytes[0] << 16) | ((uint64_t)Bytes[1] << 24) |
63*0b57cec5SDimitry Andric ((uint64_t)Bytes[2] << 0) | ((uint64_t)Bytes[3] << 8) |
64*0b57cec5SDimitry Andric ((uint64_t)Bytes[4] << 48) | ((uint64_t)Bytes[5] << 56) |
65*0b57cec5SDimitry Andric ((uint64_t)Bytes[6] << 32) | ((uint64_t)Bytes[7] << 40);
66*0b57cec5SDimitry Andric return true;
67*0b57cec5SDimitry Andric }
68*0b57cec5SDimitry Andric
readInstruction48(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint64_t & Insn)69*0b57cec5SDimitry Andric static bool readInstruction48(ArrayRef<uint8_t> Bytes, uint64_t Address,
70*0b57cec5SDimitry Andric uint64_t &Size, uint64_t &Insn) {
71*0b57cec5SDimitry Andric Size = 6;
72*0b57cec5SDimitry Andric Insn = ((uint64_t)Bytes[0] << 0) | ((uint64_t)Bytes[1] << 8) |
73*0b57cec5SDimitry Andric ((uint64_t)Bytes[2] << 32) | ((uint64_t)Bytes[3] << 40) |
74*0b57cec5SDimitry Andric ((uint64_t)Bytes[4] << 16) | ((uint64_t)Bytes[5] << 24);
75*0b57cec5SDimitry Andric return true;
76*0b57cec5SDimitry Andric }
77*0b57cec5SDimitry Andric
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn)78*0b57cec5SDimitry Andric static bool readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
79*0b57cec5SDimitry Andric uint64_t &Size, uint32_t &Insn) {
80*0b57cec5SDimitry Andric Size = 2;
81*0b57cec5SDimitry Andric Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
82*0b57cec5SDimitry Andric return true;
83*0b57cec5SDimitry Andric }
84*0b57cec5SDimitry Andric
85*0b57cec5SDimitry Andric template <unsigned B>
86*0b57cec5SDimitry Andric static DecodeStatus
87*0b57cec5SDimitry Andric DecodeSignedOperand(MCInst &Inst, unsigned InsnS, uint64_t Address = 0,
88*0b57cec5SDimitry Andric const MCDisassembler *Decoder = nullptr);
89*0b57cec5SDimitry Andric
90*0b57cec5SDimitry Andric template <unsigned B>
91*0b57cec5SDimitry Andric static DecodeStatus
92*0b57cec5SDimitry Andric DecodeFromCyclicRange(MCInst &Inst, unsigned InsnS, uint64_t Address = 0,
93*0b57cec5SDimitry Andric const MCDisassembler *Decoder = nullptr);
94*0b57cec5SDimitry Andric
95*0b57cec5SDimitry Andric template <unsigned B>
96*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTargetS(MCInst &Inst, unsigned InsnS,
97*0b57cec5SDimitry Andric uint64_t Address,
98*0b57cec5SDimitry Andric const MCDisassembler *Decoder);
99*0b57cec5SDimitry Andric
100*0b57cec5SDimitry Andric static DecodeStatus DecodeMEMrs9(MCInst &, unsigned, uint64_t,
101*0b57cec5SDimitry Andric const MCDisassembler *);
102*0b57cec5SDimitry Andric
103*0b57cec5SDimitry Andric static DecodeStatus DecodeLdLImmInstruction(MCInst &, uint64_t, uint64_t,
104*0b57cec5SDimitry Andric const MCDisassembler *);
105*0b57cec5SDimitry Andric
106*0b57cec5SDimitry Andric static DecodeStatus DecodeStLImmInstruction(MCInst &, uint64_t, uint64_t,
107*0b57cec5SDimitry Andric const MCDisassembler *);
108*0b57cec5SDimitry Andric
109*0b57cec5SDimitry Andric static DecodeStatus DecodeLdRLImmInstruction(MCInst &, uint64_t, uint64_t,
110*0b57cec5SDimitry Andric const MCDisassembler *);
111*0b57cec5SDimitry Andric
112*0b57cec5SDimitry Andric static DecodeStatus DecodeSOPwithRS12(MCInst &, uint64_t, uint64_t,
113*0b57cec5SDimitry Andric const MCDisassembler *);
114*0b57cec5SDimitry Andric
115*0b57cec5SDimitry Andric static DecodeStatus DecodeSOPwithRU6(MCInst &, uint64_t, uint64_t,
116*0b57cec5SDimitry Andric const MCDisassembler *);
117*0b57cec5SDimitry Andric
118*0b57cec5SDimitry Andric static DecodeStatus DecodeCCRU6Instruction(MCInst &, uint64_t, uint64_t,
119*0b57cec5SDimitry Andric const MCDisassembler *);
120*0b57cec5SDimitry Andric
121*0b57cec5SDimitry Andric static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t, uint64_t,
122*0b57cec5SDimitry Andric const MCDisassembler *);
123*0b57cec5SDimitry Andric
124*0b57cec5SDimitry Andric static const uint16_t GPR32DecoderTable[] = {
125*0b57cec5SDimitry Andric ARC::R0, ARC::R1, ARC::R2, ARC::R3, ARC::R4, ARC::R5, ARC::R6,
126*0b57cec5SDimitry Andric ARC::R7, ARC::R8, ARC::R9, ARC::R10, ARC::R11, ARC::R12, ARC::R13,
127*0b57cec5SDimitry Andric ARC::R14, ARC::R15, ARC::R16, ARC::R17, ARC::R18, ARC::R19, ARC::R20,
128*0b57cec5SDimitry Andric ARC::R21, ARC::R22, ARC::R23, ARC::R24, ARC::R25, ARC::GP, ARC::FP,
129*0b57cec5SDimitry Andric ARC::SP, ARC::ILINK, ARC::R30, ARC::BLINK};
130*0b57cec5SDimitry Andric
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)131*0b57cec5SDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
132*0b57cec5SDimitry Andric uint64_t Address,
133*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
134*0b57cec5SDimitry Andric if (RegNo >= 32) {
135*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Not a GPR32 register.");
136*0b57cec5SDimitry Andric return MCDisassembler::Fail;
137*0b57cec5SDimitry Andric }
138*0b57cec5SDimitry Andric
139*0b57cec5SDimitry Andric unsigned Reg = GPR32DecoderTable[RegNo];
140*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg));
141*0b57cec5SDimitry Andric return MCDisassembler::Success;
142*0b57cec5SDimitry Andric }
143*0b57cec5SDimitry Andric
DecodeGBR32ShortRegister(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)144*0b57cec5SDimitry Andric static DecodeStatus DecodeGBR32ShortRegister(MCInst &Inst, unsigned RegNo,
145*0b57cec5SDimitry Andric uint64_t Address,
146*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
147*0b57cec5SDimitry Andric // Enumerates registers from ranges [r0-r3],[r12-r15].
148*0b57cec5SDimitry Andric if (RegNo > 3)
149*0b57cec5SDimitry Andric RegNo += 8; // 4 for r12, etc...
150*0b57cec5SDimitry Andric
151*0b57cec5SDimitry Andric return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
152*0b57cec5SDimitry Andric }
153*0b57cec5SDimitry Andric
154*0b57cec5SDimitry Andric #include "ARCGenDisassemblerTables.inc"
155*0b57cec5SDimitry Andric
decodeCField(unsigned Insn)156*0b57cec5SDimitry Andric static unsigned decodeCField(unsigned Insn) {
157*0b57cec5SDimitry Andric return fieldFromInstruction(Insn, 6, 6);
158*0b57cec5SDimitry Andric }
159*0b57cec5SDimitry Andric
decodeBField(unsigned Insn)160*0b57cec5SDimitry Andric static unsigned decodeBField(unsigned Insn) {
161*0b57cec5SDimitry Andric return (fieldFromInstruction(Insn, 12, 3) << 3) |
162*0b57cec5SDimitry Andric fieldFromInstruction(Insn, 24, 3);
163*0b57cec5SDimitry Andric }
164*0b57cec5SDimitry Andric
decodeAField(unsigned Insn)165*0b57cec5SDimitry Andric static unsigned decodeAField(unsigned Insn) {
166*0b57cec5SDimitry Andric return fieldFromInstruction(Insn, 0, 6);
167*0b57cec5SDimitry Andric }
168*0b57cec5SDimitry Andric
DecodeMEMrs9(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Dec)169*0b57cec5SDimitry Andric static DecodeStatus DecodeMEMrs9(MCInst &Inst, unsigned Insn, uint64_t Address,
170*0b57cec5SDimitry Andric const MCDisassembler *Dec) {
171*0b57cec5SDimitry Andric // We have the 9-bit immediate in the low bits, 6-bit register in high bits.
172*0b57cec5SDimitry Andric unsigned S9 = Insn & 0x1ff;
173*0b57cec5SDimitry Andric unsigned R = (Insn & (0x7fff & ~0x1ff)) >> 9;
174*0b57cec5SDimitry Andric DecodeGPR32RegisterClass(Inst, R, Address, Dec);
175*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<9>(S9)));
176*0b57cec5SDimitry Andric return MCDisassembler::Success;
177*0b57cec5SDimitry Andric }
178*0b57cec5SDimitry Andric
DecodeSymbolicOperand(MCInst & Inst,uint64_t Address,uint64_t Value,const MCDisassembler * Decoder)179*0b57cec5SDimitry Andric static bool DecodeSymbolicOperand(MCInst &Inst, uint64_t Address,
180*0b57cec5SDimitry Andric uint64_t Value,
181*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
182*0b57cec5SDimitry Andric static const uint64_t AtLeast = 2;
183*0b57cec5SDimitry Andric return (nullptr != Decoder && Decoder->tryAddingSymbolicOperand(
184*0b57cec5SDimitry Andric Inst, Value, Address, true, 0, AtLeast, 0));
185*0b57cec5SDimitry Andric }
186*0b57cec5SDimitry Andric
DecodeSymbolicOperandOff(MCInst & Inst,uint64_t Address,uint64_t Offset,const MCDisassembler * Decoder)187*0b57cec5SDimitry Andric static void DecodeSymbolicOperandOff(MCInst &Inst, uint64_t Address,
188*0b57cec5SDimitry Andric uint64_t Offset,
189*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
190*0b57cec5SDimitry Andric uint64_t NextAddress = Address + Offset;
191*0b57cec5SDimitry Andric
192*0b57cec5SDimitry Andric if (!DecodeSymbolicOperand(Inst, Address, NextAddress, Decoder))
193*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Offset));
194*0b57cec5SDimitry Andric }
195*0b57cec5SDimitry Andric
196*0b57cec5SDimitry Andric template <unsigned B>
DecodeBranchTargetS(MCInst & Inst,unsigned InsnS,uint64_t Address,const MCDisassembler * Decoder)197*0b57cec5SDimitry Andric static DecodeStatus DecodeBranchTargetS(MCInst &Inst, unsigned InsnS,
198*0b57cec5SDimitry Andric uint64_t Address,
199*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
200*0b57cec5SDimitry Andric
201*0b57cec5SDimitry Andric static_assert(B > 0, "field is empty");
202*0b57cec5SDimitry Andric DecodeSymbolicOperandOff(Inst, Address, SignExtend32<B>(InsnS), Decoder);
203*0b57cec5SDimitry Andric return MCDisassembler::Success;
204*0b57cec5SDimitry Andric }
205*0b57cec5SDimitry Andric
206*0b57cec5SDimitry Andric template <unsigned B>
DecodeSignedOperand(MCInst & Inst,unsigned InsnS,uint64_t,const MCDisassembler *)207*0b57cec5SDimitry Andric static DecodeStatus DecodeSignedOperand(MCInst &Inst, unsigned InsnS,
208*0b57cec5SDimitry Andric uint64_t /*Address*/,
209*0b57cec5SDimitry Andric const MCDisassembler * /*Decoder*/) {
210*0b57cec5SDimitry Andric
211*0b57cec5SDimitry Andric static_assert(B > 0, "field is empty");
212*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(
213*0b57cec5SDimitry Andric SignExtend32<B>(maskTrailingOnes<decltype(InsnS)>(B) & InsnS)));
214*0b57cec5SDimitry Andric return MCDisassembler::Success;
215*0b57cec5SDimitry Andric }
216*0b57cec5SDimitry Andric
217*0b57cec5SDimitry Andric template <unsigned B>
DecodeFromCyclicRange(MCInst & Inst,unsigned InsnS,uint64_t,const MCDisassembler *)218*0b57cec5SDimitry Andric static DecodeStatus DecodeFromCyclicRange(MCInst &Inst, unsigned InsnS,
219*0b57cec5SDimitry Andric uint64_t /*Address*/,
220*0b57cec5SDimitry Andric const MCDisassembler * /*Decoder*/) {
221*0b57cec5SDimitry Andric
222*0b57cec5SDimitry Andric static_assert(B > 0, "field is empty");
223*0b57cec5SDimitry Andric const unsigned max = (1u << B) - 1;
224*0b57cec5SDimitry Andric Inst.addOperand(
225*0b57cec5SDimitry Andric MCOperand::createImm(InsnS < max ? static_cast<int>(InsnS) : -1));
226*0b57cec5SDimitry Andric return MCDisassembler::Success;
227*0b57cec5SDimitry Andric }
228*0b57cec5SDimitry Andric
DecodeStLImmInstruction(MCInst & Inst,uint64_t Insn,uint64_t Address,const MCDisassembler * Decoder)229*0b57cec5SDimitry Andric static DecodeStatus DecodeStLImmInstruction(MCInst &Inst, uint64_t Insn,
230*0b57cec5SDimitry Andric uint64_t Address,
231*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
232*0b57cec5SDimitry Andric unsigned SrcC, DstB, LImm;
233*0b57cec5SDimitry Andric DstB = decodeBField(Insn);
234*0b57cec5SDimitry Andric if (DstB != 62) {
235*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Decoding StLImm found non-limm register.");
236*0b57cec5SDimitry Andric return MCDisassembler::Fail;
237*0b57cec5SDimitry Andric }
238*0b57cec5SDimitry Andric SrcC = decodeCField(Insn);
239*0b57cec5SDimitry Andric DecodeGPR32RegisterClass(Inst, SrcC, Address, Decoder);
240*0b57cec5SDimitry Andric LImm = (Insn >> 32);
241*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(LImm));
242*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
243*0b57cec5SDimitry Andric return MCDisassembler::Success;
244*0b57cec5SDimitry Andric }
245*0b57cec5SDimitry Andric
DecodeLdLImmInstruction(MCInst & Inst,uint64_t Insn,uint64_t Address,const MCDisassembler * Decoder)246*0b57cec5SDimitry Andric static DecodeStatus DecodeLdLImmInstruction(MCInst &Inst, uint64_t Insn,
247*0b57cec5SDimitry Andric uint64_t Address,
248*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
249*0b57cec5SDimitry Andric unsigned DstA, SrcB, LImm;
250*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Decoding LdLImm:\n");
251*0b57cec5SDimitry Andric SrcB = decodeBField(Insn);
252*0b57cec5SDimitry Andric if (SrcB != 62) {
253*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Decoding LdLImm found non-limm register.");
254*0b57cec5SDimitry Andric return MCDisassembler::Fail;
255*0b57cec5SDimitry Andric }
256*0b57cec5SDimitry Andric DstA = decodeAField(Insn);
257*0b57cec5SDimitry Andric DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder);
258*0b57cec5SDimitry Andric LImm = (Insn >> 32);
259*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(LImm));
260*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
261*0b57cec5SDimitry Andric return MCDisassembler::Success;
262*0b57cec5SDimitry Andric }
263*0b57cec5SDimitry Andric
DecodeLdRLImmInstruction(MCInst & Inst,uint64_t Insn,uint64_t Address,const MCDisassembler * Decoder)264*0b57cec5SDimitry Andric static DecodeStatus DecodeLdRLImmInstruction(MCInst &Inst, uint64_t Insn,
265*0b57cec5SDimitry Andric uint64_t Address,
266*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
267*0b57cec5SDimitry Andric unsigned DstA, SrcB;
268*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Decoding LdRLimm\n");
269*0b57cec5SDimitry Andric DstA = decodeAField(Insn);
270*0b57cec5SDimitry Andric DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder);
271*0b57cec5SDimitry Andric SrcB = decodeBField(Insn);
272*0b57cec5SDimitry Andric DecodeGPR32RegisterClass(Inst, SrcB, Address, Decoder);
273*0b57cec5SDimitry Andric if (decodeCField(Insn) != 62) {
274*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Decoding LdRLimm found non-limm register.");
275*0b57cec5SDimitry Andric return MCDisassembler::Fail;
276*0b57cec5SDimitry Andric }
277*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm((uint32_t)(Insn >> 32)));
278*0b57cec5SDimitry Andric return MCDisassembler::Success;
279*0b57cec5SDimitry Andric }
280*0b57cec5SDimitry Andric
DecodeMoveHRegInstruction(MCInst & Inst,uint64_t Insn,uint64_t Address,const MCDisassembler * Decoder)281*0b57cec5SDimitry Andric static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t Insn,
282*0b57cec5SDimitry Andric uint64_t Address,
283*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
284*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Decoding MOV_S h-register\n");
285*0b57cec5SDimitry Andric using Field = decltype(Insn);
286*0b57cec5SDimitry Andric Field H = fieldFromInstruction(Insn, 5, 3) |
287*0b57cec5SDimitry Andric (fieldFromInstruction(Insn, 0, 2) << 3);
288*0b57cec5SDimitry Andric Field G = fieldFromInstruction(Insn, 8, 3) |
289*0b57cec5SDimitry Andric (fieldFromInstruction(Insn, 3, 2) << 3);
290*0b57cec5SDimitry Andric
291*0b57cec5SDimitry Andric auto DecodeRegisterOrImm = [&Inst, Address, Decoder](Field RegNum,
292*0b57cec5SDimitry Andric Field Value) {
293*0b57cec5SDimitry Andric if (30 == RegNum) {
294*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Value));
295*0b57cec5SDimitry Andric return MCDisassembler::Success;
296*0b57cec5SDimitry Andric }
297*0b57cec5SDimitry Andric
298*0b57cec5SDimitry Andric return DecodeGPR32RegisterClass(Inst, RegNum, Address, Decoder);
299*0b57cec5SDimitry Andric };
300*0b57cec5SDimitry Andric
301*0b57cec5SDimitry Andric if (MCDisassembler::Success != DecodeRegisterOrImm(G, 0))
302*0b57cec5SDimitry Andric return MCDisassembler::Fail;
303*0b57cec5SDimitry Andric
304*0b57cec5SDimitry Andric return DecodeRegisterOrImm(H, Insn >> 16u);
305*0b57cec5SDimitry Andric }
306*0b57cec5SDimitry Andric
DecodeCCRU6Instruction(MCInst & Inst,uint64_t Insn,uint64_t Address,const MCDisassembler * Decoder)307*0b57cec5SDimitry Andric static DecodeStatus DecodeCCRU6Instruction(MCInst &Inst, uint64_t Insn,
308*0b57cec5SDimitry Andric uint64_t Address,
309*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
310*0b57cec5SDimitry Andric unsigned DstB;
311*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Decoding CCRU6 instruction:\n");
312*0b57cec5SDimitry Andric DstB = decodeBField(Insn);
313*0b57cec5SDimitry Andric DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder);
314*0b57cec5SDimitry Andric using Field = decltype(Insn);
315*0b57cec5SDimitry Andric Field U6Field = fieldFromInstruction(Insn, 6, 6);
316*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(U6Field));
317*0b57cec5SDimitry Andric Field CCField = fieldFromInstruction(Insn, 0, 4);
318*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(CCField));
319*0b57cec5SDimitry Andric return MCDisassembler::Success;
320*0b57cec5SDimitry Andric }
321*0b57cec5SDimitry Andric
DecodeSOPwithRU6(MCInst & Inst,uint64_t Insn,uint64_t Address,const MCDisassembler * Decoder)322*0b57cec5SDimitry Andric static DecodeStatus DecodeSOPwithRU6(MCInst &Inst, uint64_t Insn,
323*0b57cec5SDimitry Andric uint64_t Address,
324*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
325*0b57cec5SDimitry Andric unsigned DstB = decodeBField(Insn);
326*0b57cec5SDimitry Andric DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder);
327*0b57cec5SDimitry Andric using Field = decltype(Insn);
328*0b57cec5SDimitry Andric Field U6 = fieldFromInstruction(Insn, 6, 6);
329*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(U6));
330*0b57cec5SDimitry Andric return MCDisassembler::Success;
331*0b57cec5SDimitry Andric }
332*0b57cec5SDimitry Andric
DecodeSOPwithRS12(MCInst & Inst,uint64_t Insn,uint64_t Address,const MCDisassembler * Decoder)333*0b57cec5SDimitry Andric static DecodeStatus DecodeSOPwithRS12(MCInst &Inst, uint64_t Insn,
334*0b57cec5SDimitry Andric uint64_t Address,
335*0b57cec5SDimitry Andric const MCDisassembler *Decoder) {
336*0b57cec5SDimitry Andric unsigned DstB = decodeBField(Insn);
337*0b57cec5SDimitry Andric DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder);
338*0b57cec5SDimitry Andric using Field = decltype(Insn);
339*0b57cec5SDimitry Andric Field Lower = fieldFromInstruction(Insn, 6, 6);
340*0b57cec5SDimitry Andric Field Upper = fieldFromInstruction(Insn, 0, 5);
341*0b57cec5SDimitry Andric Field Sign = fieldFromInstruction(Insn, 5, 1) ? -1 : 1;
342*0b57cec5SDimitry Andric Field Result = Sign * ((Upper << 6) + Lower);
343*0b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Result));
344*0b57cec5SDimitry Andric return MCDisassembler::Success;
345*0b57cec5SDimitry Andric }
346*0b57cec5SDimitry Andric
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & cStream) const347*0b57cec5SDimitry Andric DecodeStatus ARCDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
348*0b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes,
349*0b57cec5SDimitry Andric uint64_t Address,
350*0b57cec5SDimitry Andric raw_ostream &cStream) const {
351*0b57cec5SDimitry Andric MCDisassembler::DecodeStatus Result;
352*0b57cec5SDimitry Andric if (Bytes.size() < 2) {
353*0b57cec5SDimitry Andric Size = 0;
354*0b57cec5SDimitry Andric return Fail;
355*0b57cec5SDimitry Andric }
356*0b57cec5SDimitry Andric uint8_t DecodeByte = (Bytes[1] & 0xF7) >> 3;
357*0b57cec5SDimitry Andric // 0x00 -> 0x07 are 32-bit instructions.
358*0b57cec5SDimitry Andric // 0x08 -> 0x1F are 16-bit instructions.
359*0b57cec5SDimitry Andric if (DecodeByte < 0x08) {
360*0b57cec5SDimitry Andric // 32-bit instruction.
361*0b57cec5SDimitry Andric if (Bytes.size() < 4) {
362*0b57cec5SDimitry Andric // Did we decode garbage?
363*0b57cec5SDimitry Andric Size = 0;
364*0b57cec5SDimitry Andric return Fail;
365*0b57cec5SDimitry Andric }
366*0b57cec5SDimitry Andric if (Bytes.size() >= 8) {
367*0b57cec5SDimitry Andric // Attempt to decode 64-bit instruction.
368*0b57cec5SDimitry Andric uint64_t Insn64;
369*0b57cec5SDimitry Andric if (!readInstruction64(Bytes, Address, Size, Insn64))
370*0b57cec5SDimitry Andric return Fail;
371*0b57cec5SDimitry Andric Result =
372*0b57cec5SDimitry Andric decodeInstruction(DecoderTable64, Instr, Insn64, Address, this, STI);
373 if (Success == Result) {
374 LLVM_DEBUG(dbgs() << "Successfully decoded 64-bit instruction.");
375 return Result;
376 }
377 LLVM_DEBUG(dbgs() << "Not a 64-bit instruction, falling back to 32-bit.");
378 }
379 uint32_t Insn32;
380 if (!readInstruction32(Bytes, Address, Size, Insn32)) {
381 return Fail;
382 }
383 // Calling the auto-generated decoder function.
384 return decodeInstruction(DecoderTable32, Instr, Insn32, Address, this, STI);
385 } else {
386 if (Bytes.size() >= 6) {
387 // Attempt to treat as instr. with limm data.
388 uint64_t Insn48;
389 if (!readInstruction48(Bytes, Address, Size, Insn48))
390 return Fail;
391 Result =
392 decodeInstruction(DecoderTable48, Instr, Insn48, Address, this, STI);
393 if (Success == Result) {
394 LLVM_DEBUG(
395 dbgs() << "Successfully decoded 16-bit instruction with limm.");
396 return Result;
397 }
398 LLVM_DEBUG(
399 dbgs() << "Not a 16-bit instruction with limm, try without it.");
400 }
401
402 uint32_t Insn16;
403 if (!readInstruction16(Bytes, Address, Size, Insn16))
404 return Fail;
405
406 // Calling the auto-generated decoder function.
407 return decodeInstruction(DecoderTable16, Instr, Insn16, Address, this, STI);
408 }
409 }
410
createARCDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)411 static MCDisassembler *createARCDisassembler(const Target &T,
412 const MCSubtargetInfo &STI,
413 MCContext &Ctx) {
414 return new ARCDisassembler(STI, Ctx, T.createMCInstrInfo());
415 }
416
LLVMInitializeARCDisassembler()417 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARCDisassembler() {
418 // Register the disassembler.
419 TargetRegistry::RegisterMCDisassembler(getTheARCTarget(),
420 createARCDisassembler);
421 }
422