//===-- 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/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::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::printMveAddrModeQOperand(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());

  int64_t Imm = MO2.getImm();
  if (Imm != 0)
    O << ", " << markup("<imm:") << '#' << Imm << markup(">");

  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);
}
