//===-- CSKYDisassembler.cpp - Disassembler for CSKY ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the CSKYDisassembler class.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/CSKYBaseInfo.h"
#include "MCTargetDesc/CSKYMCTargetDesc.h"
#include "TargetInfo/CSKYTargetInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDecoderOps.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Endian.h"

using namespace llvm;

#define DEBUG_TYPE "csky-disassembler"

typedef MCDisassembler::DecodeStatus DecodeStatus;

namespace {
class CSKYDisassembler : public MCDisassembler {
  std::unique_ptr<MCInstrInfo const> const MCII;
  mutable StringRef symbolName;

  DecodeStatus handleCROperand(MCInst &Instr) const;

public:
  CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
                   MCInstrInfo const *MCII);

  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
                              ArrayRef<uint8_t> Bytes, uint64_t Address,
                              raw_ostream &CStream) const override;
};
} // end anonymous namespace

CSKYDisassembler::CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
                                   MCInstrInfo const *MCII)
    : MCDisassembler(STI, Ctx), MCII(MCII) {}

static MCDisassembler *createCSKYDisassembler(const Target &T,
                                              const MCSubtargetInfo &STI,
                                              MCContext &Ctx) {
  return new CSKYDisassembler(STI, Ctx, T.createMCInstrInfo());
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYDisassembler() {
  TargetRegistry::RegisterMCDisassembler(getTheCSKYTarget(),
                                         createCSKYDisassembler);
}

static const uint16_t GPRDecoderTable[] = {
    CSKY::R0,  CSKY::R1,  CSKY::R2,  CSKY::R3,  CSKY::R4,  CSKY::R5,  CSKY::R6,
    CSKY::R7,  CSKY::R8,  CSKY::R9,  CSKY::R10, CSKY::R11, CSKY::R12, CSKY::R13,
    CSKY::R14, CSKY::R15, CSKY::R16, CSKY::R17, CSKY::R18, CSKY::R19, CSKY::R20,
    CSKY::R21, CSKY::R22, CSKY::R23, CSKY::R24, CSKY::R25, CSKY::R26, CSKY::R27,
    CSKY::R28, CSKY::R29, CSKY::R30, CSKY::R31};

static const uint16_t GPRPairDecoderTable[] = {
    CSKY::R0_R1,   CSKY::R1_R2,   CSKY::R2_R3,   CSKY::R3_R4,   CSKY::R4_R5,
    CSKY::R5_R6,   CSKY::R6_R7,   CSKY::R7_R8,   CSKY::R8_R9,   CSKY::R9_R10,
    CSKY::R10_R11, CSKY::R11_R12, CSKY::R12_R13, CSKY::R13_R14, CSKY::R14_R15,
    CSKY::R15_R16, CSKY::R16_R17, CSKY::R17_R18, CSKY::R18_R19, CSKY::R19_R20,
    CSKY::R20_R21, CSKY::R21_R22, CSKY::R22_R23, CSKY::R23_R24, CSKY::R24_R25,
    CSKY::R25_R26, CSKY::R26_R27, CSKY::R27_R28, CSKY::R28_R29, CSKY::R29_R30,
    CSKY::R30_R31, CSKY::R31_R32};

static const uint16_t FPR32DecoderTable[] = {
    CSKY::F0_32,  CSKY::F1_32,  CSKY::F2_32,  CSKY::F3_32,  CSKY::F4_32,
    CSKY::F5_32,  CSKY::F6_32,  CSKY::F7_32,  CSKY::F8_32,  CSKY::F9_32,
    CSKY::F10_32, CSKY::F11_32, CSKY::F12_32, CSKY::F13_32, CSKY::F14_32,
    CSKY::F15_32, CSKY::F16_32, CSKY::F17_32, CSKY::F18_32, CSKY::F19_32,
    CSKY::F20_32, CSKY::F21_32, CSKY::F22_32, CSKY::F23_32, CSKY::F24_32,
    CSKY::F25_32, CSKY::F26_32, CSKY::F27_32, CSKY::F28_32, CSKY::F29_32,
    CSKY::F30_32, CSKY::F31_32};

static const uint16_t FPR64DecoderTable[] = {
    CSKY::F0_64,  CSKY::F1_64,  CSKY::F2_64,  CSKY::F3_64,  CSKY::F4_64,
    CSKY::F5_64,  CSKY::F6_64,  CSKY::F7_64,  CSKY::F8_64,  CSKY::F9_64,
    CSKY::F10_64, CSKY::F11_64, CSKY::F12_64, CSKY::F13_64, CSKY::F14_64,
    CSKY::F15_64, CSKY::F16_64, CSKY::F17_64, CSKY::F18_64, CSKY::F19_64,
    CSKY::F20_64, CSKY::F21_64, CSKY::F22_64, CSKY::F23_64, CSKY::F24_64,
    CSKY::F25_64, CSKY::F26_64, CSKY::F27_64, CSKY::F28_64, CSKY::F29_64,
    CSKY::F30_64, CSKY::F31_64};

static const uint16_t FPR128DecoderTable[] = {
    CSKY::F0_128,  CSKY::F1_128,  CSKY::F2_128,  CSKY::F3_128,  CSKY::F4_128,
    CSKY::F5_128,  CSKY::F6_128,  CSKY::F7_128,  CSKY::F8_128,  CSKY::F9_128,
    CSKY::F10_128, CSKY::F11_128, CSKY::F12_128, CSKY::F13_128, CSKY::F14_128,
    CSKY::F15_128, CSKY::F16_128, CSKY::F17_128, CSKY::F18_128, CSKY::F19_128,
    CSKY::F20_128, CSKY::F21_128, CSKY::F22_128, CSKY::F23_128, CSKY::F24_128,
    CSKY::F25_128, CSKY::F26_128, CSKY::F27_128, CSKY::F28_128, CSKY::F29_128,
    CSKY::F30_128, CSKY::F31_128};

static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
  if (RegNo >= 32)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  if (RegNo >= 32)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));
  return MCDisassembler::Success;
}

static DecodeStatus DecodesFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder) {
  if (RegNo >= 16)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));
  return MCDisassembler::Success;
}

static DecodeStatus DecodesFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder) {
  if (RegNo >= 16)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
  return MCDisassembler::Success;
}

static DecodeStatus DecodesFPR64_VRegisterClass(MCInst &Inst, uint64_t RegNo,
                                                uint64_t Address,
                                                const MCDisassembler *Decoder) {
  if (RegNo >= 16)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  if (RegNo >= 32)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));
  return MCDisassembler::Success;
}

// TODO
LLVM_ATTRIBUTE_UNUSED
static DecodeStatus DecodesFPR128RegisterClass(MCInst &Inst, uint64_t RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  if (RegNo >= 16)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR128DecoderTable[RegNo]));
  return MCDisassembler::Success;
}

static DecodeStatus DecodesGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
  if (RegNo >= 16)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
  return MCDisassembler::Success;
}

static DecodeStatus DecodemGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder) {
  if (RegNo >= 8)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
  return MCDisassembler::Success;
}

// TODO
LLVM_ATTRIBUTE_UNUSED
static DecodeStatus DecodeGPRSPRegisterClass(MCInst &Inst, uint64_t RegNo,
                                             uint64_t Address,
                                             const MCDisassembler *Decoder) {
  if (RegNo != 14)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));
  return MCDisassembler::Success;
}

static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint64_t RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder) {
  const FeatureBitset &FeatureBits =
      Decoder->getSubtargetInfo().getFeatureBits();
  bool hasHighReg = FeatureBits[CSKY::FeatureHighreg];

  if (RegNo >= 32 || (!hasHighReg && RegNo >= 16))
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(GPRPairDecoderTable[RegNo]));
  return MCDisassembler::Success;
}

template <unsigned N, unsigned S>
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
                                      int64_t Address,
                                      const MCDisassembler *Decoder) {
  assert(isUInt<N>(Imm) && "Invalid immediate");
  Inst.addOperand(MCOperand::createImm(Imm << S));
  return MCDisassembler::Success;
}

template <unsigned N>
static DecodeStatus decodeOImmOperand(MCInst &Inst, uint64_t Imm,
                                      int64_t Address,
                                      const MCDisassembler *Decoder) {
  assert(isUInt<N>(Imm) && "Invalid immediate");
  Inst.addOperand(MCOperand::createImm(Imm + 1));
  return MCDisassembler::Success;
}

static DecodeStatus decodeLRW16Imm8(MCInst &Inst, uint64_t Imm, int64_t Address,
                                    const MCDisassembler *Decoder) {
  assert(isUInt<8>(Imm) && "Invalid immediate");
  if ((Imm >> 7) & 0x1) {
    Inst.addOperand(MCOperand::createImm((Imm & 0x7F) << 2));
  } else {
    uint64_t V = ((Imm ^ 0xFFFFFFFF) & 0xFF);
    Inst.addOperand(MCOperand::createImm(V << 2));
  }

  return MCDisassembler::Success;
}

static DecodeStatus decodeJMPIXImmOperand(MCInst &Inst, uint64_t Imm,
                                          int64_t Address,
                                          const MCDisassembler *Decoder) {
  assert(isUInt<2>(Imm) && "Invalid immediate");

  if (Imm == 0)
    Inst.addOperand(MCOperand::createImm(16));
  else if (Imm == 1)
    Inst.addOperand(MCOperand::createImm(24));
  else if (Imm == 2)
    Inst.addOperand(MCOperand::createImm(32));
  else if (Imm == 3)
    Inst.addOperand(MCOperand::createImm(40));
  else
    return MCDisassembler::Fail;

  return MCDisassembler::Success;
}

static DecodeStatus DecodeRegSeqOperand(MCInst &Inst, uint64_t Imm,
                                        int64_t Address,
                                        const MCDisassembler *Decoder) {
  assert(isUInt<10>(Imm) && "Invalid immediate");

  auto Imm5 = Imm & 0x1f;
  auto Ry = (Imm >> 5) & 0x1f;

  if (DecodeGPRRegisterClass(Inst, Ry, Address, Decoder) ==
      MCDisassembler::Fail)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Ry + Imm5]));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeRegSeqOperandF1(MCInst &Inst, uint64_t Imm,
                                          int64_t Address,
                                          const MCDisassembler *Decoder) {
  assert(isUInt<10>(Imm) && "Invalid immediate");

  auto Imm5 = Imm & 0x1f;
  auto Ry = (Imm >> 5) & 0x1f;

  if (DecodesFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
      MCDisassembler::Fail)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeRegSeqOperandD1(MCInst &Inst, uint64_t Imm,
                                          int64_t Address,
                                          const MCDisassembler *Decoder) {
  assert(isUInt<10>(Imm) && "Invalid immediate");

  auto Imm5 = Imm & 0x1f;
  auto Ry = (Imm >> 5) & 0x1f;

  if (DecodesFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
      MCDisassembler::Fail)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeRegSeqOperandF2(MCInst &Inst, uint64_t Imm,
                                          int64_t Address,
                                          const MCDisassembler *Decoder) {
  assert(isUInt<10>(Imm) && "Invalid immediate");

  auto Imm5 = Imm & 0x1f;
  auto Ry = (Imm >> 5) & 0x1f;

  if (DecodeFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
      MCDisassembler::Fail)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));

  return MCDisassembler::Success;
}

static DecodeStatus DecodeRegSeqOperandD2(MCInst &Inst, uint64_t Imm,
                                          int64_t Address,
                                          const MCDisassembler *Decoder) {
  assert(isUInt<10>(Imm) && "Invalid immediate");

  auto Imm5 = Imm & 0x1f;
  auto Ry = (Imm >> 5) & 0x1f;

  if (DecodeFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
      MCDisassembler::Fail)
    return MCDisassembler::Fail;

  Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));

  return MCDisassembler::Success;
}

static DecodeStatus decodeImmShiftOpValue(MCInst &Inst, uint64_t Imm,
                                          int64_t Address,
                                          const MCDisassembler *Decoder) {
  Inst.addOperand(MCOperand::createImm(Log2_64(Imm)));
  return MCDisassembler::Success;
}

template <unsigned N, unsigned S>
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
                                      int64_t Address,
                                      const MCDisassembler *Decoder) {
  assert(isUInt<N>(Imm) && "Invalid immediate");
  // Sign-extend the number in the bottom N bits of Imm
  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) << S));
  return MCDisassembler::Success;
}

#include "CSKYGenDisassemblerTables.inc"

DecodeStatus CSKYDisassembler::handleCROperand(MCInst &MI) const {

  // FIXME: To query instruction info from td file or a table inc file
  switch (MI.getOpcode()) {
  default:
    return MCDisassembler::Success;
  case CSKY::LD16WSP:
  case CSKY::ST16WSP:
  case CSKY::ADDI16ZSP:
    MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::R14));
    return MCDisassembler::Success;
  case CSKY::ADDI16SPSP:
  case CSKY::SUBI16SPSP:
    MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));
    MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));
    return MCDisassembler::Success;
  case CSKY::FCMPHS_S:
  case CSKY::FCMPHS_D:
  case CSKY::FCMPLT_S:
  case CSKY::FCMPLT_D:
  case CSKY::FCMPNE_S:
  case CSKY::FCMPNE_D:
  case CSKY::FCMPUO_S:
  case CSKY::FCMPUO_D:
  case CSKY::FCMPZHS_S:
  case CSKY::FCMPZHS_D:
  case CSKY::FCMPZLS_S:
  case CSKY::FCMPZLS_D:
  case CSKY::FCMPZNE_S:
  case CSKY::FCMPZNE_D:
  case CSKY::FCMPZUO_S:
  case CSKY::FCMPZUO_D:
  case CSKY::f2FCMPHS_S:
  case CSKY::f2FCMPHS_D:
  case CSKY::f2FCMPLT_S:
  case CSKY::f2FCMPLT_D:
  case CSKY::f2FCMPNE_S:
  case CSKY::f2FCMPNE_D:
  case CSKY::f2FCMPUO_S:
  case CSKY::f2FCMPUO_D:
  case CSKY::f2FCMPHSZ_S:
  case CSKY::f2FCMPHSZ_D:
  case CSKY::f2FCMPHZ_S:
  case CSKY::f2FCMPHZ_D:
  case CSKY::f2FCMPLSZ_S:
  case CSKY::f2FCMPLSZ_D:
  case CSKY::f2FCMPLTZ_S:
  case CSKY::f2FCMPLTZ_D:
  case CSKY::f2FCMPNEZ_S:
  case CSKY::f2FCMPNEZ_D:
  case CSKY::f2FCMPUOZ_S:
  case CSKY::f2FCMPUOZ_D:

  case CSKY::BT32:
  case CSKY::BF32:
  case CSKY::BT16:
  case CSKY::BF16:
  case CSKY::CMPNEI32:
  case CSKY::CMPNEI16:
  case CSKY::CMPNE32:
  case CSKY::CMPNE16:
  case CSKY::CMPHSI32:
  case CSKY::CMPHSI16:
  case CSKY::CMPHS32:
  case CSKY::CMPHS16:
  case CSKY::CMPLTI32:
  case CSKY::CMPLTI16:
  case CSKY::CMPLT32:
  case CSKY::CMPLT16:
  case CSKY::BTSTI32:
  case CSKY::BTSTI16:
  case CSKY::TSTNBZ32:
  case CSKY::TSTNBZ16:
  case CSKY::TST32:
  case CSKY::TST16:
    MI.insert(MI.begin(), MCOperand::createReg(CSKY::C));
    return MCDisassembler::Success;
  case CSKY::LSLC32:
  case CSKY::LSRC32:
  case CSKY::ASRC32:
    MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
    return MCDisassembler::Success;
  case CSKY::MOVF32:
  case CSKY::MOVT32:
  case CSKY::MVC32:
  case CSKY::MVCV32:
  case CSKY::MVCV16:
  case CSKY::INCT32:
  case CSKY::INCF32:
  case CSKY::DECT32:
  case CSKY::DECF32:
  case CSKY::DECGT32:
  case CSKY::DECLT32:
  case CSKY::DECNE32:
  case CSKY::CLRF32:
  case CSKY::CLRT32:
  case CSKY::f2FSEL_S:
  case CSKY::f2FSEL_D:
    MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
    return MCDisassembler::Success;
  case CSKY::ADDC32:
  case CSKY::ADDC16:
  case CSKY::SUBC32:
  case CSKY::SUBC16:
  case CSKY::XSR32:
    MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));
    MI.insert(MI.end(), MCOperand::createReg(CSKY::C));
    return MCDisassembler::Success;
  case CSKY::INS32:
    MI.getOperand(3).setImm(MI.getOperand(3).getImm() +
                            MI.getOperand(4).getImm());
    return MCDisassembler::Success;
  }
}

static bool decodeFPUV3Instruction(MCInst &MI, uint32_t insn, uint64_t Address,
                                   const MCDisassembler *DisAsm,
                                   const MCSubtargetInfo &STI) {
  LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit fpuv3 table :\n");
  if (!STI.getFeatureBits()[CSKY::FeatureFPUV3_HF] &&
      !STI.getFeatureBits()[CSKY::FeatureFPUV3_SF] &&
      !STI.getFeatureBits()[CSKY::FeatureFPUV3_DF])
    return false;

  DecodeStatus Result =
      decodeInstruction(DecoderTableFPUV332, MI, insn, Address, DisAsm, STI);

  if (Result == MCDisassembler::Fail) {
    MI.clear();
    return false;
  }

  return true;
}

DecodeStatus CSKYDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
                                              ArrayRef<uint8_t> Bytes,
                                              uint64_t Address,
                                              raw_ostream &CS) const {

  uint32_t Insn;
  DecodeStatus Result = MCDisassembler::Fail;

  Insn = support::endian::read16le(Bytes.data());

  if ((Insn >> 14) == 0x3) {
    if (Bytes.size() < 4) {
      Size = 0;
      return MCDisassembler::Fail;
    }
    Insn = (Insn << 16) | support::endian::read16le(&Bytes[2]);

    if (decodeFPUV3Instruction(MI, Insn, Address, this, STI))
      Result = MCDisassembler::Success;
    else {
      LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit table :\n");
      Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
    }

    Size = 4;
  } else {
    if (Bytes.size() < 2) {
      Size = 0;
      return MCDisassembler::Fail;
    }
    LLVM_DEBUG(dbgs() << "Trying CSKY 16-bit table :\n");
    Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
    Size = 2;
  }

  handleCROperand(MI);

  return Result;
}
