//===-- ARMAsmBackend.cpp - ARM 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/ARMAsmBackend.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMAsmBackendDarwin.h"
#include "MCTargetDesc/ARMAsmBackendELF.h"
#include "MCTargetDesc/ARMAsmBackendWinCOFF.h"
#include "MCTargetDesc/ARMFixupKinds.h"
#include "MCTargetDesc/ARMMCTargetDesc.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

namespace {
class ARMELFObjectWriter : public MCELFObjectTargetWriter {
public:
  ARMELFObjectWriter(uint8_t OSABI)
      : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_ARM,
                                /*HasRelocationAddend*/ false) {}
};
} // end anonymous namespace

std::optional<MCFixupKind> ARMAsmBackend::getFixupKind(StringRef Name) const {
  return std::nullopt;
}

std::optional<MCFixupKind>
ARMAsmBackendELF::getFixupKind(StringRef Name) const {
  unsigned Type = llvm::StringSwitch<unsigned>(Name)
#define ELF_RELOC(X, Y) .Case(#X, Y)
#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
#undef ELF_RELOC
                      .Case("BFD_RELOC_NONE", ELF::R_ARM_NONE)
                      .Case("BFD_RELOC_8", ELF::R_ARM_ABS8)
                      .Case("BFD_RELOC_16", ELF::R_ARM_ABS16)
                      .Case("BFD_RELOC_32", ELF::R_ARM_ABS32)
                      .Default(-1u);
  if (Type == -1u)
    return std::nullopt;
  return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
}

const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
  const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = {
      // This table *must* be in the order that the fixup_* kinds are defined in
      // ARMFixupKinds.h.
      //
      // Name                      Offset (bits) Size (bits)     Flags
      {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_ldst_pcrel_12", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_pcrel_10", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_pcrel_9", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_ldst_abs_12", 0, 32, 0},
      {"fixup_thumb_adr_pcrel_10", 0, 8,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_adr_pcrel_12", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_condbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_thumb_blx", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_thumb_cp", 0, 8,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_thumb_bcc", 0, 8, MCFixupKindInfo::FKF_IsPCRel},
      // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
      // - 19.
      {"fixup_arm_movt_hi16", 0, 20, 0},
      {"fixup_arm_movw_lo16", 0, 20, 0},
      {"fixup_t2_movt_hi16", 0, 20, 0},
      {"fixup_t2_movw_lo16", 0, 20, 0},
      {"fixup_arm_thumb_upper_8_15", 0, 8, 0},
      {"fixup_arm_thumb_upper_0_7", 0, 8, 0},
      {"fixup_arm_thumb_lower_8_15", 0, 8, 0},
      {"fixup_arm_thumb_lower_0_7", 0, 8, 0},
      {"fixup_arm_mod_imm", 0, 12, 0},
      {"fixup_t2_so_imm", 0, 26, 0},
      {"fixup_bf_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_bf_target", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_bfl_target", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_bfc_target", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_bfcsel_else_target", 0, 32, 0},
      {"fixup_wls", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_le", 0, 32, MCFixupKindInfo::FKF_IsPCRel}};
  const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = {
      // This table *must* be in the order that the fixup_* kinds are defined in
      // ARMFixupKinds.h.
      //
      // Name                      Offset (bits) Size (bits)     Flags
      {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_ldst_pcrel_12", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_pcrel_10", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_pcrel_9", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_ldst_abs_12", 0, 32, 0},
      {"fixup_thumb_adr_pcrel_10", 8, 8,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_adr_pcrel_12", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_condbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_uncondbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_uncondbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_condbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_blx", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_thumb_blx", 0, 32,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_arm_thumb_cp", 8, 8,
       MCFixupKindInfo::FKF_IsPCRel |
           MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      {"fixup_arm_thumb_bcc", 8, 8, MCFixupKindInfo::FKF_IsPCRel},
      // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
      // - 19.
      {"fixup_arm_movt_hi16", 12, 20, 0},
      {"fixup_arm_movw_lo16", 12, 20, 0},
      {"fixup_t2_movt_hi16", 12, 20, 0},
      {"fixup_t2_movw_lo16", 12, 20, 0},
      {"fixup_arm_thumb_upper_8_15", 24, 8, 0},
      {"fixup_arm_thumb_upper_0_7", 24, 8, 0},
      {"fixup_arm_thumb_lower_8_15", 24, 8, 0},
      {"fixup_arm_thumb_lower_0_7", 24, 8, 0},
      {"fixup_arm_mod_imm", 20, 12, 0},
      {"fixup_t2_so_imm", 26, 6, 0},
      {"fixup_bf_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_bf_target", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_bfl_target", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_bfc_target", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_bfcsel_else_target", 0, 32, 0},
      {"fixup_wls", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      {"fixup_le", 0, 32, MCFixupKindInfo::FKF_IsPCRel}};

  // Fixup kinds from .reloc directive are like R_ARM_NONE. They do not require
  // any extra processing.
  if (Kind >= FirstLiteralRelocationKind)
    return MCAsmBackend::getFixupKindInfo(FK_NONE);

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

  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
         "Invalid kind!");
  return (Endian == llvm::endianness::little
              ? InfosLE
              : InfosBE)[Kind - FirstTargetFixupKind];
}

void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) {
  switch (Flag) {
  default:
    break;
  case MCAF_Code16:
    setIsThumb(true);
    break;
  case MCAF_Code32:
    setIsThumb(false);
    break;
  }
}

unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op,
                                         const MCSubtargetInfo &STI) const {
  bool HasThumb2 = STI.hasFeature(ARM::FeatureThumb2);
  bool HasV8MBaselineOps = STI.hasFeature(ARM::HasV8MBaselineOps);

  switch (Op) {
  default:
    return Op;
  case ARM::tBcc:
    return HasThumb2 ? (unsigned)ARM::t2Bcc : Op;
  case ARM::tLDRpci:
    return HasThumb2 ? (unsigned)ARM::t2LDRpci : Op;
  case ARM::tADR:
    return HasThumb2 ? (unsigned)ARM::t2ADR : Op;
  case ARM::tB:
    return HasV8MBaselineOps ? (unsigned)ARM::t2B : Op;
  case ARM::tCBZ:
    return ARM::tHINT;
  case ARM::tCBNZ:
    return ARM::tHINT;
  }
}

bool ARMAsmBackend::mayNeedRelaxation(const MCInst &Inst,
                                      const MCSubtargetInfo &STI) const {
  if (getRelaxedOpcode(Inst.getOpcode(), STI) != Inst.getOpcode())
    return true;
  return false;
}

static const char *checkPCRelOffset(uint64_t Value, int64_t Min, int64_t Max) {
  int64_t Offset = int64_t(Value) - 4;
  if (Offset < Min || Offset > Max)
    return "out of range pc-relative fixup value";
  return nullptr;
}

const char *ARMAsmBackend::reasonForFixupRelaxation(const MCFixup &Fixup,
                                                    uint64_t Value) const {
  switch (Fixup.getTargetKind()) {
  case ARM::fixup_arm_thumb_br: {
    // Relaxing tB to t2B. tB has a signed 12-bit displacement with the
    // low bit being an implied zero. There's an implied +4 offset for the
    // branch, so we adjust the other way here to determine what's
    // encodable.
    //
    // Relax if the value is too big for a (signed) i8.
    int64_t Offset = int64_t(Value) - 4;
    if (Offset > 2046 || Offset < -2048)
      return "out of range pc-relative fixup value";
    break;
  }
  case ARM::fixup_arm_thumb_bcc: {
    // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the
    // low bit being an implied zero. There's an implied +4 offset for the
    // branch, so we adjust the other way here to determine what's
    // encodable.
    //
    // Relax if the value is too big for a (signed) i8.
    int64_t Offset = int64_t(Value) - 4;
    if (Offset > 254 || Offset < -256)
      return "out of range pc-relative fixup value";
    break;
  }
  case ARM::fixup_thumb_adr_pcrel_10:
  case ARM::fixup_arm_thumb_cp: {
    // If the immediate is negative, greater than 1020, or not a multiple
    // of four, the wide version of the instruction must be used.
    int64_t Offset = int64_t(Value) - 4;
    if (Offset & 3)
      return "misaligned pc-relative fixup value";
    else if (Offset > 1020 || Offset < 0)
      return "out of range pc-relative fixup value";
    break;
  }
  case ARM::fixup_arm_thumb_cb: {
    // If we have a Thumb CBZ or CBNZ instruction and its target is the next
    // instruction it is actually out of range for the instruction.
    // It will be changed to a NOP.
    int64_t Offset = (Value & ~1);
    if (Offset == 2)
      return "will be converted to nop";
    break;
  }
  case ARM::fixup_bf_branch:
    return checkPCRelOffset(Value, 0, 30);
  case ARM::fixup_bf_target:
    return checkPCRelOffset(Value, -0x10000, +0xfffe);
  case ARM::fixup_bfl_target:
    return checkPCRelOffset(Value, -0x40000, +0x3fffe);
  case ARM::fixup_bfc_target:
    return checkPCRelOffset(Value, -0x1000, +0xffe);
  case ARM::fixup_wls:
    return checkPCRelOffset(Value, 0, +0xffe);
  case ARM::fixup_le:
    // The offset field in the LE and LETP instructions is an 11-bit
    // value shifted left by 2 (i.e. 0,2,4,...,4094), and it is
    // interpreted as a negative offset from the value read from pc,
    // i.e. from instruction_address+4.
    //
    // So an LE instruction can in principle address the instruction
    // immediately after itself, or (not very usefully) the address
    // half way through the 4-byte LE.
    return checkPCRelOffset(Value, -0xffe, 0);
  case ARM::fixup_bfcsel_else_target: {
    if (Value != 2 && Value != 4)
      return "out of range label-relative fixup value";
    break;
  }

  default:
    llvm_unreachable("Unexpected fixup kind in reasonForFixupRelaxation()!");
  }
  return nullptr;
}

bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
                                         uint64_t Value) const {
  return reasonForFixupRelaxation(Fixup, Value);
}

void ARMAsmBackend::relaxInstruction(MCInst &Inst,
                                     const MCSubtargetInfo &STI) const {
  unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode(), STI);

  // Return a diagnostic if we get here w/ a bogus instruction.
  if (RelaxedOp == Inst.getOpcode()) {
    SmallString<256> Tmp;
    raw_svector_ostream OS(Tmp);
    Inst.dump_pretty(OS);
    OS << "\n";
    report_fatal_error("unexpected instruction to relax: " + OS.str());
  }

  // If we are changing Thumb CBZ or CBNZ instruction to a NOP, aka tHINT, we
  // have to change the operands too.
  if ((Inst.getOpcode() == ARM::tCBZ || Inst.getOpcode() == ARM::tCBNZ) &&
      RelaxedOp == ARM::tHINT) {
    MCInst Res;
    Res.setOpcode(RelaxedOp);
    Res.addOperand(MCOperand::createImm(0));
    Res.addOperand(MCOperand::createImm(14));
    Res.addOperand(MCOperand::createReg(0));
    Inst = std::move(Res);
    return;
  }

  // The rest of instructions we're relaxing have the same operands.
  // We just need to update to the proper opcode.
  Inst.setOpcode(RelaxedOp);
}

bool ARMAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
                                 const MCSubtargetInfo *STI) const {
  const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8
  const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP
  const uint32_t ARMv4_NopEncoding = 0xe1a00000;   // using MOV r0,r0
  const uint32_t ARMv6T2_NopEncoding = 0xe320f000; // NOP
  if (isThumb()) {
    const uint16_t nopEncoding =
        hasNOP(STI) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
    uint64_t NumNops = Count / 2;
    for (uint64_t i = 0; i != NumNops; ++i)
      support::endian::write(OS, nopEncoding, Endian);
    if (Count & 1)
      OS << '\0';
    return true;
  }
  // ARM mode
  const uint32_t nopEncoding =
      hasNOP(STI) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
  uint64_t NumNops = Count / 4;
  for (uint64_t i = 0; i != NumNops; ++i)
    support::endian::write(OS, nopEncoding, Endian);
  // FIXME: should this function return false when unable to write exactly
  // 'Count' bytes with NOP encodings?
  switch (Count % 4) {
  default:
    break; // No leftover bytes to write
  case 1:
    OS << '\0';
    break;
  case 2:
    OS.write("\0\0", 2);
    break;
  case 3:
    OS.write("\0\0\xa0", 3);
    break;
  }

  return true;
}

static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian) {
  if (IsLittleEndian) {
    // Note that the halfwords are stored high first and low second in thumb;
    // so we need to swap the fixup value here to map properly.
    uint32_t Swapped = (Value & 0xFFFF0000) >> 16;
    Swapped |= (Value & 0x0000FFFF) << 16;
    return Swapped;
  } else
    return Value;
}

static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf,
                              bool IsLittleEndian) {
  uint32_t Value;

  if (IsLittleEndian) {
    Value = (SecondHalf & 0xFFFF) << 16;
    Value |= (FirstHalf & 0xFFFF);
  } else {
    Value = (SecondHalf & 0xFFFF);
    Value |= (FirstHalf & 0xFFFF) << 16;
  }

  return Value;
}

unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
                                         const MCFixup &Fixup,
                                         const MCValue &Target, uint64_t Value,
                                         bool IsResolved, MCContext &Ctx,
                                         const MCSubtargetInfo* STI) const {
  unsigned Kind = Fixup.getKind();
  int64_t Addend = Target.getConstant();

  // For MOVW/MOVT Instructions, the fixup value must already be within a
  // signed 16bit range.
  if ((Kind == ARM::fixup_arm_movw_lo16 || Kind == ARM::fixup_arm_movt_hi16 ||
       Kind == ARM::fixup_t2_movw_lo16 || Kind == ARM::fixup_t2_movt_hi16) &&
      (Addend < minIntN(16) || Addend > maxIntN(16))) {
    Ctx.reportError(Fixup.getLoc(), "Relocation Not In Range");
    return 0;
  }

  // MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
  // and .word relocations they put the Thumb bit into the addend if possible.
  // Other relocation types don't want this bit though (branches couldn't encode
  // it if it *was* present, and no other relocations exist) and it can
  // interfere with checking valid expressions.
  if (const MCSymbolRefExpr *A = Target.getSymA()) {
    if (A->hasSubsectionsViaSymbols() && Asm.isThumbFunc(&A->getSymbol()) &&
        A->getSymbol().isExternal() &&
        (Kind == FK_Data_4 || Kind == ARM::fixup_arm_movw_lo16 ||
         Kind == ARM::fixup_arm_movt_hi16 || Kind == ARM::fixup_t2_movw_lo16 ||
         Kind == ARM::fixup_t2_movt_hi16))
      Value |= 1;
  }

  switch (Kind) {
  default:
    return 0;
  case FK_Data_1:
  case FK_Data_2:
  case FK_Data_4:
    return Value;
  case FK_SecRel_2:
    return Value;
  case FK_SecRel_4:
    return Value;
  case ARM::fixup_arm_movt_hi16:
    assert(STI != nullptr);
    if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
      Value >>= 16;
    [[fallthrough]];
  case ARM::fixup_arm_movw_lo16: {
    unsigned Hi4 = (Value & 0xF000) >> 12;
    unsigned Lo12 = Value & 0x0FFF;
    // inst{19-16} = Hi4;
    // inst{11-0} = Lo12;
    Value = (Hi4 << 16) | (Lo12);
    return Value;
  }
  case ARM::fixup_t2_movt_hi16:
    assert(STI != nullptr);
    if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
      Value >>= 16;
    [[fallthrough]];
  case ARM::fixup_t2_movw_lo16: {
    unsigned Hi4 = (Value & 0xF000) >> 12;
    unsigned i = (Value & 0x800) >> 11;
    unsigned Mid3 = (Value & 0x700) >> 8;
    unsigned Lo8 = Value & 0x0FF;
    // inst{19-16} = Hi4;
    // inst{26} = i;
    // inst{14-12} = Mid3;
    // inst{7-0} = Lo8;
    Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
    return swapHalfWords(Value, Endian == llvm::endianness::little);
  }
  case ARM::fixup_arm_thumb_upper_8_15:
    if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
      return (Value & 0xff000000) >> 24;
    return Value & 0xff;
  case ARM::fixup_arm_thumb_upper_0_7:
    if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
      return (Value & 0x00ff0000) >> 16;
    return Value & 0xff;
  case ARM::fixup_arm_thumb_lower_8_15:
    if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
      return (Value & 0x0000ff00) >> 8;
    return Value & 0xff;
  case ARM::fixup_arm_thumb_lower_0_7:
    return Value & 0x000000ff;
  case ARM::fixup_arm_ldst_pcrel_12:
    // ARM PC-relative values are offset by 8.
    Value -= 4;
    [[fallthrough]];
  case ARM::fixup_t2_ldst_pcrel_12:
    // Offset by 4, adjusted by two due to the half-word ordering of thumb.
    Value -= 4;
    [[fallthrough]];
  case ARM::fixup_arm_ldst_abs_12: {
    bool isAdd = true;
    if ((int64_t)Value < 0) {
      Value = -Value;
      isAdd = false;
    }
    if (Value >= 4096) {
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
      return 0;
    }
    Value |= isAdd << 23;

    // Same addressing mode as fixup_arm_pcrel_10,
    // but with 16-bit halfwords swapped.
    if (Kind == ARM::fixup_t2_ldst_pcrel_12)
      return swapHalfWords(Value, Endian == llvm::endianness::little);

    return Value;
  }
  case ARM::fixup_arm_adr_pcrel_12: {
    // ARM PC-relative values are offset by 8.
    Value -= 8;
    unsigned opc = 4; // bits {24-21}. Default to add: 0b0100
    if ((int64_t)Value < 0) {
      Value = -Value;
      opc = 2; // 0b0010
    }
    if (ARM_AM::getSOImmVal(Value) == -1) {
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
      return 0;
    }
    // Encode the immediate and shift the opcode into place.
    return ARM_AM::getSOImmVal(Value) | (opc << 21);
  }

  case ARM::fixup_t2_adr_pcrel_12: {
    Value -= 4;
    unsigned opc = 0;
    if ((int64_t)Value < 0) {
      Value = -Value;
      opc = 5;
    }

    uint32_t out = (opc << 21);
    out |= (Value & 0x800) << 15;
    out |= (Value & 0x700) << 4;
    out |= (Value & 0x0FF);

    return swapHalfWords(out, Endian == llvm::endianness::little);
  }

  case ARM::fixup_arm_condbranch:
  case ARM::fixup_arm_uncondbranch:
  case ARM::fixup_arm_uncondbl:
  case ARM::fixup_arm_condbl:
  case ARM::fixup_arm_blx:
    // Check that the relocation value is legal.
    Value -= 8;
    if (!isInt<26>(Value)) {
      Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
      return 0;
    }
    // Alignment differs for blx. Because we are switching to thumb ISA, we use
    // 16-bit alignment. Otherwise, use 32-bit.
    if ((Kind == ARM::fixup_arm_blx && Value % 2 != 0) ||
        (Kind != ARM::fixup_arm_blx && Value % 4 != 0)) {
      Ctx.reportError(Fixup.getLoc(), "Relocation not aligned");
      return 0;
    }

    // These values don't encode the low two bits since they're always zero.
    // Offset by 8 just as above.
    if (const MCSymbolRefExpr *SRE =
            dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
      if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL)
        return 0;
    return 0xffffff & (Value >> 2);
  case ARM::fixup_t2_uncondbranch: {
    if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
        Value != 4) {
      // MSVC link.exe and lld do not support this relocation type
      // with a non-zero offset. ("Value" is offset by 4 at this point.)
      Ctx.reportError(Fixup.getLoc(),
                      "cannot perform a PC-relative fixup with a non-zero "
                      "symbol offset");
    }
    Value = Value - 4;
    if (!isInt<25>(Value)) {
      Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
      return 0;
    }

    Value >>= 1; // Low bit is not encoded.

    uint32_t out = 0;
    bool I = Value & 0x800000;
    bool J1 = Value & 0x400000;
    bool J2 = Value & 0x200000;
    J1 ^= I;
    J2 ^= I;

    out |= I << 26;                 // S bit
    out |= !J1 << 13;               // J1 bit
    out |= !J2 << 11;               // J2 bit
    out |= (Value & 0x1FF800) << 5; // imm6 field
    out |= (Value & 0x0007FF);      // imm11 field

    return swapHalfWords(out, Endian == llvm::endianness::little);
  }
  case ARM::fixup_t2_condbranch: {
    Value = Value - 4;
    if (!isInt<21>(Value)) {
      Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
      return 0;
    }

    Value >>= 1; // Low bit is not encoded.

    uint64_t out = 0;
    out |= (Value & 0x80000) << 7; // S bit
    out |= (Value & 0x40000) >> 7; // J2 bit
    out |= (Value & 0x20000) >> 4; // J1 bit
    out |= (Value & 0x1F800) << 5; // imm6 field
    out |= (Value & 0x007FF);      // imm11 field

    return swapHalfWords(out, Endian == llvm::endianness::little);
  }
  case ARM::fixup_arm_thumb_bl: {
    if (!isInt<25>(Value - 4) ||
        (!STI->hasFeature(ARM::FeatureThumb2) &&
         !STI->hasFeature(ARM::HasV8MBaselineOps) &&
         !STI->hasFeature(ARM::HasV6MOps) &&
         !isInt<23>(Value - 4))) {
      Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
      return 0;
    }
    if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
        Value != 4) {
      // MSVC link.exe and lld do not support this relocation type
      // with a non-zero offset. ("Value" is offset by 4 at this point.)
      Ctx.reportError(Fixup.getLoc(),
                      "cannot perform a PC-relative fixup with a non-zero "
                      "symbol offset");
    }

    // The value doesn't encode the low bit (always zero) and is offset by
    // four. The 32-bit immediate value is encoded as
    //   imm32 = SignExtend(S:I1:I2:imm10:imm11:0)
    // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
    // The value is encoded into disjoint bit positions in the destination
    // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
    // J = either J1 or J2 bit
    //
    //   BL:  xxxxxSIIIIIIIIII xxJxJIIIIIIIIIII
    //
    // Note that the halfwords are stored high first, low second; so we need
    // to transpose the fixup value here to map properly.
    uint32_t offset = (Value - 4) >> 1;
    uint32_t signBit = (offset & 0x800000) >> 23;
    uint32_t I1Bit = (offset & 0x400000) >> 22;
    uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
    uint32_t I2Bit = (offset & 0x200000) >> 21;
    uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
    uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
    uint32_t imm11Bits = (offset & 0x000007FF);

    uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
    uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
                           (uint16_t)imm11Bits);
    return joinHalfWords(FirstHalf, SecondHalf,
                         Endian == llvm::endianness::little);
  }
  case ARM::fixup_arm_thumb_blx: {
    if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
        Value != 4) {
      // MSVC link.exe and lld do not support this relocation type
      // with a non-zero offset. ("Value" is offset by 4 at this point.)
      Ctx.reportError(Fixup.getLoc(),
                      "cannot perform a PC-relative fixup with a non-zero "
                      "symbol offset");
    }
    // The value doesn't encode the low two bits (always zero) and is offset by
    // four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as
    //   imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
    // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
    // The value is encoded into disjoint bit positions in the destination
    // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
    // J = either J1 or J2 bit, 0 = zero.
    //
    //   BLX: xxxxxSIIIIIIIIII xxJxJIIIIIIIIII0
    //
    // Note that the halfwords are stored high first, low second; so we need
    // to transpose the fixup value here to map properly.
    if (Value % 4 != 0) {
      Ctx.reportError(Fixup.getLoc(), "misaligned ARM call destination");
      return 0;
    }

    uint32_t offset = (Value - 4) >> 2;
    if (const MCSymbolRefExpr *SRE =
            dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
      if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL)
        offset = 0;
    uint32_t signBit = (offset & 0x400000) >> 22;
    uint32_t I1Bit = (offset & 0x200000) >> 21;
    uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
    uint32_t I2Bit = (offset & 0x100000) >> 20;
    uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
    uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
    uint32_t imm10LBits = (offset & 0x3FF);

    uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
    uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
                           ((uint16_t)imm10LBits) << 1);
    return joinHalfWords(FirstHalf, SecondHalf,
                         Endian == llvm::endianness::little);
  }
  case ARM::fixup_thumb_adr_pcrel_10:
  case ARM::fixup_arm_thumb_cp:
    // On CPUs supporting Thumb2, this will be relaxed to an ldr.w, otherwise we
    // could have an error on our hands.
    assert(STI != nullptr);
    if (!STI->hasFeature(ARM::FeatureThumb2) && IsResolved) {
      const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
      if (FixupDiagnostic) {
        Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
        return 0;
      }
    }
    // Offset by 4, and don't encode the low two bits.
    return ((Value - 4) >> 2) & 0xff;
  case ARM::fixup_arm_thumb_cb: {
    // CB instructions can only branch to offsets in [4, 126] in multiples of 2
    // so ensure that the raw value LSB is zero and it lies in [2, 130].
    // An offset of 2 will be relaxed to a NOP.
    if ((int64_t)Value < 2 || Value > 0x82 || Value & 1) {
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
      return 0;
    }
    // Offset by 4 and don't encode the lower bit, which is always 0.
    // FIXME: diagnose if no Thumb2
    uint32_t Binary = (Value - 4) >> 1;
    return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
  }
  case ARM::fixup_arm_thumb_br:
    // Offset by 4 and don't encode the lower bit, which is always 0.
    assert(STI != nullptr);
    if (!STI->hasFeature(ARM::FeatureThumb2) &&
        !STI->hasFeature(ARM::HasV8MBaselineOps)) {
      const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
      if (FixupDiagnostic) {
        Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
        return 0;
      }
    }
    return ((Value - 4) >> 1) & 0x7ff;
  case ARM::fixup_arm_thumb_bcc:
    // Offset by 4 and don't encode the lower bit, which is always 0.
    assert(STI != nullptr);
    if (!STI->hasFeature(ARM::FeatureThumb2)) {
      const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
      if (FixupDiagnostic) {
        Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
        return 0;
      }
    }
    return ((Value - 4) >> 1) & 0xff;
  case ARM::fixup_arm_pcrel_10_unscaled: {
    Value = Value - 8; // ARM fixups offset by an additional word and don't
                       // need to adjust for the half-word ordering.
    bool isAdd = true;
    if ((int64_t)Value < 0) {
      Value = -Value;
      isAdd = false;
    }
    // The value has the low 4 bits encoded in [3:0] and the high 4 in [11:8].
    if (Value >= 256) {
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
      return 0;
    }
    Value = (Value & 0xf) | ((Value & 0xf0) << 4);
    return Value | (isAdd << 23);
  }
  case ARM::fixup_arm_pcrel_10:
    Value = Value - 4; // ARM fixups offset by an additional word and don't
                       // need to adjust for the half-word ordering.
    [[fallthrough]];
  case ARM::fixup_t2_pcrel_10: {
    // Offset by 4, adjusted by two due to the half-word ordering of thumb.
    Value = Value - 4;
    bool isAdd = true;
    if ((int64_t)Value < 0) {
      Value = -Value;
      isAdd = false;
    }
    // These values don't encode the low two bits since they're always zero.
    Value >>= 2;
    if (Value >= 256) {
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
      return 0;
    }
    Value |= isAdd << 23;

    // Same addressing mode as fixup_arm_pcrel_10, but with 16-bit halfwords
    // swapped.
    if (Kind == ARM::fixup_t2_pcrel_10)
      return swapHalfWords(Value, Endian == llvm::endianness::little);

    return Value;
  }
  case ARM::fixup_arm_pcrel_9:
    Value = Value - 4; // ARM fixups offset by an additional word and don't
                       // need to adjust for the half-word ordering.
    [[fallthrough]];
  case ARM::fixup_t2_pcrel_9: {
    // Offset by 4, adjusted by two due to the half-word ordering of thumb.
    Value = Value - 4;
    bool isAdd = true;
    if ((int64_t)Value < 0) {
      Value = -Value;
      isAdd = false;
    }
    // These values don't encode the low bit since it's always zero.
    if (Value & 1) {
      Ctx.reportError(Fixup.getLoc(), "invalid value for this fixup");
      return 0;
    }
    Value >>= 1;
    if (Value >= 256) {
      Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
      return 0;
    }
    Value |= isAdd << 23;

    // Same addressing mode as fixup_arm_pcrel_9, but with 16-bit halfwords
    // swapped.
    if (Kind == ARM::fixup_t2_pcrel_9)
      return swapHalfWords(Value, Endian == llvm::endianness::little);

    return Value;
  }
  case ARM::fixup_arm_mod_imm:
    Value = ARM_AM::getSOImmVal(Value);
    if (Value >> 12) {
      Ctx.reportError(Fixup.getLoc(), "out of range immediate fixup value");
      return 0;
    }
    return Value;
  case ARM::fixup_t2_so_imm: {
    Value = ARM_AM::getT2SOImmVal(Value);
    if ((int64_t)Value < 0) {
      Ctx.reportError(Fixup.getLoc(), "out of range immediate fixup value");
      return 0;
    }
    // Value will contain a 12-bit value broken up into a 4-bit shift in bits
    // 11:8 and the 8-bit immediate in 0:7. The instruction has the immediate
    // in 0:7. The 4-bit shift is split up into i:imm3 where i is placed at bit
    // 10 of the upper half-word and imm3 is placed at 14:12 of the lower
    // half-word.
    uint64_t EncValue = 0;
    EncValue |= (Value & 0x800) << 15;
    EncValue |= (Value & 0x700) << 4;
    EncValue |= (Value & 0xff);
    return swapHalfWords(EncValue, Endian == llvm::endianness::little);
  }
  case ARM::fixup_bf_branch: {
    const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
    if (FixupDiagnostic) {
      Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
      return 0;
    }
    uint32_t out = (((Value - 4) >> 1) & 0xf) << 23;
    return swapHalfWords(out, Endian == llvm::endianness::little);
  }
  case ARM::fixup_bf_target:
  case ARM::fixup_bfl_target:
  case ARM::fixup_bfc_target: {
    const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
    if (FixupDiagnostic) {
      Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
      return 0;
    }
    uint32_t out = 0;
    uint32_t HighBitMask = (Kind == ARM::fixup_bf_target ? 0xf800 :
                            Kind == ARM::fixup_bfl_target ? 0x3f800 : 0x800);
    out |= (((Value - 4) >> 1) & 0x1) << 11;
    out |= (((Value - 4) >> 1) & 0x7fe);
    out |= (((Value - 4) >> 1) & HighBitMask) << 5;
    return swapHalfWords(out, Endian == llvm::endianness::little);
  }
  case ARM::fixup_bfcsel_else_target: {
    // If this is a fixup of a branch future's else target then it should be a
    // constant MCExpr representing the distance between the branch targetted
    // and the instruction after that same branch.
    Value = Target.getConstant();

    const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
    if (FixupDiagnostic) {
      Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
      return 0;
    }
    uint32_t out = ((Value >> 2) & 1) << 17;
    return swapHalfWords(out, Endian == llvm::endianness::little);
  }
  case ARM::fixup_wls:
  case ARM::fixup_le: {
    const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
    if (FixupDiagnostic) {
      Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
      return 0;
    }
    uint64_t real_value = Value - 4;
    uint32_t out = 0;
    if (Kind == ARM::fixup_le)
      real_value = -real_value;
    out |= ((real_value >> 1) & 0x1) << 11;
    out |= ((real_value >> 1) & 0x7fe);
    return swapHalfWords(out, Endian == llvm::endianness::little);
  }
  }
}

bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
                                          const MCFixup &Fixup,
                                          const MCValue &Target, const uint64_t,
                                          const MCSubtargetInfo *STI) {
  const MCSymbolRefExpr *A = Target.getSymA();
  const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
  const unsigned FixupKind = Fixup.getKind();
  if (FixupKind >= FirstLiteralRelocationKind)
    return true;
  if (FixupKind == ARM::fixup_arm_thumb_bl) {
    assert(Sym && "How did we resolve this?");

    // If the symbol is external the linker will handle it.
    // FIXME: Should we handle it as an optimization?

    // If the symbol is out of range, produce a relocation and hope the
    // linker can handle it. GNU AS produces an error in this case.
    if (Sym->isExternal())
      return true;
  }
  // Create relocations for unconditional branches to function symbols with
  // different execution mode in ELF binaries.
  if (Sym && Sym->isELF()) {
    unsigned Type = cast<MCSymbolELF>(Sym)->getType();
    if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)) {
      if (Asm.isThumbFunc(Sym) && (FixupKind == ARM::fixup_arm_uncondbranch))
        return true;
      if (!Asm.isThumbFunc(Sym) && (FixupKind == ARM::fixup_arm_thumb_br ||
                                    FixupKind == ARM::fixup_arm_thumb_bl ||
                                    FixupKind == ARM::fixup_t2_condbranch ||
                                    FixupKind == ARM::fixup_t2_uncondbranch))
        return true;
    }
  }
  // We must always generate a relocation for BL/BLX instructions if we have
  // a symbol to reference, as the linker relies on knowing the destination
  // symbol's thumb-ness to get interworking right.
  if (A && (FixupKind == ARM::fixup_arm_thumb_blx ||
            FixupKind == ARM::fixup_arm_blx ||
            FixupKind == ARM::fixup_arm_uncondbl ||
            FixupKind == ARM::fixup_arm_condbl))
    return true;
  return false;
}

/// 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:
  case ARM::fixup_arm_thumb_bcc:
  case ARM::fixup_arm_thumb_cp:
  case ARM::fixup_thumb_adr_pcrel_10:
  case ARM::fixup_arm_thumb_upper_8_15:
  case ARM::fixup_arm_thumb_upper_0_7:
  case ARM::fixup_arm_thumb_lower_8_15:
  case ARM::fixup_arm_thumb_lower_0_7:
    return 1;

  case FK_Data_2:
  case ARM::fixup_arm_thumb_br:
  case ARM::fixup_arm_thumb_cb:
  case ARM::fixup_arm_mod_imm:
    return 2;

  case ARM::fixup_arm_pcrel_10_unscaled:
  case ARM::fixup_arm_ldst_pcrel_12:
  case ARM::fixup_arm_pcrel_10:
  case ARM::fixup_arm_pcrel_9:
  case ARM::fixup_arm_ldst_abs_12:
  case ARM::fixup_arm_adr_pcrel_12:
  case ARM::fixup_arm_uncondbl:
  case ARM::fixup_arm_condbl:
  case ARM::fixup_arm_blx:
  case ARM::fixup_arm_condbranch:
  case ARM::fixup_arm_uncondbranch:
    return 3;

  case FK_Data_4:
  case ARM::fixup_t2_ldst_pcrel_12:
  case ARM::fixup_t2_condbranch:
  case ARM::fixup_t2_uncondbranch:
  case ARM::fixup_t2_pcrel_10:
  case ARM::fixup_t2_pcrel_9:
  case ARM::fixup_t2_adr_pcrel_12:
  case ARM::fixup_arm_thumb_bl:
  case ARM::fixup_arm_thumb_blx:
  case ARM::fixup_arm_movt_hi16:
  case ARM::fixup_arm_movw_lo16:
  case ARM::fixup_t2_movt_hi16:
  case ARM::fixup_t2_movw_lo16:
  case ARM::fixup_t2_so_imm:
  case ARM::fixup_bf_branch:
  case ARM::fixup_bf_target:
  case ARM::fixup_bfl_target:
  case ARM::fixup_bfc_target:
  case ARM::fixup_bfcsel_else_target:
  case ARM::fixup_wls:
  case ARM::fixup_le:
    return 4;

  case FK_SecRel_2:
    return 2;
  case FK_SecRel_4:
    return 4;
  }
}

/// getFixupKindContainerSizeBytes - The number of bytes of the
/// container involved in big endian.
static unsigned getFixupKindContainerSizeBytes(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:
    return 4;

  case ARM::fixup_arm_thumb_bcc:
  case ARM::fixup_arm_thumb_cp:
  case ARM::fixup_thumb_adr_pcrel_10:
  case ARM::fixup_arm_thumb_br:
  case ARM::fixup_arm_thumb_cb:
  case ARM::fixup_arm_thumb_upper_8_15:
  case ARM::fixup_arm_thumb_upper_0_7:
  case ARM::fixup_arm_thumb_lower_8_15:
  case ARM::fixup_arm_thumb_lower_0_7:
    // Instruction size is 2 bytes.
    return 2;

  case ARM::fixup_arm_pcrel_10_unscaled:
  case ARM::fixup_arm_ldst_pcrel_12:
  case ARM::fixup_arm_pcrel_10:
  case ARM::fixup_arm_pcrel_9:
  case ARM::fixup_arm_adr_pcrel_12:
  case ARM::fixup_arm_uncondbl:
  case ARM::fixup_arm_condbl:
  case ARM::fixup_arm_blx:
  case ARM::fixup_arm_condbranch:
  case ARM::fixup_arm_uncondbranch:
  case ARM::fixup_t2_ldst_pcrel_12:
  case ARM::fixup_t2_condbranch:
  case ARM::fixup_t2_uncondbranch:
  case ARM::fixup_t2_pcrel_10:
  case ARM::fixup_t2_pcrel_9:
  case ARM::fixup_t2_adr_pcrel_12:
  case ARM::fixup_arm_thumb_bl:
  case ARM::fixup_arm_thumb_blx:
  case ARM::fixup_arm_movt_hi16:
  case ARM::fixup_arm_movw_lo16:
  case ARM::fixup_t2_movt_hi16:
  case ARM::fixup_t2_movw_lo16:
  case ARM::fixup_arm_mod_imm:
  case ARM::fixup_t2_so_imm:
  case ARM::fixup_bf_branch:
  case ARM::fixup_bf_target:
  case ARM::fixup_bfl_target:
  case ARM::fixup_bfc_target:
  case ARM::fixup_bfcsel_else_target:
  case ARM::fixup_wls:
  case ARM::fixup_le:
    // Instruction size is 4 bytes.
    return 4;
  }
}

void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                               const MCValue &Target,
                               MutableArrayRef<char> Data, uint64_t Value,
                               bool IsResolved,
                               const MCSubtargetInfo* STI) const {
  unsigned Kind = Fixup.getKind();
  if (Kind >= FirstLiteralRelocationKind)
    return;
  MCContext &Ctx = Asm.getContext();
  Value = adjustFixupValue(Asm, Fixup, Target, Value, IsResolved, Ctx, STI);
  if (!Value)
    return; // Doesn't change encoding.
  const unsigned NumBytes = getFixupKindNumBytes(Kind);

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

  // Used to point to big endian bytes.
  unsigned FullSizeBytes;
  if (Endian == llvm::endianness::big) {
    FullSizeBytes = getFixupKindContainerSizeBytes(Kind);
    assert((Offset + FullSizeBytes) <= Data.size() && "Invalid fixup size!");
    assert(NumBytes <= FullSizeBytes && "Invalid fixup size!");
  }

  // 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 : (FullSizeBytes - 1 - i);
    Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
  }
}

namespace CU {

/// Compact unwind encoding values.
enum CompactUnwindEncodings {
  UNWIND_ARM_MODE_MASK                         = 0x0F000000,
  UNWIND_ARM_MODE_FRAME                        = 0x01000000,
  UNWIND_ARM_MODE_FRAME_D                      = 0x02000000,
  UNWIND_ARM_MODE_DWARF                        = 0x04000000,

  UNWIND_ARM_FRAME_STACK_ADJUST_MASK           = 0x00C00000,

  UNWIND_ARM_FRAME_FIRST_PUSH_R4               = 0x00000001,
  UNWIND_ARM_FRAME_FIRST_PUSH_R5               = 0x00000002,
  UNWIND_ARM_FRAME_FIRST_PUSH_R6               = 0x00000004,

  UNWIND_ARM_FRAME_SECOND_PUSH_R8              = 0x00000008,
  UNWIND_ARM_FRAME_SECOND_PUSH_R9              = 0x00000010,
  UNWIND_ARM_FRAME_SECOND_PUSH_R10             = 0x00000020,
  UNWIND_ARM_FRAME_SECOND_PUSH_R11             = 0x00000040,
  UNWIND_ARM_FRAME_SECOND_PUSH_R12             = 0x00000080,

  UNWIND_ARM_FRAME_D_REG_COUNT_MASK            = 0x00000F00,

  UNWIND_ARM_DWARF_SECTION_OFFSET              = 0x00FFFFFF
};

} // end CU namespace

/// Generate compact unwind encoding for the function based on the CFI
/// instructions. If the CFI instructions describe a frame that cannot be
/// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which
/// tells the runtime to fallback and unwind using dwarf.
uint64_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
    const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const {
  DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n");
  // Only armv7k uses CFI based unwinding.
  if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K)
    return 0;
  // No .cfi directives means no frame.
  ArrayRef<MCCFIInstruction> Instrs = FI->Instructions;
  if (Instrs.empty())
    return 0;
  if (!isDarwinCanonicalPersonality(FI->Personality) &&
      !Ctxt->emitCompactUnwindNonCanonical())
    return CU::UNWIND_ARM_MODE_DWARF;

  // Start off assuming CFA is at SP+0.
  MCRegister CFARegister = ARM::SP;
  int CFARegisterOffset = 0;
  // Mark savable registers as initially unsaved
  DenseMap<MCRegister, int> RegOffsets;
  int FloatRegCount = 0;
  // Process each .cfi directive and build up compact unwind info.
  for (const MCCFIInstruction &Inst : Instrs) {
    MCRegister Reg;
    switch (Inst.getOperation()) {
    case MCCFIInstruction::OpDefCfa: // DW_CFA_def_cfa
      CFARegisterOffset = Inst.getOffset();
      CFARegister = *MRI.getLLVMRegNum(Inst.getRegister(), true);
      break;
    case MCCFIInstruction::OpDefCfaOffset: // DW_CFA_def_cfa_offset
      CFARegisterOffset = Inst.getOffset();
      break;
    case MCCFIInstruction::OpDefCfaRegister: // DW_CFA_def_cfa_register
      CFARegister = *MRI.getLLVMRegNum(Inst.getRegister(), true);
      break;
    case MCCFIInstruction::OpOffset: // DW_CFA_offset
      Reg = *MRI.getLLVMRegNum(Inst.getRegister(), true);
      if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
        RegOffsets[Reg] = Inst.getOffset();
      else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
        RegOffsets[Reg] = Inst.getOffset();
        ++FloatRegCount;
      } else {
        DEBUG_WITH_TYPE("compact-unwind",
                        llvm::dbgs() << ".cfi_offset on unknown register="
                                     << Inst.getRegister() << "\n");
        return CU::UNWIND_ARM_MODE_DWARF;
      }
      break;
    case MCCFIInstruction::OpRelOffset: // DW_CFA_advance_loc
      // Ignore
      break;
    default:
      // Directive not convertable to compact unwind, bail out.
      DEBUG_WITH_TYPE("compact-unwind",
                      llvm::dbgs()
                          << "CFI directive not compatible with compact "
                             "unwind encoding, opcode="
                          << uint8_t(Inst.getOperation()) << "\n");
      return CU::UNWIND_ARM_MODE_DWARF;
      break;
    }
  }

  // If no frame set up, return no unwind info.
  if ((CFARegister == ARM::SP) && (CFARegisterOffset == 0))
    return 0;

  // Verify standard frame (lr/r7) was used.
  if (CFARegister != ARM::R7) {
    DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "frame register is "
                                                   << CFARegister
                                                   << " instead of r7\n");
    return CU::UNWIND_ARM_MODE_DWARF;
  }
  int StackAdjust = CFARegisterOffset - 8;
  if (RegOffsets.lookup(ARM::LR) != (-4 - StackAdjust)) {
    DEBUG_WITH_TYPE(
        "compact-unwind",
        llvm::dbgs() << "LR not saved as standard frame, StackAdjust="
                     << StackAdjust
                     << ", CFARegisterOffset=" << CFARegisterOffset
                     << ", lr save at offset=" << RegOffsets[ARM::LR] << "\n");
    return CU::UNWIND_ARM_MODE_DWARF;
  }
  if (RegOffsets.lookup(ARM::R7) != (-8 - StackAdjust)) {
    DEBUG_WITH_TYPE("compact-unwind",
                    llvm::dbgs() << "r7 not saved as standard frame\n");
    return CU::UNWIND_ARM_MODE_DWARF;
  }
  uint32_t CompactUnwindEncoding = CU::UNWIND_ARM_MODE_FRAME;

  // If var-args are used, there may be a stack adjust required.
  switch (StackAdjust) {
  case 0:
    break;
  case 4:
    CompactUnwindEncoding |= 0x00400000;
    break;
  case 8:
    CompactUnwindEncoding |= 0x00800000;
    break;
  case 12:
    CompactUnwindEncoding |= 0x00C00000;
    break;
  default:
    DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs()
                                          << ".cfi_def_cfa stack adjust ("
                                          << StackAdjust << ") out of range\n");
    return CU::UNWIND_ARM_MODE_DWARF;
  }

  // If r6 is saved, it must be right below r7.
  static struct {
    unsigned Reg;
    unsigned Encoding;
  } GPRCSRegs[] = {{ARM::R6, CU::UNWIND_ARM_FRAME_FIRST_PUSH_R6},
                   {ARM::R5, CU::UNWIND_ARM_FRAME_FIRST_PUSH_R5},
                   {ARM::R4, CU::UNWIND_ARM_FRAME_FIRST_PUSH_R4},
                   {ARM::R12, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R12},
                   {ARM::R11, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R11},
                   {ARM::R10, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R10},
                   {ARM::R9, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R9},
                   {ARM::R8, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R8}};

  int CurOffset = -8 - StackAdjust;
  for (auto CSReg : GPRCSRegs) {
    auto Offset = RegOffsets.find(CSReg.Reg);
    if (Offset == RegOffsets.end())
      continue;

    int RegOffset = Offset->second;
    if (RegOffset != CurOffset - 4) {
      DEBUG_WITH_TYPE("compact-unwind",
                      llvm::dbgs() << MRI.getName(CSReg.Reg) << " saved at "
                                   << RegOffset << " but only supported at "
                                   << CurOffset << "\n");
      return CU::UNWIND_ARM_MODE_DWARF;
    }
    CompactUnwindEncoding |= CSReg.Encoding;
    CurOffset -= 4;
  }

  // If no floats saved, we are done.
  if (FloatRegCount == 0)
    return CompactUnwindEncoding;

  // Switch mode to include D register saving.
  CompactUnwindEncoding &= ~CU::UNWIND_ARM_MODE_MASK;
  CompactUnwindEncoding |= CU::UNWIND_ARM_MODE_FRAME_D;

  // FIXME: supporting more than 4 saved D-registers compactly would be trivial,
  // but needs coordination with the linker and libunwind.
  if (FloatRegCount > 4) {
    DEBUG_WITH_TYPE("compact-unwind",
                    llvm::dbgs() << "unsupported number of D registers saved ("
                                 << FloatRegCount << ")\n");
      return CU::UNWIND_ARM_MODE_DWARF;
  }

  // Floating point registers must either be saved sequentially, or we defer to
  // DWARF. No gaps allowed here so check that each saved d-register is
  // precisely where it should be.
  static MCPhysReg FPRCSRegs[] = {ARM::D8, ARM::D10, ARM::D12, ARM::D14};
  for (int Idx = FloatRegCount - 1; Idx >= 0; --Idx) {
    auto Offset = RegOffsets.find(FPRCSRegs[Idx]);
    if (Offset == RegOffsets.end()) {
      DEBUG_WITH_TYPE("compact-unwind",
                      llvm::dbgs() << FloatRegCount << " D-regs saved, but "
                                   << MRI.getName(FPRCSRegs[Idx])
                                   << " not saved\n");
      return CU::UNWIND_ARM_MODE_DWARF;
    } else if (Offset->second != CurOffset - 8) {
      DEBUG_WITH_TYPE("compact-unwind",
                      llvm::dbgs() << FloatRegCount << " D-regs saved, but "
                                   << MRI.getName(FPRCSRegs[Idx])
                                   << " saved at " << Offset->second
                                   << ", expected at " << CurOffset - 8
                                   << "\n");
      return CU::UNWIND_ARM_MODE_DWARF;
    }
    CurOffset -= 8;
  }

  return CompactUnwindEncoding | ((FloatRegCount - 1) << 8);
}

static MCAsmBackend *createARMAsmBackend(const Target &T,
                                         const MCSubtargetInfo &STI,
                                         const MCRegisterInfo &MRI,
                                         const MCTargetOptions &Options,
                                         llvm::endianness Endian) {
  const Triple &TheTriple = STI.getTargetTriple();
  switch (TheTriple.getObjectFormat()) {
  default:
    llvm_unreachable("unsupported object format");
  case Triple::MachO:
    return new ARMAsmBackendDarwin(T, STI, MRI);
  case Triple::COFF:
    assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported");
    return new ARMAsmBackendWinCOFF(T, STI.getTargetTriple().isThumb());
  case Triple::ELF:
    assert(TheTriple.isOSBinFormatELF() && "using ELF for non-ELF target");
    uint8_t OSABI = Options.FDPIC
                        ? ELF::ELFOSABI_ARM_FDPIC
                        : MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
    return new ARMAsmBackendELF(T, STI.getTargetTriple().isThumb(), OSABI,
                                Endian);
  }
}

MCAsmBackend *llvm::createARMLEAsmBackend(const Target &T,
                                          const MCSubtargetInfo &STI,
                                          const MCRegisterInfo &MRI,
                                          const MCTargetOptions &Options) {
  return createARMAsmBackend(T, STI, MRI, Options, llvm::endianness::little);
}

MCAsmBackend *llvm::createARMBEAsmBackend(const Target &T,
                                          const MCSubtargetInfo &STI,
                                          const MCRegisterInfo &MRI,
                                          const MCTargetOptions &Options) {
  return createARMAsmBackend(T, STI, MRI, Options, llvm::endianness::big);
}
