xref: /src/contrib/llvm-project/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1145449b1SDimitry Andric //===-- CSKYDisassembler.cpp - Disassembler for CSKY ----------------------===//
2145449b1SDimitry Andric //
3145449b1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4145449b1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5145449b1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6145449b1SDimitry Andric //
7145449b1SDimitry Andric //===----------------------------------------------------------------------===//
8145449b1SDimitry Andric //
9145449b1SDimitry Andric // This file implements the CSKYDisassembler class.
10145449b1SDimitry Andric //
11145449b1SDimitry Andric //===----------------------------------------------------------------------===//
12145449b1SDimitry Andric 
13145449b1SDimitry Andric #include "MCTargetDesc/CSKYBaseInfo.h"
14145449b1SDimitry Andric #include "MCTargetDesc/CSKYMCTargetDesc.h"
15145449b1SDimitry Andric #include "TargetInfo/CSKYTargetInfo.h"
16145449b1SDimitry Andric #include "llvm/ADT/DenseMap.h"
17145449b1SDimitry Andric #include "llvm/MC/MCContext.h"
18145449b1SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
19145449b1SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
20145449b1SDimitry Andric #include "llvm/MC/MCInst.h"
21145449b1SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
22145449b1SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
23145449b1SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
24145449b1SDimitry Andric #include "llvm/MC/TargetRegistry.h"
25145449b1SDimitry Andric #include "llvm/Support/Endian.h"
26145449b1SDimitry Andric 
27145449b1SDimitry Andric using namespace llvm;
28145449b1SDimitry Andric 
29145449b1SDimitry Andric #define DEBUG_TYPE "csky-disassembler"
30145449b1SDimitry Andric 
31145449b1SDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
32145449b1SDimitry Andric 
33145449b1SDimitry Andric namespace {
34145449b1SDimitry Andric class CSKYDisassembler : public MCDisassembler {
35145449b1SDimitry Andric   std::unique_ptr<MCInstrInfo const> const MCII;
36145449b1SDimitry Andric   mutable StringRef symbolName;
37145449b1SDimitry Andric 
38145449b1SDimitry Andric   DecodeStatus handleCROperand(MCInst &Instr) const;
39145449b1SDimitry Andric 
40145449b1SDimitry Andric public:
41145449b1SDimitry Andric   CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
42145449b1SDimitry Andric                    MCInstrInfo const *MCII);
43145449b1SDimitry Andric 
44145449b1SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
45145449b1SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
46145449b1SDimitry Andric                               raw_ostream &CStream) const override;
47145449b1SDimitry Andric };
48145449b1SDimitry Andric } // end anonymous namespace
49145449b1SDimitry Andric 
CSKYDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)50145449b1SDimitry Andric CSKYDisassembler::CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
51145449b1SDimitry Andric                                    MCInstrInfo const *MCII)
52145449b1SDimitry Andric     : MCDisassembler(STI, Ctx), MCII(MCII) {}
53145449b1SDimitry Andric 
createCSKYDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)54145449b1SDimitry Andric static MCDisassembler *createCSKYDisassembler(const Target &T,
55145449b1SDimitry Andric                                               const MCSubtargetInfo &STI,
56145449b1SDimitry Andric                                               MCContext &Ctx) {
57145449b1SDimitry Andric   return new CSKYDisassembler(STI, Ctx, T.createMCInstrInfo());
58145449b1SDimitry Andric }
59145449b1SDimitry Andric 
LLVMInitializeCSKYDisassembler()60145449b1SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYDisassembler() {
61145449b1SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheCSKYTarget(),
62145449b1SDimitry Andric                                          createCSKYDisassembler);
63145449b1SDimitry Andric }
64145449b1SDimitry Andric 
65145449b1SDimitry Andric static const uint16_t GPRDecoderTable[] = {
66145449b1SDimitry Andric     CSKY::R0,  CSKY::R1,  CSKY::R2,  CSKY::R3,  CSKY::R4,  CSKY::R5,  CSKY::R6,
67145449b1SDimitry Andric     CSKY::R7,  CSKY::R8,  CSKY::R9,  CSKY::R10, CSKY::R11, CSKY::R12, CSKY::R13,
68145449b1SDimitry Andric     CSKY::R14, CSKY::R15, CSKY::R16, CSKY::R17, CSKY::R18, CSKY::R19, CSKY::R20,
69145449b1SDimitry Andric     CSKY::R21, CSKY::R22, CSKY::R23, CSKY::R24, CSKY::R25, CSKY::R26, CSKY::R27,
70145449b1SDimitry Andric     CSKY::R28, CSKY::R29, CSKY::R30, CSKY::R31};
71145449b1SDimitry Andric 
72145449b1SDimitry Andric static const uint16_t GPRPairDecoderTable[] = {
73145449b1SDimitry Andric     CSKY::R0_R1,   CSKY::R1_R2,   CSKY::R2_R3,   CSKY::R3_R4,   CSKY::R4_R5,
74145449b1SDimitry Andric     CSKY::R5_R6,   CSKY::R6_R7,   CSKY::R7_R8,   CSKY::R8_R9,   CSKY::R9_R10,
75145449b1SDimitry Andric     CSKY::R10_R11, CSKY::R11_R12, CSKY::R12_R13, CSKY::R13_R14, CSKY::R14_R15,
76145449b1SDimitry Andric     CSKY::R15_R16, CSKY::R16_R17, CSKY::R17_R18, CSKY::R18_R19, CSKY::R19_R20,
77145449b1SDimitry Andric     CSKY::R20_R21, CSKY::R21_R22, CSKY::R22_R23, CSKY::R23_R24, CSKY::R24_R25,
78145449b1SDimitry Andric     CSKY::R25_R26, CSKY::R26_R27, CSKY::R27_R28, CSKY::R28_R29, CSKY::R29_R30,
79145449b1SDimitry Andric     CSKY::R30_R31, CSKY::R31_R32};
80145449b1SDimitry Andric 
81145449b1SDimitry Andric static const uint16_t FPR32DecoderTable[] = {
82145449b1SDimitry Andric     CSKY::F0_32,  CSKY::F1_32,  CSKY::F2_32,  CSKY::F3_32,  CSKY::F4_32,
83145449b1SDimitry Andric     CSKY::F5_32,  CSKY::F6_32,  CSKY::F7_32,  CSKY::F8_32,  CSKY::F9_32,
84145449b1SDimitry Andric     CSKY::F10_32, CSKY::F11_32, CSKY::F12_32, CSKY::F13_32, CSKY::F14_32,
85145449b1SDimitry Andric     CSKY::F15_32, CSKY::F16_32, CSKY::F17_32, CSKY::F18_32, CSKY::F19_32,
86145449b1SDimitry Andric     CSKY::F20_32, CSKY::F21_32, CSKY::F22_32, CSKY::F23_32, CSKY::F24_32,
87145449b1SDimitry Andric     CSKY::F25_32, CSKY::F26_32, CSKY::F27_32, CSKY::F28_32, CSKY::F29_32,
88145449b1SDimitry Andric     CSKY::F30_32, CSKY::F31_32};
89145449b1SDimitry Andric 
90145449b1SDimitry Andric static const uint16_t FPR64DecoderTable[] = {
91145449b1SDimitry Andric     CSKY::F0_64,  CSKY::F1_64,  CSKY::F2_64,  CSKY::F3_64,  CSKY::F4_64,
92145449b1SDimitry Andric     CSKY::F5_64,  CSKY::F6_64,  CSKY::F7_64,  CSKY::F8_64,  CSKY::F9_64,
93145449b1SDimitry Andric     CSKY::F10_64, CSKY::F11_64, CSKY::F12_64, CSKY::F13_64, CSKY::F14_64,
94145449b1SDimitry Andric     CSKY::F15_64, CSKY::F16_64, CSKY::F17_64, CSKY::F18_64, CSKY::F19_64,
95145449b1SDimitry Andric     CSKY::F20_64, CSKY::F21_64, CSKY::F22_64, CSKY::F23_64, CSKY::F24_64,
96145449b1SDimitry Andric     CSKY::F25_64, CSKY::F26_64, CSKY::F27_64, CSKY::F28_64, CSKY::F29_64,
97145449b1SDimitry Andric     CSKY::F30_64, CSKY::F31_64};
98145449b1SDimitry Andric 
99145449b1SDimitry Andric static const uint16_t FPR128DecoderTable[] = {
100145449b1SDimitry Andric     CSKY::F0_128,  CSKY::F1_128,  CSKY::F2_128,  CSKY::F3_128,  CSKY::F4_128,
101145449b1SDimitry Andric     CSKY::F5_128,  CSKY::F6_128,  CSKY::F7_128,  CSKY::F8_128,  CSKY::F9_128,
102145449b1SDimitry Andric     CSKY::F10_128, CSKY::F11_128, CSKY::F12_128, CSKY::F13_128, CSKY::F14_128,
103145449b1SDimitry Andric     CSKY::F15_128, CSKY::F16_128, CSKY::F17_128, CSKY::F18_128, CSKY::F19_128,
104145449b1SDimitry Andric     CSKY::F20_128, CSKY::F21_128, CSKY::F22_128, CSKY::F23_128, CSKY::F24_128,
105145449b1SDimitry Andric     CSKY::F25_128, CSKY::F26_128, CSKY::F27_128, CSKY::F28_128, CSKY::F29_128,
106145449b1SDimitry Andric     CSKY::F30_128, CSKY::F31_128};
107145449b1SDimitry Andric 
DecodeGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)108145449b1SDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
109145449b1SDimitry Andric                                            uint64_t Address,
110145449b1SDimitry Andric                                            const MCDisassembler *Decoder) {
111145449b1SDimitry Andric   if (RegNo >= 32)
112145449b1SDimitry Andric     return MCDisassembler::Fail;
113145449b1SDimitry Andric 
114145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
115145449b1SDimitry Andric   return MCDisassembler::Success;
116145449b1SDimitry Andric }
117145449b1SDimitry Andric 
DecodeFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)118145449b1SDimitry Andric static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
119145449b1SDimitry Andric                                              uint64_t Address,
120145449b1SDimitry Andric                                              const MCDisassembler *Decoder) {
121145449b1SDimitry Andric   if (RegNo >= 32)
122145449b1SDimitry Andric     return MCDisassembler::Fail;
123145449b1SDimitry Andric 
124145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));
125145449b1SDimitry Andric   return MCDisassembler::Success;
126145449b1SDimitry Andric }
127145449b1SDimitry Andric 
DecodesFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)128145449b1SDimitry Andric static DecodeStatus DecodesFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
129145449b1SDimitry Andric                                               uint64_t Address,
130145449b1SDimitry Andric                                               const MCDisassembler *Decoder) {
131145449b1SDimitry Andric   if (RegNo >= 16)
132145449b1SDimitry Andric     return MCDisassembler::Fail;
133145449b1SDimitry Andric 
134145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));
135145449b1SDimitry Andric   return MCDisassembler::Success;
136145449b1SDimitry Andric }
137145449b1SDimitry Andric 
DecodesFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)138145449b1SDimitry Andric static DecodeStatus DecodesFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
139145449b1SDimitry Andric                                               uint64_t Address,
140145449b1SDimitry Andric                                               const MCDisassembler *Decoder) {
141145449b1SDimitry Andric   if (RegNo >= 16)
142145449b1SDimitry Andric     return MCDisassembler::Fail;
143145449b1SDimitry Andric 
144145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
145145449b1SDimitry Andric   return MCDisassembler::Success;
146145449b1SDimitry Andric }
147145449b1SDimitry Andric 
DecodesFPR64_VRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)148145449b1SDimitry Andric static DecodeStatus DecodesFPR64_VRegisterClass(MCInst &Inst, uint64_t RegNo,
149145449b1SDimitry Andric                                                 uint64_t Address,
150145449b1SDimitry Andric                                                 const MCDisassembler *Decoder) {
151145449b1SDimitry Andric   if (RegNo >= 16)
152145449b1SDimitry Andric     return MCDisassembler::Fail;
153145449b1SDimitry Andric 
154145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
155145449b1SDimitry Andric   return MCDisassembler::Success;
156145449b1SDimitry Andric }
157145449b1SDimitry Andric 
DecodeFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)158145449b1SDimitry Andric static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
159145449b1SDimitry Andric                                              uint64_t Address,
160145449b1SDimitry Andric                                              const MCDisassembler *Decoder) {
161145449b1SDimitry Andric   if (RegNo >= 32)
162145449b1SDimitry Andric     return MCDisassembler::Fail;
163145449b1SDimitry Andric 
164145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
165145449b1SDimitry Andric   return MCDisassembler::Success;
166145449b1SDimitry Andric }
167145449b1SDimitry Andric 
168145449b1SDimitry Andric // TODO
169145449b1SDimitry Andric LLVM_ATTRIBUTE_UNUSED
DecodesFPR128RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)170145449b1SDimitry Andric static DecodeStatus DecodesFPR128RegisterClass(MCInst &Inst, uint64_t RegNo,
171145449b1SDimitry Andric                                                uint64_t Address,
172145449b1SDimitry Andric                                                const MCDisassembler *Decoder) {
173145449b1SDimitry Andric   if (RegNo >= 16)
174145449b1SDimitry Andric     return MCDisassembler::Fail;
175145449b1SDimitry Andric 
176145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR128DecoderTable[RegNo]));
177145449b1SDimitry Andric   return MCDisassembler::Success;
178145449b1SDimitry Andric }
179145449b1SDimitry Andric 
DecodesGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)180145449b1SDimitry Andric static DecodeStatus DecodesGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
181145449b1SDimitry Andric                                             uint64_t Address,
182145449b1SDimitry Andric                                             const MCDisassembler *Decoder) {
183145449b1SDimitry Andric   if (RegNo >= 16)
184145449b1SDimitry Andric     return MCDisassembler::Fail;
185145449b1SDimitry Andric 
186145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
187145449b1SDimitry Andric   return MCDisassembler::Success;
188145449b1SDimitry Andric }
189145449b1SDimitry Andric 
DecodemGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)190145449b1SDimitry Andric static DecodeStatus DecodemGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
191145449b1SDimitry Andric                                             uint64_t Address,
192145449b1SDimitry Andric                                             const MCDisassembler *Decoder) {
193145449b1SDimitry Andric   if (RegNo >= 8)
194145449b1SDimitry Andric     return MCDisassembler::Fail;
195145449b1SDimitry Andric 
196145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
197145449b1SDimitry Andric   return MCDisassembler::Success;
198145449b1SDimitry Andric }
199145449b1SDimitry Andric 
200145449b1SDimitry Andric // TODO
201145449b1SDimitry Andric LLVM_ATTRIBUTE_UNUSED
DecodeGPRSPRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)202145449b1SDimitry Andric static DecodeStatus DecodeGPRSPRegisterClass(MCInst &Inst, uint64_t RegNo,
203145449b1SDimitry Andric                                              uint64_t Address,
204145449b1SDimitry Andric                                              const MCDisassembler *Decoder) {
205145449b1SDimitry Andric   if (RegNo != 14)
206145449b1SDimitry Andric     return MCDisassembler::Fail;
207145449b1SDimitry Andric 
208145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
209145449b1SDimitry Andric   return MCDisassembler::Success;
210145449b1SDimitry Andric }
211145449b1SDimitry Andric 
DecodeGPRPairRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)212145449b1SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint64_t RegNo,
213145449b1SDimitry Andric                                                uint64_t Address,
214145449b1SDimitry Andric                                                const MCDisassembler *Decoder) {
215145449b1SDimitry Andric   const FeatureBitset &FeatureBits =
216145449b1SDimitry Andric       Decoder->getSubtargetInfo().getFeatureBits();
217145449b1SDimitry Andric   bool hasHighReg = FeatureBits[CSKY::FeatureHighreg];
218145449b1SDimitry Andric 
219145449b1SDimitry Andric   if (RegNo >= 32 || (!hasHighReg && RegNo >= 16))
220145449b1SDimitry Andric     return MCDisassembler::Fail;
221145449b1SDimitry Andric 
222145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRPairDecoderTable[RegNo]));
223145449b1SDimitry Andric   return MCDisassembler::Success;
224145449b1SDimitry Andric }
225145449b1SDimitry Andric 
226145449b1SDimitry Andric template <unsigned N, unsigned S>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)227145449b1SDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
228145449b1SDimitry Andric                                       int64_t Address,
229145449b1SDimitry Andric                                       const MCDisassembler *Decoder) {
230145449b1SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
231145449b1SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm << S));
232145449b1SDimitry Andric   return MCDisassembler::Success;
233145449b1SDimitry Andric }
234145449b1SDimitry Andric 
235145449b1SDimitry Andric template <unsigned N>
decodeOImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)236145449b1SDimitry Andric static DecodeStatus decodeOImmOperand(MCInst &Inst, uint64_t Imm,
237145449b1SDimitry Andric                                       int64_t Address,
238145449b1SDimitry Andric                                       const MCDisassembler *Decoder) {
239145449b1SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
240145449b1SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm + 1));
241145449b1SDimitry Andric   return MCDisassembler::Success;
242145449b1SDimitry Andric }
243145449b1SDimitry Andric 
decodeLRW16Imm8(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)244145449b1SDimitry Andric static DecodeStatus decodeLRW16Imm8(MCInst &Inst, uint64_t Imm, int64_t Address,
245145449b1SDimitry Andric                                     const MCDisassembler *Decoder) {
246145449b1SDimitry Andric   assert(isUInt<8>(Imm) && "Invalid immediate");
247145449b1SDimitry Andric   if ((Imm >> 7) & 0x1) {
248145449b1SDimitry Andric     Inst.addOperand(MCOperand::createImm((Imm & 0x7F) << 2));
249145449b1SDimitry Andric   } else {
250145449b1SDimitry Andric     uint64_t V = ((Imm ^ 0xFFFFFFFF) & 0xFF);
251145449b1SDimitry Andric     Inst.addOperand(MCOperand::createImm(V << 2));
252145449b1SDimitry Andric   }
253145449b1SDimitry Andric 
254145449b1SDimitry Andric   return MCDisassembler::Success;
255145449b1SDimitry Andric }
256145449b1SDimitry Andric 
decodeJMPIXImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)257145449b1SDimitry Andric static DecodeStatus decodeJMPIXImmOperand(MCInst &Inst, uint64_t Imm,
258145449b1SDimitry Andric                                           int64_t Address,
259145449b1SDimitry Andric                                           const MCDisassembler *Decoder) {
260145449b1SDimitry Andric   assert(isUInt<2>(Imm) && "Invalid immediate");
261145449b1SDimitry Andric 
262145449b1SDimitry Andric   if (Imm == 0)
263145449b1SDimitry Andric     Inst.addOperand(MCOperand::createImm(16));
264145449b1SDimitry Andric   else if (Imm == 1)
265145449b1SDimitry Andric     Inst.addOperand(MCOperand::createImm(24));
266145449b1SDimitry Andric   else if (Imm == 2)
267145449b1SDimitry Andric     Inst.addOperand(MCOperand::createImm(32));
268145449b1SDimitry Andric   else if (Imm == 3)
269145449b1SDimitry Andric     Inst.addOperand(MCOperand::createImm(40));
270145449b1SDimitry Andric   else
271145449b1SDimitry Andric     return MCDisassembler::Fail;
272145449b1SDimitry Andric 
273145449b1SDimitry Andric   return MCDisassembler::Success;
274145449b1SDimitry Andric }
275145449b1SDimitry Andric 
DecodeRegSeqOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)276145449b1SDimitry Andric static DecodeStatus DecodeRegSeqOperand(MCInst &Inst, uint64_t Imm,
277145449b1SDimitry Andric                                         int64_t Address,
278145449b1SDimitry Andric                                         const MCDisassembler *Decoder) {
279145449b1SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
280145449b1SDimitry Andric 
281145449b1SDimitry Andric   auto Imm5 = Imm & 0x1f;
282145449b1SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
283145449b1SDimitry Andric 
284145449b1SDimitry Andric   if (DecodeGPRRegisterClass(Inst, Ry, Address, Decoder) ==
285145449b1SDimitry Andric       MCDisassembler::Fail)
286145449b1SDimitry Andric     return MCDisassembler::Fail;
287145449b1SDimitry Andric 
288145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Ry + Imm5]));
289145449b1SDimitry Andric 
290145449b1SDimitry Andric   return MCDisassembler::Success;
291145449b1SDimitry Andric }
292145449b1SDimitry Andric 
DecodeRegSeqOperandF1(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)293145449b1SDimitry Andric static DecodeStatus DecodeRegSeqOperandF1(MCInst &Inst, uint64_t Imm,
294145449b1SDimitry Andric                                           int64_t Address,
295145449b1SDimitry Andric                                           const MCDisassembler *Decoder) {
296145449b1SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
297145449b1SDimitry Andric 
298145449b1SDimitry Andric   auto Imm5 = Imm & 0x1f;
299145449b1SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
300145449b1SDimitry Andric 
301145449b1SDimitry Andric   if (DecodesFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
302145449b1SDimitry Andric       MCDisassembler::Fail)
303145449b1SDimitry Andric     return MCDisassembler::Fail;
304145449b1SDimitry Andric 
305145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));
306145449b1SDimitry Andric 
307145449b1SDimitry Andric   return MCDisassembler::Success;
308145449b1SDimitry Andric }
309145449b1SDimitry Andric 
DecodeRegSeqOperandD1(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)310145449b1SDimitry Andric static DecodeStatus DecodeRegSeqOperandD1(MCInst &Inst, uint64_t Imm,
311145449b1SDimitry Andric                                           int64_t Address,
312145449b1SDimitry Andric                                           const MCDisassembler *Decoder) {
313145449b1SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
314145449b1SDimitry Andric 
315145449b1SDimitry Andric   auto Imm5 = Imm & 0x1f;
316145449b1SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
317145449b1SDimitry Andric 
318145449b1SDimitry Andric   if (DecodesFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
319145449b1SDimitry Andric       MCDisassembler::Fail)
320145449b1SDimitry Andric     return MCDisassembler::Fail;
321145449b1SDimitry Andric 
322145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));
323145449b1SDimitry Andric 
324145449b1SDimitry Andric   return MCDisassembler::Success;
325145449b1SDimitry Andric }
326145449b1SDimitry Andric 
DecodeRegSeqOperandF2(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)327145449b1SDimitry Andric static DecodeStatus DecodeRegSeqOperandF2(MCInst &Inst, uint64_t Imm,
328145449b1SDimitry Andric                                           int64_t Address,
329145449b1SDimitry Andric                                           const MCDisassembler *Decoder) {
330145449b1SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
331145449b1SDimitry Andric 
332145449b1SDimitry Andric   auto Imm5 = Imm & 0x1f;
333145449b1SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
334145449b1SDimitry Andric 
335145449b1SDimitry Andric   if (DecodeFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
336145449b1SDimitry Andric       MCDisassembler::Fail)
337145449b1SDimitry Andric     return MCDisassembler::Fail;
338145449b1SDimitry Andric 
339145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));
340145449b1SDimitry Andric 
341145449b1SDimitry Andric   return MCDisassembler::Success;
342145449b1SDimitry Andric }
343145449b1SDimitry Andric 
DecodeRegSeqOperandD2(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)344145449b1SDimitry Andric static DecodeStatus DecodeRegSeqOperandD2(MCInst &Inst, uint64_t Imm,
345145449b1SDimitry Andric                                           int64_t Address,
346145449b1SDimitry Andric                                           const MCDisassembler *Decoder) {
347145449b1SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
348145449b1SDimitry Andric 
349145449b1SDimitry Andric   auto Imm5 = Imm & 0x1f;
350145449b1SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
351145449b1SDimitry Andric 
352145449b1SDimitry Andric   if (DecodeFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
353145449b1SDimitry Andric       MCDisassembler::Fail)
354145449b1SDimitry Andric     return MCDisassembler::Fail;
355145449b1SDimitry Andric 
356145449b1SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));
357145449b1SDimitry Andric 
358145449b1SDimitry Andric   return MCDisassembler::Success;
359145449b1SDimitry Andric }
360145449b1SDimitry Andric 
decodeImmShiftOpValue(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)361145449b1SDimitry Andric static DecodeStatus decodeImmShiftOpValue(MCInst &Inst, uint64_t Imm,
362145449b1SDimitry Andric                                           int64_t Address,
363145449b1SDimitry Andric                                           const MCDisassembler *Decoder) {
364e3b55780SDimitry Andric   Inst.addOperand(MCOperand::createImm(Log2_64(Imm)));
365145449b1SDimitry Andric   return MCDisassembler::Success;
366145449b1SDimitry Andric }
367145449b1SDimitry Andric 
368145449b1SDimitry Andric template <unsigned N, unsigned S>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)369145449b1SDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
370145449b1SDimitry Andric                                       int64_t Address,
371145449b1SDimitry Andric                                       const MCDisassembler *Decoder) {
372145449b1SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
373145449b1SDimitry Andric   // Sign-extend the number in the bottom N bits of Imm
374145449b1SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) << S));
375145449b1SDimitry Andric   return MCDisassembler::Success;
376145449b1SDimitry Andric }
377145449b1SDimitry Andric 
378145449b1SDimitry Andric #include "CSKYGenDisassemblerTables.inc"
379145449b1SDimitry Andric 
handleCROperand(MCInst & MI) const380145449b1SDimitry Andric DecodeStatus CSKYDisassembler::handleCROperand(MCInst &MI) const {
381145449b1SDimitry Andric 
382145449b1SDimitry Andric   // FIXME: To query instruction info from td file or a table inc file
383145449b1SDimitry Andric   switch (MI.getOpcode()) {
384145449b1SDimitry Andric   default:
385145449b1SDimitry Andric     return MCDisassembler::Success;
386145449b1SDimitry Andric   case CSKY::LD16WSP:
387145449b1SDimitry Andric   case CSKY::ST16WSP:
388145449b1SDimitry Andric   case CSKY::ADDI16ZSP:
389145449b1SDimitry Andric     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::R14));
390145449b1SDimitry Andric     return MCDisassembler::Success;
391145449b1SDimitry Andric   case CSKY::ADDI16SPSP:
392145449b1SDimitry Andric   case CSKY::SUBI16SPSP:
393145449b1SDimitry Andric     MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));
394145449b1SDimitry Andric     MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));
395145449b1SDimitry Andric     return MCDisassembler::Success;
396145449b1SDimitry Andric   case CSKY::FCMPHS_S:
397145449b1SDimitry Andric   case CSKY::FCMPHS_D:
398145449b1SDimitry Andric   case CSKY::FCMPLT_S:
399145449b1SDimitry Andric   case CSKY::FCMPLT_D:
400145449b1SDimitry Andric   case CSKY::FCMPNE_S:
401145449b1SDimitry Andric   case CSKY::FCMPNE_D:
402145449b1SDimitry Andric   case CSKY::FCMPUO_S:
403145449b1SDimitry Andric   case CSKY::FCMPUO_D:
404145449b1SDimitry Andric   case CSKY::FCMPZHS_S:
405145449b1SDimitry Andric   case CSKY::FCMPZHS_D:
406145449b1SDimitry Andric   case CSKY::FCMPZLS_S:
407145449b1SDimitry Andric   case CSKY::FCMPZLS_D:
408145449b1SDimitry Andric   case CSKY::FCMPZNE_S:
409145449b1SDimitry Andric   case CSKY::FCMPZNE_D:
410145449b1SDimitry Andric   case CSKY::FCMPZUO_S:
411145449b1SDimitry Andric   case CSKY::FCMPZUO_D:
412145449b1SDimitry Andric   case CSKY::f2FCMPHS_S:
413145449b1SDimitry Andric   case CSKY::f2FCMPHS_D:
414145449b1SDimitry Andric   case CSKY::f2FCMPLT_S:
415145449b1SDimitry Andric   case CSKY::f2FCMPLT_D:
416145449b1SDimitry Andric   case CSKY::f2FCMPNE_S:
417145449b1SDimitry Andric   case CSKY::f2FCMPNE_D:
418145449b1SDimitry Andric   case CSKY::f2FCMPUO_S:
419145449b1SDimitry Andric   case CSKY::f2FCMPUO_D:
420145449b1SDimitry Andric   case CSKY::f2FCMPHSZ_S:
421145449b1SDimitry Andric   case CSKY::f2FCMPHSZ_D:
422145449b1SDimitry Andric   case CSKY::f2FCMPHZ_S:
423145449b1SDimitry Andric   case CSKY::f2FCMPHZ_D:
424145449b1SDimitry Andric   case CSKY::f2FCMPLSZ_S:
425145449b1SDimitry Andric   case CSKY::f2FCMPLSZ_D:
426145449b1SDimitry Andric   case CSKY::f2FCMPLTZ_S:
427145449b1SDimitry Andric   case CSKY::f2FCMPLTZ_D:
428145449b1SDimitry Andric   case CSKY::f2FCMPNEZ_S:
429145449b1SDimitry Andric   case CSKY::f2FCMPNEZ_D:
430145449b1SDimitry Andric   case CSKY::f2FCMPUOZ_S:
431145449b1SDimitry Andric   case CSKY::f2FCMPUOZ_D:
432145449b1SDimitry Andric 
433145449b1SDimitry Andric   case CSKY::BT32:
434145449b1SDimitry Andric   case CSKY::BF32:
435145449b1SDimitry Andric   case CSKY::BT16:
436145449b1SDimitry Andric   case CSKY::BF16:
437145449b1SDimitry Andric   case CSKY::CMPNEI32:
438145449b1SDimitry Andric   case CSKY::CMPNEI16:
439145449b1SDimitry Andric   case CSKY::CMPNE32:
440145449b1SDimitry Andric   case CSKY::CMPNE16:
441145449b1SDimitry Andric   case CSKY::CMPHSI32:
442145449b1SDimitry Andric   case CSKY::CMPHSI16:
443145449b1SDimitry Andric   case CSKY::CMPHS32:
444145449b1SDimitry Andric   case CSKY::CMPHS16:
445145449b1SDimitry Andric   case CSKY::CMPLTI32:
446145449b1SDimitry Andric   case CSKY::CMPLTI16:
447145449b1SDimitry Andric   case CSKY::CMPLT32:
448145449b1SDimitry Andric   case CSKY::CMPLT16:
449145449b1SDimitry Andric   case CSKY::BTSTI32:
450145449b1SDimitry Andric   case CSKY::BTSTI16:
451145449b1SDimitry Andric   case CSKY::TSTNBZ32:
452145449b1SDimitry Andric   case CSKY::TSTNBZ16:
453145449b1SDimitry Andric   case CSKY::TST32:
454145449b1SDimitry Andric   case CSKY::TST16:
455145449b1SDimitry Andric     MI.insert(MI.begin(), MCOperand::createReg(CSKY::C));
456145449b1SDimitry Andric     return MCDisassembler::Success;
457145449b1SDimitry Andric   case CSKY::LSLC32:
458145449b1SDimitry Andric   case CSKY::LSRC32:
459145449b1SDimitry Andric   case CSKY::ASRC32:
460145449b1SDimitry Andric     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
461145449b1SDimitry Andric     return MCDisassembler::Success;
462145449b1SDimitry Andric   case CSKY::MOVF32:
463145449b1SDimitry Andric   case CSKY::MOVT32:
464145449b1SDimitry Andric   case CSKY::MVC32:
465145449b1SDimitry Andric   case CSKY::MVCV32:
466145449b1SDimitry Andric   case CSKY::MVCV16:
467145449b1SDimitry Andric   case CSKY::INCT32:
468145449b1SDimitry Andric   case CSKY::INCF32:
469145449b1SDimitry Andric   case CSKY::DECT32:
470145449b1SDimitry Andric   case CSKY::DECF32:
471145449b1SDimitry Andric   case CSKY::DECGT32:
472145449b1SDimitry Andric   case CSKY::DECLT32:
473145449b1SDimitry Andric   case CSKY::DECNE32:
474145449b1SDimitry Andric   case CSKY::CLRF32:
475145449b1SDimitry Andric   case CSKY::CLRT32:
476145449b1SDimitry Andric   case CSKY::f2FSEL_S:
477145449b1SDimitry Andric   case CSKY::f2FSEL_D:
478145449b1SDimitry Andric     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
479145449b1SDimitry Andric     return MCDisassembler::Success;
480145449b1SDimitry Andric   case CSKY::ADDC32:
481145449b1SDimitry Andric   case CSKY::ADDC16:
482145449b1SDimitry Andric   case CSKY::SUBC32:
483145449b1SDimitry Andric   case CSKY::SUBC16:
484145449b1SDimitry Andric   case CSKY::XSR32:
485145449b1SDimitry Andric     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
486145449b1SDimitry Andric     MI.insert(MI.end(), MCOperand::createReg(CSKY::C));
487145449b1SDimitry Andric     return MCDisassembler::Success;
488145449b1SDimitry Andric   case CSKY::INS32:
489145449b1SDimitry Andric     MI.getOperand(3).setImm(MI.getOperand(3).getImm() +
490145449b1SDimitry Andric                             MI.getOperand(4).getImm());
491145449b1SDimitry Andric     return MCDisassembler::Success;
492145449b1SDimitry Andric   }
493145449b1SDimitry Andric }
494145449b1SDimitry Andric 
decodeFPUV3Instruction(MCInst & MI,uint32_t insn,uint64_t Address,const MCDisassembler * DisAsm,const MCSubtargetInfo & STI)495145449b1SDimitry Andric static bool decodeFPUV3Instruction(MCInst &MI, uint32_t insn, uint64_t Address,
496145449b1SDimitry Andric                                    const MCDisassembler *DisAsm,
497145449b1SDimitry Andric                                    const MCSubtargetInfo &STI) {
498145449b1SDimitry Andric   LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit fpuv3 table :\n");
4997fa27ce4SDimitry Andric   if (!STI.hasFeature(CSKY::FeatureFPUV3_HF) &&
5007fa27ce4SDimitry Andric       !STI.hasFeature(CSKY::FeatureFPUV3_SF) &&
5017fa27ce4SDimitry Andric       !STI.hasFeature(CSKY::FeatureFPUV3_DF))
502145449b1SDimitry Andric     return false;
503145449b1SDimitry Andric 
504145449b1SDimitry Andric   DecodeStatus Result =
505145449b1SDimitry Andric       decodeInstruction(DecoderTableFPUV332, MI, insn, Address, DisAsm, STI);
506145449b1SDimitry Andric 
507145449b1SDimitry Andric   if (Result == MCDisassembler::Fail) {
508145449b1SDimitry Andric     MI.clear();
509145449b1SDimitry Andric     return false;
510145449b1SDimitry Andric   }
511145449b1SDimitry Andric 
512145449b1SDimitry Andric   return true;
513145449b1SDimitry Andric }
514145449b1SDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const515145449b1SDimitry Andric DecodeStatus CSKYDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
516145449b1SDimitry Andric                                               ArrayRef<uint8_t> Bytes,
517145449b1SDimitry Andric                                               uint64_t Address,
518145449b1SDimitry Andric                                               raw_ostream &CS) const {
519145449b1SDimitry Andric 
520145449b1SDimitry Andric   uint32_t Insn;
521145449b1SDimitry Andric   DecodeStatus Result = MCDisassembler::Fail;
522145449b1SDimitry Andric 
523145449b1SDimitry Andric   Insn = support::endian::read16le(Bytes.data());
524145449b1SDimitry Andric 
525145449b1SDimitry Andric   if ((Insn >> 14) == 0x3) {
526145449b1SDimitry Andric     if (Bytes.size() < 4) {
527145449b1SDimitry Andric       Size = 0;
528145449b1SDimitry Andric       return MCDisassembler::Fail;
529145449b1SDimitry Andric     }
530145449b1SDimitry Andric     Insn = (Insn << 16) | support::endian::read16le(&Bytes[2]);
531145449b1SDimitry Andric 
532145449b1SDimitry Andric     if (decodeFPUV3Instruction(MI, Insn, Address, this, STI))
533145449b1SDimitry Andric       Result = MCDisassembler::Success;
534145449b1SDimitry Andric     else {
535145449b1SDimitry Andric       LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit table :\n");
536145449b1SDimitry Andric       Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
537145449b1SDimitry Andric     }
538145449b1SDimitry Andric 
539145449b1SDimitry Andric     Size = 4;
540145449b1SDimitry Andric   } else {
541145449b1SDimitry Andric     if (Bytes.size() < 2) {
542145449b1SDimitry Andric       Size = 0;
543145449b1SDimitry Andric       return MCDisassembler::Fail;
544145449b1SDimitry Andric     }
545145449b1SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying CSKY 16-bit table :\n");
546145449b1SDimitry Andric     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
547145449b1SDimitry Andric     Size = 2;
548145449b1SDimitry Andric   }
549145449b1SDimitry Andric 
550145449b1SDimitry Andric   handleCROperand(MI);
551145449b1SDimitry Andric 
552145449b1SDimitry Andric   return Result;
553145449b1SDimitry Andric }
554