//===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class prints an ARM MCInst to a .s file.
//
//===----------------------------------------------------------------------===//

#include "ARMInstPrinter.h"
#include "Utils/ARMBaseInfo.h"
#include "ARMBaseRegisterInfo.h"
#include "ARMBaseRegisterInfo.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) {}

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

void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
                               StringRef Annot, const MCSubtargetInfo &STI) {
  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, STI, O);
      return;
    }
    break;
  }
  }

  if (!printAliasInstr(MI, STI, O))
    printInstruction(MI, 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(">");
}

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::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) {
  assert(std::is_sorted(MI->begin() + OpNum, MI->end(),
                        [&](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;
    }

    llvm_unreachable("Unexpected mask value!");
    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::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::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 Firstcond = MI->getOperand(OpNum - 1).getImm();
  unsigned CondBit0 = Firstcond & 1;
  unsigned NumTZ = countTrailingZeros(Mask);
  assert(NumTZ <= 3 && "Invalid IT mask!");
  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
    bool T = ((Mask >> Pos) & 1) == CondBit0;
    if (T)
      O << 't';
    else
      O << 'e';
  }
}

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::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
                                            const MCSubtargetInfo &STI,
                                            raw_ostream &O) {
  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
  unsigned EltBits;
  uint64_t Val = ARM_AM::decodeNEONModImm(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<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;
}

