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