//===-- 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/MCDecoder.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;
using namespace llvm::MCD;

#define DEBUG_TYPE "csky-disassembler"

typedef MCDisassembler::DecodeStatus DecodeStatus;

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

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;
}

static DecodeStatus DecodeGPRSPRegisterClass(MCInst &Inst,
                                             const MCDisassembler *Decoder) {
  Inst.addOperand(MCOperand::createReg(CSKY::R14));
  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;
}

static DecodeStatus DecodeCARRYRegisterClass(MCInst &Inst,
                                             const MCDisassembler *Decoder) {
  Inst.addOperand(MCOperand::createReg(CSKY::C));
  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"

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.hasFeature(CSKY::FeatureFPUV3_HF) &&
      !STI.hasFeature(CSKY::FeatureFPUV3_SF) &&
      !STI.hasFeature(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;
  }

  if (MI.getOpcode() == CSKY::INS32) {
    MI.getOperand(3).setImm(MI.getOperand(3).getImm() +
                            MI.getOperand(4).getImm());
  }

  return Result;
}
