//===-- CSKYAsmBackend.cpp - CSKY Assembler Backend -----------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "CSKYAsmBackend.h"
#include "MCTargetDesc/CSKYMCTargetDesc.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/Support/Debug.h"

#define DEBUG_TYPE "csky-asmbackend"

using namespace llvm;

std::unique_ptr<MCObjectTargetWriter>
CSKYAsmBackend::createObjectTargetWriter() const {
  return createCSKYELFObjectWriter();
}

const MCFixupKindInfo &
CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {

  static llvm::DenseMap<unsigned, MCFixupKindInfo> Infos = {
      {CSKY::Fixups::fixup_csky_addr32, {"fixup_csky_addr32", 0, 32, 0}},
      {CSKY::Fixups::fixup_csky_addr_hi16, {"fixup_csky_addr_hi16", 0, 32, 0}},
      {CSKY::Fixups::fixup_csky_addr_lo16, {"fixup_csky_addr_lo16", 0, 32, 0}},
      {CSKY::Fixups::fixup_csky_pcrel_imm16_scale2,
       {"fixup_csky_pcrel_imm16_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
      {CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4,
       {"fixup_csky_pcrel_uimm16_scale4", 0, 32,
        MCFixupKindInfo::FKF_IsPCRel |
            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
      {CSKY::Fixups::fixup_csky_pcrel_uimm8_scale4,
       {"fixup_csky_pcrel_uimm8_scale4", 0, 32,
        MCFixupKindInfo::FKF_IsPCRel |
            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
      {CSKY::Fixups::fixup_csky_pcrel_imm26_scale2,
       {"fixup_csky_pcrel_imm26_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
      {CSKY::Fixups::fixup_csky_pcrel_imm18_scale2,
       {"fixup_csky_pcrel_imm18_scale2", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
      {CSKY::Fixups::fixup_csky_got32, {"fixup_csky_got32", 0, 32, 0}},
      {CSKY::Fixups::fixup_csky_got_imm18_scale4,
       {"fixup_csky_got_imm18_scale4", 0, 32, 0}},
      {CSKY::Fixups::fixup_csky_gotoff, {"fixup_csky_gotoff", 0, 32, 0}},
      {CSKY::Fixups::fixup_csky_gotpc,
       {"fixup_csky_gotpc", 0, 32, MCFixupKindInfo::FKF_IsPCRel}},
      {CSKY::Fixups::fixup_csky_plt32, {"fixup_csky_plt32", 0, 32, 0}},
      {CSKY::Fixups::fixup_csky_plt_imm18_scale4,
       {"fixup_csky_plt_imm18_scale4", 0, 32, 0}},
      {CSKY::Fixups::fixup_csky_pcrel_imm10_scale2,
       {"fixup_csky_pcrel_imm10_scale2", 0, 16, MCFixupKindInfo::FKF_IsPCRel}},
      {CSKY::Fixups::fixup_csky_pcrel_uimm7_scale4,
       {"fixup_csky_pcrel_uimm7_scale4", 0, 16,
        MCFixupKindInfo::FKF_IsPCRel |
            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}},
      {CSKY::Fixups::fixup_csky_doffset_imm18,
       {"fixup_csky_doffset_imm18", 0, 18, 0}},
      {CSKY::Fixups::fixup_csky_doffset_imm18_scale2,
       {"fixup_csky_doffset_imm18_scale2", 0, 18, 0}},
      {CSKY::Fixups::fixup_csky_doffset_imm18_scale4,
       {"fixup_csky_doffset_imm18_scale4", 0, 18, 0}}};

  assert(Infos.size() == CSKY::NumTargetFixupKinds &&
         "Not all fixup kinds added to Infos array");

  if (FirstTargetFixupKind <= Kind && Kind < FirstLiteralRelocationKind) {
    assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
           "Invalid kind!");

    return Infos[Kind];
  } else if (Kind < FirstTargetFixupKind) {
    return MCAsmBackend::getFixupKindInfo(Kind);
  } else {
    return MCAsmBackend::getFixupKindInfo(FK_NONE);
  }
}

static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
                                 MCContext &Ctx) {
  switch (Fixup.getTargetKind()) {
  default:
    llvm_unreachable("Unknown fixup kind!");
  case CSKY::fixup_csky_got32:
  case CSKY::fixup_csky_got_imm18_scale4:
  case CSKY::fixup_csky_gotoff:
  case CSKY::fixup_csky_gotpc:
  case CSKY::fixup_csky_plt32:
  case CSKY::fixup_csky_plt_imm18_scale4:
    llvm_unreachable("Relocation should be unconditionally forced\n");
  case FK_Data_1:
  case FK_Data_2:
  case FK_Data_4:
  case FK_Data_8:
    return Value;
  case CSKY::fixup_csky_addr32:
    return Value & 0xffffffff;
  case CSKY::fixup_csky_pcrel_imm16_scale2:
    if (!isIntN(17, Value))
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
    if (Value & 0x1)
      Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");

    return (Value >> 1) & 0xffff;
  case CSKY::fixup_csky_pcrel_uimm16_scale4:
    if (!isUIntN(18, Value))
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
    if (Value & 0x3)
      Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");

    return (Value >> 2) & 0xffff;
  case CSKY::fixup_csky_pcrel_imm26_scale2:
    if (!isIntN(27, Value))
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
    if (Value & 0x1)
      Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");

    return (Value >> 1) & 0x3ffffff;
  case CSKY::fixup_csky_pcrel_imm18_scale2:
    if (!isIntN(19, Value))
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
    if (Value & 0x1)
      Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");

    return (Value >> 1) & 0x3ffff;
  case CSKY::fixup_csky_pcrel_uimm8_scale4: {
    if (!isUIntN(10, Value))
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
    if (Value & 0x3)
      Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");

    unsigned IMM4L = (Value >> 2) & 0xf;
    unsigned IMM4H = (Value >> 6) & 0xf;

    Value = (IMM4H << 21) | (IMM4L << 4);
    return Value;
  }
  case CSKY::fixup_csky_pcrel_imm10_scale2:
    if (!isIntN(11, Value))
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
    if (Value & 0x1)
      Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned.");

    return (Value >> 1) & 0x3ff;
  case CSKY::fixup_csky_pcrel_uimm7_scale4:
    if ((Value >> 2) > 0xfe)
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
    if (Value & 0x3)
      Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");

    if ((Value >> 2) <= 0x7f) {
      unsigned IMM5L = (Value >> 2) & 0x1f;
      unsigned IMM2H = (Value >> 7) & 0x3;

      Value = (1 << 12) | (IMM2H << 8) | IMM5L;
    } else {
      unsigned IMM5L = (~Value >> 2) & 0x1f;
      unsigned IMM2H = (~Value >> 7) & 0x3;

      Value = (IMM2H << 8) | IMM5L;
    }

    return Value;
  }
}

bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
                                                  bool Resolved, uint64_t Value,
                                                  const MCRelaxableFragment *DF,
                                                  const MCAsmLayout &Layout,
                                                  const bool WasForced) const {
  // Return true if the symbol is actually unresolved.
  // Resolved could be always false when shouldForceRelocation return true.
  // We use !WasForced to indicate that the symbol is unresolved and not forced
  // by shouldForceRelocation.
  if (!Resolved && !WasForced)
    return true;

  int64_t Offset = int64_t(Value);
  switch (Fixup.getTargetKind()) {
  default:
    return false;
  case CSKY::fixup_csky_pcrel_imm10_scale2:
    return !isShiftedInt<10, 1>(Offset);
  case CSKY::fixup_csky_pcrel_imm16_scale2:
    return !isShiftedInt<16, 1>(Offset);
  case CSKY::fixup_csky_pcrel_imm26_scale2:
    return !isShiftedInt<26, 1>(Offset);
  case CSKY::fixup_csky_pcrel_uimm7_scale4:
    return ((Value >> 2) > 0xfe) || (Value & 0x3);
  }
}

void CSKYAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                const MCValue &Target,
                                MutableArrayRef<char> Data, uint64_t Value,
                                bool IsResolved,
                                const MCSubtargetInfo *STI) const {
  MCFixupKind Kind = Fixup.getKind();
  if (Kind >= FirstLiteralRelocationKind)
    return;
  MCContext &Ctx = Asm.getContext();
  MCFixupKindInfo Info = getFixupKindInfo(Kind);
  if (!Value)
    return; // Doesn't change encoding.
  // Apply any target-specific value adjustments.
  Value = adjustFixupValue(Fixup, Value, Ctx);

  // Shift the value into position.
  Value <<= Info.TargetOffset;

  unsigned Offset = Fixup.getOffset();
  unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8;

  assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");

  // For each byte of the fragment that the fixup touches, mask in the
  // bits from the fixup value.
  bool IsLittleEndian = (Endian == support::little);
  bool IsInstFixup = (Kind >= FirstTargetFixupKind);

  if (IsLittleEndian && IsInstFixup && (NumBytes == 4)) {
    Data[Offset + 0] |= uint8_t((Value >> 16) & 0xff);
    Data[Offset + 1] |= uint8_t((Value >> 24) & 0xff);
    Data[Offset + 2] |= uint8_t(Value & 0xff);
    Data[Offset + 3] |= uint8_t((Value >> 8) & 0xff);
  } else {
    for (unsigned I = 0; I != NumBytes; I++) {
      unsigned Idx = IsLittleEndian ? I : (NumBytes - 1 - I);
      Data[Offset + Idx] |= uint8_t((Value >> (I * 8)) & 0xff);
    }
  }
}

bool CSKYAsmBackend::mayNeedRelaxation(const MCInst &Inst,
                                       const MCSubtargetInfo &STI) const {
  switch (Inst.getOpcode()) {
  default:
    return false;
  case CSKY::JBR32:
  case CSKY::JBT32:
  case CSKY::JBF32:
  case CSKY::JBSR32:
    if (!STI.getFeatureBits()[CSKY::Has2E3])
      return false;
    return true;
  case CSKY::JBR16:
  case CSKY::JBT16:
  case CSKY::JBF16:
  case CSKY::LRW16:
  case CSKY::BR16:
    return true;
  }
}

bool CSKYAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
                                           const MCFixup &Fixup,
                                           const MCValue &Target) {
  if (Fixup.getKind() >= FirstLiteralRelocationKind)
    return true;
  switch (Fixup.getTargetKind()) {
  default:
    break;
  case CSKY::fixup_csky_got32:
  case CSKY::fixup_csky_got_imm18_scale4:
  case CSKY::fixup_csky_gotoff:
  case CSKY::fixup_csky_gotpc:
  case CSKY::fixup_csky_plt32:
  case CSKY::fixup_csky_plt_imm18_scale4:
  case CSKY::fixup_csky_doffset_imm18:
  case CSKY::fixup_csky_doffset_imm18_scale2:
  case CSKY::fixup_csky_doffset_imm18_scale4:
    return true;
  }

  return false;
}

bool CSKYAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
                                          const MCRelaxableFragment *DF,
                                          const MCAsmLayout &Layout) const {
  return false;
}

void CSKYAsmBackend::relaxInstruction(MCInst &Inst,
                                      const MCSubtargetInfo &STI) const {
  MCInst Res;

  switch (Inst.getOpcode()) {
  default:
    LLVM_DEBUG(Inst.dump());
    llvm_unreachable("Opcode not expected!");
  case CSKY::LRW16:
    Res.setOpcode(CSKY::LRW32);
    Res.addOperand(Inst.getOperand(0));
    Res.addOperand(Inst.getOperand(1));
    break;
  case CSKY::BR16:
    Res.setOpcode(CSKY::BR32);
    Res.addOperand(Inst.getOperand(0));
    break;
  case CSKY::JBSR32:
    Res.setOpcode(CSKY::JSRI32);
    Res.addOperand(Inst.getOperand(1));
    break;
  case CSKY::JBR32:
    Res.setOpcode(CSKY::JMPI32);
    Res.addOperand(Inst.getOperand(1));
    break;
  case CSKY::JBT32:
  case CSKY::JBF32:
    Res.setOpcode(Inst.getOpcode() == CSKY::JBT32 ? CSKY::JBT_E : CSKY::JBF_E);
    Res.addOperand(Inst.getOperand(0));
    Res.addOperand(Inst.getOperand(1));
    Res.addOperand(Inst.getOperand(2));
    break;
  case CSKY::JBR16:
    Res.setOpcode(CSKY::JBR32);
    Res.addOperand(Inst.getOperand(0));
    Res.addOperand(Inst.getOperand(1));
    break;
  case CSKY::JBT16:
  case CSKY::JBF16:
    // ck801
    unsigned opcode;
    if (STI.getFeatureBits()[CSKY::HasE2])
      opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT32 : CSKY::JBF32;
    else
      opcode = Inst.getOpcode() == CSKY::JBT16 ? CSKY::JBT_E : CSKY::JBF_E;

    Res.setOpcode(opcode);
    Res.addOperand(Inst.getOperand(0));
    Res.addOperand(Inst.getOperand(1));
    Res.addOperand(Inst.getOperand(2));
    break;
  }
  Inst = std::move(Res);
}

bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
                                  const MCSubtargetInfo *STI) const {
  OS.write_zeros(Count);
  return true;
}

MCAsmBackend *llvm::createCSKYAsmBackend(const Target &T,
                                         const MCSubtargetInfo &STI,
                                         const MCRegisterInfo &MRI,
                                         const MCTargetOptions &Options) {
  return new CSKYAsmBackend(STI, Options);
}
