xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
181ad6265SDimitry Andric //===-- CSKYDisassembler.cpp - Disassembler for CSKY ----------------------===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric //
981ad6265SDimitry Andric // This file implements the CSKYDisassembler class.
1081ad6265SDimitry Andric //
1181ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1281ad6265SDimitry Andric 
1381ad6265SDimitry Andric #include "MCTargetDesc/CSKYBaseInfo.h"
1481ad6265SDimitry Andric #include "MCTargetDesc/CSKYMCTargetDesc.h"
1581ad6265SDimitry Andric #include "TargetInfo/CSKYTargetInfo.h"
1681ad6265SDimitry Andric #include "llvm/ADT/DenseMap.h"
1781ad6265SDimitry Andric #include "llvm/MC/MCContext.h"
1881ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
1981ad6265SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
2081ad6265SDimitry Andric #include "llvm/MC/MCInst.h"
2181ad6265SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
2281ad6265SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
2381ad6265SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
2481ad6265SDimitry Andric #include "llvm/MC/TargetRegistry.h"
2581ad6265SDimitry Andric #include "llvm/Support/Endian.h"
2681ad6265SDimitry Andric 
2781ad6265SDimitry Andric using namespace llvm;
2881ad6265SDimitry Andric 
2981ad6265SDimitry Andric #define DEBUG_TYPE "csky-disassembler"
3081ad6265SDimitry Andric 
3181ad6265SDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
3281ad6265SDimitry Andric 
3381ad6265SDimitry Andric namespace {
3481ad6265SDimitry Andric class CSKYDisassembler : public MCDisassembler {
3581ad6265SDimitry Andric   std::unique_ptr<MCInstrInfo const> const MCII;
3681ad6265SDimitry Andric   mutable StringRef symbolName;
3781ad6265SDimitry Andric 
3881ad6265SDimitry Andric   DecodeStatus handleCROperand(MCInst &Instr) const;
3981ad6265SDimitry Andric 
4081ad6265SDimitry Andric public:
4181ad6265SDimitry Andric   CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
4281ad6265SDimitry Andric                    MCInstrInfo const *MCII);
4381ad6265SDimitry Andric 
4481ad6265SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
4581ad6265SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
4681ad6265SDimitry Andric                               raw_ostream &CStream) const override;
4781ad6265SDimitry Andric };
4881ad6265SDimitry Andric } // end anonymous namespace
4981ad6265SDimitry Andric 
CSKYDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)5081ad6265SDimitry Andric CSKYDisassembler::CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
5181ad6265SDimitry Andric                                    MCInstrInfo const *MCII)
5281ad6265SDimitry Andric     : MCDisassembler(STI, Ctx), MCII(MCII) {}
5381ad6265SDimitry Andric 
createCSKYDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)5481ad6265SDimitry Andric static MCDisassembler *createCSKYDisassembler(const Target &T,
5581ad6265SDimitry Andric                                               const MCSubtargetInfo &STI,
5681ad6265SDimitry Andric                                               MCContext &Ctx) {
5781ad6265SDimitry Andric   return new CSKYDisassembler(STI, Ctx, T.createMCInstrInfo());
5881ad6265SDimitry Andric }
5981ad6265SDimitry Andric 
LLVMInitializeCSKYDisassembler()6081ad6265SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYDisassembler() {
6181ad6265SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheCSKYTarget(),
6281ad6265SDimitry Andric                                          createCSKYDisassembler);
6381ad6265SDimitry Andric }
6481ad6265SDimitry Andric 
6581ad6265SDimitry Andric static const uint16_t GPRDecoderTable[] = {
6681ad6265SDimitry Andric     CSKY::R0,  CSKY::R1,  CSKY::R2,  CSKY::R3,  CSKY::R4,  CSKY::R5,  CSKY::R6,
6781ad6265SDimitry Andric     CSKY::R7,  CSKY::R8,  CSKY::R9,  CSKY::R10, CSKY::R11, CSKY::R12, CSKY::R13,
6881ad6265SDimitry Andric     CSKY::R14, CSKY::R15, CSKY::R16, CSKY::R17, CSKY::R18, CSKY::R19, CSKY::R20,
6981ad6265SDimitry Andric     CSKY::R21, CSKY::R22, CSKY::R23, CSKY::R24, CSKY::R25, CSKY::R26, CSKY::R27,
7081ad6265SDimitry Andric     CSKY::R28, CSKY::R29, CSKY::R30, CSKY::R31};
7181ad6265SDimitry Andric 
7281ad6265SDimitry Andric static const uint16_t GPRPairDecoderTable[] = {
7381ad6265SDimitry Andric     CSKY::R0_R1,   CSKY::R1_R2,   CSKY::R2_R3,   CSKY::R3_R4,   CSKY::R4_R5,
7481ad6265SDimitry Andric     CSKY::R5_R6,   CSKY::R6_R7,   CSKY::R7_R8,   CSKY::R8_R9,   CSKY::R9_R10,
7581ad6265SDimitry Andric     CSKY::R10_R11, CSKY::R11_R12, CSKY::R12_R13, CSKY::R13_R14, CSKY::R14_R15,
7681ad6265SDimitry Andric     CSKY::R15_R16, CSKY::R16_R17, CSKY::R17_R18, CSKY::R18_R19, CSKY::R19_R20,
7781ad6265SDimitry Andric     CSKY::R20_R21, CSKY::R21_R22, CSKY::R22_R23, CSKY::R23_R24, CSKY::R24_R25,
7881ad6265SDimitry Andric     CSKY::R25_R26, CSKY::R26_R27, CSKY::R27_R28, CSKY::R28_R29, CSKY::R29_R30,
7981ad6265SDimitry Andric     CSKY::R30_R31, CSKY::R31_R32};
8081ad6265SDimitry Andric 
8181ad6265SDimitry Andric static const uint16_t FPR32DecoderTable[] = {
8281ad6265SDimitry Andric     CSKY::F0_32,  CSKY::F1_32,  CSKY::F2_32,  CSKY::F3_32,  CSKY::F4_32,
8381ad6265SDimitry Andric     CSKY::F5_32,  CSKY::F6_32,  CSKY::F7_32,  CSKY::F8_32,  CSKY::F9_32,
8481ad6265SDimitry Andric     CSKY::F10_32, CSKY::F11_32, CSKY::F12_32, CSKY::F13_32, CSKY::F14_32,
8581ad6265SDimitry Andric     CSKY::F15_32, CSKY::F16_32, CSKY::F17_32, CSKY::F18_32, CSKY::F19_32,
8681ad6265SDimitry Andric     CSKY::F20_32, CSKY::F21_32, CSKY::F22_32, CSKY::F23_32, CSKY::F24_32,
8781ad6265SDimitry Andric     CSKY::F25_32, CSKY::F26_32, CSKY::F27_32, CSKY::F28_32, CSKY::F29_32,
8881ad6265SDimitry Andric     CSKY::F30_32, CSKY::F31_32};
8981ad6265SDimitry Andric 
9081ad6265SDimitry Andric static const uint16_t FPR64DecoderTable[] = {
9181ad6265SDimitry Andric     CSKY::F0_64,  CSKY::F1_64,  CSKY::F2_64,  CSKY::F3_64,  CSKY::F4_64,
9281ad6265SDimitry Andric     CSKY::F5_64,  CSKY::F6_64,  CSKY::F7_64,  CSKY::F8_64,  CSKY::F9_64,
9381ad6265SDimitry Andric     CSKY::F10_64, CSKY::F11_64, CSKY::F12_64, CSKY::F13_64, CSKY::F14_64,
9481ad6265SDimitry Andric     CSKY::F15_64, CSKY::F16_64, CSKY::F17_64, CSKY::F18_64, CSKY::F19_64,
9581ad6265SDimitry Andric     CSKY::F20_64, CSKY::F21_64, CSKY::F22_64, CSKY::F23_64, CSKY::F24_64,
9681ad6265SDimitry Andric     CSKY::F25_64, CSKY::F26_64, CSKY::F27_64, CSKY::F28_64, CSKY::F29_64,
9781ad6265SDimitry Andric     CSKY::F30_64, CSKY::F31_64};
9881ad6265SDimitry Andric 
9981ad6265SDimitry Andric static const uint16_t FPR128DecoderTable[] = {
10081ad6265SDimitry Andric     CSKY::F0_128,  CSKY::F1_128,  CSKY::F2_128,  CSKY::F3_128,  CSKY::F4_128,
10181ad6265SDimitry Andric     CSKY::F5_128,  CSKY::F6_128,  CSKY::F7_128,  CSKY::F8_128,  CSKY::F9_128,
10281ad6265SDimitry Andric     CSKY::F10_128, CSKY::F11_128, CSKY::F12_128, CSKY::F13_128, CSKY::F14_128,
10381ad6265SDimitry Andric     CSKY::F15_128, CSKY::F16_128, CSKY::F17_128, CSKY::F18_128, CSKY::F19_128,
10481ad6265SDimitry Andric     CSKY::F20_128, CSKY::F21_128, CSKY::F22_128, CSKY::F23_128, CSKY::F24_128,
10581ad6265SDimitry Andric     CSKY::F25_128, CSKY::F26_128, CSKY::F27_128, CSKY::F28_128, CSKY::F29_128,
10681ad6265SDimitry Andric     CSKY::F30_128, CSKY::F31_128};
10781ad6265SDimitry Andric 
DecodeGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)10881ad6265SDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
10981ad6265SDimitry Andric                                            uint64_t Address,
11081ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
11181ad6265SDimitry Andric   if (RegNo >= 32)
11281ad6265SDimitry Andric     return MCDisassembler::Fail;
11381ad6265SDimitry Andric 
11481ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
11581ad6265SDimitry Andric   return MCDisassembler::Success;
11681ad6265SDimitry Andric }
11781ad6265SDimitry Andric 
DecodeFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)11881ad6265SDimitry Andric static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
11981ad6265SDimitry Andric                                              uint64_t Address,
12081ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
12181ad6265SDimitry Andric   if (RegNo >= 32)
12281ad6265SDimitry Andric     return MCDisassembler::Fail;
12381ad6265SDimitry Andric 
12481ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));
12581ad6265SDimitry Andric   return MCDisassembler::Success;
12681ad6265SDimitry Andric }
12781ad6265SDimitry Andric 
DecodesFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)12881ad6265SDimitry Andric static DecodeStatus DecodesFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
12981ad6265SDimitry Andric                                               uint64_t Address,
13081ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
13181ad6265SDimitry Andric   if (RegNo >= 16)
13281ad6265SDimitry Andric     return MCDisassembler::Fail;
13381ad6265SDimitry Andric 
13481ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));
13581ad6265SDimitry Andric   return MCDisassembler::Success;
13681ad6265SDimitry Andric }
13781ad6265SDimitry Andric 
DecodesFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)13881ad6265SDimitry Andric static DecodeStatus DecodesFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
13981ad6265SDimitry Andric                                               uint64_t Address,
14081ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
14181ad6265SDimitry Andric   if (RegNo >= 16)
14281ad6265SDimitry Andric     return MCDisassembler::Fail;
14381ad6265SDimitry Andric 
14481ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
14581ad6265SDimitry Andric   return MCDisassembler::Success;
14681ad6265SDimitry Andric }
14781ad6265SDimitry Andric 
DecodesFPR64_VRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)14881ad6265SDimitry Andric static DecodeStatus DecodesFPR64_VRegisterClass(MCInst &Inst, uint64_t RegNo,
14981ad6265SDimitry Andric                                                 uint64_t Address,
15081ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
15181ad6265SDimitry Andric   if (RegNo >= 16)
15281ad6265SDimitry Andric     return MCDisassembler::Fail;
15381ad6265SDimitry Andric 
15481ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
15581ad6265SDimitry Andric   return MCDisassembler::Success;
15681ad6265SDimitry Andric }
15781ad6265SDimitry Andric 
DecodeFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)15881ad6265SDimitry Andric static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
15981ad6265SDimitry Andric                                              uint64_t Address,
16081ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
16181ad6265SDimitry Andric   if (RegNo >= 32)
16281ad6265SDimitry Andric     return MCDisassembler::Fail;
16381ad6265SDimitry Andric 
16481ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
16581ad6265SDimitry Andric   return MCDisassembler::Success;
16681ad6265SDimitry Andric }
16781ad6265SDimitry Andric 
16881ad6265SDimitry Andric // TODO
16981ad6265SDimitry Andric LLVM_ATTRIBUTE_UNUSED
DecodesFPR128RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)17081ad6265SDimitry Andric static DecodeStatus DecodesFPR128RegisterClass(MCInst &Inst, uint64_t RegNo,
17181ad6265SDimitry Andric                                                uint64_t Address,
17281ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
17381ad6265SDimitry Andric   if (RegNo >= 16)
17481ad6265SDimitry Andric     return MCDisassembler::Fail;
17581ad6265SDimitry Andric 
17681ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR128DecoderTable[RegNo]));
17781ad6265SDimitry Andric   return MCDisassembler::Success;
17881ad6265SDimitry Andric }
17981ad6265SDimitry Andric 
DecodesGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)18081ad6265SDimitry Andric static DecodeStatus DecodesGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
18181ad6265SDimitry Andric                                             uint64_t Address,
18281ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
18381ad6265SDimitry Andric   if (RegNo >= 16)
18481ad6265SDimitry Andric     return MCDisassembler::Fail;
18581ad6265SDimitry Andric 
18681ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
18781ad6265SDimitry Andric   return MCDisassembler::Success;
18881ad6265SDimitry Andric }
18981ad6265SDimitry Andric 
DecodemGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)19081ad6265SDimitry Andric static DecodeStatus DecodemGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
19181ad6265SDimitry Andric                                             uint64_t Address,
19281ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
19381ad6265SDimitry Andric   if (RegNo >= 8)
19481ad6265SDimitry Andric     return MCDisassembler::Fail;
19581ad6265SDimitry Andric 
19681ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
19781ad6265SDimitry Andric   return MCDisassembler::Success;
19881ad6265SDimitry Andric }
19981ad6265SDimitry Andric 
20081ad6265SDimitry Andric // TODO
20181ad6265SDimitry Andric LLVM_ATTRIBUTE_UNUSED
DecodeGPRSPRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)20281ad6265SDimitry Andric static DecodeStatus DecodeGPRSPRegisterClass(MCInst &Inst, uint64_t RegNo,
20381ad6265SDimitry Andric                                              uint64_t Address,
20481ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
20581ad6265SDimitry Andric   if (RegNo != 14)
20681ad6265SDimitry Andric     return MCDisassembler::Fail;
20781ad6265SDimitry Andric 
20881ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
20981ad6265SDimitry Andric   return MCDisassembler::Success;
21081ad6265SDimitry Andric }
21181ad6265SDimitry Andric 
DecodeGPRPairRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)21281ad6265SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint64_t RegNo,
21381ad6265SDimitry Andric                                                uint64_t Address,
21481ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
21581ad6265SDimitry Andric   const FeatureBitset &FeatureBits =
21681ad6265SDimitry Andric       Decoder->getSubtargetInfo().getFeatureBits();
21781ad6265SDimitry Andric   bool hasHighReg = FeatureBits[CSKY::FeatureHighreg];
21881ad6265SDimitry Andric 
21981ad6265SDimitry Andric   if (RegNo >= 32 || (!hasHighReg && RegNo >= 16))
22081ad6265SDimitry Andric     return MCDisassembler::Fail;
22181ad6265SDimitry Andric 
22281ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRPairDecoderTable[RegNo]));
22381ad6265SDimitry Andric   return MCDisassembler::Success;
22481ad6265SDimitry Andric }
22581ad6265SDimitry Andric 
22681ad6265SDimitry Andric template <unsigned N, unsigned S>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)22781ad6265SDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
22881ad6265SDimitry Andric                                       int64_t Address,
22981ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
23081ad6265SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
23181ad6265SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm << S));
23281ad6265SDimitry Andric   return MCDisassembler::Success;
23381ad6265SDimitry Andric }
23481ad6265SDimitry Andric 
23581ad6265SDimitry Andric template <unsigned N>
decodeOImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)23681ad6265SDimitry Andric static DecodeStatus decodeOImmOperand(MCInst &Inst, uint64_t Imm,
23781ad6265SDimitry Andric                                       int64_t Address,
23881ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
23981ad6265SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
24081ad6265SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm + 1));
24181ad6265SDimitry Andric   return MCDisassembler::Success;
24281ad6265SDimitry Andric }
24381ad6265SDimitry Andric 
decodeLRW16Imm8(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)24481ad6265SDimitry Andric static DecodeStatus decodeLRW16Imm8(MCInst &Inst, uint64_t Imm, int64_t Address,
24581ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
24681ad6265SDimitry Andric   assert(isUInt<8>(Imm) && "Invalid immediate");
24781ad6265SDimitry Andric   if ((Imm >> 7) & 0x1) {
24881ad6265SDimitry Andric     Inst.addOperand(MCOperand::createImm((Imm & 0x7F) << 2));
24981ad6265SDimitry Andric   } else {
25081ad6265SDimitry Andric     uint64_t V = ((Imm ^ 0xFFFFFFFF) & 0xFF);
25181ad6265SDimitry Andric     Inst.addOperand(MCOperand::createImm(V << 2));
25281ad6265SDimitry Andric   }
25381ad6265SDimitry Andric 
25481ad6265SDimitry Andric   return MCDisassembler::Success;
25581ad6265SDimitry Andric }
25681ad6265SDimitry Andric 
decodeJMPIXImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)25781ad6265SDimitry Andric static DecodeStatus decodeJMPIXImmOperand(MCInst &Inst, uint64_t Imm,
25881ad6265SDimitry Andric                                           int64_t Address,
25981ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
26081ad6265SDimitry Andric   assert(isUInt<2>(Imm) && "Invalid immediate");
26181ad6265SDimitry Andric 
26281ad6265SDimitry Andric   if (Imm == 0)
26381ad6265SDimitry Andric     Inst.addOperand(MCOperand::createImm(16));
26481ad6265SDimitry Andric   else if (Imm == 1)
26581ad6265SDimitry Andric     Inst.addOperand(MCOperand::createImm(24));
26681ad6265SDimitry Andric   else if (Imm == 2)
26781ad6265SDimitry Andric     Inst.addOperand(MCOperand::createImm(32));
26881ad6265SDimitry Andric   else if (Imm == 3)
26981ad6265SDimitry Andric     Inst.addOperand(MCOperand::createImm(40));
27081ad6265SDimitry Andric   else
27181ad6265SDimitry Andric     return MCDisassembler::Fail;
27281ad6265SDimitry Andric 
27381ad6265SDimitry Andric   return MCDisassembler::Success;
27481ad6265SDimitry Andric }
27581ad6265SDimitry Andric 
DecodeRegSeqOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)27681ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperand(MCInst &Inst, uint64_t Imm,
27781ad6265SDimitry Andric                                         int64_t Address,
27881ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
27981ad6265SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
28081ad6265SDimitry Andric 
28181ad6265SDimitry Andric   auto Imm5 = Imm & 0x1f;
28281ad6265SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
28381ad6265SDimitry Andric 
28481ad6265SDimitry Andric   if (DecodeGPRRegisterClass(Inst, Ry, Address, Decoder) ==
28581ad6265SDimitry Andric       MCDisassembler::Fail)
28681ad6265SDimitry Andric     return MCDisassembler::Fail;
28781ad6265SDimitry Andric 
28881ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Ry + Imm5]));
28981ad6265SDimitry Andric 
29081ad6265SDimitry Andric   return MCDisassembler::Success;
29181ad6265SDimitry Andric }
29281ad6265SDimitry Andric 
DecodeRegSeqOperandF1(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)29381ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperandF1(MCInst &Inst, uint64_t Imm,
29481ad6265SDimitry Andric                                           int64_t Address,
29581ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
29681ad6265SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
29781ad6265SDimitry Andric 
29881ad6265SDimitry Andric   auto Imm5 = Imm & 0x1f;
29981ad6265SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
30081ad6265SDimitry Andric 
30181ad6265SDimitry Andric   if (DecodesFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
30281ad6265SDimitry Andric       MCDisassembler::Fail)
30381ad6265SDimitry Andric     return MCDisassembler::Fail;
30481ad6265SDimitry Andric 
30581ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));
30681ad6265SDimitry Andric 
30781ad6265SDimitry Andric   return MCDisassembler::Success;
30881ad6265SDimitry Andric }
30981ad6265SDimitry Andric 
DecodeRegSeqOperandD1(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)31081ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperandD1(MCInst &Inst, uint64_t Imm,
31181ad6265SDimitry Andric                                           int64_t Address,
31281ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
31381ad6265SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
31481ad6265SDimitry Andric 
31581ad6265SDimitry Andric   auto Imm5 = Imm & 0x1f;
31681ad6265SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
31781ad6265SDimitry Andric 
31881ad6265SDimitry Andric   if (DecodesFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
31981ad6265SDimitry Andric       MCDisassembler::Fail)
32081ad6265SDimitry Andric     return MCDisassembler::Fail;
32181ad6265SDimitry Andric 
32281ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));
32381ad6265SDimitry Andric 
32481ad6265SDimitry Andric   return MCDisassembler::Success;
32581ad6265SDimitry Andric }
32681ad6265SDimitry Andric 
DecodeRegSeqOperandF2(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)32781ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperandF2(MCInst &Inst, uint64_t Imm,
32881ad6265SDimitry Andric                                           int64_t Address,
32981ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
33081ad6265SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
33181ad6265SDimitry Andric 
33281ad6265SDimitry Andric   auto Imm5 = Imm & 0x1f;
33381ad6265SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
33481ad6265SDimitry Andric 
33581ad6265SDimitry Andric   if (DecodeFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
33681ad6265SDimitry Andric       MCDisassembler::Fail)
33781ad6265SDimitry Andric     return MCDisassembler::Fail;
33881ad6265SDimitry Andric 
33981ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));
34081ad6265SDimitry Andric 
34181ad6265SDimitry Andric   return MCDisassembler::Success;
34281ad6265SDimitry Andric }
34381ad6265SDimitry Andric 
DecodeRegSeqOperandD2(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)34481ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperandD2(MCInst &Inst, uint64_t Imm,
34581ad6265SDimitry Andric                                           int64_t Address,
34681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
34781ad6265SDimitry Andric   assert(isUInt<10>(Imm) && "Invalid immediate");
34881ad6265SDimitry Andric 
34981ad6265SDimitry Andric   auto Imm5 = Imm & 0x1f;
35081ad6265SDimitry Andric   auto Ry = (Imm >> 5) & 0x1f;
35181ad6265SDimitry Andric 
35281ad6265SDimitry Andric   if (DecodeFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
35381ad6265SDimitry Andric       MCDisassembler::Fail)
35481ad6265SDimitry Andric     return MCDisassembler::Fail;
35581ad6265SDimitry Andric 
35681ad6265SDimitry Andric   Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));
35781ad6265SDimitry Andric 
35881ad6265SDimitry Andric   return MCDisassembler::Success;
35981ad6265SDimitry Andric }
36081ad6265SDimitry Andric 
decodeImmShiftOpValue(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)36181ad6265SDimitry Andric static DecodeStatus decodeImmShiftOpValue(MCInst &Inst, uint64_t Imm,
36281ad6265SDimitry Andric                                           int64_t Address,
36381ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
364bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(Log2_64(Imm)));
36581ad6265SDimitry Andric   return MCDisassembler::Success;
36681ad6265SDimitry Andric }
36781ad6265SDimitry Andric 
36881ad6265SDimitry Andric template <unsigned N, unsigned S>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)36981ad6265SDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
37081ad6265SDimitry Andric                                       int64_t Address,
37181ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
37281ad6265SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
37381ad6265SDimitry Andric   // Sign-extend the number in the bottom N bits of Imm
37481ad6265SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) << S));
37581ad6265SDimitry Andric   return MCDisassembler::Success;
37681ad6265SDimitry Andric }
37781ad6265SDimitry Andric 
37881ad6265SDimitry Andric #include "CSKYGenDisassemblerTables.inc"
37981ad6265SDimitry Andric 
handleCROperand(MCInst & MI) const38081ad6265SDimitry Andric DecodeStatus CSKYDisassembler::handleCROperand(MCInst &MI) const {
38181ad6265SDimitry Andric 
38281ad6265SDimitry Andric   // FIXME: To query instruction info from td file or a table inc file
38381ad6265SDimitry Andric   switch (MI.getOpcode()) {
38481ad6265SDimitry Andric   default:
38581ad6265SDimitry Andric     return MCDisassembler::Success;
38681ad6265SDimitry Andric   case CSKY::LD16WSP:
38781ad6265SDimitry Andric   case CSKY::ST16WSP:
38881ad6265SDimitry Andric   case CSKY::ADDI16ZSP:
38981ad6265SDimitry Andric     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::R14));
39081ad6265SDimitry Andric     return MCDisassembler::Success;
39181ad6265SDimitry Andric   case CSKY::ADDI16SPSP:
39281ad6265SDimitry Andric   case CSKY::SUBI16SPSP:
39381ad6265SDimitry Andric     MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));
39481ad6265SDimitry Andric     MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));
39581ad6265SDimitry Andric     return MCDisassembler::Success;
39681ad6265SDimitry Andric   case CSKY::FCMPHS_S:
39781ad6265SDimitry Andric   case CSKY::FCMPHS_D:
39881ad6265SDimitry Andric   case CSKY::FCMPLT_S:
39981ad6265SDimitry Andric   case CSKY::FCMPLT_D:
40081ad6265SDimitry Andric   case CSKY::FCMPNE_S:
40181ad6265SDimitry Andric   case CSKY::FCMPNE_D:
40281ad6265SDimitry Andric   case CSKY::FCMPUO_S:
40381ad6265SDimitry Andric   case CSKY::FCMPUO_D:
40481ad6265SDimitry Andric   case CSKY::FCMPZHS_S:
40581ad6265SDimitry Andric   case CSKY::FCMPZHS_D:
40681ad6265SDimitry Andric   case CSKY::FCMPZLS_S:
40781ad6265SDimitry Andric   case CSKY::FCMPZLS_D:
40881ad6265SDimitry Andric   case CSKY::FCMPZNE_S:
40981ad6265SDimitry Andric   case CSKY::FCMPZNE_D:
41081ad6265SDimitry Andric   case CSKY::FCMPZUO_S:
41181ad6265SDimitry Andric   case CSKY::FCMPZUO_D:
41281ad6265SDimitry Andric   case CSKY::f2FCMPHS_S:
41381ad6265SDimitry Andric   case CSKY::f2FCMPHS_D:
41481ad6265SDimitry Andric   case CSKY::f2FCMPLT_S:
41581ad6265SDimitry Andric   case CSKY::f2FCMPLT_D:
41681ad6265SDimitry Andric   case CSKY::f2FCMPNE_S:
41781ad6265SDimitry Andric   case CSKY::f2FCMPNE_D:
41881ad6265SDimitry Andric   case CSKY::f2FCMPUO_S:
41981ad6265SDimitry Andric   case CSKY::f2FCMPUO_D:
42081ad6265SDimitry Andric   case CSKY::f2FCMPHSZ_S:
42181ad6265SDimitry Andric   case CSKY::f2FCMPHSZ_D:
42281ad6265SDimitry Andric   case CSKY::f2FCMPHZ_S:
42381ad6265SDimitry Andric   case CSKY::f2FCMPHZ_D:
42481ad6265SDimitry Andric   case CSKY::f2FCMPLSZ_S:
42581ad6265SDimitry Andric   case CSKY::f2FCMPLSZ_D:
42681ad6265SDimitry Andric   case CSKY::f2FCMPLTZ_S:
42781ad6265SDimitry Andric   case CSKY::f2FCMPLTZ_D:
42881ad6265SDimitry Andric   case CSKY::f2FCMPNEZ_S:
42981ad6265SDimitry Andric   case CSKY::f2FCMPNEZ_D:
43081ad6265SDimitry Andric   case CSKY::f2FCMPUOZ_S:
43181ad6265SDimitry Andric   case CSKY::f2FCMPUOZ_D:
43281ad6265SDimitry Andric 
43381ad6265SDimitry Andric   case CSKY::BT32:
43481ad6265SDimitry Andric   case CSKY::BF32:
43581ad6265SDimitry Andric   case CSKY::BT16:
43681ad6265SDimitry Andric   case CSKY::BF16:
43781ad6265SDimitry Andric   case CSKY::CMPNEI32:
43881ad6265SDimitry Andric   case CSKY::CMPNEI16:
43981ad6265SDimitry Andric   case CSKY::CMPNE32:
44081ad6265SDimitry Andric   case CSKY::CMPNE16:
44181ad6265SDimitry Andric   case CSKY::CMPHSI32:
44281ad6265SDimitry Andric   case CSKY::CMPHSI16:
44381ad6265SDimitry Andric   case CSKY::CMPHS32:
44481ad6265SDimitry Andric   case CSKY::CMPHS16:
44581ad6265SDimitry Andric   case CSKY::CMPLTI32:
44681ad6265SDimitry Andric   case CSKY::CMPLTI16:
44781ad6265SDimitry Andric   case CSKY::CMPLT32:
44881ad6265SDimitry Andric   case CSKY::CMPLT16:
44981ad6265SDimitry Andric   case CSKY::BTSTI32:
45081ad6265SDimitry Andric   case CSKY::BTSTI16:
45181ad6265SDimitry Andric   case CSKY::TSTNBZ32:
45281ad6265SDimitry Andric   case CSKY::TSTNBZ16:
45381ad6265SDimitry Andric   case CSKY::TST32:
45481ad6265SDimitry Andric   case CSKY::TST16:
45581ad6265SDimitry Andric     MI.insert(MI.begin(), MCOperand::createReg(CSKY::C));
45681ad6265SDimitry Andric     return MCDisassembler::Success;
45781ad6265SDimitry Andric   case CSKY::LSLC32:
45881ad6265SDimitry Andric   case CSKY::LSRC32:
45981ad6265SDimitry Andric   case CSKY::ASRC32:
46081ad6265SDimitry Andric     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
46181ad6265SDimitry Andric     return MCDisassembler::Success;
46281ad6265SDimitry Andric   case CSKY::MOVF32:
46381ad6265SDimitry Andric   case CSKY::MOVT32:
46481ad6265SDimitry Andric   case CSKY::MVC32:
46581ad6265SDimitry Andric   case CSKY::MVCV32:
46681ad6265SDimitry Andric   case CSKY::MVCV16:
46781ad6265SDimitry Andric   case CSKY::INCT32:
46881ad6265SDimitry Andric   case CSKY::INCF32:
46981ad6265SDimitry Andric   case CSKY::DECT32:
47081ad6265SDimitry Andric   case CSKY::DECF32:
47181ad6265SDimitry Andric   case CSKY::DECGT32:
47281ad6265SDimitry Andric   case CSKY::DECLT32:
47381ad6265SDimitry Andric   case CSKY::DECNE32:
47481ad6265SDimitry Andric   case CSKY::CLRF32:
47581ad6265SDimitry Andric   case CSKY::CLRT32:
47681ad6265SDimitry Andric   case CSKY::f2FSEL_S:
47781ad6265SDimitry Andric   case CSKY::f2FSEL_D:
47881ad6265SDimitry Andric     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
47981ad6265SDimitry Andric     return MCDisassembler::Success;
48081ad6265SDimitry Andric   case CSKY::ADDC32:
48181ad6265SDimitry Andric   case CSKY::ADDC16:
48281ad6265SDimitry Andric   case CSKY::SUBC32:
48381ad6265SDimitry Andric   case CSKY::SUBC16:
48481ad6265SDimitry Andric   case CSKY::XSR32:
48581ad6265SDimitry Andric     MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
48681ad6265SDimitry Andric     MI.insert(MI.end(), MCOperand::createReg(CSKY::C));
48781ad6265SDimitry Andric     return MCDisassembler::Success;
48881ad6265SDimitry Andric   case CSKY::INS32:
48981ad6265SDimitry Andric     MI.getOperand(3).setImm(MI.getOperand(3).getImm() +
49081ad6265SDimitry Andric                             MI.getOperand(4).getImm());
49181ad6265SDimitry Andric     return MCDisassembler::Success;
49281ad6265SDimitry Andric   }
49381ad6265SDimitry Andric }
49481ad6265SDimitry Andric 
decodeFPUV3Instruction(MCInst & MI,uint32_t insn,uint64_t Address,const MCDisassembler * DisAsm,const MCSubtargetInfo & STI)49581ad6265SDimitry Andric static bool decodeFPUV3Instruction(MCInst &MI, uint32_t insn, uint64_t Address,
49681ad6265SDimitry Andric                                    const MCDisassembler *DisAsm,
49781ad6265SDimitry Andric                                    const MCSubtargetInfo &STI) {
49881ad6265SDimitry Andric   LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit fpuv3 table :\n");
499*06c3fb27SDimitry Andric   if (!STI.hasFeature(CSKY::FeatureFPUV3_HF) &&
500*06c3fb27SDimitry Andric       !STI.hasFeature(CSKY::FeatureFPUV3_SF) &&
501*06c3fb27SDimitry Andric       !STI.hasFeature(CSKY::FeatureFPUV3_DF))
50281ad6265SDimitry Andric     return false;
50381ad6265SDimitry Andric 
50481ad6265SDimitry Andric   DecodeStatus Result =
50581ad6265SDimitry Andric       decodeInstruction(DecoderTableFPUV332, MI, insn, Address, DisAsm, STI);
50681ad6265SDimitry Andric 
50781ad6265SDimitry Andric   if (Result == MCDisassembler::Fail) {
50881ad6265SDimitry Andric     MI.clear();
50981ad6265SDimitry Andric     return false;
51081ad6265SDimitry Andric   }
51181ad6265SDimitry Andric 
51281ad6265SDimitry Andric   return true;
51381ad6265SDimitry Andric }
51481ad6265SDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const51581ad6265SDimitry Andric DecodeStatus CSKYDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
51681ad6265SDimitry Andric                                               ArrayRef<uint8_t> Bytes,
51781ad6265SDimitry Andric                                               uint64_t Address,
51881ad6265SDimitry Andric                                               raw_ostream &CS) const {
51981ad6265SDimitry Andric 
52081ad6265SDimitry Andric   uint32_t Insn;
52181ad6265SDimitry Andric   DecodeStatus Result = MCDisassembler::Fail;
52281ad6265SDimitry Andric 
52381ad6265SDimitry Andric   Insn = support::endian::read16le(Bytes.data());
52481ad6265SDimitry Andric 
52581ad6265SDimitry Andric   if ((Insn >> 14) == 0x3) {
52681ad6265SDimitry Andric     if (Bytes.size() < 4) {
52781ad6265SDimitry Andric       Size = 0;
52881ad6265SDimitry Andric       return MCDisassembler::Fail;
52981ad6265SDimitry Andric     }
53081ad6265SDimitry Andric     Insn = (Insn << 16) | support::endian::read16le(&Bytes[2]);
53181ad6265SDimitry Andric 
53281ad6265SDimitry Andric     if (decodeFPUV3Instruction(MI, Insn, Address, this, STI))
53381ad6265SDimitry Andric       Result = MCDisassembler::Success;
53481ad6265SDimitry Andric     else {
53581ad6265SDimitry Andric       LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit table :\n");
53681ad6265SDimitry Andric       Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
53781ad6265SDimitry Andric     }
53881ad6265SDimitry Andric 
53981ad6265SDimitry Andric     Size = 4;
54081ad6265SDimitry Andric   } else {
54181ad6265SDimitry Andric     if (Bytes.size() < 2) {
54281ad6265SDimitry Andric       Size = 0;
54381ad6265SDimitry Andric       return MCDisassembler::Fail;
54481ad6265SDimitry Andric     }
54581ad6265SDimitry Andric     LLVM_DEBUG(dbgs() << "Trying CSKY 16-bit table :\n");
54681ad6265SDimitry Andric     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
54781ad6265SDimitry Andric     Size = 2;
54881ad6265SDimitry Andric   }
54981ad6265SDimitry Andric 
55081ad6265SDimitry Andric   handleCROperand(MI);
55181ad6265SDimitry Andric 
55281ad6265SDimitry Andric   return Result;
55381ad6265SDimitry Andric }
554