//===-- 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 "Hexagon.h"
#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 {
    MCFixupKind Kind = Fixup.getKind();

    switch((unsigned)Kind) {
      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 ((unsigned)Fixup.getKind()) {
      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);
}
