diff options
Diffstat (limited to 'llvm/lib/Target/ARM/MCTargetDesc')
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp | 1582 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h | 249 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt | 2 | 
5 files changed, 1834 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp new file mode 100644 index 00000000000..ec5fd16cd7d --- /dev/null +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp @@ -0,0 +1,1582 @@ +//===-- 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, 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; +  } +  case ARM::TSB: +  case ARM::t2TSB: +    O << "\ttsb\tcsync"; +    return; +  case ARM::t2DSB: +    switch (MI->getOperand(0).getImm()) { +    default: +      if (!printAliasInstr(MI, STI, O)) +        printInstruction(MI, STI, O); +      break; +    case 0: +      O << "\tssbb"; +      break; +    case 4: +      O << "\tpssbb"; +      break; +    } +    printAnnotation(O, Annot); +    return; +  } + +  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::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) { +  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; +    } + +    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::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; +} + diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h new file mode 100644 index 00000000000..d07daa7bd15 --- /dev/null +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h @@ -0,0 +1,249 @@ +//===- ARMInstPrinter.h - Convert ARM MCInst to assembly syntax -*- C++ -*-===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMINSTPRINTER_H +#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMINSTPRINTER_H + +#include "MCTargetDesc/ARMMCTargetDesc.h" +#include "llvm/MC/MCInstPrinter.h" + +namespace llvm { + +class ARMInstPrinter : public MCInstPrinter { +public: +  ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, +                 const MCRegisterInfo &MRI); + +  bool applyTargetSpecificCLOption(StringRef Opt) override; + +  void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, +                 const MCSubtargetInfo &STI) override; +  void printRegName(raw_ostream &OS, unsigned RegNo) const override; + +  // Autogenerated by tblgen. +  void printInstruction(const MCInst *MI, const MCSubtargetInfo &STI, +                        raw_ostream &O); +  virtual bool printAliasInstr(const MCInst *MI, const MCSubtargetInfo &STI, +                               raw_ostream &O); +  virtual void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx, +                                       unsigned PrintMethodIdx, +                                       const MCSubtargetInfo &STI, +                                       raw_ostream &O); +  static const char *getRegisterName(unsigned RegNo, +                                     unsigned AltIdx = ARM::NoRegAltName); + +  void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, +                    raw_ostream &O); + +  void printSORegRegOperand(const MCInst *MI, unsigned OpNum, +                            const MCSubtargetInfo &STI, raw_ostream &O); +  void printSORegImmOperand(const MCInst *MI, unsigned OpNum, +                            const MCSubtargetInfo &STI, raw_ostream &O); + +  void printAddrModeTBB(const MCInst *MI, unsigned OpNum, +                        const MCSubtargetInfo &STI, raw_ostream &O); +  void printAddrModeTBH(const MCInst *MI, unsigned OpNum, +                        const MCSubtargetInfo &STI, raw_ostream &O); +  void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, +                             const MCSubtargetInfo &STI, raw_ostream &O); +  void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, +                           const MCSubtargetInfo &STI, raw_ostream &O); +  void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, +                                  const MCSubtargetInfo &STI, raw_ostream &O); +  void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, +                                   const MCSubtargetInfo &STI, raw_ostream &O); +  template <bool AlwaysPrintImm0> +  void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, +                             const MCSubtargetInfo &STI, raw_ostream &O); +  void printAddrMode3OffsetOperand(const MCInst *MI, unsigned OpNum, +                                   const MCSubtargetInfo &STI, raw_ostream &O); +  void printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, raw_ostream &O, +                                  bool AlwaysPrintImm0); +  void printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum, +                               const MCSubtargetInfo &STI, raw_ostream &O); +  void printPostIdxRegOperand(const MCInst *MI, unsigned OpNum, +                              const MCSubtargetInfo &STI, raw_ostream &O); +  void printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum, +                                 const MCSubtargetInfo &STI, raw_ostream &O); + +  void printLdStmModeOperand(const MCInst *MI, unsigned OpNum, +                             const MCSubtargetInfo &STI, raw_ostream &O); +  template <bool AlwaysPrintImm0> +  void printAddrMode5Operand(const MCInst *MI, unsigned OpNum, +                             const MCSubtargetInfo &STI, raw_ostream &O); +  template <bool AlwaysPrintImm0> +  void printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum, +                                 const MCSubtargetInfo &STI, raw_ostream &O); +  void printAddrMode6Operand(const MCInst *MI, unsigned OpNum, +                             const MCSubtargetInfo &STI, raw_ostream &O); +  void printAddrMode7Operand(const MCInst *MI, unsigned OpNum, +                             const MCSubtargetInfo &STI, raw_ostream &O); +  void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum, +                                   const MCSubtargetInfo &STI, raw_ostream &O); + +  void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum, +                                      const MCSubtargetInfo &STI, +                                      raw_ostream &O); +  void printMemBOption(const MCInst *MI, unsigned OpNum, +                       const MCSubtargetInfo &STI, raw_ostream &O); +  void printInstSyncBOption(const MCInst *MI, unsigned OpNum, +                            const MCSubtargetInfo &STI, raw_ostream &O); +  void printTraceSyncBOption(const MCInst *MI, unsigned OpNum, +                             const MCSubtargetInfo &STI, raw_ostream &O); +  void printShiftImmOperand(const MCInst *MI, unsigned OpNum, +                            const MCSubtargetInfo &STI, raw_ostream &O); +  void printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, +                           const MCSubtargetInfo &STI, raw_ostream &O); +  void printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, +                           const MCSubtargetInfo &STI, raw_ostream &O); + +  template <unsigned scale> +  void printAdrLabelOperand(const MCInst *MI, unsigned OpNum, +                            const MCSubtargetInfo &STI, raw_ostream &O); +  void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, +                              const MCSubtargetInfo &STI, raw_ostream &O); +  void printThumbSRImm(const MCInst *MI, unsigned OpNum, +                       const MCSubtargetInfo &STI, raw_ostream &O); +  void printThumbITMask(const MCInst *MI, unsigned OpNum, +                        const MCSubtargetInfo &STI, raw_ostream &O); +  void printThumbAddrModeRROperand(const MCInst *MI, unsigned OpNum, +                                   const MCSubtargetInfo &STI, raw_ostream &O); +  void printThumbAddrModeImm5SOperand(const MCInst *MI, unsigned OpNum, +                                      const MCSubtargetInfo &STI, +                                      raw_ostream &O, unsigned Scale); +  void printThumbAddrModeImm5S1Operand(const MCInst *MI, unsigned OpNum, +                                       const MCSubtargetInfo &STI, +                                       raw_ostream &O); +  void printThumbAddrModeImm5S2Operand(const MCInst *MI, unsigned OpNum, +                                       const MCSubtargetInfo &STI, +                                       raw_ostream &O); +  void printThumbAddrModeImm5S4Operand(const MCInst *MI, unsigned OpNum, +                                       const MCSubtargetInfo &STI, +                                       raw_ostream &O); +  void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum, +                                   const MCSubtargetInfo &STI, raw_ostream &O); + +  void printT2SOOperand(const MCInst *MI, unsigned OpNum, +                        const MCSubtargetInfo &STI, raw_ostream &O); +  template <bool AlwaysPrintImm0> +  void printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, +                                 const MCSubtargetInfo &STI, raw_ostream &O); +  template <bool AlwaysPrintImm0> +  void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum, +                                  const MCSubtargetInfo &STI, raw_ostream &O); +  template <bool AlwaysPrintImm0> +  void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum, +                                    const MCSubtargetInfo &STI, raw_ostream &O); +  void printT2AddrModeImm0_1020s4Operand(const MCInst *MI, unsigned OpNum, +                                         const MCSubtargetInfo &STI, +                                         raw_ostream &O); +  void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum, +                                        const MCSubtargetInfo &STI, +                                        raw_ostream &O); +  void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum, +                                          const MCSubtargetInfo &STI, +                                          raw_ostream &O); +  void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum, +                                   const MCSubtargetInfo &STI, raw_ostream &O); + +  void printSetendOperand(const MCInst *MI, unsigned OpNum, +                          const MCSubtargetInfo &STI, raw_ostream &O); +  void printCPSIMod(const MCInst *MI, unsigned OpNum, +                    const MCSubtargetInfo &STI, raw_ostream &O); +  void printCPSIFlag(const MCInst *MI, unsigned OpNum, +                     const MCSubtargetInfo &STI, raw_ostream &O); +  void printMSRMaskOperand(const MCInst *MI, unsigned OpNum, +                           const MCSubtargetInfo &STI, raw_ostream &O); +  void printBankedRegOperand(const MCInst *MI, unsigned OpNum, +                             const MCSubtargetInfo &STI, raw_ostream &O); +  void printPredicateOperand(const MCInst *MI, unsigned OpNum, +                             const MCSubtargetInfo &STI, raw_ostream &O); +  void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum, +                                      const MCSubtargetInfo &STI, +                                      raw_ostream &O); +  void printSBitModifierOperand(const MCInst *MI, unsigned OpNum, +                                const MCSubtargetInfo &STI, raw_ostream &O); +  void printRegisterList(const MCInst *MI, unsigned OpNum, +                         const MCSubtargetInfo &STI, raw_ostream &O); +  void printNoHashImmediate(const MCInst *MI, unsigned OpNum, +                            const MCSubtargetInfo &STI, raw_ostream &O); +  void printPImmediate(const MCInst *MI, unsigned OpNum, +                       const MCSubtargetInfo &STI, raw_ostream &O); +  void printCImmediate(const MCInst *MI, unsigned OpNum, +                       const MCSubtargetInfo &STI, raw_ostream &O); +  void printCoprocOptionImm(const MCInst *MI, unsigned OpNum, +                            const MCSubtargetInfo &STI, raw_ostream &O); +  void printFPImmOperand(const MCInst *MI, unsigned OpNum, +                         const MCSubtargetInfo &STI, raw_ostream &O); +  void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, +                              const MCSubtargetInfo &STI, raw_ostream &O); +  void printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, +                              const MCSubtargetInfo &STI, raw_ostream &O); +  void printRotImmOperand(const MCInst *MI, unsigned OpNum, +                          const MCSubtargetInfo &STI, raw_ostream &O); +  void printModImmOperand(const MCInst *MI, unsigned OpNum, +                          const MCSubtargetInfo &STI, raw_ostream &O); +  void printGPRPairOperand(const MCInst *MI, unsigned OpNum, +                           const MCSubtargetInfo &STI, raw_ostream &O); + +  void printPCLabel(const MCInst *MI, unsigned OpNum, +                    const MCSubtargetInfo &STI, raw_ostream &O); +  void printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum, +                                 const MCSubtargetInfo &STI, raw_ostream &O); +  void printFBits16(const MCInst *MI, unsigned OpNum, +                    const MCSubtargetInfo &STI, raw_ostream &O); +  void printFBits32(const MCInst *MI, unsigned OpNum, +                    const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorIndex(const MCInst *MI, unsigned OpNum, +                        const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListOne(const MCInst *MI, unsigned OpNum, +                          const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListTwo(const MCInst *MI, unsigned OpNum, +                          const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum, +                                const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListThree(const MCInst *MI, unsigned OpNum, +                            const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListFour(const MCInst *MI, unsigned OpNum, +                           const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListOneAllLanes(const MCInst *MI, unsigned OpNum, +                                  const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListTwoAllLanes(const MCInst *MI, unsigned OpNum, +                                  const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListThreeAllLanes(const MCInst *MI, unsigned OpNum, +                                    const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListFourAllLanes(const MCInst *MI, unsigned OpNum, +                                   const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListTwoSpacedAllLanes(const MCInst *MI, unsigned OpNum, +                                        const MCSubtargetInfo &STI, +                                        raw_ostream &O); +  void printVectorListThreeSpacedAllLanes(const MCInst *MI, unsigned OpNum, +                                          const MCSubtargetInfo &STI, +                                          raw_ostream &O); +  void printVectorListFourSpacedAllLanes(const MCInst *MI, unsigned OpNum, +                                         const MCSubtargetInfo &STI, +                                         raw_ostream &O); +  void printVectorListThreeSpaced(const MCInst *MI, unsigned OpNum, +                                  const MCSubtargetInfo &STI, raw_ostream &O); +  void printVectorListFourSpaced(const MCInst *MI, unsigned OpNum, +                                 const MCSubtargetInfo &STI, raw_ostream &O); +  template<int64_t Angle, int64_t Remainder> +  void printComplexRotationOp(const MCInst *MI, unsigned OpNum, +                              const MCSubtargetInfo &STI, raw_ostream &O); + +private: +  unsigned DefaultAltIdx = ARM::NoRegAltName; +}; + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMINSTPRINTER_H diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 9f2672f912f..2b38b49beb8 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -12,8 +12,8 @@  #include "ARMMCTargetDesc.h"  #include "ARMBaseInfo.h" +#include "ARMInstPrinter.h"  #include "ARMMCAsmInfo.h" -#include "InstPrinter/ARMInstPrinter.h"  #include "llvm/ADT/Triple.h"  #include "llvm/MC/MCAsmBackend.h"  #include "llvm/MC/MCCodeEmitter.h" diff --git a/llvm/lib/Target/ARM/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/ARM/MCTargetDesc/CMakeLists.txt index cb5742ccc6e..14a6395854a 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/CMakeLists.txt +++ b/llvm/lib/Target/ARM/MCTargetDesc/CMakeLists.txt @@ -2,6 +2,7 @@ add_llvm_library(LLVMARMDesc    ARMAsmBackend.cpp    ARMELFObjectWriter.cpp    ARMELFStreamer.cpp +  ARMInstPrinter.cpp    ARMMachObjectWriter.cpp    ARMMachORelocationInfo.cpp    ARMMCAsmInfo.cpp diff --git a/llvm/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt b/llvm/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt index fd99351f803..7bb296c1d3c 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt +++ b/llvm/lib/Target/ARM/MCTargetDesc/LLVMBuild.txt @@ -18,5 +18,5 @@  type = Library  name = ARMDesc  parent = ARM -required_libraries = ARMAsmPrinter ARMInfo MC MCDisassembler Support +required_libraries = ARMInfo ARMUtils MC MCDisassembler Support  add_to_library_groups = ARM  | 

