//===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file provides ARM specific target descriptions.
//
//===----------------------------------------------------------------------===//

#include "ARMMCTargetDesc.h"
#include "ARMAddressingModes.h"
#include "ARMBaseInfo.h"
#include "ARMInstPrinter.h"
#include "ARMMCAsmInfo.h"
#include "TargetInfo/ARMTargetInfo.h"
#include "llvm/ADT/Triple.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetParser.h"

using namespace llvm;

#define GET_REGINFO_MC_DESC
#include "ARMGenRegisterInfo.inc"

static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
                                  std::string &Info) {
  if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
      (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
      (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
      // Checks for the deprecated CP15ISB encoding:
      // mcr p15, #0, rX, c7, c5, #4
      (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
    if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
      if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
        Info = "deprecated since v7, use 'isb'";
        return true;
      }

      // Checks for the deprecated CP15DSB encoding:
      // mcr p15, #0, rX, c7, c10, #4
      if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
        Info = "deprecated since v7, use 'dsb'";
        return true;
      }
    }
    // Checks for the deprecated CP15DMB encoding:
    // mcr p15, #0, rX, c7, c10, #5
    if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
        (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
      Info = "deprecated since v7, use 'dmb'";
      return true;
    }
  }
  if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
      ((MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 10) ||
       (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 11))) {
    Info = "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
           "point instructions";
    return true;
  }
  return false;
}

static bool getMRCDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
                                  std::string &Info) {
  if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
      ((MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 10) ||
       (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 11))) {
    Info = "since v7, cp10 and cp11 are reserved for advanced SIMD or floating "
           "point instructions";
    return true;
  }
  return false;
}

static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
                                 std::string &Info) {
  if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
      MI.getOperand(1).getImm() != 8) {
    Info = "applying IT instruction to more than one subsequent instruction is "
           "deprecated";
    return true;
  }

  return false;
}

static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
                                       std::string &Info) {
  assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
         "cannot predicate thumb instructions");

  assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
  for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
    assert(MI.getOperand(OI).isReg() && "expected register");
    if (MI.getOperand(OI).getReg() == ARM::PC) {
      Info = "use of PC in the list is deprecated";
      return true;
    }
  }
  return false;
}

static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
                                      std::string &Info) {
  assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
         "cannot predicate thumb instructions");

  assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
  bool ListContainsPC = false, ListContainsLR = false;
  for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
    assert(MI.getOperand(OI).isReg() && "expected register");
    switch (MI.getOperand(OI).getReg()) {
    default:
      break;
    case ARM::LR:
      ListContainsLR = true;
      break;
    case ARM::PC:
      ListContainsPC = true;
      break;
    }
  }

  if (ListContainsPC && ListContainsLR) {
    Info = "use of LR and PC simultaneously in the list is deprecated";
    return true;
  }

  return false;
}

#define GET_INSTRINFO_MC_DESC
#include "ARMGenInstrInfo.inc"

#define GET_SUBTARGETINFO_MC_DESC
#include "ARMGenSubtargetInfo.inc"

std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
  std::string ARMArchFeature;

  ARM::ArchKind ArchID = ARM::parseArch(TT.getArchName());
  if (ArchID != ARM::ArchKind::INVALID &&  (CPU.empty() || CPU == "generic"))
    ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str();

  if (TT.isThumb()) {
    if (!ARMArchFeature.empty())
      ARMArchFeature += ",";
    ARMArchFeature += "+thumb-mode,+v4t";
  }

  if (TT.isOSNaCl()) {
    if (!ARMArchFeature.empty())
      ARMArchFeature += ",";
    ARMArchFeature += "+nacl-trap";
  }

  if (TT.isOSWindows()) {
    if (!ARMArchFeature.empty())
      ARMArchFeature += ",";
    ARMArchFeature += "+noarm";
  }

  return ARMArchFeature;
}

bool ARM_MC::isPredicated(const MCInst &MI, const MCInstrInfo *MCII) {
  const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
  int PredOpIdx = Desc.findFirstPredOperandIdx();
  return PredOpIdx != -1 && MI.getOperand(PredOpIdx).getImm() != ARMCC::AL;
}

bool ARM_MC::isCPSRDefined(const MCInst &MI, const MCInstrInfo *MCII) {
  const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
  for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
    const MCOperand &MO = MI.getOperand(I);
    if (MO.isReg() && MO.getReg() == ARM::CPSR &&
        Desc.OpInfo[I].isOptionalDef())
      return true;
  }
  return false;
}

uint64_t ARM_MC::evaluateBranchTarget(const MCInstrDesc &InstDesc,
                                      uint64_t Addr, int64_t Imm) {
  // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
  // is 4 bytes.
  uint64_t Offset =
      ((InstDesc.TSFlags & ARMII::FormMask) == ARMII::ThumbFrm) ? 4 : 8;

  // A Thumb instruction BLX(i) can be 16-bit aligned while targets Arm code
  // which is 32-bit aligned. The target address for the case is calculated as
  //   targetAddress = Align(PC,4) + imm32;
  // where
  //   Align(x, y) = y * (x DIV y);
  if (InstDesc.getOpcode() == ARM::tBLXi)
    Addr &= ~0x3;

  return Addr + Imm + Offset;
}

MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
                                                  StringRef CPU, StringRef FS) {
  std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
  if (!FS.empty()) {
    if (!ArchFS.empty())
      ArchFS = (Twine(ArchFS) + "," + FS).str();
    else
      ArchFS = std::string(FS);
  }

  return createARMMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, ArchFS);
}

static MCInstrInfo *createARMMCInstrInfo() {
  MCInstrInfo *X = new MCInstrInfo();
  InitARMMCInstrInfo(X);
  return X;
}

void ARM_MC::initLLVMToCVRegMapping(MCRegisterInfo *MRI) {
  // Mapping from CodeView to MC register id.
  static const struct {
    codeview::RegisterId CVReg;
    MCPhysReg Reg;
  } RegMap[] = {
      {codeview::RegisterId::ARM_R0, ARM::R0},
      {codeview::RegisterId::ARM_R1, ARM::R1},
      {codeview::RegisterId::ARM_R2, ARM::R2},
      {codeview::RegisterId::ARM_R3, ARM::R3},
      {codeview::RegisterId::ARM_R4, ARM::R4},
      {codeview::RegisterId::ARM_R5, ARM::R5},
      {codeview::RegisterId::ARM_R6, ARM::R6},
      {codeview::RegisterId::ARM_R7, ARM::R7},
      {codeview::RegisterId::ARM_R8, ARM::R8},
      {codeview::RegisterId::ARM_R9, ARM::R9},
      {codeview::RegisterId::ARM_R10, ARM::R10},
      {codeview::RegisterId::ARM_R11, ARM::R11},
      {codeview::RegisterId::ARM_R12, ARM::R12},
      {codeview::RegisterId::ARM_SP, ARM::SP},
      {codeview::RegisterId::ARM_LR, ARM::LR},
      {codeview::RegisterId::ARM_PC, ARM::PC},
      {codeview::RegisterId::ARM_CPSR, ARM::CPSR},
      {codeview::RegisterId::ARM_FPSCR, ARM::FPSCR},
      {codeview::RegisterId::ARM_FPEXC, ARM::FPEXC},
      {codeview::RegisterId::ARM_FS0, ARM::S0},
      {codeview::RegisterId::ARM_FS1, ARM::S1},
      {codeview::RegisterId::ARM_FS2, ARM::S2},
      {codeview::RegisterId::ARM_FS3, ARM::S3},
      {codeview::RegisterId::ARM_FS4, ARM::S4},
      {codeview::RegisterId::ARM_FS5, ARM::S5},
      {codeview::RegisterId::ARM_FS6, ARM::S6},
      {codeview::RegisterId::ARM_FS7, ARM::S7},
      {codeview::RegisterId::ARM_FS8, ARM::S8},
      {codeview::RegisterId::ARM_FS9, ARM::S9},
      {codeview::RegisterId::ARM_FS10, ARM::S10},
      {codeview::RegisterId::ARM_FS11, ARM::S11},
      {codeview::RegisterId::ARM_FS12, ARM::S12},
      {codeview::RegisterId::ARM_FS13, ARM::S13},
      {codeview::RegisterId::ARM_FS14, ARM::S14},
      {codeview::RegisterId::ARM_FS15, ARM::S15},
      {codeview::RegisterId::ARM_FS16, ARM::S16},
      {codeview::RegisterId::ARM_FS17, ARM::S17},
      {codeview::RegisterId::ARM_FS18, ARM::S18},
      {codeview::RegisterId::ARM_FS19, ARM::S19},
      {codeview::RegisterId::ARM_FS20, ARM::S20},
      {codeview::RegisterId::ARM_FS21, ARM::S21},
      {codeview::RegisterId::ARM_FS22, ARM::S22},
      {codeview::RegisterId::ARM_FS23, ARM::S23},
      {codeview::RegisterId::ARM_FS24, ARM::S24},
      {codeview::RegisterId::ARM_FS25, ARM::S25},
      {codeview::RegisterId::ARM_FS26, ARM::S26},
      {codeview::RegisterId::ARM_FS27, ARM::S27},
      {codeview::RegisterId::ARM_FS28, ARM::S28},
      {codeview::RegisterId::ARM_FS29, ARM::S29},
      {codeview::RegisterId::ARM_FS30, ARM::S30},
      {codeview::RegisterId::ARM_FS31, ARM::S31},
      {codeview::RegisterId::ARM_ND0, ARM::D0},
      {codeview::RegisterId::ARM_ND1, ARM::D1},
      {codeview::RegisterId::ARM_ND2, ARM::D2},
      {codeview::RegisterId::ARM_ND3, ARM::D3},
      {codeview::RegisterId::ARM_ND4, ARM::D4},
      {codeview::RegisterId::ARM_ND5, ARM::D5},
      {codeview::RegisterId::ARM_ND6, ARM::D6},
      {codeview::RegisterId::ARM_ND7, ARM::D7},
      {codeview::RegisterId::ARM_ND8, ARM::D8},
      {codeview::RegisterId::ARM_ND9, ARM::D9},
      {codeview::RegisterId::ARM_ND10, ARM::D10},
      {codeview::RegisterId::ARM_ND11, ARM::D11},
      {codeview::RegisterId::ARM_ND12, ARM::D12},
      {codeview::RegisterId::ARM_ND13, ARM::D13},
      {codeview::RegisterId::ARM_ND14, ARM::D14},
      {codeview::RegisterId::ARM_ND15, ARM::D15},
      {codeview::RegisterId::ARM_ND16, ARM::D16},
      {codeview::RegisterId::ARM_ND17, ARM::D17},
      {codeview::RegisterId::ARM_ND18, ARM::D18},
      {codeview::RegisterId::ARM_ND19, ARM::D19},
      {codeview::RegisterId::ARM_ND20, ARM::D20},
      {codeview::RegisterId::ARM_ND21, ARM::D21},
      {codeview::RegisterId::ARM_ND22, ARM::D22},
      {codeview::RegisterId::ARM_ND23, ARM::D23},
      {codeview::RegisterId::ARM_ND24, ARM::D24},
      {codeview::RegisterId::ARM_ND25, ARM::D25},
      {codeview::RegisterId::ARM_ND26, ARM::D26},
      {codeview::RegisterId::ARM_ND27, ARM::D27},
      {codeview::RegisterId::ARM_ND28, ARM::D28},
      {codeview::RegisterId::ARM_ND29, ARM::D29},
      {codeview::RegisterId::ARM_ND30, ARM::D30},
      {codeview::RegisterId::ARM_ND31, ARM::D31},
      {codeview::RegisterId::ARM_NQ0, ARM::Q0},
      {codeview::RegisterId::ARM_NQ1, ARM::Q1},
      {codeview::RegisterId::ARM_NQ2, ARM::Q2},
      {codeview::RegisterId::ARM_NQ3, ARM::Q3},
      {codeview::RegisterId::ARM_NQ4, ARM::Q4},
      {codeview::RegisterId::ARM_NQ5, ARM::Q5},
      {codeview::RegisterId::ARM_NQ6, ARM::Q6},
      {codeview::RegisterId::ARM_NQ7, ARM::Q7},
      {codeview::RegisterId::ARM_NQ8, ARM::Q8},
      {codeview::RegisterId::ARM_NQ9, ARM::Q9},
      {codeview::RegisterId::ARM_NQ10, ARM::Q10},
      {codeview::RegisterId::ARM_NQ11, ARM::Q11},
      {codeview::RegisterId::ARM_NQ12, ARM::Q12},
      {codeview::RegisterId::ARM_NQ13, ARM::Q13},
      {codeview::RegisterId::ARM_NQ14, ARM::Q14},
      {codeview::RegisterId::ARM_NQ15, ARM::Q15},
  };
  for (unsigned I = 0; I < array_lengthof(RegMap); ++I)
    MRI->mapLLVMRegToCVReg(RegMap[I].Reg, static_cast<int>(RegMap[I].CVReg));
}

static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
  MCRegisterInfo *X = new MCRegisterInfo();
  InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
  ARM_MC::initLLVMToCVRegMapping(X);
  return X;
}

static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI,
                                     const Triple &TheTriple,
                                     const MCTargetOptions &Options) {
  MCAsmInfo *MAI;
  if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO())
    MAI = new ARMMCAsmInfoDarwin(TheTriple);
  else if (TheTriple.isWindowsMSVCEnvironment())
    MAI = new ARMCOFFMCAsmInfoMicrosoft();
  else if (TheTriple.isOSWindows())
    MAI = new ARMCOFFMCAsmInfoGNU();
  else
    MAI = new ARMELFMCAsmInfo(TheTriple);

  unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
  MAI->addInitialFrameState(MCCFIInstruction::cfiDefCfa(nullptr, Reg, 0));

  return MAI;
}

static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
                                     std::unique_ptr<MCAsmBackend> &&MAB,
                                     std::unique_ptr<MCObjectWriter> &&OW,
                                     std::unique_ptr<MCCodeEmitter> &&Emitter,
                                     bool RelaxAll) {
  return createARMELFStreamer(
      Ctx, std::move(MAB), std::move(OW), std::move(Emitter), false,
      (T.getArch() == Triple::thumb || T.getArch() == Triple::thumbeb),
      T.isAndroid());
}

static MCStreamer *
createARMMachOStreamer(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&MAB,
                       std::unique_ptr<MCObjectWriter> &&OW,
                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
                       bool DWARFMustBeAtTheEnd) {
  return createMachOStreamer(Ctx, std::move(MAB), std::move(OW),
                             std::move(Emitter), false, DWARFMustBeAtTheEnd);
}

static MCInstPrinter *createARMMCInstPrinter(const Triple &T,
                                             unsigned SyntaxVariant,
                                             const MCAsmInfo &MAI,
                                             const MCInstrInfo &MII,
                                             const MCRegisterInfo &MRI) {
  if (SyntaxVariant == 0)
    return new ARMInstPrinter(MAI, MII, MRI);
  return nullptr;
}

static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT,
                                                   MCContext &Ctx) {
  if (TT.isOSBinFormatMachO())
    return createARMMachORelocationInfo(Ctx);
  // Default to the stock relocation info.
  return llvm::createMCRelocationInfo(TT, Ctx);
}

namespace {

class ARMMCInstrAnalysis : public MCInstrAnalysis {
public:
  ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}

  bool isUnconditionalBranch(const MCInst &Inst) const override {
    // BCCs with the "always" predicate are unconditional branches.
    if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
      return true;
    return MCInstrAnalysis::isUnconditionalBranch(Inst);
  }

  bool isConditionalBranch(const MCInst &Inst) const override {
    // BCCs with the "always" predicate are unconditional branches.
    if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL)
      return false;
    return MCInstrAnalysis::isConditionalBranch(Inst);
  }

  bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
                      uint64_t &Target) const override {
    const MCInstrDesc &Desc = Info->get(Inst.getOpcode());

    // Find the PC-relative immediate operand in the instruction.
    for (unsigned OpNum = 0; OpNum < Desc.getNumOperands(); ++OpNum) {
      if (Inst.getOperand(OpNum).isImm() &&
          Desc.OpInfo[OpNum].OperandType == MCOI::OPERAND_PCREL) {
        int64_t Imm = Inst.getOperand(OpNum).getImm();
        Target = ARM_MC::evaluateBranchTarget(Desc, Addr, Imm);
        return true;
      }
    }
    return false;
  }

  Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
                                                  const MCSubtargetInfo *STI,
                                                  uint64_t Addr,
                                                  uint64_t Size) const override;
};

} // namespace

static Optional<uint64_t>
// NOLINTNEXTLINE(readability-identifier-naming)
evaluateMemOpAddrForAddrMode_i12(const MCInst &Inst, const MCInstrDesc &Desc,
                                 unsigned MemOpIndex, uint64_t Addr) {
  if (MemOpIndex + 1 >= Desc.getNumOperands())
    return None;

  const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
  const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
  if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
    return None;

  int32_t OffImm = (int32_t)MO2.getImm();
  // Special value for #-0. All others are normal.
  if (OffImm == INT32_MIN)
    OffImm = 0;
  return Addr + OffImm;
}

static Optional<uint64_t> evaluateMemOpAddrForAddrMode3(const MCInst &Inst,
                                                        const MCInstrDesc &Desc,
                                                        unsigned MemOpIndex,
                                                        uint64_t Addr) {
  if (MemOpIndex + 2 >= Desc.getNumOperands())
    return None;

  const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
  const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
  const MCOperand &MO3 = Inst.getOperand(MemOpIndex + 2);
  if (!MO1.isReg() || MO1.getReg() != ARM::PC || MO2.getReg() || !MO3.isImm())
    return None;

  unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
  ARM_AM::AddrOpc Op = ARM_AM::getAM3Op(MO3.getImm());

  if (Op == ARM_AM::sub)
    return Addr - ImmOffs;
  return Addr + ImmOffs;
}

static Optional<uint64_t> evaluateMemOpAddrForAddrMode5(const MCInst &Inst,
                                                        const MCInstrDesc &Desc,
                                                        unsigned MemOpIndex,
                                                        uint64_t Addr) {
  if (MemOpIndex + 1 >= Desc.getNumOperands())
    return None;

  const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
  const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
  if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
    return None;

  unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
  ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());

  if (Op == ARM_AM::sub)
    return Addr - ImmOffs * 4;
  return Addr + ImmOffs * 4;
}

static Optional<uint64_t>
evaluateMemOpAddrForAddrMode5FP16(const MCInst &Inst, const MCInstrDesc &Desc,
                                  unsigned MemOpIndex, uint64_t Addr) {
  if (MemOpIndex + 1 >= Desc.getNumOperands())
    return None;

  const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
  const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
  if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
    return None;

  unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
  ARM_AM::AddrOpc Op = ARM_AM::getAM5FP16Op(MO2.getImm());

  if (Op == ARM_AM::sub)
    return Addr - ImmOffs * 2;
  return Addr + ImmOffs * 2;
}

static Optional<uint64_t>
// NOLINTNEXTLINE(readability-identifier-naming)
evaluateMemOpAddrForAddrModeT2_i8s4(const MCInst &Inst, const MCInstrDesc &Desc,
                                    unsigned MemOpIndex, uint64_t Addr) {
  if (MemOpIndex + 1 >= Desc.getNumOperands())
    return None;

  const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
  const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
  if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
    return None;

  int32_t OffImm = (int32_t)MO2.getImm();
  assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");

  // Special value for #-0. All others are normal.
  if (OffImm == INT32_MIN)
    OffImm = 0;
  return Addr + OffImm;
}

static Optional<uint64_t>
// NOLINTNEXTLINE(readability-identifier-naming)
evaluateMemOpAddrForAddrModeT2_pc(const MCInst &Inst, const MCInstrDesc &Desc,
                                  unsigned MemOpIndex, uint64_t Addr) {
  const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
  if (!MO1.isImm())
    return None;

  int32_t OffImm = (int32_t)MO1.getImm();

  // Special value for #-0. All others are normal.
  if (OffImm == INT32_MIN)
    OffImm = 0;
  return Addr + OffImm;
}

static Optional<uint64_t>
// NOLINTNEXTLINE(readability-identifier-naming)
evaluateMemOpAddrForAddrModeT1_s(const MCInst &Inst, const MCInstrDesc &Desc,
                                 unsigned MemOpIndex, uint64_t Addr) {
  return evaluateMemOpAddrForAddrModeT2_pc(Inst, Desc, MemOpIndex, Addr);
}

Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
    const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
    uint64_t Size) const {
  const MCInstrDesc &Desc = Info->get(Inst.getOpcode());

  // Only load instructions can have PC-relative memory addressing.
  if (!Desc.mayLoad())
    return None;

  // PC-relative addressing does not update the base register.
  uint64_t TSFlags = Desc.TSFlags;
  unsigned IndexMode =
      (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
  if (IndexMode != ARMII::IndexModeNone)
    return None;

  // Find the memory addressing operand in the instruction.
  unsigned OpIndex = Desc.NumDefs;
  while (OpIndex < Desc.getNumOperands() &&
         Desc.OpInfo[OpIndex].OperandType != MCOI::OPERAND_MEMORY)
    ++OpIndex;
  if (OpIndex == Desc.getNumOperands())
    return None;

  // Base address for PC-relative addressing is always 32-bit aligned.
  Addr &= ~0x3;

  // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
  // is 4 bytes.
  switch (Desc.TSFlags & ARMII::FormMask) {
  default:
    Addr += 8;
    break;
  case ARMII::ThumbFrm:
    Addr += 4;
    break;
  // VLDR* instructions share the same opcode (and thus the same form) for Arm
  // and Thumb. Use a bit longer route through STI in that case.
  case ARMII::VFPLdStFrm:
    Addr += STI->getFeatureBits()[ARM::ModeThumb] ? 4 : 8;
    break;
  }

  // Eveluate the address depending on the addressing mode
  unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
  switch (AddrMode) {
  default:
    return None;
  case ARMII::AddrMode_i12:
    return evaluateMemOpAddrForAddrMode_i12(Inst, Desc, OpIndex, Addr);
  case ARMII::AddrMode3:
    return evaluateMemOpAddrForAddrMode3(Inst, Desc, OpIndex, Addr);
  case ARMII::AddrMode5:
    return evaluateMemOpAddrForAddrMode5(Inst, Desc, OpIndex, Addr);
  case ARMII::AddrMode5FP16:
    return evaluateMemOpAddrForAddrMode5FP16(Inst, Desc, OpIndex, Addr);
  case ARMII::AddrModeT2_i8s4:
    return evaluateMemOpAddrForAddrModeT2_i8s4(Inst, Desc, OpIndex, Addr);
  case ARMII::AddrModeT2_pc:
    return evaluateMemOpAddrForAddrModeT2_pc(Inst, Desc, OpIndex, Addr);
  case ARMII::AddrModeT1_s:
    return evaluateMemOpAddrForAddrModeT1_s(Inst, Desc, OpIndex, Addr);
  }
}

static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
  return new ARMMCInstrAnalysis(Info);
}

bool ARM::isCDECoproc(size_t Coproc, const MCSubtargetInfo &STI) {
  // Unfortunately we don't have ARMTargetInfo in the disassembler, so we have
  // to rely on feature bits.
  if (Coproc >= 8)
    return false;
  return STI.getFeatureBits()[ARM::FeatureCoprocCDE0 + Coproc];
}

// Force static initialization.
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTargetMC() {
  for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(),
                    &getTheThumbLETarget(), &getTheThumbBETarget()}) {
    // Register the MC asm info.
    RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);

    // Register the MC instruction info.
    TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);

    // Register the MC register info.
    TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);

    // Register the MC subtarget info.
    TargetRegistry::RegisterMCSubtargetInfo(*T,
                                            ARM_MC::createARMMCSubtargetInfo);

    TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
    TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer);
    TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer);

    // Register the obj target streamer.
    TargetRegistry::RegisterObjectTargetStreamer(*T,
                                                 createARMObjectTargetStreamer);

    // Register the asm streamer.
    TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer);

    // Register the null TargetStreamer.
    TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer);

    // Register the MCInstPrinter.
    TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter);

    // Register the MC relocation info.
    TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo);
  }

  // Register the MC instruction analyzer.
  for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(),
                    &getTheThumbLETarget(), &getTheThumbBETarget()})
    TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis);

  for (Target *T : {&getTheARMLETarget(), &getTheThumbLETarget()}) {
    TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
    TargetRegistry::RegisterMCAsmBackend(*T, createARMLEAsmBackend);
  }
  for (Target *T : {&getTheARMBETarget(), &getTheThumbBETarget()}) {
    TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
    TargetRegistry::RegisterMCAsmBackend(*T, createARMBEAsmBackend);
  }
}
