//===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
//
// 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 class prints an ARM MCInst to a .s file.
//
//===----------------------------------------------------------------------===//

#include "ARMInstPrinter.h"
#include "Utils/ARMBaseInfo.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMBaseInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstdint>

using namespace llvm;

#define DEBUG_TYPE "asm-printer"

#define PRINT_ALIAS_INSTR
#include "ARMGenAsmWriter.inc"

/// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
///
/// getSORegOffset returns an integer from 0-31, representing '32' as 0.
static unsigned translateShiftImm(unsigned imm) {
  // lsr #32 and asr #32 exist, but should be encoded as a 0.
  assert((imm & ~0x1f) == 0 && "Invalid shift encoding");

  if (imm == 0)
    return 32;
  return imm;
}

/// Prints the shift value with an immediate value.
static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
                             unsigned ShImm, bool UseMarkup) {
  if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
    return;
  O << ", ";

  assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
  O << getShiftOpcStr(ShOpc);

  if (ShOpc != ARM_AM::rrx) {
    O << " ";
    if (UseMarkup)
      O << "<imm:";
    O << "#" << translateShiftImm(ShImm);
    if (UseMarkup)
      O << ">";
  }
}

ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
                               const MCRegisterInfo &MRI)
    : MCInstPrinter(MAI, MII, MRI) {}

bool ARMInstPrinter::applyTargetSpecificCLOption(StringRef Opt) {
  if (Opt == "reg-names-std") {
    DefaultAltIdx = ARM::NoRegAltName;
    return true;
  }
  if (Opt == "reg-names-raw") {
    DefaultAltIdx = ARM::RegNamesRaw;
    return true;
  }
  return false;
}

void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
  OS << markup("<reg:") << getRegisterName(RegNo, DefaultAltIdx) << markup(">");
}

void ARMInstPrinter::printInst(const MCInst *MI, uint64_t Address,
                               StringRef Annot, const MCSubtargetInfo &STI,
                               raw_ostream &O) {
  unsigned Opcode = MI->getOpcode();

  switch (Opcode) {
  // Check for MOVs and print canonical forms, instead.
  case ARM::MOVsr: {
    // FIXME: Thumb variants?
    const MCOperand &Dst = MI->getOperand(0);
    const MCOperand &MO1 = MI->getOperand(1);
    const MCOperand &MO2 = MI->getOperand(2);
    const MCOperand &MO3 = MI->getOperand(3);

    O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
    printSBitModifierOperand(MI, 6, STI, O);
    printPredicateOperand(MI, 4, STI, O);

    O << '\t';
    printRegName(O, Dst.getReg());
    O << ", ";
    printRegName(O, MO1.getReg());

    O << ", ";
    printRegName(O, MO2.getReg());
    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
    printAnnotation(O, Annot);
    return;
  }

  case ARM::MOVsi: {
    // FIXME: Thumb variants?
    const MCOperand &Dst = MI->getOperand(0);
    const MCOperand &MO1 = MI->getOperand(1);
    const MCOperand &MO2 = MI->getOperand(2);

    O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()));
    printSBitModifierOperand(MI, 5, STI, O);
    printPredicateOperand(MI, 3, STI, O);

    O << '\t';
    printRegName(O, Dst.getReg());
    O << ", ";
    printRegName(O, MO1.getReg());

    if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) {
      printAnnotation(O, Annot);
      return;
    }

    O << ", " << markup("<imm:") << "#"
      << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) << markup(">");
    printAnnotation(O, Annot);
    return;
  }

  // A8.6.123 PUSH
  case ARM::STMDB_UPD:
  case ARM::t2STMDB_UPD:
    if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
      // Should only print PUSH if there are at least two registers in the list.
      O << '\t' << "push";
      printPredicateOperand(MI, 2, STI, O);
      if (Opcode == ARM::t2STMDB_UPD)
        O << ".w";
      O << '\t';
      printRegisterList(MI, 4, STI, O);
      printAnnotation(O, Annot);
      return;
    } else
      break;

  case ARM::STR_PRE_IMM:
    if (MI->getOperand(2).getReg() == ARM::SP &&
        MI->getOperand(3).getImm() == -4) {
      O << '\t' << "push";
      printPredicateOperand(MI, 4, STI, O);
      O << "\t{";
      printRegName(O, MI->getOperand(1).getReg());
      O << "}";
      printAnnotation(O, Annot);
      return;
    } else
      break;

  // A8.6.122 POP
  case ARM::LDMIA_UPD:
  case ARM::t2LDMIA_UPD:
    if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
      // Should only print POP if there are at least two registers in the list.
      O << '\t' << "pop";
      printPredicateOperand(MI, 2, STI, O);
      if (Opcode == ARM::t2LDMIA_UPD)
        O << ".w";
      O << '\t';
      printRegisterList(MI, 4, STI, O);
      printAnnotation(O, Annot);
      return;
    } else
      break;

  case ARM::LDR_POST_IMM:
    if (MI->getOperand(2).getReg() == ARM::SP &&
        MI->getOperand(4).getImm() == 4) {
      O << '\t' << "pop";
      printPredicateOperand(MI, 5, STI, O);
      O << "\t{";
      printRegName(O, MI->getOperand(0).getReg());
      O << "}";
      printAnnotation(O, Annot);
      return;
    } else
      break;

  // A8.6.355 VPUSH
  case ARM::VSTMSDB_UPD:
  case ARM::VSTMDDB_UPD:
    if (MI->getOperand(0).getReg() == ARM::SP) {
      O << '\t' << "vpush";
      printPredicateOperand(MI, 2, STI, O);
      O << '\t';
      printRegisterList(MI, 4, STI, O);
      printAnnotation(O, Annot);
      return;
    } else
      break;

  // A8.6.354 VPOP
  case ARM::VLDMSIA_UPD:
  case ARM::VLDMDIA_UPD:
    if (MI->getOperand(0).getReg() == ARM::SP) {
      O << '\t' << "vpop";
      printPredicateOperand(MI, 2, STI, O);
      O << '\t';
      printRegisterList(MI, 4, STI, O);
      printAnnotation(O, Annot);
      return;
    } else
      break;

  case ARM::tLDMIA: {
    bool Writeback = true;
    unsigned BaseReg = MI->getOperand(0).getReg();
    for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
      if (MI->getOperand(i).getReg() == BaseReg)
        Writeback = false;
    }

    O << "\tldm";

    printPredicateOperand(MI, 1, STI, O);
    O << '\t';
    printRegName(O, BaseReg);
    if (Writeback)
      O << "!";
    O << ", ";
    printRegisterList(MI, 3, STI, O);
    printAnnotation(O, Annot);
    return;
  }

  // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
  // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
  // a single GPRPair reg operand is used in the .td file to replace the two
  // GPRs. However, when decoding them, the two GRPs cannot be automatically
  // expressed as a GPRPair, so we have to manually merge them.
  // FIXME: We would really like to be able to tablegen'erate this.
  case ARM::LDREXD:
  case ARM::STREXD:
  case ARM::LDAEXD:
  case ARM::STLEXD: {
    const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
    bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
    unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
    if (MRC.contains(Reg)) {
      MCInst NewMI;
      MCOperand NewReg;
      NewMI.setOpcode(Opcode);

      if (isStore)
        NewMI.addOperand(MI->getOperand(0));
      NewReg = MCOperand::createReg(MRI.getMatchingSuperReg(
          Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID)));
      NewMI.addOperand(NewReg);

      // Copy the rest operands into NewMI.
      for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
        NewMI.addOperand(MI->getOperand(i));
      printInstruction(&NewMI, Address, STI, O);
      return;
    }
    break;
  }
  case ARM::TSB:
  case ARM::t2TSB:
    O << "\ttsb\tcsync";
    return;
  case ARM::t2DSB:
    switch (MI->getOperand(0).getImm()) {
    default:
      if (!printAliasInstr(MI, Address, STI, O))
        printInstruction(MI, Address, STI, O);
      break;
    case 0:
      O << "\tssbb";
      break;
    case 4:
      O << "\tpssbb";
      break;
    }
    printAnnotation(O, Annot);
    return;
  }

  if (!printAliasInstr(MI, Address, STI, O))
    printInstruction(MI, Address, STI, O);

  printAnnotation(O, Annot);
}

void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
                                  const MCSubtargetInfo &STI, raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNo);
  if (Op.isReg()) {
    unsigned Reg = Op.getReg();
    printRegName(O, Reg);
  } else if (Op.isImm()) {
    O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">");
  } else {
    assert(Op.isExpr() && "unknown operand kind in printOperand");
    const MCExpr *Expr = Op.getExpr();
    switch (Expr->getKind()) {
    case MCExpr::Binary:
      O << '#';
      Expr->print(O, &MAI);
      break;
    case MCExpr::Constant: {
      // If a symbolic branch target was added as a constant expression then
      // print that address in hex. And only print 32 unsigned bits for the
      // address.
      const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
      int64_t TargetAddress;
      if (!Constant->evaluateAsAbsolute(TargetAddress)) {
        O << '#';
        Expr->print(O, &MAI);
      } else {
        O << "0x";
        O.write_hex(static_cast<uint32_t>(TargetAddress));
      }
      break;
    }
    default:
      // FIXME: Should we always treat this as if it is a constant literal and
      // prefix it with '#'?
      Expr->print(O, &MAI);
      break;
    }
  }
}

void ARMInstPrinter::printOperand(const MCInst *MI, uint64_t Address,
                                  unsigned OpNum, const MCSubtargetInfo &STI,
                                  raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNum);
  if (!Op.isImm() || !PrintBranchImmAsAddress || getUseMarkup())
    return printOperand(MI, OpNum, STI, O);
  uint64_t Target = ARM_MC::evaluateBranchTarget(MII.get(MI->getOpcode()),
                                                 Address, Op.getImm());
  Target &= 0xffffffff;
  O << formatHex(Target);
  if (CommentStream)
    *CommentStream << "imm = #" << formatImm(Op.getImm()) << '\n';
}

void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
                                               const MCSubtargetInfo &STI,
                                               raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  if (MO1.isExpr()) {
    MO1.getExpr()->print(O, &MAI);
    return;
  }

  O << markup("<mem:") << "[pc, ";

  int32_t OffImm = (int32_t)MO1.getImm();
  bool isSub = OffImm < 0;

  // Special value for #-0. All others are normal.
  if (OffImm == INT32_MIN)
    OffImm = 0;
  if (isSub) {
    O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
  } else {
    O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
  }
  O << "]" << markup(">");
}

// so_reg is a 4-operand unit corresponding to register forms of the A5.1
// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
//    REG 0   0           - e.g. R5
//    REG REG 0,SH_OPC    - e.g. R5, ROR R3
//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  const MCOperand &MO3 = MI->getOperand(OpNum + 2);

  printRegName(O, MO1.getReg());

  // Print the shift opc.
  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
  if (ShOpc == ARM_AM::rrx)
    return;

  O << ' ';
  printRegName(O, MO2.getReg());
  assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
}

void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  printRegName(O, MO1.getReg());

  // Print the shift opc.
  printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
                   ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
}

//===--------------------------------------------------------------------===//
// Addressing Mode #2
//===--------------------------------------------------------------------===//

void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
                                                const MCSubtargetInfo &STI,
                                                raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(Op);
  const MCOperand &MO2 = MI->getOperand(Op + 1);
  const MCOperand &MO3 = MI->getOperand(Op + 2);

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());

  if (!MO2.getReg()) {
    if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
      O << ", " << markup("<imm:") << "#"
        << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
        << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">");
    }
    O << "]" << markup(">");
    return;
  }

  O << ", ";
  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()));
  printRegName(O, MO2.getReg());

  printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
                   ARM_AM::getAM2Offset(MO3.getImm()), UseMarkup);
  O << "]" << markup(">");
}

void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
                                      const MCSubtargetInfo &STI,
                                      raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(Op);
  const MCOperand &MO2 = MI->getOperand(Op + 1);
  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());
  O << ", ";
  printRegName(O, MO2.getReg());
  O << "]" << markup(">");
}

void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
                                      const MCSubtargetInfo &STI,
                                      raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(Op);
  const MCOperand &MO2 = MI->getOperand(Op + 1);
  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());
  O << ", ";
  printRegName(O, MO2.getReg());
  O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">");
}

void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(Op);

  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
    printOperand(MI, Op, STI, O);
    return;
  }

#ifndef NDEBUG
  const MCOperand &MO3 = MI->getOperand(Op + 2);
  unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
  assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
#endif

  printAM2PreOrOffsetIndexOp(MI, Op, STI, O);
}

void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
                                                 unsigned OpNum,
                                                 const MCSubtargetInfo &STI,
                                                 raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  if (!MO1.getReg()) {
    unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
    O << markup("<imm:") << '#'
      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs
      << markup(">");
    return;
  }

  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()));
  printRegName(O, MO1.getReg());

  printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
                   ARM_AM::getAM2Offset(MO2.getImm()), UseMarkup);
}

//===--------------------------------------------------------------------===//
// Addressing Mode #3
//===--------------------------------------------------------------------===//

void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
                                                raw_ostream &O,
                                                bool AlwaysPrintImm0) {
  const MCOperand &MO1 = MI->getOperand(Op);
  const MCOperand &MO2 = MI->getOperand(Op + 1);
  const MCOperand &MO3 = MI->getOperand(Op + 2);

  O << markup("<mem:") << '[';
  printRegName(O, MO1.getReg());

  if (MO2.getReg()) {
    O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
    printRegName(O, MO2.getReg());
    O << ']' << markup(">");
    return;
  }

  // If the op is sub we have to print the immediate even if it is 0
  unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
  ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm());

  if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
    O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs
      << markup(">");
  }
  O << ']' << markup(">");
}

template <bool AlwaysPrintImm0>
void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(Op);
  if (!MO1.isReg()) { //  For label symbolic references.
    printOperand(MI, Op, STI, O);
    return;
  }

  assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) !=
             ARMII::IndexModePost &&
         "unexpected idxmode");
  printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
}

void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
                                                 unsigned OpNum,
                                                 const MCSubtargetInfo &STI,
                                                 raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  if (MO1.getReg()) {
    O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()));
    printRegName(O, MO1.getReg());
    return;
  }

  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
  O << markup("<imm:") << '#'
    << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs
    << markup(">");
}

void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum,
                                             const MCSubtargetInfo &STI,
                                             raw_ostream &O) {
  const MCOperand &MO = MI->getOperand(OpNum);
  unsigned Imm = MO.getImm();
  O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff)
    << markup(">");
}

void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum,
                                            const MCSubtargetInfo &STI,
                                            raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  O << (MO2.getImm() ? "" : "-");
  printRegName(O, MO1.getReg());
}

void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum,
                                               const MCSubtargetInfo &STI,
                                               raw_ostream &O) {
  const MCOperand &MO = MI->getOperand(OpNum);
  unsigned Imm = MO.getImm();
  O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2)
    << markup(">");
}

template<int shift>
void ARMInstPrinter::printMveAddrModeRQOperand(const MCInst *MI, unsigned OpNum,
                                               const MCSubtargetInfo &STI,
                                               raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());
  O << ", ";
  printRegName(O, MO2.getReg());

  if (shift > 0)
    printRegImmShift(O, ARM_AM::uxtw, shift, UseMarkup);

  O << "]" << markup(">");
}

void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  ARM_AM::AMSubMode Mode =
      ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm());
  O << ARM_AM::getAMSubModeStr(Mode);
}

template <bool AlwaysPrintImm0>
void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
    printOperand(MI, OpNum, STI, O);
    return;
  }

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());

  unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
  ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());
  if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
    O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op)
      << ImmOffs * 4 << markup(">");
  }
  O << "]" << markup(">");
}

template <bool AlwaysPrintImm0>
void ARMInstPrinter::printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum,
                                               const MCSubtargetInfo &STI,
                                               raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum+1);

  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
    printOperand(MI, OpNum, STI, O);
    return;
  }

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());

  unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
  unsigned Op = ARM_AM::getAM5FP16Op(MO2.getImm());
  if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
    O << ", "
      << markup("<imm:")
      << "#"
      << ARM_AM::getAddrOpcStr(ARM_AM::getAM5FP16Op(MO2.getImm()))
      << ImmOffs * 2
      << markup(">");
  }
  O << "]" << markup(">");
}

void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());
  if (MO2.getImm()) {
    O << ":" << (MO2.getImm() << 3);
  }
  O << "]" << markup(">");
}

void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());
  O << "]" << markup(">");
}

void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
                                                 unsigned OpNum,
                                                 const MCSubtargetInfo &STI,
                                                 raw_ostream &O) {
  const MCOperand &MO = MI->getOperand(OpNum);
  if (MO.getReg() == 0)
    O << "!";
  else {
    O << ", ";
    printRegName(O, MO.getReg());
  }
}

void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
                                                    unsigned OpNum,
                                                    const MCSubtargetInfo &STI,
                                                    raw_ostream &O) {
  const MCOperand &MO = MI->getOperand(OpNum);
  uint32_t v = ~MO.getImm();
  int32_t lsb = countTrailingZeros(v);
  int32_t width = (32 - countLeadingZeros(v)) - lsb;
  assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
  O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:")
    << '#' << width << markup(">");
}

void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
                                     const MCSubtargetInfo &STI,
                                     raw_ostream &O) {
  unsigned val = MI->getOperand(OpNum).getImm();
  O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]);
}

void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
  unsigned val = MI->getOperand(OpNum).getImm();
  O << ARM_ISB::InstSyncBOptToString(val);
}

void ARMInstPrinter::printTraceSyncBOption(const MCInst *MI, unsigned OpNum,
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
  unsigned val = MI->getOperand(OpNum).getImm();
  O << ARM_TSB::TraceSyncBOptToString(val);
}

void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
  unsigned ShiftOp = MI->getOperand(OpNum).getImm();
  bool isASR = (ShiftOp & (1 << 5)) != 0;
  unsigned Amt = ShiftOp & 0x1f;
  if (isASR) {
    O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt)
      << markup(">");
  } else if (Amt) {
    O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">");
  }
}

void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
                                         const MCSubtargetInfo &STI,
                                         raw_ostream &O) {
  unsigned Imm = MI->getOperand(OpNum).getImm();
  if (Imm == 0)
    return;
  assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
  O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">");
}

void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
                                         const MCSubtargetInfo &STI,
                                         raw_ostream &O) {
  unsigned Imm = MI->getOperand(OpNum).getImm();
  // A shift amount of 32 is encoded as 0.
  if (Imm == 0)
    Imm = 32;
  assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
  O << ", asr " << markup("<imm:") << "#" << Imm << markup(">");
}

void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  if (MI->getOpcode() != ARM::t2CLRM) {
    assert(is_sorted(drop_begin(*MI, OpNum),
                     [&](const MCOperand &LHS, const MCOperand &RHS) {
                       return MRI.getEncodingValue(LHS.getReg()) <
                              MRI.getEncodingValue(RHS.getReg());
                     }));
  }

  O << "{";
  for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
    if (i != OpNum)
      O << ", ";
    printRegName(O, MI->getOperand(i).getReg());
  }
  O << "}";
}

void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
                                         const MCSubtargetInfo &STI,
                                         raw_ostream &O) {
  unsigned Reg = MI->getOperand(OpNum).getReg();
  printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
  O << ", ";
  printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
}

void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNum);
  if (Op.getImm())
    O << "be";
  else
    O << "le";
}

void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
                                  const MCSubtargetInfo &STI, raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNum);
  O << ARM_PROC::IModToString(Op.getImm());
}

void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
                                   const MCSubtargetInfo &STI, raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNum);
  unsigned IFlags = Op.getImm();
  for (int i = 2; i >= 0; --i)
    if (IFlags & (1 << i))
      O << ARM_PROC::IFlagsToString(1 << i);

  if (IFlags == 0)
    O << "none";
}

void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
                                         const MCSubtargetInfo &STI,
                                         raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNum);
  const FeatureBitset &FeatureBits = STI.getFeatureBits();
  if (FeatureBits[ARM::FeatureMClass]) {

    unsigned SYSm = Op.getImm() & 0xFFF; // 12-bit SYSm
    unsigned Opcode = MI->getOpcode();

    // For writes, handle extended mask bits if the DSP extension is present.
    if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) {
      auto TheReg =ARMSysReg::lookupMClassSysRegBy12bitSYSmValue(SYSm);
      if (TheReg && TheReg->isInRequiredFeatures({ARM::FeatureDSP})) {
          O << TheReg->Name;
          return;
      }
    }

    // Handle the basic 8-bit mask.
    SYSm &= 0xff;
    if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
      // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
      // alias for MSR APSR_nzcvq.
      auto TheReg = ARMSysReg::lookupMClassSysRegAPSRNonDeprecated(SYSm);
      if (TheReg) {
          O << TheReg->Name;
          return;
      }
    }

    auto TheReg = ARMSysReg::lookupMClassSysRegBy8bitSYSmValue(SYSm);
    if (TheReg) {
      O << TheReg->Name;
      return;
    }

    O << SYSm;

    return;
  }

  // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
  // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
  unsigned SpecRegRBit = Op.getImm() >> 4;
  unsigned Mask = Op.getImm() & 0xf;

  if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
    O << "APSR_";
    switch (Mask) {
    default:
      llvm_unreachable("Unexpected mask value!");
    case 4:
      O << "g";
      return;
    case 8:
      O << "nzcvq";
      return;
    case 12:
      O << "nzcvqg";
      return;
    }
  }

  if (SpecRegRBit)
    O << "SPSR";
  else
    O << "CPSR";

  if (Mask) {
    O << '_';
    if (Mask & 8)
      O << 'f';
    if (Mask & 4)
      O << 's';
    if (Mask & 2)
      O << 'x';
    if (Mask & 1)
      O << 'c';
  }
}

void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  uint32_t Banked = MI->getOperand(OpNum).getImm();
  auto TheReg = ARMBankedReg::lookupBankedRegByEncoding(Banked);
  assert(TheReg && "invalid banked register operand");
  std::string Name = TheReg->Name;

  uint32_t isSPSR = (Banked & 0x20) >> 5;
  if (isSPSR)
    Name.replace(0, 4, "SPSR"); // convert 'spsr_' to 'SPSR_'
  O << Name;
}

void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
                                           const MCSubtargetInfo &STI,
                                           raw_ostream &O) {
  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
  // Handle the undefined 15 CC value here for printing so we don't abort().
  if ((unsigned)CC == 15)
    O << "<und>";
  else if (CC != ARMCC::AL)
    O << ARMCondCodeToString(CC);
}

void ARMInstPrinter::printMandatoryRestrictedPredicateOperand(
    const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    raw_ostream &O) {
  if ((ARMCC::CondCodes)MI->getOperand(OpNum).getImm() == ARMCC::HS)
    O << "cs";
  else
    printMandatoryPredicateOperand(MI, OpNum, STI, O);
}

void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
                                                    unsigned OpNum,
                                                    const MCSubtargetInfo &STI,
                                                    raw_ostream &O) {
  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
  O << ARMCondCodeToString(CC);
}

void ARMInstPrinter::printMandatoryInvertedPredicateOperand(const MCInst *MI,
                                                            unsigned OpNum,
                                                            const MCSubtargetInfo &STI,
                                                            raw_ostream &O) {
  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
  O << ARMCondCodeToString(ARMCC::getOppositeCondition(CC));
}

void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
                                              const MCSubtargetInfo &STI,
                                              raw_ostream &O) {
  if (MI->getOperand(OpNum).getReg()) {
    assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
           "Expect ARM CPSR register!");
    O << 's';
  }
}

void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
  O << MI->getOperand(OpNum).getImm();
}

void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
                                     const MCSubtargetInfo &STI,
                                     raw_ostream &O) {
  O << "p" << MI->getOperand(OpNum).getImm();
}

void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
                                     const MCSubtargetInfo &STI,
                                     raw_ostream &O) {
  O << "c" << MI->getOperand(OpNum).getImm();
}

void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum,
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
  O << "{" << MI->getOperand(OpNum).getImm() << "}";
}

void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
                                  const MCSubtargetInfo &STI, raw_ostream &O) {
  llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
}

template <unsigned scale>
void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
  const MCOperand &MO = MI->getOperand(OpNum);

  if (MO.isExpr()) {
    MO.getExpr()->print(O, &MAI);
    return;
  }

  int32_t OffImm = (int32_t)MO.getImm() << scale;

  O << markup("<imm:");
  if (OffImm == INT32_MIN)
    O << "#-0";
  else if (OffImm < 0)
    O << "#-" << -OffImm;
  else
    O << "#" << OffImm;
  O << markup(">");
}

void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
                                            const MCSubtargetInfo &STI,
                                            raw_ostream &O) {
  O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
    << markup(">");
}

void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
                                     const MCSubtargetInfo &STI,
                                     raw_ostream &O) {
  unsigned Imm = MI->getOperand(OpNum).getImm();
  O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm))
    << markup(">");
}

void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
                                      const MCSubtargetInfo &STI,
                                      raw_ostream &O) {
  // (3 - the number of trailing zeros) is the number of then / else.
  unsigned Mask = MI->getOperand(OpNum).getImm();
  unsigned NumTZ = countTrailingZeros(Mask);
  assert(NumTZ <= 3 && "Invalid IT mask!");
  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
    if ((Mask >> Pos) & 1)
      O << 'e';
    else
      O << 't';
  }
}

void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
                                                 const MCSubtargetInfo &STI,
                                                 raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(Op);
  const MCOperand &MO2 = MI->getOperand(Op + 1);

  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
    printOperand(MI, Op, STI, O);
    return;
  }

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());
  if (unsigned RegNum = MO2.getReg()) {
    O << ", ";
    printRegName(O, RegNum);
  }
  O << "]" << markup(">");
}

void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
                                                    unsigned Op,
                                                    const MCSubtargetInfo &STI,
                                                    raw_ostream &O,
                                                    unsigned Scale) {
  const MCOperand &MO1 = MI->getOperand(Op);
  const MCOperand &MO2 = MI->getOperand(Op + 1);

  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
    printOperand(MI, Op, STI, O);
    return;
  }

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());
  if (unsigned ImmOffs = MO2.getImm()) {
    O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale)
      << markup(">");
  }
  O << "]" << markup(">");
}

void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
                                                     unsigned Op,
                                                     const MCSubtargetInfo &STI,
                                                     raw_ostream &O) {
  printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1);
}

void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
                                                     unsigned Op,
                                                     const MCSubtargetInfo &STI,
                                                     raw_ostream &O) {
  printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2);
}

void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
                                                     unsigned Op,
                                                     const MCSubtargetInfo &STI,
                                                     raw_ostream &O) {
  printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
}

void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
                                                 const MCSubtargetInfo &STI,
                                                 raw_ostream &O) {
  printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
}

// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
// register with shift forms.
// REG 0   0           - e.g. R5
// REG IMM, SH_OPC     - e.g. R5, LSL #3
void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
                                      const MCSubtargetInfo &STI,
                                      raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  unsigned Reg = MO1.getReg();
  printRegName(O, Reg);

  // Print the shift opc.
  assert(MO2.isImm() && "Not a valid t2_so_reg value!");
  printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
                   ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
}

template <bool AlwaysPrintImm0>
void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
                                               const MCSubtargetInfo &STI,
                                               raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
    printOperand(MI, OpNum, STI, O);
    return;
  }

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());

  int32_t OffImm = (int32_t)MO2.getImm();
  bool isSub = OffImm < 0;
  // Special value for #-0. All others are normal.
  if (OffImm == INT32_MIN)
    OffImm = 0;
  if (isSub) {
    O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
  } else if (AlwaysPrintImm0 || OffImm > 0) {
    O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
  }
  O << "]" << markup(">");
}

template <bool AlwaysPrintImm0>
void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
                                                unsigned OpNum,
                                                const MCSubtargetInfo &STI,
                                                raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());

  int32_t OffImm = (int32_t)MO2.getImm();
  bool isSub = OffImm < 0;
  // Don't print +0.
  if (OffImm == INT32_MIN)
    OffImm = 0;
  if (isSub) {
    O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
  } else if (AlwaysPrintImm0 || OffImm > 0) {
    O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
  }
  O << "]" << markup(">");
}

template <bool AlwaysPrintImm0>
void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
                                                  unsigned OpNum,
                                                  const MCSubtargetInfo &STI,
                                                  raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  if (!MO1.isReg()) { //  For label symbolic references.
    printOperand(MI, OpNum, STI, O);
    return;
  }

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());

  int32_t OffImm = (int32_t)MO2.getImm();
  bool isSub = OffImm < 0;

  assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");

  // Don't print +0.
  if (OffImm == INT32_MIN)
    OffImm = 0;
  if (isSub) {
    O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
  } else if (AlwaysPrintImm0 || OffImm > 0) {
    O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
  }
  O << "]" << markup(">");
}

void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(
    const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());
  if (MO2.getImm()) {
    O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4)
      << markup(">");
  }
  O << "]" << markup(">");
}

void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(
    const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  int32_t OffImm = (int32_t)MO1.getImm();
  O << ", " << markup("<imm:");
  if (OffImm == INT32_MIN)
    O << "#-0";
  else if (OffImm < 0)
    O << "#-" << -OffImm;
  else
    O << "#" << OffImm;
  O << markup(">");
}

void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(
    const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  int32_t OffImm = (int32_t)MO1.getImm();

  assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");

  O << ", " << markup("<imm:");
  if (OffImm == INT32_MIN)
    O << "#-0";
  else if (OffImm < 0)
    O << "#-" << -OffImm;
  else
    O << "#" << OffImm;
  O << markup(">");
}

void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
                                                 unsigned OpNum,
                                                 const MCSubtargetInfo &STI,
                                                 raw_ostream &O) {
  const MCOperand &MO1 = MI->getOperand(OpNum);
  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
  const MCOperand &MO3 = MI->getOperand(OpNum + 2);

  O << markup("<mem:") << "[";
  printRegName(O, MO1.getReg());

  assert(MO2.getReg() && "Invalid so_reg load / store address!");
  O << ", ";
  printRegName(O, MO2.getReg());

  unsigned ShAmt = MO3.getImm();
  if (ShAmt) {
    assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
    O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">");
  }
  O << "]" << markup(">");
}

void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
                                       const MCSubtargetInfo &STI,
                                       raw_ostream &O) {
  const MCOperand &MO = MI->getOperand(OpNum);
  O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm())
    << markup(">");
}

void ARMInstPrinter::printVMOVModImmOperand(const MCInst *MI, unsigned OpNum,
                                            const MCSubtargetInfo &STI,
                                            raw_ostream &O) {
  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
  unsigned EltBits;
  uint64_t Val = ARM_AM::decodeVMOVModImm(EncodedImm, EltBits);
  O << markup("<imm:") << "#0x";
  O.write_hex(Val);
  O << markup(">");
}

void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
                                            const MCSubtargetInfo &STI,
                                            raw_ostream &O) {
  unsigned Imm = MI->getOperand(OpNum).getImm();
  O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">");
}

void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  unsigned Imm = MI->getOperand(OpNum).getImm();
  if (Imm == 0)
    return;
  assert(Imm <= 3 && "illegal ror immediate!");
  O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">");
}

void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  MCOperand Op = MI->getOperand(OpNum);

  // Support for fixups (MCFixup)
  if (Op.isExpr())
    return printOperand(MI, OpNum, STI, O);

  unsigned Bits = Op.getImm() & 0xFF;
  unsigned Rot = (Op.getImm() & 0xF00) >> 7;

  bool PrintUnsigned = false;
  switch (MI->getOpcode()) {
  case ARM::MOVi:
    // Movs to PC should be treated unsigned
    PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
    break;
  case ARM::MSRi:
    // Movs to special registers should be treated unsigned
    PrintUnsigned = true;
    break;
  }

  int32_t Rotated = ARM_AM::rotr32(Bits, Rot);
  if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
    // #rot has the least possible value
    O << "#" << markup("<imm:");
    if (PrintUnsigned)
      O << static_cast<uint32_t>(Rotated);
    else
      O << Rotated;
    O << markup(">");
    return;
  }

  // Explicit #bits, #rot implied
  O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:")
    << Rot << markup(">");
}

void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
                                  const MCSubtargetInfo &STI, raw_ostream &O) {
  O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm()
    << markup(">");
}

void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
                                  const MCSubtargetInfo &STI, raw_ostream &O) {
  O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm()
    << markup(">");
}

void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
                                      const MCSubtargetInfo &STI,
                                      raw_ostream &O) {
  O << "[" << MI->getOperand(OpNum).getImm() << "]";
}

void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << "}";
}

void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  unsigned Reg = MI->getOperand(OpNum).getReg();
  unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
  unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
  O << "{";
  printRegName(O, Reg0);
  O << ", ";
  printRegName(O, Reg1);
  O << "}";
}

void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum,
                                              const MCSubtargetInfo &STI,
                                              raw_ostream &O) {
  unsigned Reg = MI->getOperand(OpNum).getReg();
  unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
  unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
  O << "{";
  printRegName(O, Reg0);
  O << ", ";
  printRegName(O, Reg1);
  O << "}";
}

void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum,
                                          const MCSubtargetInfo &STI,
                                          raw_ostream &O) {
  // Normally, it's not safe to use register enum values directly with
  // addition to get the next register, but for VFP registers, the
  // sort order is guaranteed because they're all of the form D<n>.
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 1);
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  O << "}";
}

void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
                                         const MCSubtargetInfo &STI,
                                         raw_ostream &O) {
  // Normally, it's not safe to use register enum values directly with
  // addition to get the next register, but for VFP registers, the
  // sort order is guaranteed because they're all of the form D<n>.
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 1);
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 3);
  O << "}";
}

void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI,
                                                unsigned OpNum,
                                                const MCSubtargetInfo &STI,
                                                raw_ostream &O) {
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << "[]}";
}

void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
                                                unsigned OpNum,
                                                const MCSubtargetInfo &STI,
                                                raw_ostream &O) {
  unsigned Reg = MI->getOperand(OpNum).getReg();
  unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
  unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
  O << "{";
  printRegName(O, Reg0);
  O << "[], ";
  printRegName(O, Reg1);
  O << "[]}";
}

void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI,
                                                  unsigned OpNum,
                                                  const MCSubtargetInfo &STI,
                                                  raw_ostream &O) {
  // Normally, it's not safe to use register enum values directly with
  // addition to get the next register, but for VFP registers, the
  // sort order is guaranteed because they're all of the form D<n>.
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 1);
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  O << "[]}";
}

void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
                                                 unsigned OpNum,
                                                 const MCSubtargetInfo &STI,
                                                 raw_ostream &O) {
  // Normally, it's not safe to use register enum values directly with
  // addition to get the next register, but for VFP registers, the
  // sort order is guaranteed because they're all of the form D<n>.
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 1);
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 3);
  O << "[]}";
}

void ARMInstPrinter::printVectorListTwoSpacedAllLanes(
    const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    raw_ostream &O) {
  unsigned Reg = MI->getOperand(OpNum).getReg();
  unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
  unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
  O << "{";
  printRegName(O, Reg0);
  O << "[], ";
  printRegName(O, Reg1);
  O << "[]}";
}

void ARMInstPrinter::printVectorListThreeSpacedAllLanes(
    const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    raw_ostream &O) {
  // Normally, it's not safe to use register enum values directly with
  // addition to get the next register, but for VFP registers, the
  // sort order is guaranteed because they're all of the form D<n>.
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 4);
  O << "[]}";
}

void ARMInstPrinter::printVectorListFourSpacedAllLanes(
    const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    raw_ostream &O) {
  // Normally, it's not safe to use register enum values directly with
  // addition to get the next register, but for VFP registers, the
  // sort order is guaranteed because they're all of the form D<n>.
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 4);
  O << "[], ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 6);
  O << "[]}";
}

void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI,
                                                unsigned OpNum,
                                                const MCSubtargetInfo &STI,
                                                raw_ostream &O) {
  // Normally, it's not safe to use register enum values directly with
  // addition to get the next register, but for VFP registers, the
  // sort order is guaranteed because they're all of the form D<n>.
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 4);
  O << "}";
}

void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum,
                                               const MCSubtargetInfo &STI,
                                               raw_ostream &O) {
  // Normally, it's not safe to use register enum values directly with
  // addition to get the next register, but for VFP registers, the
  // sort order is guaranteed because they're all of the form D<n>.
  O << "{";
  printRegName(O, MI->getOperand(OpNum).getReg());
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 4);
  O << ", ";
  printRegName(O, MI->getOperand(OpNum).getReg() + 6);
  O << "}";
}

template<unsigned NumRegs>
void ARMInstPrinter::printMVEVectorList(const MCInst *MI, unsigned OpNum,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  unsigned Reg = MI->getOperand(OpNum).getReg();
  const char *Prefix = "{";
  for (unsigned i = 0; i < NumRegs; i++) {
    O << Prefix;
    printRegName(O, MRI.getSubReg(Reg, ARM::qsub_0 + i));
    Prefix = ", ";
  }
  O << "}";
}

template<int64_t Angle, int64_t Remainder>
void ARMInstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo,
                                            const MCSubtargetInfo &STI,
                                            raw_ostream &O) {
  unsigned Val = MI->getOperand(OpNo).getImm();
  O << "#" << (Val * Angle) + Remainder;
}

void ARMInstPrinter::printVPTPredicateOperand(const MCInst *MI, unsigned OpNum,
                                              const MCSubtargetInfo &STI,
                                              raw_ostream &O) {
  ARMVCC::VPTCodes CC = (ARMVCC::VPTCodes)MI->getOperand(OpNum).getImm();
  if (CC != ARMVCC::None)
    O << ARMVPTPredToString(CC);
}

void ARMInstPrinter::printVPTMask(const MCInst *MI, unsigned OpNum,
                                  const MCSubtargetInfo &STI,
                                  raw_ostream &O) {
  // (3 - the number of trailing zeroes) is the number of them / else.
  unsigned Mask = MI->getOperand(OpNum).getImm();
  unsigned NumTZ = countTrailingZeros(Mask);
  assert(NumTZ <= 3 && "Invalid VPT mask!");
  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
    bool T = ((Mask >> Pos) & 1) == 0;
    if (T)
      O << 't';
    else
      O << 'e';
  }
}

void ARMInstPrinter::printMveSaturateOp(const MCInst *MI, unsigned OpNum,
                                        const MCSubtargetInfo &STI,
                                        raw_ostream &O) {
  uint32_t Val = MI->getOperand(OpNum).getImm();
  assert(Val <= 1 && "Invalid MVE saturate operand");
  O << "#" << (Val == 1 ? 48 : 64);
}
