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
CSKYDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)50 CSKYDisassembler::CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
51 MCInstrInfo const *MCII)
52 : MCDisassembler(STI, Ctx), MCII(MCII) {}
53
createCSKYDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)54 static MCDisassembler *createCSKYDisassembler(const Target &T,
55 const MCSubtargetInfo &STI,
56 MCContext &Ctx) {
57 return new CSKYDisassembler(STI, Ctx, T.createMCInstrInfo());
58 }
59
LLVMInitializeCSKYDisassembler()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
DecodeGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodesFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodesFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodesFPR64_VRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodesFPR128RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodesGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodemGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeGPRSPRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeGPRPairRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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>
decodeOImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeLRW16Imm8(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeJMPIXImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
DecodeRegSeqOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
DecodeRegSeqOperandF1(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
DecodeRegSeqOperandD1(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
DecodeRegSeqOperandF2(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
DecodeRegSeqOperandD2(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeImmShiftOpValue(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
handleCROperand(MCInst & MI) const380 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
decodeFPUV3Instruction(MCInst & MI,uint32_t insn,uint64_t Address,const MCDisassembler * DisAsm,const MCSubtargetInfo & STI)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
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const515 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