//===-- HexagonAsmBackend.cpp - Hexagon 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 "HexagonFixupKinds.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
#include "MCTargetDesc/HexagonMCChecker.h"
#include "MCTargetDesc/HexagonMCCodeEmitter.h"
#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonMCShuffler.h"
#include "MCTargetDesc/HexagonMCTargetDesc.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/TargetRegistry.h"

#include <sstream>

using namespace llvm;
using namespace Hexagon;

#define DEBUG_TYPE "hexagon-asm-backend"

static cl::opt<bool> DisableFixup
  ("mno-fixup", cl::desc("Disable fixing up resolved relocations for Hexagon"));

namespace {

class HexagonAsmBackend : public MCAsmBackend {
  uint8_t OSABI;
  StringRef CPU;
  mutable uint64_t relaxedCnt;
  std::unique_ptr <MCInstrInfo> MCII;
  std::unique_ptr <MCInst *> RelaxTarget;
  MCInst * Extender;

  void ReplaceInstruction(MCCodeEmitter &E, MCRelaxableFragment &RF,
                          MCInst &HMB) const {
    SmallVector<MCFixup, 4> Fixups;
    SmallString<256> Code;
    raw_svector_ostream VecOS(Code);
    E.encodeInstruction(HMB, VecOS, Fixups, *RF.getSubtargetInfo());

    // Update the fragment.
    RF.setInst(HMB);
    RF.getContents() = Code;
    RF.getFixups() = Fixups;
  }

public:
  HexagonAsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,
                    StringRef CPU)
      : MCAsmBackend(support::little), OSABI(OSABI), CPU(CPU),
        MCII(T.createMCInstrInfo()), RelaxTarget(new MCInst *),
        Extender(nullptr) {}

  std::unique_ptr<MCObjectTargetWriter>
  createObjectTargetWriter() const override {
    return createHexagonELFObjectWriter(OSABI, CPU);
  }

  void setExtender(MCContext &Context) const {
    if (Extender == nullptr)
      const_cast<HexagonAsmBackend *>(this)->Extender = new (Context) MCInst;
  }

  MCInst *takeExtender() const {
    assert(Extender != nullptr);
    MCInst * Result = Extender;
    const_cast<HexagonAsmBackend *>(this)->Extender = nullptr;
    return Result;
  }

  unsigned getNumFixupKinds() const override {
    return Hexagon::NumTargetFixupKinds;
  }

  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
    const static MCFixupKindInfo Infos[Hexagon::NumTargetFixupKinds] = {
      // This table *must* be in same the order of fixup_* kinds in
      // HexagonFixupKinds.h.
      //
      // namei                          offset  bits    flags
      { "fixup_Hexagon_B22_PCREL",      0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_B15_PCREL",      0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_B7_PCREL",       0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_LO16",           0,      32,     0 },
      { "fixup_Hexagon_HI16",           0,      32,     0 },
      { "fixup_Hexagon_32",             0,      32,     0 },
      { "fixup_Hexagon_16",             0,      32,     0 },
      { "fixup_Hexagon_8",              0,      32,     0 },
      { "fixup_Hexagon_GPREL16_0",      0,      32,     0 },
      { "fixup_Hexagon_GPREL16_1",      0,      32,     0 },
      { "fixup_Hexagon_GPREL16_2",      0,      32,     0 },
      { "fixup_Hexagon_GPREL16_3",      0,      32,     0 },
      { "fixup_Hexagon_HL16",           0,      32,     0 },
      { "fixup_Hexagon_B13_PCREL",      0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_B9_PCREL",       0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_B32_PCREL_X",    0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_32_6_X",         0,      32,     0 },
      { "fixup_Hexagon_B22_PCREL_X",    0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_B15_PCREL_X",    0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_B13_PCREL_X",    0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_B9_PCREL_X",     0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_B7_PCREL_X",     0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_16_X",           0,      32,     0 },
      { "fixup_Hexagon_12_X",           0,      32,     0 },
      { "fixup_Hexagon_11_X",           0,      32,     0 },
      { "fixup_Hexagon_10_X",           0,      32,     0 },
      { "fixup_Hexagon_9_X",            0,      32,     0 },
      { "fixup_Hexagon_8_X",            0,      32,     0 },
      { "fixup_Hexagon_7_X",            0,      32,     0 },
      { "fixup_Hexagon_6_X",            0,      32,     0 },
      { "fixup_Hexagon_32_PCREL",       0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_COPY",           0,      32,     0 },
      { "fixup_Hexagon_GLOB_DAT",       0,      32,     0 },
      { "fixup_Hexagon_JMP_SLOT",       0,      32,     0 },
      { "fixup_Hexagon_RELATIVE",       0,      32,     0 },
      { "fixup_Hexagon_PLT_B22_PCREL",  0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_GOTREL_LO16",    0,      32,     0 },
      { "fixup_Hexagon_GOTREL_HI16",    0,      32,     0 },
      { "fixup_Hexagon_GOTREL_32",      0,      32,     0 },
      { "fixup_Hexagon_GOT_LO16",       0,      32,     0 },
      { "fixup_Hexagon_GOT_HI16",       0,      32,     0 },
      { "fixup_Hexagon_GOT_32",         0,      32,     0 },
      { "fixup_Hexagon_GOT_16",         0,      32,     0 },
      { "fixup_Hexagon_DTPMOD_32",      0,      32,     0 },
      { "fixup_Hexagon_DTPREL_LO16",    0,      32,     0 },
      { "fixup_Hexagon_DTPREL_HI16",    0,      32,     0 },
      { "fixup_Hexagon_DTPREL_32",      0,      32,     0 },
      { "fixup_Hexagon_DTPREL_16",      0,      32,     0 },
      { "fixup_Hexagon_GD_PLT_B22_PCREL",0,     32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_LD_PLT_B22_PCREL",0,     32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_GD_GOT_LO16",    0,      32,     0 },
      { "fixup_Hexagon_GD_GOT_HI16",    0,      32,     0 },
      { "fixup_Hexagon_GD_GOT_32",      0,      32,     0 },
      { "fixup_Hexagon_GD_GOT_16",      0,      32,     0 },
      { "fixup_Hexagon_LD_GOT_LO16",    0,      32,     0 },
      { "fixup_Hexagon_LD_GOT_HI16",    0,      32,     0 },
      { "fixup_Hexagon_LD_GOT_32",      0,      32,     0 },
      { "fixup_Hexagon_LD_GOT_16",      0,      32,     0 },
      { "fixup_Hexagon_IE_LO16",        0,      32,     0 },
      { "fixup_Hexagon_IE_HI16",        0,      32,     0 },
      { "fixup_Hexagon_IE_32",          0,      32,     0 },
      { "fixup_Hexagon_IE_16",          0,      32,     0 },
      { "fixup_Hexagon_IE_GOT_LO16",    0,      32,     0 },
      { "fixup_Hexagon_IE_GOT_HI16",    0,      32,     0 },
      { "fixup_Hexagon_IE_GOT_32",      0,      32,     0 },
      { "fixup_Hexagon_IE_GOT_16",      0,      32,     0 },
      { "fixup_Hexagon_TPREL_LO16",     0,      32,     0 },
      { "fixup_Hexagon_TPREL_HI16",     0,      32,     0 },
      { "fixup_Hexagon_TPREL_32",       0,      32,     0 },
      { "fixup_Hexagon_TPREL_16",       0,      32,     0 },
      { "fixup_Hexagon_6_PCREL_X",      0,      32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_GOTREL_32_6_X",  0,      32,     0 },
      { "fixup_Hexagon_GOTREL_16_X",    0,      32,     0 },
      { "fixup_Hexagon_GOTREL_11_X",    0,      32,     0 },
      { "fixup_Hexagon_GOT_32_6_X",     0,      32,     0 },
      { "fixup_Hexagon_GOT_16_X",       0,      32,     0 },
      { "fixup_Hexagon_GOT_11_X",       0,      32,     0 },
      { "fixup_Hexagon_DTPREL_32_6_X",  0,      32,     0 },
      { "fixup_Hexagon_DTPREL_16_X",    0,      32,     0 },
      { "fixup_Hexagon_DTPREL_11_X",    0,      32,     0 },
      { "fixup_Hexagon_GD_GOT_32_6_X",  0,      32,     0 },
      { "fixup_Hexagon_GD_GOT_16_X",    0,      32,     0 },
      { "fixup_Hexagon_GD_GOT_11_X",    0,      32,     0 },
      { "fixup_Hexagon_LD_GOT_32_6_X",  0,      32,     0 },
      { "fixup_Hexagon_LD_GOT_16_X",    0,      32,     0 },
      { "fixup_Hexagon_LD_GOT_11_X",    0,      32,     0 },
      { "fixup_Hexagon_IE_32_6_X",      0,      32,     0 },
      { "fixup_Hexagon_IE_16_X",        0,      32,     0 },
      { "fixup_Hexagon_IE_GOT_32_6_X",  0,      32,     0 },
      { "fixup_Hexagon_IE_GOT_16_X",    0,      32,     0 },
      { "fixup_Hexagon_IE_GOT_11_X",    0,      32,     0 },
      { "fixup_Hexagon_TPREL_32_6_X",   0,      32,     0 },
      { "fixup_Hexagon_TPREL_16_X",     0,      32,     0 },
      { "fixup_Hexagon_TPREL_11_X",     0,      32,     0 },
      { "fixup_Hexagon_GD_PLT_B22_PCREL_X",0,     32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_GD_PLT_B32_PCREL_X",0,     32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_LD_PLT_B22_PCREL_X",0,     32,     MCFixupKindInfo::FKF_IsPCRel },
      { "fixup_Hexagon_LD_PLT_B32_PCREL_X",0,     32,     MCFixupKindInfo::FKF_IsPCRel }
    };

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

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

  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
                             const MCValue &Target) override {
    switch(Fixup.getTargetKind()) {
      default:
        llvm_unreachable("Unknown Fixup Kind!");

      case fixup_Hexagon_LO16:
      case fixup_Hexagon_HI16:
      case fixup_Hexagon_16:
      case fixup_Hexagon_8:
      case fixup_Hexagon_GPREL16_0:
      case fixup_Hexagon_GPREL16_1:
      case fixup_Hexagon_GPREL16_2:
      case fixup_Hexagon_GPREL16_3:
      case fixup_Hexagon_HL16:
      case fixup_Hexagon_32_6_X:
      case fixup_Hexagon_16_X:
      case fixup_Hexagon_12_X:
      case fixup_Hexagon_11_X:
      case fixup_Hexagon_10_X:
      case fixup_Hexagon_9_X:
      case fixup_Hexagon_8_X:
      case fixup_Hexagon_7_X:
      case fixup_Hexagon_6_X:
      case fixup_Hexagon_COPY:
      case fixup_Hexagon_GLOB_DAT:
      case fixup_Hexagon_JMP_SLOT:
      case fixup_Hexagon_RELATIVE:
      case fixup_Hexagon_PLT_B22_PCREL:
      case fixup_Hexagon_GOTREL_LO16:
      case fixup_Hexagon_GOTREL_HI16:
      case fixup_Hexagon_GOTREL_32:
      case fixup_Hexagon_GOT_LO16:
      case fixup_Hexagon_GOT_HI16:
      case fixup_Hexagon_GOT_32:
      case fixup_Hexagon_GOT_16:
      case fixup_Hexagon_DTPMOD_32:
      case fixup_Hexagon_DTPREL_LO16:
      case fixup_Hexagon_DTPREL_HI16:
      case fixup_Hexagon_DTPREL_32:
      case fixup_Hexagon_DTPREL_16:
      case fixup_Hexagon_GD_PLT_B22_PCREL:
      case fixup_Hexagon_LD_PLT_B22_PCREL:
      case fixup_Hexagon_GD_GOT_LO16:
      case fixup_Hexagon_GD_GOT_HI16:
      case fixup_Hexagon_GD_GOT_32:
      case fixup_Hexagon_GD_GOT_16:
      case fixup_Hexagon_LD_GOT_LO16:
      case fixup_Hexagon_LD_GOT_HI16:
      case fixup_Hexagon_LD_GOT_32:
      case fixup_Hexagon_LD_GOT_16:
      case fixup_Hexagon_IE_LO16:
      case fixup_Hexagon_IE_HI16:
      case fixup_Hexagon_IE_32:
      case fixup_Hexagon_IE_16:
      case fixup_Hexagon_IE_GOT_LO16:
      case fixup_Hexagon_IE_GOT_HI16:
      case fixup_Hexagon_IE_GOT_32:
      case fixup_Hexagon_IE_GOT_16:
      case fixup_Hexagon_TPREL_LO16:
      case fixup_Hexagon_TPREL_HI16:
      case fixup_Hexagon_TPREL_32:
      case fixup_Hexagon_TPREL_16:
      case fixup_Hexagon_GOTREL_32_6_X:
      case fixup_Hexagon_GOTREL_16_X:
      case fixup_Hexagon_GOTREL_11_X:
      case fixup_Hexagon_GOT_32_6_X:
      case fixup_Hexagon_GOT_16_X:
      case fixup_Hexagon_GOT_11_X:
      case fixup_Hexagon_DTPREL_32_6_X:
      case fixup_Hexagon_DTPREL_16_X:
      case fixup_Hexagon_DTPREL_11_X:
      case fixup_Hexagon_GD_GOT_32_6_X:
      case fixup_Hexagon_GD_GOT_16_X:
      case fixup_Hexagon_GD_GOT_11_X:
      case fixup_Hexagon_LD_GOT_32_6_X:
      case fixup_Hexagon_LD_GOT_16_X:
      case fixup_Hexagon_LD_GOT_11_X:
      case fixup_Hexagon_IE_32_6_X:
      case fixup_Hexagon_IE_16_X:
      case fixup_Hexagon_IE_GOT_32_6_X:
      case fixup_Hexagon_IE_GOT_16_X:
      case fixup_Hexagon_IE_GOT_11_X:
      case fixup_Hexagon_TPREL_32_6_X:
      case fixup_Hexagon_TPREL_16_X:
      case fixup_Hexagon_TPREL_11_X:
      case fixup_Hexagon_32_PCREL:
      case fixup_Hexagon_6_PCREL_X:
      case fixup_Hexagon_23_REG:
      case fixup_Hexagon_27_REG:
      case fixup_Hexagon_GD_PLT_B22_PCREL_X:
      case fixup_Hexagon_GD_PLT_B32_PCREL_X:
      case fixup_Hexagon_LD_PLT_B22_PCREL_X:
      case fixup_Hexagon_LD_PLT_B32_PCREL_X:
        // These relocations should always have a relocation recorded
        return true;

      case fixup_Hexagon_B22_PCREL:
        //IsResolved = false;
        break;

      case fixup_Hexagon_B13_PCREL:
      case fixup_Hexagon_B13_PCREL_X:
      case fixup_Hexagon_B32_PCREL_X:
      case fixup_Hexagon_B22_PCREL_X:
      case fixup_Hexagon_B15_PCREL:
      case fixup_Hexagon_B15_PCREL_X:
      case fixup_Hexagon_B9_PCREL:
      case fixup_Hexagon_B9_PCREL_X:
      case fixup_Hexagon_B7_PCREL:
      case fixup_Hexagon_B7_PCREL_X:
        if (DisableFixup)
          return true;
        break;

      case FK_Data_1:
      case FK_Data_2:
      case FK_Data_4:
      case FK_PCRel_4:
      case fixup_Hexagon_32:
        // Leave these relocations alone as they are used for EH.
        return false;
    }
    return false;
  }

  /// getFixupKindNumBytes - The number of bytes the fixup may change.
  static unsigned getFixupKindNumBytes(unsigned Kind) {
    switch (Kind) {
    default:
        return 0;

      case FK_Data_1:
        return 1;
      case FK_Data_2:
        return 2;
      case FK_Data_4:         // this later gets mapped to R_HEX_32
      case FK_PCRel_4:        // this later gets mapped to R_HEX_32_PCREL
      case fixup_Hexagon_32:
      case fixup_Hexagon_B32_PCREL_X:
      case fixup_Hexagon_B22_PCREL:
      case fixup_Hexagon_B22_PCREL_X:
      case fixup_Hexagon_B15_PCREL:
      case fixup_Hexagon_B15_PCREL_X:
      case fixup_Hexagon_B13_PCREL:
      case fixup_Hexagon_B13_PCREL_X:
      case fixup_Hexagon_B9_PCREL:
      case fixup_Hexagon_B9_PCREL_X:
      case fixup_Hexagon_B7_PCREL:
      case fixup_Hexagon_B7_PCREL_X:
      case fixup_Hexagon_GD_PLT_B32_PCREL_X:
      case fixup_Hexagon_LD_PLT_B32_PCREL_X:
        return 4;
    }
  }

  // Make up for left shift when encoding the operand.
  static uint64_t adjustFixupValue(MCFixupKind Kind, uint64_t Value) {
    switch((unsigned)Kind) {
      default:
        break;

      case fixup_Hexagon_B7_PCREL:
      case fixup_Hexagon_B9_PCREL:
      case fixup_Hexagon_B13_PCREL:
      case fixup_Hexagon_B15_PCREL:
      case fixup_Hexagon_B22_PCREL:
        Value >>= 2;
        break;

      case fixup_Hexagon_B7_PCREL_X:
      case fixup_Hexagon_B9_PCREL_X:
      case fixup_Hexagon_B13_PCREL_X:
      case fixup_Hexagon_B15_PCREL_X:
      case fixup_Hexagon_B22_PCREL_X:
        Value &= 0x3f;
        break;

      case fixup_Hexagon_B32_PCREL_X:
      case fixup_Hexagon_GD_PLT_B32_PCREL_X:
      case fixup_Hexagon_LD_PLT_B32_PCREL_X:
        Value >>= 6;
        break;
    }
    return (Value);
  }

  void HandleFixupError(const int bits, const int align_bits,
    const int64_t FixupValue, const char *fixupStr) const {
    // Error: value 1124 out of range: -1024-1023 when resolving
    // symbol in file xprtsock.S
    const APInt IntMin = APInt::getSignedMinValue(bits+align_bits);
    const APInt IntMax = APInt::getSignedMaxValue(bits+align_bits);
    std::stringstream errStr;
    errStr << "\nError: value " <<
      FixupValue <<
      " out of range: " <<
      IntMin.getSExtValue() <<
      "-" <<
      IntMax.getSExtValue() <<
      " when resolving " <<
      fixupStr <<
      " fixup\n";
    llvm_unreachable(errStr.str().c_str());
  }

  /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
  /// data fragment, at the offset specified by the fixup and following the
  /// fixup kind as appropriate.
  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                  const MCValue &Target, MutableArrayRef<char> Data,
                  uint64_t FixupValue, bool IsResolved,
                  const MCSubtargetInfo *STI) const override {

    // When FixupValue is 0 the relocation is external and there
    // is nothing for us to do.
    if (!FixupValue) return;

    MCFixupKind Kind = Fixup.getKind();
    uint64_t Value;
    uint32_t InstMask;
    uint32_t Reloc;

    // LLVM gives us an encoded value, we have to convert it back
    // to a real offset before we can use it.
    uint32_t Offset = Fixup.getOffset();
    unsigned NumBytes = getFixupKindNumBytes(Kind);
    assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
    char *InstAddr = Data.data() + Offset;

    Value = adjustFixupValue(Kind, FixupValue);
    if(!Value)
      return;
    int sValue = (int)Value;

    switch((unsigned)Kind) {
      default:
        return;

      case fixup_Hexagon_B7_PCREL:
        if (!(isIntN(7, sValue)))
          HandleFixupError(7, 2, (int64_t)FixupValue, "B7_PCREL");
        LLVM_FALLTHROUGH;
      case fixup_Hexagon_B7_PCREL_X:
        InstMask = 0x00001f18;  // Word32_B7
        Reloc = (((Value >> 2) & 0x1f) << 8) |    // Value 6-2 = Target 12-8
                ((Value & 0x3) << 3);             // Value 1-0 = Target 4-3
        break;

      case fixup_Hexagon_B9_PCREL:
        if (!(isIntN(9, sValue)))
          HandleFixupError(9, 2, (int64_t)FixupValue, "B9_PCREL");
        LLVM_FALLTHROUGH;
      case fixup_Hexagon_B9_PCREL_X:
        InstMask = 0x003000fe;  // Word32_B9
        Reloc = (((Value >> 7) & 0x3) << 20) |    // Value 8-7 = Target 21-20
                ((Value & 0x7f) << 1);            // Value 6-0 = Target 7-1
        break;

        // Since the existing branches that use this relocation cannot be
        // extended, they should only be fixed up if the target is within range.
      case fixup_Hexagon_B13_PCREL:
        if (!(isIntN(13, sValue)))
          HandleFixupError(13, 2, (int64_t)FixupValue, "B13_PCREL");
        LLVM_FALLTHROUGH;
      case fixup_Hexagon_B13_PCREL_X:
        InstMask = 0x00202ffe;  // Word32_B13
        Reloc = (((Value >> 12) & 0x1) << 21) |    // Value 12   = Target 21
                (((Value >> 11) & 0x1) << 13) |    // Value 11   = Target 13
                ((Value & 0x7ff) << 1);            // Value 10-0 = Target 11-1
        break;

      case fixup_Hexagon_B15_PCREL:
        if (!(isIntN(15, sValue)))
          HandleFixupError(15, 2, (int64_t)FixupValue, "B15_PCREL");
        LLVM_FALLTHROUGH;
      case fixup_Hexagon_B15_PCREL_X:
        InstMask = 0x00df20fe;  // Word32_B15
        Reloc = (((Value >> 13) & 0x3) << 22) |    // Value 14-13 = Target 23-22
                (((Value >> 8) & 0x1f) << 16) |    // Value 12-8  = Target 20-16
                (((Value >> 7) & 0x1)  << 13) |    // Value 7     = Target 13
                ((Value & 0x7f) << 1);             // Value 6-0   = Target 7-1
        break;

      case fixup_Hexagon_B22_PCREL:
        if (!(isIntN(22, sValue)))
          HandleFixupError(22, 2, (int64_t)FixupValue, "B22_PCREL");
        LLVM_FALLTHROUGH;
      case fixup_Hexagon_B22_PCREL_X:
        InstMask = 0x01ff3ffe;  // Word32_B22
        Reloc = (((Value >> 13) & 0x1ff) << 16) |  // Value 21-13 = Target 24-16
                ((Value & 0x1fff) << 1);           // Value 12-0  = Target 13-1
        break;

      case fixup_Hexagon_B32_PCREL_X:
        InstMask = 0x0fff3fff;  // Word32_X26
        Reloc = (((Value >> 14) & 0xfff) << 16) |  // Value 25-14 = Target 27-16
                (Value & 0x3fff);                  // Value 13-0  = Target 13-0
        break;

      case FK_Data_1:
      case FK_Data_2:
      case FK_Data_4:
      case fixup_Hexagon_32:
        InstMask = 0xffffffff;  // Word32
        Reloc = Value;
        break;
    }

    LLVM_DEBUG(dbgs() << "Name=" << getFixupKindInfo(Kind).Name << "("
                      << (unsigned)Kind << ")\n");
    LLVM_DEBUG(
        uint32_t OldData = 0; for (unsigned i = 0; i < NumBytes; i++) OldData |=
                              (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
        dbgs() << "\tBValue=0x"; dbgs().write_hex(Value) << ": AValue=0x";
        dbgs().write_hex(FixupValue)
        << ": Offset=" << Offset << ": Size=" << Data.size() << ": OInst=0x";
        dbgs().write_hex(OldData) << ": Reloc=0x"; dbgs().write_hex(Reloc););

    // 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++){
      InstAddr[i] &= uint8_t(~InstMask >> (i * 8)) & 0xff; // Clear reloc bits
      InstAddr[i] |= uint8_t(Reloc >> (i * 8)) & 0xff;     // Apply new reloc
    }

    LLVM_DEBUG(uint32_t NewData = 0;
               for (unsigned i = 0; i < NumBytes; i++) NewData |=
               (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
               dbgs() << ": NInst=0x"; dbgs().write_hex(NewData) << "\n";);
  }

  bool isInstRelaxable(MCInst const &HMI) const {
    const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI);
    bool Relaxable = false;
    // Branches and loop-setup insns are handled as necessary by relaxation.
    if (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeJ ||
        (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCJ &&
         MCID.isBranch()) ||
        (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeNCJ &&
         MCID.isBranch()) ||
        (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCR &&
         HMI.getOpcode() != Hexagon::C4_addipc))
      if (HexagonMCInstrInfo::isExtendable(*MCII, HMI)) {
        Relaxable = true;
        MCOperand const &Operand =
            HMI.getOperand(HexagonMCInstrInfo::getExtendableOp(*MCII, HMI));
        if (HexagonMCInstrInfo::mustNotExtend(*Operand.getExpr()))
          Relaxable = false;
      }

    return Relaxable;
  }

  /// MayNeedRelaxation - Check whether the given instruction may need
  /// relaxation.
  ///
  /// \param Inst - The instruction to test.
  bool mayNeedRelaxation(MCInst const &Inst,
                         const MCSubtargetInfo &STI) const override {
    return true;
  }

  /// fixupNeedsRelaxation - Target specific predicate for whether a given
  /// fixup requires the associated instruction to be relaxed.
  bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
                                    uint64_t Value,
                                    const MCRelaxableFragment *DF,
                                    const MCAsmLayout &Layout,
                                    const bool WasForced) const override {
    MCInst const &MCB = DF->getInst();
    assert(HexagonMCInstrInfo::isBundle(MCB));

    *RelaxTarget = nullptr;
    MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction(
        MCB, Fixup.getOffset() / HEXAGON_INSTR_SIZE));
    bool Relaxable = isInstRelaxable(MCI);
    if (Relaxable == false)
      return false;
    // If we cannot resolve the fixup value, it requires relaxation.
    if (!Resolved) {
      switch (Fixup.getTargetKind()) {
      case fixup_Hexagon_B22_PCREL:
        // GetFixupCount assumes B22 won't relax
        LLVM_FALLTHROUGH;
      default:
        return false;
        break;
      case fixup_Hexagon_B13_PCREL:
      case fixup_Hexagon_B15_PCREL:
      case fixup_Hexagon_B9_PCREL:
      case fixup_Hexagon_B7_PCREL: {
        if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {
          ++relaxedCnt;
          *RelaxTarget = &MCI;
          setExtender(Layout.getAssembler().getContext());
          return true;
        } else {
          return false;
        }
        break;
      }
      }
    }

    MCFixupKind Kind = Fixup.getKind();
    int64_t sValue = Value;
    int64_t maxValue;

    switch ((unsigned)Kind) {
    case fixup_Hexagon_B7_PCREL:
      maxValue = 1 << 8;
      break;
    case fixup_Hexagon_B9_PCREL:
      maxValue = 1 << 10;
      break;
    case fixup_Hexagon_B15_PCREL:
      maxValue = 1 << 16;
      break;
    case fixup_Hexagon_B22_PCREL:
      maxValue = 1 << 23;
      break;
    default:
      maxValue = INT64_MAX;
      break;
    }

    bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;

    if (isFarAway) {
      if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {
        ++relaxedCnt;
        *RelaxTarget = &MCI;
        setExtender(Layout.getAssembler().getContext());
        return true;
      }
    }

    return false;
  }

  /// Simple predicate for targets where !Resolved implies requiring relaxation
  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
                            const MCRelaxableFragment *DF,
                            const MCAsmLayout &Layout) const override {
    llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
  }

  void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
                        MCInst &Res) const override {
    assert(HexagonMCInstrInfo::isBundle(Inst) &&
           "Hexagon relaxInstruction only works on bundles");

    Res.setOpcode(Hexagon::BUNDLE);
    Res.addOperand(MCOperand::createImm(Inst.getOperand(0).getImm()));
    // Copy the results into the bundle.
    bool Update = false;
    for (auto &I : HexagonMCInstrInfo::bundleInstructions(Inst)) {
      MCInst &CrntHMI = const_cast<MCInst &>(*I.getInst());

      // if immediate extender needed, add it in
      if (*RelaxTarget == &CrntHMI) {
        Update = true;
        assert((HexagonMCInstrInfo::bundleSize(Res) < HEXAGON_PACKET_SIZE) &&
               "No room to insert extender for relaxation");

        MCInst *HMIx = takeExtender();
        *HMIx = HexagonMCInstrInfo::deriveExtender(
                *MCII, CrntHMI,
                HexagonMCInstrInfo::getExtendableOperand(*MCII, CrntHMI));
        Res.addOperand(MCOperand::createInst(HMIx));
        *RelaxTarget = nullptr;
      }
      // now copy over the original instruction(the one we may have extended)
      Res.addOperand(MCOperand::createInst(I.getInst()));
    }
    (void)Update;
    assert(Update && "Didn't find relaxation target");
  }

  bool writeNopData(raw_ostream &OS, uint64_t Count) const override {
    static const uint32_t Nopcode  = 0x7f000000, // Hard-coded NOP.
                          ParseIn  = 0x00004000, // In packet parse-bits.
                          ParseEnd = 0x0000c000; // End of packet parse-bits.

    while(Count % HEXAGON_INSTR_SIZE) {
      LLVM_DEBUG(dbgs() << "Alignment not a multiple of the instruction size:"
                        << Count % HEXAGON_INSTR_SIZE << "/"
                        << HEXAGON_INSTR_SIZE << "\n");
      --Count;
      OS << '\0';
    }

    while(Count) {
      Count -= HEXAGON_INSTR_SIZE;
      // Close the packet whenever a multiple of the maximum packet size remains
      uint32_t ParseBits = (Count % (HEXAGON_PACKET_SIZE * HEXAGON_INSTR_SIZE))?
                           ParseIn: ParseEnd;
      support::endian::write<uint32_t>(OS, Nopcode | ParseBits, Endian);
    }
    return true;
  }

  void finishLayout(MCAssembler const &Asm,
                    MCAsmLayout &Layout) const override {
    for (auto I : Layout.getSectionOrder()) {
      auto &Fragments = I->getFragmentList();
      for (auto &J : Fragments) {
        switch (J.getKind()) {
        default:
          break;
        case MCFragment::FT_Align: {
          auto Size = Asm.computeFragmentSize(Layout, J);
          for (auto K = J.getIterator();
               K != Fragments.begin() && Size >= HEXAGON_PACKET_SIZE;) {
            --K;
            switch (K->getKind()) {
            default:
              break;
            case MCFragment::FT_Align: {
              // Don't pad before other alignments
              Size = 0;
              break;
            }
            case MCFragment::FT_Relaxable: {
              MCContext &Context = Asm.getContext();
              auto &RF = cast<MCRelaxableFragment>(*K);
              auto &Inst = const_cast<MCInst &>(RF.getInst());
              while (Size > 0 && HexagonMCInstrInfo::bundleSize(Inst) < 4) {
                MCInst *Nop = new (Context) MCInst;
                Nop->setOpcode(Hexagon::A2_nop);
                Inst.addOperand(MCOperand::createInst(Nop));
                Size -= 4;
                if (!HexagonMCChecker(
                         Context, *MCII, *RF.getSubtargetInfo(), Inst,
                         *Context.getRegisterInfo(), false)
                         .check()) {
                  Inst.erase(Inst.end() - 1);
                  Size = 0;
                }
              }
              bool Error = HexagonMCShuffle(Context, true, *MCII,
                                            *RF.getSubtargetInfo(), Inst);
              //assert(!Error);
              (void)Error;
              ReplaceInstruction(Asm.getEmitter(), RF, Inst);
              Layout.invalidateFragmentsFrom(&RF);
              Size = 0; // Only look back one instruction
              break;
            }
            }
          }
        }
        }
      }
    }
  }
}; // class HexagonAsmBackend

} // namespace

// MCAsmBackend
MCAsmBackend *llvm::createHexagonAsmBackend(Target const &T,
                                            const MCSubtargetInfo &STI,
                                            MCRegisterInfo const & /*MRI*/,
                                            const MCTargetOptions &Options) {
  const Triple &TT = STI.getTargetTriple();
  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());

  StringRef CPUString = Hexagon_MC::selectHexagonCPU(STI.getCPU());
  return new HexagonAsmBackend(T, TT, OSABI, CPUString);
}
