xref: /openbsd-src/gnu/llvm/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
1*d415bd75Srobert //===-- CSKYDisassembler.cpp - Disassembler for CSKY ----------------------===//
2*d415bd75Srobert //
3*d415bd75Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*d415bd75Srobert // See https://llvm.org/LICENSE.txt for license information.
5*d415bd75Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*d415bd75Srobert //
7*d415bd75Srobert //===----------------------------------------------------------------------===//
8*d415bd75Srobert //
9*d415bd75Srobert // This file implements the CSKYDisassembler class.
10*d415bd75Srobert //
11*d415bd75Srobert //===----------------------------------------------------------------------===//
12*d415bd75Srobert 
13*d415bd75Srobert #include "MCTargetDesc/CSKYBaseInfo.h"
14*d415bd75Srobert #include "MCTargetDesc/CSKYMCTargetDesc.h"
15*d415bd75Srobert #include "TargetInfo/CSKYTargetInfo.h"
16*d415bd75Srobert #include "llvm/ADT/DenseMap.h"
17*d415bd75Srobert #include "llvm/MC/MCContext.h"
18*d415bd75Srobert #include "llvm/MC/MCDecoderOps.h"
19*d415bd75Srobert #include "llvm/MC/MCDisassembler/MCDisassembler.h"
20*d415bd75Srobert #include "llvm/MC/MCInst.h"
21*d415bd75Srobert #include "llvm/MC/MCInstrInfo.h"
22*d415bd75Srobert #include "llvm/MC/MCRegisterInfo.h"
23*d415bd75Srobert #include "llvm/MC/MCSubtargetInfo.h"
24*d415bd75Srobert #include "llvm/MC/TargetRegistry.h"
25*d415bd75Srobert #include "llvm/Support/Endian.h"
26*d415bd75Srobert 
27*d415bd75Srobert using namespace llvm;
28*d415bd75Srobert 
29*d415bd75Srobert #define DEBUG_TYPE "csky-disassembler"
30*d415bd75Srobert 
31*d415bd75Srobert typedef MCDisassembler::DecodeStatus DecodeStatus;
32*d415bd75Srobert 
33*d415bd75Srobert namespace {
34*d415bd75Srobert class CSKYDisassembler : public MCDisassembler {
35*d415bd75Srobert   std::unique_ptr<MCInstrInfo const> const MCII;
36*d415bd75Srobert   mutable StringRef symbolName;
37*d415bd75Srobert 
38*d415bd75Srobert   DecodeStatus handleCROperand(MCInst &Instr) const;
39*d415bd75Srobert 
40*d415bd75Srobert public:
41*d415bd75Srobert   CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
42*d415bd75Srobert                    MCInstrInfo const *MCII);
43*d415bd75Srobert 
44*d415bd75Srobert   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
45*d415bd75Srobert                               ArrayRef<uint8_t> Bytes, uint64_t Address,
46*d415bd75Srobert                               raw_ostream &CStream) const override;
47*d415bd75Srobert };
48*d415bd75Srobert } // end anonymous namespace
49*d415bd75Srobert 
CSKYDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)50*d415bd75Srobert CSKYDisassembler::CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
51*d415bd75Srobert                                    MCInstrInfo const *MCII)
52*d415bd75Srobert     : MCDisassembler(STI, Ctx), MCII(MCII) {}
53*d415bd75Srobert 
createCSKYDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)54*d415bd75Srobert static MCDisassembler *createCSKYDisassembler(const Target &T,
55*d415bd75Srobert                                               const MCSubtargetInfo &STI,
56*d415bd75Srobert                                               MCContext &Ctx) {
57*d415bd75Srobert   return new CSKYDisassembler(STI, Ctx, T.createMCInstrInfo());
58*d415bd75Srobert }
59*d415bd75Srobert 
LLVMInitializeCSKYDisassembler()60*d415bd75Srobert extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYDisassembler() {
61*d415bd75Srobert   TargetRegistry::RegisterMCDisassembler(getTheCSKYTarget(),
62*d415bd75Srobert                                          createCSKYDisassembler);
63*d415bd75Srobert }
64*d415bd75Srobert 
65*d415bd75Srobert static const uint16_t GPRDecoderTable[] = {
66*d415bd75Srobert     CSKY::R0,  CSKY::R1,  CSKY::R2,  CSKY::R3,  CSKY::R4,  CSKY::R5,  CSKY::R6,
67*d415bd75Srobert     CSKY::R7,  CSKY::R8,  CSKY::R9,  CSKY::R10, CSKY::R11, CSKY::R12, CSKY::R13,
68*d415bd75Srobert     CSKY::R14, CSKY::R15, CSKY::R16, CSKY::R17, CSKY::R18, CSKY::R19, CSKY::R20,
69*d415bd75Srobert     CSKY::R21, CSKY::R22, CSKY::R23, CSKY::R24, CSKY::R25, CSKY::R26, CSKY::R27,
70*d415bd75Srobert     CSKY::R28, CSKY::R29, CSKY::R30, CSKY::R31};
71*d415bd75Srobert 
72*d415bd75Srobert static const uint16_t GPRPairDecoderTable[] = {
73*d415bd75Srobert     CSKY::R0_R1,   CSKY::R1_R2,   CSKY::R2_R3,   CSKY::R3_R4,   CSKY::R4_R5,
74*d415bd75Srobert     CSKY::R5_R6,   CSKY::R6_R7,   CSKY::R7_R8,   CSKY::R8_R9,   CSKY::R9_R10,
75*d415bd75Srobert     CSKY::R10_R11, CSKY::R11_R12, CSKY::R12_R13, CSKY::R13_R14, CSKY::R14_R15,
76*d415bd75Srobert     CSKY::R15_R16, CSKY::R16_R17, CSKY::R17_R18, CSKY::R18_R19, CSKY::R19_R20,
77*d415bd75Srobert     CSKY::R20_R21, CSKY::R21_R22, CSKY::R22_R23, CSKY::R23_R24, CSKY::R24_R25,
78*d415bd75Srobert     CSKY::R25_R26, CSKY::R26_R27, CSKY::R27_R28, CSKY::R28_R29, CSKY::R29_R30,
79*d415bd75Srobert     CSKY::R30_R31, CSKY::R31_R32};
80*d415bd75Srobert 
81*d415bd75Srobert static const uint16_t FPR32DecoderTable[] = {
82*d415bd75Srobert     CSKY::F0_32,  CSKY::F1_32,  CSKY::F2_32,  CSKY::F3_32,  CSKY::F4_32,
83*d415bd75Srobert     CSKY::F5_32,  CSKY::F6_32,  CSKY::F7_32,  CSKY::F8_32,  CSKY::F9_32,
84*d415bd75Srobert     CSKY::F10_32, CSKY::F11_32, CSKY::F12_32, CSKY::F13_32, CSKY::F14_32,
85*d415bd75Srobert     CSKY::F15_32, CSKY::F16_32, CSKY::F17_32, CSKY::F18_32, CSKY::F19_32,
86*d415bd75Srobert     CSKY::F20_32, CSKY::F21_32, CSKY::F22_32, CSKY::F23_32, CSKY::F24_32,
87*d415bd75Srobert     CSKY::F25_32, CSKY::F26_32, CSKY::F27_32, CSKY::F28_32, CSKY::F29_32,
88*d415bd75Srobert     CSKY::F30_32, CSKY::F31_32};
89*d415bd75Srobert 
90*d415bd75Srobert static const uint16_t FPR64DecoderTable[] = {
91*d415bd75Srobert     CSKY::F0_64,  CSKY::F1_64,  CSKY::F2_64,  CSKY::F3_64,  CSKY::F4_64,
92*d415bd75Srobert     CSKY::F5_64,  CSKY::F6_64,  CSKY::F7_64,  CSKY::F8_64,  CSKY::F9_64,
93*d415bd75Srobert     CSKY::F10_64, CSKY::F11_64, CSKY::F12_64, CSKY::F13_64, CSKY::F14_64,
94*d415bd75Srobert     CSKY::F15_64, CSKY::F16_64, CSKY::F17_64, CSKY::F18_64, CSKY::F19_64,
95*d415bd75Srobert     CSKY::F20_64, CSKY::F21_64, CSKY::F22_64, CSKY::F23_64, CSKY::F24_64,
96*d415bd75Srobert     CSKY::F25_64, CSKY::F26_64, CSKY::F27_64, CSKY::F28_64, CSKY::F29_64,
97*d415bd75Srobert     CSKY::F30_64, CSKY::F31_64};
98*d415bd75Srobert 
99*d415bd75Srobert static const uint16_t FPR128DecoderTable[] = {
100*d415bd75Srobert     CSKY::F0_128,  CSKY::F1_128,  CSKY::F2_128,  CSKY::F3_128,  CSKY::F4_128,
101*d415bd75Srobert     CSKY::F5_128,  CSKY::F6_128,  CSKY::F7_128,  CSKY::F8_128,  CSKY::F9_128,
102*d415bd75Srobert     CSKY::F10_128, CSKY::F11_128, CSKY::F12_128, CSKY::F13_128, CSKY::F14_128,
103*d415bd75Srobert     CSKY::F15_128, CSKY::F16_128, CSKY::F17_128, CSKY::F18_128, CSKY::F19_128,
104*d415bd75Srobert     CSKY::F20_128, CSKY::F21_128, CSKY::F22_128, CSKY::F23_128, CSKY::F24_128,
105*d415bd75Srobert     CSKY::F25_128, CSKY::F26_128, CSKY::F27_128, CSKY::F28_128, CSKY::F29_128,
106*d415bd75Srobert     CSKY::F30_128, CSKY::F31_128};
107*d415bd75Srobert 
DecodeGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)108*d415bd75Srobert static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
109*d415bd75Srobert                                            uint64_t Address,
110*d415bd75Srobert                                            const MCDisassembler *Decoder) {
111*d415bd75Srobert   if (RegNo >= 32)
112*d415bd75Srobert     return MCDisassembler::Fail;
113*d415bd75Srobert 
114*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
115*d415bd75Srobert   return MCDisassembler::Success;
116*d415bd75Srobert }
117*d415bd75Srobert 
DecodeFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)118*d415bd75Srobert static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
119*d415bd75Srobert                                              uint64_t Address,
120*d415bd75Srobert                                              const MCDisassembler *Decoder) {
121*d415bd75Srobert   if (RegNo >= 32)
122*d415bd75Srobert     return MCDisassembler::Fail;
123*d415bd75Srobert 
124*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));
125*d415bd75Srobert   return MCDisassembler::Success;
126*d415bd75Srobert }
127*d415bd75Srobert 
DecodesFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)128*d415bd75Srobert static DecodeStatus DecodesFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
129*d415bd75Srobert                                               uint64_t Address,
130*d415bd75Srobert                                               const MCDisassembler *Decoder) {
131*d415bd75Srobert   if (RegNo >= 16)
132*d415bd75Srobert     return MCDisassembler::Fail;
133*d415bd75Srobert 
134*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));
135*d415bd75Srobert   return MCDisassembler::Success;
136*d415bd75Srobert }
137*d415bd75Srobert 
DecodesFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)138*d415bd75Srobert static DecodeStatus DecodesFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
139*d415bd75Srobert                                               uint64_t Address,
140*d415bd75Srobert                                               const MCDisassembler *Decoder) {
141*d415bd75Srobert   if (RegNo >= 16)
142*d415bd75Srobert     return MCDisassembler::Fail;
143*d415bd75Srobert 
144*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
145*d415bd75Srobert   return MCDisassembler::Success;
146*d415bd75Srobert }
147*d415bd75Srobert 
DecodesFPR64_VRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)148*d415bd75Srobert static DecodeStatus DecodesFPR64_VRegisterClass(MCInst &Inst, uint64_t RegNo,
149*d415bd75Srobert                                                 uint64_t Address,
150*d415bd75Srobert                                                 const MCDisassembler *Decoder) {
151*d415bd75Srobert   if (RegNo >= 16)
152*d415bd75Srobert     return MCDisassembler::Fail;
153*d415bd75Srobert 
154*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
155*d415bd75Srobert   return MCDisassembler::Success;
156*d415bd75Srobert }
157*d415bd75Srobert 
DecodeFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)158*d415bd75Srobert static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
159*d415bd75Srobert                                              uint64_t Address,
160*d415bd75Srobert                                              const MCDisassembler *Decoder) {
161*d415bd75Srobert   if (RegNo >= 32)
162*d415bd75Srobert     return MCDisassembler::Fail;
163*d415bd75Srobert 
164*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
165*d415bd75Srobert   return MCDisassembler::Success;
166*d415bd75Srobert }
167*d415bd75Srobert 
168*d415bd75Srobert // TODO
169*d415bd75Srobert LLVM_ATTRIBUTE_UNUSED
DecodesFPR128RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)170*d415bd75Srobert static DecodeStatus DecodesFPR128RegisterClass(MCInst &Inst, uint64_t RegNo,
171*d415bd75Srobert                                                uint64_t Address,
172*d415bd75Srobert                                                const MCDisassembler *Decoder) {
173*d415bd75Srobert   if (RegNo >= 16)
174*d415bd75Srobert     return MCDisassembler::Fail;
175*d415bd75Srobert 
176*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR128DecoderTable[RegNo]));
177*d415bd75Srobert   return MCDisassembler::Success;
178*d415bd75Srobert }
179*d415bd75Srobert 
DecodesGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)180*d415bd75Srobert static DecodeStatus DecodesGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
181*d415bd75Srobert                                             uint64_t Address,
182*d415bd75Srobert                                             const MCDisassembler *Decoder) {
183*d415bd75Srobert   if (RegNo >= 16)
184*d415bd75Srobert     return MCDisassembler::Fail;
185*d415bd75Srobert 
186*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
187*d415bd75Srobert   return MCDisassembler::Success;
188*d415bd75Srobert }
189*d415bd75Srobert 
DecodemGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)190*d415bd75Srobert static DecodeStatus DecodemGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
191*d415bd75Srobert                                             uint64_t Address,
192*d415bd75Srobert                                             const MCDisassembler *Decoder) {
193*d415bd75Srobert   if (RegNo >= 8)
194*d415bd75Srobert     return MCDisassembler::Fail;
195*d415bd75Srobert 
196*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
197*d415bd75Srobert   return MCDisassembler::Success;
198*d415bd75Srobert }
199*d415bd75Srobert 
200*d415bd75Srobert // TODO
201*d415bd75Srobert LLVM_ATTRIBUTE_UNUSED
DecodeGPRSPRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)202*d415bd75Srobert static DecodeStatus DecodeGPRSPRegisterClass(MCInst &Inst, uint64_t RegNo,
203*d415bd75Srobert                                              uint64_t Address,
204*d415bd75Srobert                                              const MCDisassembler *Decoder) {
205*d415bd75Srobert   if (RegNo != 14)
206*d415bd75Srobert     return MCDisassembler::Fail;
207*d415bd75Srobert 
208*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
209*d415bd75Srobert   return MCDisassembler::Success;
210*d415bd75Srobert }
211*d415bd75Srobert 
DecodeGPRPairRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)212*d415bd75Srobert static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint64_t RegNo,
213*d415bd75Srobert                                                uint64_t Address,
214*d415bd75Srobert                                                const MCDisassembler *Decoder) {
215*d415bd75Srobert   const FeatureBitset &FeatureBits =
216*d415bd75Srobert       Decoder->getSubtargetInfo().getFeatureBits();
217*d415bd75Srobert   bool hasHighReg = FeatureBits[CSKY::FeatureHighreg];
218*d415bd75Srobert 
219*d415bd75Srobert   if (RegNo >= 32 || (!hasHighReg && RegNo >= 16))
220*d415bd75Srobert     return MCDisassembler::Fail;
221*d415bd75Srobert 
222*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(GPRPairDecoderTable[RegNo]));
223*d415bd75Srobert   return MCDisassembler::Success;
224*d415bd75Srobert }
225*d415bd75Srobert 
226*d415bd75Srobert template <unsigned N, unsigned S>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)227*d415bd75Srobert static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
228*d415bd75Srobert                                       int64_t Address,
229*d415bd75Srobert                                       const MCDisassembler *Decoder) {
230*d415bd75Srobert   assert(isUInt<N>(Imm) && "Invalid immediate");
231*d415bd75Srobert   Inst.addOperand(MCOperand::createImm(Imm << S));
232*d415bd75Srobert   return MCDisassembler::Success;
233*d415bd75Srobert }
234*d415bd75Srobert 
235*d415bd75Srobert template <unsigned N>
decodeOImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)236*d415bd75Srobert static DecodeStatus decodeOImmOperand(MCInst &Inst, uint64_t Imm,
237*d415bd75Srobert                                       int64_t Address,
238*d415bd75Srobert                                       const MCDisassembler *Decoder) {
239*d415bd75Srobert   assert(isUInt<N>(Imm) && "Invalid immediate");
240*d415bd75Srobert   Inst.addOperand(MCOperand::createImm(Imm + 1));
241*d415bd75Srobert   return MCDisassembler::Success;
242*d415bd75Srobert }
243*d415bd75Srobert 
decodeLRW16Imm8(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)244*d415bd75Srobert static DecodeStatus decodeLRW16Imm8(MCInst &Inst, uint64_t Imm, int64_t Address,
245*d415bd75Srobert                                     const MCDisassembler *Decoder) {
246*d415bd75Srobert   assert(isUInt<8>(Imm) && "Invalid immediate");
247*d415bd75Srobert   if ((Imm >> 7) & 0x1) {
248*d415bd75Srobert     Inst.addOperand(MCOperand::createImm((Imm & 0x7F) << 2));
249*d415bd75Srobert   } else {
250*d415bd75Srobert     uint64_t V = ((Imm ^ 0xFFFFFFFF) & 0xFF);
251*d415bd75Srobert     Inst.addOperand(MCOperand::createImm(V << 2));
252*d415bd75Srobert   }
253*d415bd75Srobert 
254*d415bd75Srobert   return MCDisassembler::Success;
255*d415bd75Srobert }
256*d415bd75Srobert 
decodeJMPIXImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)257*d415bd75Srobert static DecodeStatus decodeJMPIXImmOperand(MCInst &Inst, uint64_t Imm,
258*d415bd75Srobert                                           int64_t Address,
259*d415bd75Srobert                                           const MCDisassembler *Decoder) {
260*d415bd75Srobert   assert(isUInt<2>(Imm) && "Invalid immediate");
261*d415bd75Srobert 
262*d415bd75Srobert   if (Imm == 0)
263*d415bd75Srobert     Inst.addOperand(MCOperand::createImm(16));
264*d415bd75Srobert   else if (Imm == 1)
265*d415bd75Srobert     Inst.addOperand(MCOperand::createImm(24));
266*d415bd75Srobert   else if (Imm == 2)
267*d415bd75Srobert     Inst.addOperand(MCOperand::createImm(32));
268*d415bd75Srobert   else if (Imm == 3)
269*d415bd75Srobert     Inst.addOperand(MCOperand::createImm(40));
270*d415bd75Srobert   else
271*d415bd75Srobert     return MCDisassembler::Fail;
272*d415bd75Srobert 
273*d415bd75Srobert   return MCDisassembler::Success;
274*d415bd75Srobert }
275*d415bd75Srobert 
DecodeRegSeqOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)276*d415bd75Srobert static DecodeStatus DecodeRegSeqOperand(MCInst &Inst, uint64_t Imm,
277*d415bd75Srobert                                         int64_t Address,
278*d415bd75Srobert                                         const MCDisassembler *Decoder) {
279*d415bd75Srobert   assert(isUInt<10>(Imm) && "Invalid immediate");
280*d415bd75Srobert 
281*d415bd75Srobert   auto Imm5 = Imm & 0x1f;
282*d415bd75Srobert   auto Ry = (Imm >> 5) & 0x1f;
283*d415bd75Srobert 
284*d415bd75Srobert   if (DecodeGPRRegisterClass(Inst, Ry, Address, Decoder) ==
285*d415bd75Srobert       MCDisassembler::Fail)
286*d415bd75Srobert     return MCDisassembler::Fail;
287*d415bd75Srobert 
288*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Ry + Imm5]));
289*d415bd75Srobert 
290*d415bd75Srobert   return MCDisassembler::Success;
291*d415bd75Srobert }
292*d415bd75Srobert 
DecodeRegSeqOperandF1(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)293*d415bd75Srobert static DecodeStatus DecodeRegSeqOperandF1(MCInst &Inst, uint64_t Imm,
294*d415bd75Srobert                                           int64_t Address,
295*d415bd75Srobert                                           const MCDisassembler *Decoder) {
296*d415bd75Srobert   assert(isUInt<10>(Imm) && "Invalid immediate");
297*d415bd75Srobert 
298*d415bd75Srobert   auto Imm5 = Imm & 0x1f;
299*d415bd75Srobert   auto Ry = (Imm >> 5) & 0x1f;
300*d415bd75Srobert 
301*d415bd75Srobert   if (DecodesFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
302*d415bd75Srobert       MCDisassembler::Fail)
303*d415bd75Srobert     return MCDisassembler::Fail;
304*d415bd75Srobert 
305*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));
306*d415bd75Srobert 
307*d415bd75Srobert   return MCDisassembler::Success;
308*d415bd75Srobert }
309*d415bd75Srobert 
DecodeRegSeqOperandD1(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)310*d415bd75Srobert static DecodeStatus DecodeRegSeqOperandD1(MCInst &Inst, uint64_t Imm,
311*d415bd75Srobert                                           int64_t Address,
312*d415bd75Srobert                                           const MCDisassembler *Decoder) {
313*d415bd75Srobert   assert(isUInt<10>(Imm) && "Invalid immediate");
314*d415bd75Srobert 
315*d415bd75Srobert   auto Imm5 = Imm & 0x1f;
316*d415bd75Srobert   auto Ry = (Imm >> 5) & 0x1f;
317*d415bd75Srobert 
318*d415bd75Srobert   if (DecodesFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
319*d415bd75Srobert       MCDisassembler::Fail)
320*d415bd75Srobert     return MCDisassembler::Fail;
321*d415bd75Srobert 
322*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));
323*d415bd75Srobert 
324*d415bd75Srobert   return MCDisassembler::Success;
325*d415bd75Srobert }
326*d415bd75Srobert 
DecodeRegSeqOperandF2(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)327*d415bd75Srobert static DecodeStatus DecodeRegSeqOperandF2(MCInst &Inst, uint64_t Imm,
328*d415bd75Srobert                                           int64_t Address,
329*d415bd75Srobert                                           const MCDisassembler *Decoder) {
330*d415bd75Srobert   assert(isUInt<10>(Imm) && "Invalid immediate");
331*d415bd75Srobert 
332*d415bd75Srobert   auto Imm5 = Imm & 0x1f;
333*d415bd75Srobert   auto Ry = (Imm >> 5) & 0x1f;
334*d415bd75Srobert 
335*d415bd75Srobert   if (DecodeFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
336*d415bd75Srobert       MCDisassembler::Fail)
337*d415bd75Srobert     return MCDisassembler::Fail;
338*d415bd75Srobert 
339*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));
340*d415bd75Srobert 
341*d415bd75Srobert   return MCDisassembler::Success;
342*d415bd75Srobert }
343*d415bd75Srobert 
DecodeRegSeqOperandD2(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)344*d415bd75Srobert static DecodeStatus DecodeRegSeqOperandD2(MCInst &Inst, uint64_t Imm,
345*d415bd75Srobert                                           int64_t Address,
346*d415bd75Srobert                                           const MCDisassembler *Decoder) {
347*d415bd75Srobert   assert(isUInt<10>(Imm) && "Invalid immediate");
348*d415bd75Srobert 
349*d415bd75Srobert   auto Imm5 = Imm & 0x1f;
350*d415bd75Srobert   auto Ry = (Imm >> 5) & 0x1f;
351*d415bd75Srobert 
352*d415bd75Srobert   if (DecodeFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
353*d415bd75Srobert       MCDisassembler::Fail)
354*d415bd75Srobert     return MCDisassembler::Fail;
355*d415bd75Srobert 
356*d415bd75Srobert   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));
357*d415bd75Srobert 
358*d415bd75Srobert   return MCDisassembler::Success;
359*d415bd75Srobert }
360*d415bd75Srobert 
decodeImmShiftOpValue(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)361*d415bd75Srobert static DecodeStatus decodeImmShiftOpValue(MCInst &Inst, uint64_t Imm,
362*d415bd75Srobert                                           int64_t Address,
363*d415bd75Srobert                                           const MCDisassembler *Decoder) {
364*d415bd75Srobert   Inst.addOperand(MCOperand::createImm(Log2_64(Imm)));
365*d415bd75Srobert   return MCDisassembler::Success;
366*d415bd75Srobert }
367*d415bd75Srobert 
368*d415bd75Srobert template <unsigned N, unsigned S>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)369*d415bd75Srobert static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
370*d415bd75Srobert                                       int64_t Address,
371*d415bd75Srobert                                       const MCDisassembler *Decoder) {
372*d415bd75Srobert   assert(isUInt<N>(Imm) && "Invalid immediate");
373*d415bd75Srobert   // Sign-extend the number in the bottom N bits of Imm
374*d415bd75Srobert   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) << S));
375*d415bd75Srobert   return MCDisassembler::Success;
376*d415bd75Srobert }
377*d415bd75Srobert 
378*d415bd75Srobert #include "CSKYGenDisassemblerTables.inc"
379*d415bd75Srobert 
handleCROperand(MCInst & MI) const380*d415bd75Srobert DecodeStatus CSKYDisassembler::handleCROperand(MCInst &MI) const {
381*d415bd75Srobert 
382*d415bd75Srobert   // FIXME: To query instruction info from td file or a table inc file
383*d415bd75Srobert   switch (MI.getOpcode()) {
384*d415bd75Srobert   default:
385*d415bd75Srobert     return MCDisassembler::Success;
386*d415bd75Srobert   case CSKY::LD16WSP:
387*d415bd75Srobert   case CSKY::ST16WSP:
388*d415bd75Srobert   case CSKY::ADDI16ZSP:
389*d415bd75Srobert     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::R14));
390*d415bd75Srobert     return MCDisassembler::Success;
391*d415bd75Srobert   case CSKY::ADDI16SPSP:
392*d415bd75Srobert   case CSKY::SUBI16SPSP:
393*d415bd75Srobert     MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));
394*d415bd75Srobert     MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));
395*d415bd75Srobert     return MCDisassembler::Success;
396*d415bd75Srobert   case CSKY::FCMPHS_S:
397*d415bd75Srobert   case CSKY::FCMPHS_D:
398*d415bd75Srobert   case CSKY::FCMPLT_S:
399*d415bd75Srobert   case CSKY::FCMPLT_D:
400*d415bd75Srobert   case CSKY::FCMPNE_S:
401*d415bd75Srobert   case CSKY::FCMPNE_D:
402*d415bd75Srobert   case CSKY::FCMPUO_S:
403*d415bd75Srobert   case CSKY::FCMPUO_D:
404*d415bd75Srobert   case CSKY::FCMPZHS_S:
405*d415bd75Srobert   case CSKY::FCMPZHS_D:
406*d415bd75Srobert   case CSKY::FCMPZLS_S:
407*d415bd75Srobert   case CSKY::FCMPZLS_D:
408*d415bd75Srobert   case CSKY::FCMPZNE_S:
409*d415bd75Srobert   case CSKY::FCMPZNE_D:
410*d415bd75Srobert   case CSKY::FCMPZUO_S:
411*d415bd75Srobert   case CSKY::FCMPZUO_D:
412*d415bd75Srobert   case CSKY::f2FCMPHS_S:
413*d415bd75Srobert   case CSKY::f2FCMPHS_D:
414*d415bd75Srobert   case CSKY::f2FCMPLT_S:
415*d415bd75Srobert   case CSKY::f2FCMPLT_D:
416*d415bd75Srobert   case CSKY::f2FCMPNE_S:
417*d415bd75Srobert   case CSKY::f2FCMPNE_D:
418*d415bd75Srobert   case CSKY::f2FCMPUO_S:
419*d415bd75Srobert   case CSKY::f2FCMPUO_D:
420*d415bd75Srobert   case CSKY::f2FCMPHSZ_S:
421*d415bd75Srobert   case CSKY::f2FCMPHSZ_D:
422*d415bd75Srobert   case CSKY::f2FCMPHZ_S:
423*d415bd75Srobert   case CSKY::f2FCMPHZ_D:
424*d415bd75Srobert   case CSKY::f2FCMPLSZ_S:
425*d415bd75Srobert   case CSKY::f2FCMPLSZ_D:
426*d415bd75Srobert   case CSKY::f2FCMPLTZ_S:
427*d415bd75Srobert   case CSKY::f2FCMPLTZ_D:
428*d415bd75Srobert   case CSKY::f2FCMPNEZ_S:
429*d415bd75Srobert   case CSKY::f2FCMPNEZ_D:
430*d415bd75Srobert   case CSKY::f2FCMPUOZ_S:
431*d415bd75Srobert   case CSKY::f2FCMPUOZ_D:
432*d415bd75Srobert 
433*d415bd75Srobert   case CSKY::BT32:
434*d415bd75Srobert   case CSKY::BF32:
435*d415bd75Srobert   case CSKY::BT16:
436*d415bd75Srobert   case CSKY::BF16:
437*d415bd75Srobert   case CSKY::CMPNEI32:
438*d415bd75Srobert   case CSKY::CMPNEI16:
439*d415bd75Srobert   case CSKY::CMPNE32:
440*d415bd75Srobert   case CSKY::CMPNE16:
441*d415bd75Srobert   case CSKY::CMPHSI32:
442*d415bd75Srobert   case CSKY::CMPHSI16:
443*d415bd75Srobert   case CSKY::CMPHS32:
444*d415bd75Srobert   case CSKY::CMPHS16:
445*d415bd75Srobert   case CSKY::CMPLTI32:
446*d415bd75Srobert   case CSKY::CMPLTI16:
447*d415bd75Srobert   case CSKY::CMPLT32:
448*d415bd75Srobert   case CSKY::CMPLT16:
449*d415bd75Srobert   case CSKY::BTSTI32:
450*d415bd75Srobert   case CSKY::BTSTI16:
451*d415bd75Srobert   case CSKY::TSTNBZ32:
452*d415bd75Srobert   case CSKY::TSTNBZ16:
453*d415bd75Srobert   case CSKY::TST32:
454*d415bd75Srobert   case CSKY::TST16:
455*d415bd75Srobert     MI.insert(MI.begin(), MCOperand::createReg(CSKY::C));
456*d415bd75Srobert     return MCDisassembler::Success;
457*d415bd75Srobert   case CSKY::LSLC32:
458*d415bd75Srobert   case CSKY::LSRC32:
459*d415bd75Srobert   case CSKY::ASRC32:
460*d415bd75Srobert     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
461*d415bd75Srobert     return MCDisassembler::Success;
462*d415bd75Srobert   case CSKY::MOVF32:
463*d415bd75Srobert   case CSKY::MOVT32:
464*d415bd75Srobert   case CSKY::MVC32:
465*d415bd75Srobert   case CSKY::MVCV32:
466*d415bd75Srobert   case CSKY::MVCV16:
467*d415bd75Srobert   case CSKY::INCT32:
468*d415bd75Srobert   case CSKY::INCF32:
469*d415bd75Srobert   case CSKY::DECT32:
470*d415bd75Srobert   case CSKY::DECF32:
471*d415bd75Srobert   case CSKY::DECGT32:
472*d415bd75Srobert   case CSKY::DECLT32:
473*d415bd75Srobert   case CSKY::DECNE32:
474*d415bd75Srobert   case CSKY::CLRF32:
475*d415bd75Srobert   case CSKY::CLRT32:
476*d415bd75Srobert   case CSKY::f2FSEL_S:
477*d415bd75Srobert   case CSKY::f2FSEL_D:
478*d415bd75Srobert     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
479*d415bd75Srobert     return MCDisassembler::Success;
480*d415bd75Srobert   case CSKY::ADDC32:
481*d415bd75Srobert   case CSKY::ADDC16:
482*d415bd75Srobert   case CSKY::SUBC32:
483*d415bd75Srobert   case CSKY::SUBC16:
484*d415bd75Srobert   case CSKY::XSR32:
485*d415bd75Srobert     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
486*d415bd75Srobert     MI.insert(MI.end(), MCOperand::createReg(CSKY::C));
487*d415bd75Srobert     return MCDisassembler::Success;
488*d415bd75Srobert   case CSKY::INS32:
489*d415bd75Srobert     MI.getOperand(3).setImm(MI.getOperand(3).getImm() +
490*d415bd75Srobert                             MI.getOperand(4).getImm());
491*d415bd75Srobert     return MCDisassembler::Success;
492*d415bd75Srobert   }
493*d415bd75Srobert }
494*d415bd75Srobert 
decodeFPUV3Instruction(MCInst & MI,uint32_t insn,uint64_t Address,const MCDisassembler * DisAsm,const MCSubtargetInfo & STI)495*d415bd75Srobert static bool decodeFPUV3Instruction(MCInst &MI, uint32_t insn, uint64_t Address,
496*d415bd75Srobert                                    const MCDisassembler *DisAsm,
497*d415bd75Srobert                                    const MCSubtargetInfo &STI) {
498*d415bd75Srobert   LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit fpuv3 table :\n");
499*d415bd75Srobert   if (!STI.getFeatureBits()[CSKY::FeatureFPUV3_HF] &&
500*d415bd75Srobert       !STI.getFeatureBits()[CSKY::FeatureFPUV3_SF] &&
501*d415bd75Srobert       !STI.getFeatureBits()[CSKY::FeatureFPUV3_DF])
502*d415bd75Srobert     return false;
503*d415bd75Srobert 
504*d415bd75Srobert   DecodeStatus Result =
505*d415bd75Srobert       decodeInstruction(DecoderTableFPUV332, MI, insn, Address, DisAsm, STI);
506*d415bd75Srobert 
507*d415bd75Srobert   if (Result == MCDisassembler::Fail) {
508*d415bd75Srobert     MI.clear();
509*d415bd75Srobert     return false;
510*d415bd75Srobert   }
511*d415bd75Srobert 
512*d415bd75Srobert   return true;
513*d415bd75Srobert }
514*d415bd75Srobert 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const515*d415bd75Srobert DecodeStatus CSKYDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
516*d415bd75Srobert                                               ArrayRef<uint8_t> Bytes,
517*d415bd75Srobert                                               uint64_t Address,
518*d415bd75Srobert                                               raw_ostream &CS) const {
519*d415bd75Srobert 
520*d415bd75Srobert   uint32_t Insn;
521*d415bd75Srobert   DecodeStatus Result = MCDisassembler::Fail;
522*d415bd75Srobert 
523*d415bd75Srobert   Insn = support::endian::read16le(Bytes.data());
524*d415bd75Srobert 
525*d415bd75Srobert   if ((Insn >> 14) == 0x3) {
526*d415bd75Srobert     if (Bytes.size() < 4) {
527*d415bd75Srobert       Size = 0;
528*d415bd75Srobert       return MCDisassembler::Fail;
529*d415bd75Srobert     }
530*d415bd75Srobert     Insn = (Insn << 16) | support::endian::read16le(&Bytes[2]);
531*d415bd75Srobert 
532*d415bd75Srobert     if (decodeFPUV3Instruction(MI, Insn, Address, this, STI))
533*d415bd75Srobert       Result = MCDisassembler::Success;
534*d415bd75Srobert     else {
535*d415bd75Srobert       LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit table :\n");
536*d415bd75Srobert       Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
537*d415bd75Srobert     }
538*d415bd75Srobert 
539*d415bd75Srobert     Size = 4;
540*d415bd75Srobert   } else {
541*d415bd75Srobert     if (Bytes.size() < 2) {
542*d415bd75Srobert       Size = 0;
543*d415bd75Srobert       return MCDisassembler::Fail;
544*d415bd75Srobert     }
545*d415bd75Srobert     LLVM_DEBUG(dbgs() << "Trying CSKY 16-bit table :\n");
546*d415bd75Srobert     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
547*d415bd75Srobert     Size = 2;
548*d415bd75Srobert   }
549*d415bd75Srobert 
550*d415bd75Srobert   handleCROperand(MI);
551*d415bd75Srobert 
552*d415bd75Srobert   return Result;
553*d415bd75Srobert }
554