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