//===-- VEAsmBackend.cpp - VE 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 "MCTargetDesc/VEFixupKinds.h"
#include "MCTargetDesc/VEMCTargetDesc.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/EndianStream.h"

using namespace llvm;

static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
  switch (Kind) {
  default:
    llvm_unreachable("Unknown fixup kind!");
  case FK_Data_1:
  case FK_Data_2:
  case FK_Data_4:
  case FK_Data_8:
    return Value;
  case VE::fixup_ve_hi32:
  case VE::fixup_ve_pc_hi32:
  case VE::fixup_ve_got_hi32:
  case VE::fixup_ve_gotoff_hi32:
  case VE::fixup_ve_plt_hi32:
  case VE::fixup_ve_tls_gd_hi32:
  case VE::fixup_ve_tpoff_hi32:
    return (Value >> 32) & 0xffffffff;
  case VE::fixup_ve_reflong:
  case VE::fixup_ve_srel32:
  case VE::fixup_ve_lo32:
  case VE::fixup_ve_pc_lo32:
  case VE::fixup_ve_got_lo32:
  case VE::fixup_ve_gotoff_lo32:
  case VE::fixup_ve_plt_lo32:
  case VE::fixup_ve_tls_gd_lo32:
  case VE::fixup_ve_tpoff_lo32:
    return Value & 0xffffffff;
  }
}

/// getFixupKindNumBytes - The number of bytes the fixup may change.
static unsigned getFixupKindNumBytes(unsigned Kind) {
  switch (Kind) {
  default:
    llvm_unreachable("Unknown fixup kind!");
  case FK_Data_1:
    return 1;
  case FK_Data_2:
    return 2;
  case FK_Data_4:
  case VE::fixup_ve_reflong:
  case VE::fixup_ve_srel32:
  case VE::fixup_ve_hi32:
  case VE::fixup_ve_lo32:
  case VE::fixup_ve_pc_hi32:
  case VE::fixup_ve_pc_lo32:
  case VE::fixup_ve_got_hi32:
  case VE::fixup_ve_got_lo32:
  case VE::fixup_ve_gotoff_hi32:
  case VE::fixup_ve_gotoff_lo32:
  case VE::fixup_ve_plt_hi32:
  case VE::fixup_ve_plt_lo32:
  case VE::fixup_ve_tls_gd_hi32:
  case VE::fixup_ve_tls_gd_lo32:
  case VE::fixup_ve_tpoff_hi32:
  case VE::fixup_ve_tpoff_lo32:
    return 4;
  case FK_Data_8:
    return 8;
  }
}

namespace {
class VEAsmBackend : public MCAsmBackend {
protected:
  const Target &TheTarget;

public:
  VEAsmBackend(const Target &T)
      : MCAsmBackend(llvm::endianness::little), TheTarget(T) {}

  MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override {
    const static MCFixupKindInfo Infos[VE::NumTargetFixupKinds] = {
        // name, offset, bits, flags
        {"fixup_ve_reflong", 0, 32, 0},     {"fixup_ve_srel32", 0, 32, 0},
        {"fixup_ve_hi32", 0, 32, 0},        {"fixup_ve_lo32", 0, 32, 0},
        {"fixup_ve_pc_hi32", 0, 32, 0},     {"fixup_ve_pc_lo32", 0, 32, 0},
        {"fixup_ve_got_hi32", 0, 32, 0},    {"fixup_ve_got_lo32", 0, 32, 0},
        {"fixup_ve_gotoff_hi32", 0, 32, 0}, {"fixup_ve_gotoff_lo32", 0, 32, 0},
        {"fixup_ve_plt_hi32", 0, 32, 0},    {"fixup_ve_plt_lo32", 0, 32, 0},
        {"fixup_ve_tls_gd_hi32", 0, 32, 0}, {"fixup_ve_tls_gd_lo32", 0, 32, 0},
        {"fixup_ve_tpoff_hi32", 0, 32, 0},  {"fixup_ve_tpoff_lo32", 0, 32, 0},
    };

    if (Kind < FirstTargetFixupKind)
      return MCAsmBackend::getFixupKindInfo(Kind);

    assert(unsigned(Kind - FirstTargetFixupKind) < VE::NumTargetFixupKinds &&
           "Invalid kind!");
    return Infos[Kind - FirstTargetFixupKind];
  }

  void applyFixup(const MCFragment &, const MCFixup &, const MCValue &,
                  uint8_t *, uint64_t Value, bool IsResolved) override;

  bool mayNeedRelaxation(unsigned Opcode, ArrayRef<MCOperand> Operands,
                         const MCSubtargetInfo &STI) const override {
    // Not implemented yet.  For example, if we have a branch with
    // lager than SIMM32 immediate value, we want to relaxation such
    // branch instructions.
    return false;
  }

  bool writeNopData(raw_ostream &OS, uint64_t Count,
                    const MCSubtargetInfo *STI) const override {
    if ((Count % 8) != 0)
      return false;

    for (uint64_t i = 0; i < Count; i += 8)
      support::endian::write<uint64_t>(OS, 0x7900000000000000ULL,
                                       llvm::endianness::little);

    return true;
  }
};

class ELFVEAsmBackend : public VEAsmBackend {
  Triple::OSType OSType;

public:
  ELFVEAsmBackend(const Target &T, Triple::OSType OSType)
      : VEAsmBackend(T), OSType(OSType) {}

  std::unique_ptr<MCObjectTargetWriter>
  createObjectTargetWriter() const override {
    uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
    return createVEELFObjectWriter(OSABI);
  }
};
} // end anonymous namespace

void VEAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
                              const MCValue &Target, uint8_t *Data,
                              uint64_t Value, bool IsResolved) {
  switch (Fixup.getKind()) {
  case VE::fixup_ve_tls_gd_hi32:
  case VE::fixup_ve_tls_gd_lo32:
  case VE::fixup_ve_tpoff_hi32:
  case VE::fixup_ve_tpoff_lo32:
    IsResolved = false;
    break;
  }
  maybeAddReloc(F, Fixup, Target, Value, IsResolved);
  Value = adjustFixupValue(Fixup.getKind(), Value);
  if (!Value)
    return; // Doesn't change encoding.

  MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());

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

  unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
  assert(Fixup.getOffset() + NumBytes <= F.getSize() &&
         "Invalid fixup offset!");
  // For each byte of the fragment that the fixup touches, mask in the bits
  // from the fixup value. The Value has been "split up" into the
  // appropriate bitfields above.
  for (unsigned i = 0; i != NumBytes; ++i) {
    unsigned Idx = Endian == llvm::endianness::little ? i : (NumBytes - 1) - i;
    Data[Idx] |= static_cast<uint8_t>((Value >> (i * 8)) & 0xff);
  }
}

MCAsmBackend *llvm::createVEAsmBackend(const Target &T,
                                       const MCSubtargetInfo &STI,
                                       const MCRegisterInfo &MRI,
                                       const MCTargetOptions &Options) {
  return new ELFVEAsmBackend(T, STI.getTargetTriple().getOS());
}
