LCOV - code coverage report
Current view: top level - lib/Target/ARM/InstPrinter - ARMInstPrinter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 694 784 88.5 %
Date: 2018-06-17 00:07:59 Functions: 86 94 91.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This class prints an ARM MCInst to a .s file.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "ARMInstPrinter.h"
      15             : #include "Utils/ARMBaseInfo.h"
      16             : #include "MCTargetDesc/ARMAddressingModes.h"
      17             : #include "MCTargetDesc/ARMBaseInfo.h"
      18             : #include "llvm/MC/MCAsmInfo.h"
      19             : #include "llvm/MC/MCExpr.h"
      20             : #include "llvm/MC/MCInst.h"
      21             : #include "llvm/MC/MCInstrInfo.h"
      22             : #include "llvm/MC/MCRegisterInfo.h"
      23             : #include "llvm/MC/MCSubtargetInfo.h"
      24             : #include "llvm/MC/SubtargetFeature.h"
      25             : #include "llvm/Support/Casting.h"
      26             : #include "llvm/Support/ErrorHandling.h"
      27             : #include "llvm/Support/MathExtras.h"
      28             : #include "llvm/Support/raw_ostream.h"
      29             : #include <algorithm>
      30             : #include <cassert>
      31             : #include <cstdint>
      32             : 
      33             : using namespace llvm;
      34             : 
      35             : #define DEBUG_TYPE "asm-printer"
      36             : 
      37             : #define PRINT_ALIAS_INSTR
      38             : #include "ARMGenAsmWriter.inc"
      39             : 
      40             : /// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
      41             : ///
      42             : /// getSORegOffset returns an integer from 0-31, representing '32' as 0.
      43             : static unsigned translateShiftImm(unsigned imm) {
      44             :   // lsr #32 and asr #32 exist, but should be encoded as a 0.
      45             :   assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
      46             : 
      47        2052 :   if (imm == 0)
      48             :     return 32;
      49             :   return imm;
      50             : }
      51             : 
      52             : /// Prints the shift value with an immediate value.
      53        2074 : static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
      54             :                              unsigned ShImm, bool UseMarkup) {
      55        2074 :   if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
      56             :     return;
      57        1676 :   O << ", ";
      58             : 
      59             :   assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
      60        1676 :   O << getShiftOpcStr(ShOpc);
      61             : 
      62        1676 :   if (ShOpc != ARM_AM::rrx) {
      63        1601 :     O << " ";
      64        1601 :     if (UseMarkup)
      65           0 :       O << "<imm:";
      66        1601 :     O << "#" << translateShiftImm(ShImm);
      67        1601 :     if (UseMarkup)
      68           0 :       O << ">";
      69             :   }
      70             : }
      71             : 
      72        3538 : ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
      73             :                                const MCRegisterInfo &MRI)
      74        3538 :     : MCInstPrinter(MAI, MII, MRI) {}
      75             : 
      76      277500 : void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
      77      832500 :   OS << markup("<reg:") << getRegisterName(RegNo) << markup(">");
      78      277500 : }
      79             : 
      80      149582 : void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
      81             :                                StringRef Annot, const MCSubtargetInfo &STI) {
      82      149582 :   unsigned Opcode = MI->getOpcode();
      83             : 
      84      149582 :   switch (Opcode) {
      85             :   // Check for MOVs and print canonical forms, instead.
      86             :   case ARM::MOVsr: {
      87             :     // FIXME: Thumb variants?
      88             :     const MCOperand &Dst = MI->getOperand(0);
      89             :     const MCOperand &MO1 = MI->getOperand(1);
      90             :     const MCOperand &MO2 = MI->getOperand(2);
      91             :     const MCOperand &MO3 = MI->getOperand(3);
      92             : 
      93         202 :     O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
      94         101 :     printSBitModifierOperand(MI, 6, STI, O);
      95         101 :     printPredicateOperand(MI, 4, STI, O);
      96             : 
      97             :     O << '\t';
      98         101 :     printRegName(O, Dst.getReg());
      99         101 :     O << ", ";
     100         101 :     printRegName(O, MO1.getReg());
     101             : 
     102         101 :     O << ", ";
     103         101 :     printRegName(O, MO2.getReg());
     104             :     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
     105         101 :     printAnnotation(O, Annot);
     106         101 :     return;
     107             :   }
     108             : 
     109             :   case ARM::MOVsi: {
     110             :     // FIXME: Thumb variants?
     111             :     const MCOperand &Dst = MI->getOperand(0);
     112             :     const MCOperand &MO1 = MI->getOperand(1);
     113             :     const MCOperand &MO2 = MI->getOperand(2);
     114             : 
     115         954 :     O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()));
     116         477 :     printSBitModifierOperand(MI, 5, STI, O);
     117         477 :     printPredicateOperand(MI, 3, STI, O);
     118             : 
     119             :     O << '\t';
     120         477 :     printRegName(O, Dst.getReg());
     121         477 :     O << ", ";
     122         477 :     printRegName(O, MO1.getReg());
     123             : 
     124         954 :     if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) {
     125          26 :       printAnnotation(O, Annot);
     126          26 :       return;
     127             :     }
     128             : 
     129        1353 :     O << ", " << markup("<imm:") << "#"
     130         902 :       << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) << markup(">");
     131         451 :     printAnnotation(O, Annot);
     132         451 :     return;
     133             :   }
     134             : 
     135             :   // A8.6.123 PUSH
     136             :   case ARM::STMDB_UPD:
     137             :   case ARM::t2STMDB_UPD:
     138        4952 :     if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
     139             :       // Should only print PUSH if there are at least two registers in the list.
     140        2453 :       O << '\t' << "push";
     141        2453 :       printPredicateOperand(MI, 2, STI, O);
     142        2453 :       if (Opcode == ARM::t2STMDB_UPD)
     143         160 :         O << ".w";
     144             :       O << '\t';
     145        2453 :       printRegisterList(MI, 4, STI, O);
     146        2453 :       printAnnotation(O, Annot);
     147        2453 :       return;
     148             :     } else
     149             :       break;
     150             : 
     151             :   case ARM::STR_PRE_IMM:
     152         461 :     if (MI->getOperand(2).getReg() == ARM::SP &&
     153         223 :         MI->getOperand(3).getImm() == -4) {
     154         210 :       O << '\t' << "push";
     155         210 :       printPredicateOperand(MI, 4, STI, O);
     156         210 :       O << "\t{";
     157         420 :       printRegName(O, MI->getOperand(1).getReg());
     158         210 :       O << "}";
     159         210 :       printAnnotation(O, Annot);
     160         210 :       return;
     161             :     } else
     162             :       break;
     163             : 
     164             :   // A8.6.122 POP
     165             :   case ARM::LDMIA_UPD:
     166             :   case ARM::t2LDMIA_UPD:
     167        4992 :     if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
     168             :       // Should only print POP if there are at least two registers in the list.
     169        2455 :       O << '\t' << "pop";
     170        2455 :       printPredicateOperand(MI, 2, STI, O);
     171        2455 :       if (Opcode == ARM::t2LDMIA_UPD)
     172         202 :         O << ".w";
     173             :       O << '\t';
     174        2455 :       printRegisterList(MI, 4, STI, O);
     175        2455 :       printAnnotation(O, Annot);
     176        2455 :       return;
     177             :     } else
     178             :       break;
     179             : 
     180             :   case ARM::LDR_POST_IMM:
     181         689 :     if (MI->getOperand(2).getReg() == ARM::SP &&
     182         203 :         MI->getOperand(4).getImm() == 4) {
     183         200 :       O << '\t' << "pop";
     184         200 :       printPredicateOperand(MI, 5, STI, O);
     185         200 :       O << "\t{";
     186         400 :       printRegName(O, MI->getOperand(0).getReg());
     187         200 :       O << "}";
     188         200 :       printAnnotation(O, Annot);
     189         200 :       return;
     190             :     } else
     191             :       break;
     192             : 
     193             :   // A8.6.355 VPUSH
     194             :   case ARM::VSTMSDB_UPD:
     195             :   case ARM::VSTMDDB_UPD:
     196         278 :     if (MI->getOperand(0).getReg() == ARM::SP) {
     197         276 :       O << '\t' << "vpush";
     198         276 :       printPredicateOperand(MI, 2, STI, O);
     199             :       O << '\t';
     200         276 :       printRegisterList(MI, 4, STI, O);
     201         276 :       printAnnotation(O, Annot);
     202         276 :       return;
     203             :     } else
     204             :       break;
     205             : 
     206             :   // A8.6.354 VPOP
     207             :   case ARM::VLDMSIA_UPD:
     208             :   case ARM::VLDMDIA_UPD:
     209         288 :     if (MI->getOperand(0).getReg() == ARM::SP) {
     210         284 :       O << '\t' << "vpop";
     211         284 :       printPredicateOperand(MI, 2, STI, O);
     212             :       O << '\t';
     213         284 :       printRegisterList(MI, 4, STI, O);
     214         284 :       printAnnotation(O, Annot);
     215         284 :       return;
     216             :     } else
     217             :       break;
     218             : 
     219         213 :   case ARM::tLDMIA: {
     220             :     bool Writeback = true;
     221         213 :     unsigned BaseReg = MI->getOperand(0).getReg();
     222        1841 :     for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
     223         814 :       if (MI->getOperand(i).getReg() == BaseReg)
     224             :         Writeback = false;
     225             :     }
     226             : 
     227         213 :     O << "\tldm";
     228             : 
     229         213 :     printPredicateOperand(MI, 1, STI, O);
     230             :     O << '\t';
     231         213 :     printRegName(O, BaseReg);
     232         213 :     if (Writeback)
     233          51 :       O << "!";
     234         213 :     O << ", ";
     235         213 :     printRegisterList(MI, 3, STI, O);
     236         213 :     printAnnotation(O, Annot);
     237         213 :     return;
     238             :   }
     239             : 
     240             :   // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
     241             :   // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
     242             :   // a single GPRPair reg operand is used in the .td file to replace the two
     243             :   // GPRs. However, when decoding them, the two GRPs cannot be automatically
     244             :   // expressed as a GPRPair, so we have to manually merge them.
     245             :   // FIXME: We would really like to be able to tablegen'erate this.
     246         170 :   case ARM::LDREXD:
     247             :   case ARM::STREXD:
     248             :   case ARM::LDAEXD:
     249             :   case ARM::STLEXD: {
     250         170 :     const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
     251         170 :     bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
     252         340 :     unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
     253         170 :     if (MRC.contains(Reg)) {
     254             :       MCInst NewMI;
     255             :       MCOperand NewReg;
     256             :       NewMI.setOpcode(Opcode);
     257             : 
     258           0 :       if (isStore)
     259             :         NewMI.addOperand(MI->getOperand(0));
     260           0 :       NewReg = MCOperand::createReg(MRI.getMatchingSuperReg(
     261           0 :           Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID)));
     262             :       NewMI.addOperand(NewReg);
     263             : 
     264             :       // Copy the rest operands into NewMI.
     265           0 :       for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
     266             :         NewMI.addOperand(MI->getOperand(i));
     267           0 :       printInstruction(&NewMI, STI, O);
     268             :       return;
     269             :     }
     270             :     break;
     271             :   }
     272             :   }
     273             : 
     274      142913 :   if (!printAliasInstr(MI, STI, O))
     275      142514 :     printInstruction(MI, STI, O);
     276             : 
     277      142913 :   printAnnotation(O, Annot);
     278             : }
     279             : 
     280      218444 : void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
     281             :                                   const MCSubtargetInfo &STI, raw_ostream &O) {
     282             :   const MCOperand &Op = MI->getOperand(OpNo);
     283      218444 :   if (Op.isReg()) {
     284      189411 :     unsigned Reg = Op.getReg();
     285      189411 :     printRegName(O, Reg);
     286       29033 :   } else if (Op.isImm()) {
     287       61464 :     O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">");
     288             :   } else {
     289             :     assert(Op.isExpr() && "unknown operand kind in printOperand");
     290       13667 :     const MCExpr *Expr = Op.getExpr();
     291       13667 :     switch (Expr->getKind()) {
     292             :     case MCExpr::Binary:
     293             :       O << '#';
     294           2 :       Expr->print(O, &MAI);
     295           2 :       break;
     296             :     case MCExpr::Constant: {
     297             :       // If a symbolic branch target was added as a constant expression then
     298             :       // print that address in hex. And only print 32 unsigned bits for the
     299             :       // address.
     300             :       const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
     301             :       int64_t TargetAddress;
     302           1 :       if (!Constant->evaluateAsAbsolute(TargetAddress)) {
     303             :         O << '#';
     304           0 :         Expr->print(O, &MAI);
     305             :       } else {
     306           1 :         O << "0x";
     307           1 :         O.write_hex(static_cast<uint32_t>(TargetAddress));
     308             :       }
     309             :       break;
     310             :     }
     311       13664 :     default:
     312             :       // FIXME: Should we always treat this as if it is a constant literal and
     313             :       // prefix it with '#'?
     314       13664 :       Expr->print(O, &MAI);
     315       13664 :       break;
     316             :     }
     317             :   }
     318      218444 : }
     319             : 
     320        1228 : void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
     321             :                                                const MCSubtargetInfo &STI,
     322             :                                                raw_ostream &O) {
     323             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     324        1228 :   if (MO1.isExpr()) {
     325        1047 :     MO1.getExpr()->print(O, &MAI);
     326        1047 :     return;
     327             :   }
     328             : 
     329         362 :   O << markup("<mem:") << "[pc, ";
     330             : 
     331         181 :   int32_t OffImm = (int32_t)MO1.getImm();
     332             :   bool isSub = OffImm < 0;
     333             : 
     334             :   // Special value for #-0. All others are normal.
     335         181 :   if (OffImm == INT32_MIN)
     336             :     OffImm = 0;
     337         181 :   if (isSub) {
     338         152 :     O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
     339             :   } else {
     340         210 :     O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
     341             :   }
     342         362 :   O << "]" << markup(">");
     343             : }
     344             : 
     345             : // so_reg is a 4-operand unit corresponding to register forms of the A5.1
     346             : // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
     347             : //    REG 0   0           - e.g. R5
     348             : //    REG REG 0,SH_OPC    - e.g. R5, ROR R3
     349             : //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
     350         349 : void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
     351             :                                           const MCSubtargetInfo &STI,
     352             :                                           raw_ostream &O) {
     353             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     354         349 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
     355         349 :   const MCOperand &MO3 = MI->getOperand(OpNum + 2);
     356             : 
     357         349 :   printRegName(O, MO1.getReg());
     358             : 
     359             :   // Print the shift opc.
     360         349 :   ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
     361         698 :   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
     362         349 :   if (ShOpc == ARM_AM::rrx)
     363             :     return;
     364             : 
     365             :   O << ' ';
     366         349 :   printRegName(O, MO2.getReg());
     367             :   assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
     368             : }
     369             : 
     370        1002 : void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
     371             :                                           const MCSubtargetInfo &STI,
     372             :                                           raw_ostream &O) {
     373             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     374        1002 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
     375             : 
     376        1002 :   printRegName(O, MO1.getReg());
     377             : 
     378             :   // Print the shift opc.
     379        3006 :   printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
     380        2004 :                    ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
     381        1002 : }
     382             : 
     383             : //===--------------------------------------------------------------------===//
     384             : // Addressing Mode #2
     385             : //===--------------------------------------------------------------------===//
     386             : 
     387         477 : void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
     388             :                                                 const MCSubtargetInfo &STI,
     389             :                                                 raw_ostream &O) {
     390             :   const MCOperand &MO1 = MI->getOperand(Op);
     391         477 :   const MCOperand &MO2 = MI->getOperand(Op + 1);
     392         477 :   const MCOperand &MO3 = MI->getOperand(Op + 2);
     393             : 
     394         954 :   O << markup("<mem:") << "[";
     395         477 :   printRegName(O, MO1.getReg());
     396             : 
     397         477 :   if (!MO2.getReg()) {
     398           0 :     if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
     399           0 :       O << ", " << markup("<imm:") << "#"
     400           0 :         << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
     401           0 :         << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">");
     402             :     }
     403           0 :     O << "]" << markup(">");
     404           0 :     return;
     405             :   }
     406             : 
     407         477 :   O << ", ";
     408         954 :   O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()));
     409         477 :   printRegName(O, MO2.getReg());
     410             : 
     411        1431 :   printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
     412         954 :                    ARM_AM::getAM2Offset(MO3.getImm()), UseMarkup);
     413         954 :   O << "]" << markup(">");
     414             : }
     415             : 
     416          27 : void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
     417             :                                       const MCSubtargetInfo &STI,
     418             :                                       raw_ostream &O) {
     419             :   const MCOperand &MO1 = MI->getOperand(Op);
     420          27 :   const MCOperand &MO2 = MI->getOperand(Op + 1);
     421          54 :   O << markup("<mem:") << "[";
     422          27 :   printRegName(O, MO1.getReg());
     423          27 :   O << ", ";
     424          27 :   printRegName(O, MO2.getReg());
     425          54 :   O << "]" << markup(">");
     426          27 : }
     427             : 
     428           9 : void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
     429             :                                       const MCSubtargetInfo &STI,
     430             :                                       raw_ostream &O) {
     431             :   const MCOperand &MO1 = MI->getOperand(Op);
     432           9 :   const MCOperand &MO2 = MI->getOperand(Op + 1);
     433          18 :   O << markup("<mem:") << "[";
     434           9 :   printRegName(O, MO1.getReg());
     435           9 :   O << ", ";
     436           9 :   printRegName(O, MO2.getReg());
     437          36 :   O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">");
     438           9 : }
     439             : 
     440         477 : void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
     441             :                                            const MCSubtargetInfo &STI,
     442             :                                            raw_ostream &O) {
     443             :   const MCOperand &MO1 = MI->getOperand(Op);
     444             : 
     445         477 :   if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
     446           0 :     printOperand(MI, Op, STI, O);
     447           0 :     return;
     448             :   }
     449             : 
     450             : #ifndef NDEBUG
     451             :   const MCOperand &MO3 = MI->getOperand(Op + 2);
     452             :   unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
     453             :   assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
     454             : #endif
     455             : 
     456         477 :   printAM2PreOrOffsetIndexOp(MI, Op, STI, O);
     457             : }
     458             : 
     459        1833 : void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
     460             :                                                  unsigned OpNum,
     461             :                                                  const MCSubtargetInfo &STI,
     462             :                                                  raw_ostream &O) {
     463             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     464        1833 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
     465             : 
     466        1833 :   if (!MO1.getReg()) {
     467        1778 :     unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
     468        5334 :     O << markup("<imm:") << '#'
     469        3556 :       << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs
     470        1778 :       << markup(">");
     471        1778 :     return;
     472             :   }
     473             : 
     474         110 :   O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()));
     475          55 :   printRegName(O, MO1.getReg());
     476             : 
     477         165 :   printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
     478         110 :                    ARM_AM::getAM2Offset(MO2.getImm()), UseMarkup);
     479             : }
     480             : 
     481             : //===--------------------------------------------------------------------===//
     482             : // Addressing Mode #3
     483             : //===--------------------------------------------------------------------===//
     484             : 
     485         879 : void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
     486             :                                                 raw_ostream &O,
     487             :                                                 bool AlwaysPrintImm0) {
     488             :   const MCOperand &MO1 = MI->getOperand(Op);
     489         879 :   const MCOperand &MO2 = MI->getOperand(Op + 1);
     490         879 :   const MCOperand &MO3 = MI->getOperand(Op + 2);
     491             : 
     492        2637 :   O << markup("<mem:") << '[';
     493         879 :   printRegName(O, MO1.getReg());
     494             : 
     495         879 :   if (MO2.getReg()) {
     496          70 :     O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
     497          35 :     printRegName(O, MO2.getReg());
     498          35 :     O << ']' << markup(">");
     499          35 :     return;
     500             :   }
     501             : 
     502             :   // If the op is sub we have to print the immediate even if it is 0
     503         844 :   unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
     504             :   ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm());
     505             : 
     506         844 :   if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
     507         972 :     O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs
     508         243 :       << markup(">");
     509             :   }
     510         844 :   O << ']' << markup(">");
     511             : }
     512             : 
     513             : template <bool AlwaysPrintImm0>
     514         880 : void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op,
     515             :                                            const MCSubtargetInfo &STI,
     516             :                                            raw_ostream &O) {
     517             :   const MCOperand &MO1 = MI->getOperand(Op);
     518         880 :   if (!MO1.isReg()) { //  For label symbolic references.
     519           1 :     printOperand(MI, Op, STI, O);
     520           1 :     return;
     521             :   }
     522             : 
     523             :   assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) !=
     524             :              ARMII::IndexModePost &&
     525             :          "unexpected idxmode");
     526         879 :   printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
     527             : }
     528             : 
     529         396 : void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
     530             :                                                  unsigned OpNum,
     531             :                                                  const MCSubtargetInfo &STI,
     532             :                                                  raw_ostream &O) {
     533             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     534         396 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
     535             : 
     536         396 :   if (MO1.getReg()) {
     537          56 :     O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()));
     538          28 :     printRegName(O, MO1.getReg());
     539          28 :     return;
     540             :   }
     541             : 
     542         368 :   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
     543        1104 :   O << markup("<imm:") << '#'
     544         736 :     << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs
     545         368 :     << markup(">");
     546             : }
     547             : 
     548          25 : void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum,
     549             :                                              const MCSubtargetInfo &STI,
     550             :                                              raw_ostream &O) {
     551             :   const MCOperand &MO = MI->getOperand(OpNum);
     552          25 :   unsigned Imm = MO.getImm();
     553         100 :   O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff)
     554          25 :     << markup(">");
     555          25 : }
     556             : 
     557          27 : void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum,
     558             :                                             const MCSubtargetInfo &STI,
     559             :                                             raw_ostream &O) {
     560             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     561          27 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
     562             : 
     563          27 :   O << (MO2.getImm() ? "" : "-");
     564          27 :   printRegName(O, MO1.getReg());
     565          27 : }
     566             : 
     567         225 : void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum,
     568             :                                                const MCSubtargetInfo &STI,
     569             :                                                raw_ostream &O) {
     570             :   const MCOperand &MO = MI->getOperand(OpNum);
     571         225 :   unsigned Imm = MO.getImm();
     572         900 :   O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2)
     573         225 :     << markup(">");
     574         225 : }
     575             : 
     576           0 : void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
     577             :                                            const MCSubtargetInfo &STI,
     578             :                                            raw_ostream &O) {
     579             :   ARM_AM::AMSubMode Mode =
     580           0 :       ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm());
     581           0 :   O << ARM_AM::getAMSubModeStr(Mode);
     582           0 : }
     583             : 
     584             : template <bool AlwaysPrintImm0>
     585        4732 : void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
     586             :                                            const MCSubtargetInfo &STI,
     587             :                                            raw_ostream &O) {
     588             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     589        4732 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
     590             : 
     591        4732 :   if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
     592         806 :     printOperand(MI, OpNum, STI, O);
     593         806 :     return;
     594             :   }
     595             : 
     596        7852 :   O << markup("<mem:") << "[";
     597        3926 :   printRegName(O, MO1.getReg());
     598             : 
     599        7852 :   unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
     600             :   ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());
     601        3752 :   if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
     602        6685 :     O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op)
     603        4011 :       << ImmOffs * 4 << markup(">");
     604             :   }
     605        7852 :   O << "]" << markup(">");
     606             : }
     607             : 
     608             : template <bool AlwaysPrintImm0>
     609         522 : void ARMInstPrinter::printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum,
     610             :                                                const MCSubtargetInfo &STI,
     611             :                                                raw_ostream &O) {
     612             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     613         522 :   const MCOperand &MO2 = MI->getOperand(OpNum+1);
     614             : 
     615         522 :   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
     616         266 :     printOperand(MI, OpNum, STI, O);
     617         266 :     return;
     618             :   }
     619             : 
     620         512 :   O << markup("<mem:") << "[";
     621         256 :   printRegName(O, MO1.getReg());
     622             : 
     623         512 :   unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
     624             :   unsigned Op = ARM_AM::getAM5FP16Op(MO2.getImm());
     625         256 :   if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
     626         152 :     O << ", "
     627         152 :       << markup("<imm:")
     628          76 :       << "#"
     629         152 :       << ARM_AM::getAddrOpcStr(ARM_AM::getAM5FP16Op(MO2.getImm()))
     630          76 :       << ImmOffs * 2
     631         152 :       << markup(">");
     632             :   }
     633         512 :   O << "]" << markup(">");
     634             : }
     635             : 
     636        7079 : void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
     637             :                                            const MCSubtargetInfo &STI,
     638             :                                            raw_ostream &O) {
     639             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     640        7079 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
     641             : 
     642       14158 :   O << markup("<mem:") << "[";
     643        7079 :   printRegName(O, MO1.getReg());
     644        7079 :   if (MO2.getImm()) {
     645        3515 :     O << ":" << (MO2.getImm() << 3);
     646             :   }
     647       14158 :   O << "]" << markup(">");
     648        7079 : }
     649             : 
     650        4759 : void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
     651             :                                            const MCSubtargetInfo &STI,
     652             :                                            raw_ostream &O) {
     653             :   const MCOperand &MO1 = MI->getOperand(OpNum);
     654        9518 :   O << markup("<mem:") << "[";
     655        4759 :   printRegName(O, MO1.getReg());
     656        9518 :   O << "]" << markup(">");
     657        4759 : }
     658             : 
     659         718 : void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
     660             :                                                  unsigned OpNum,
     661             :                                                  const MCSubtargetInfo &STI,
     662             :                                                  raw_ostream &O) {
     663             :   const MCOperand &MO = MI->getOperand(OpNum);
     664         718 :   if (MO.getReg() == 0)
     665         393 :     O << "!";
     666             :   else {
     667         325 :     O << ", ";
     668         325 :     printRegName(O, MO.getReg());
     669             :   }
     670         718 : }
     671             : 
     672         293 : void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
     673             :                                                     unsigned OpNum,
     674             :                                                     const MCSubtargetInfo &STI,
     675             :                                                     raw_ostream &O) {
     676             :   const MCOperand &MO = MI->getOperand(OpNum);
     677         293 :   uint32_t v = ~MO.getImm();
     678         293 :   int32_t lsb = countTrailingZeros(v);
     679         293 :   int32_t width = (32 - countLeadingZeros(v)) - lsb;
     680             :   assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
     681        1465 :   O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:")
     682         293 :     << '#' << width << markup(">");
     683         293 : }
     684             : 
     685         646 : void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
     686             :                                      const MCSubtargetInfo &STI,
     687             :                                      raw_ostream &O) {
     688         646 :   unsigned val = MI->getOperand(OpNum).getImm();
     689         646 :   O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]);
     690         646 : }
     691             : 
     692          35 : void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
     693             :                                           const MCSubtargetInfo &STI,
     694             :                                           raw_ostream &O) {
     695          35 :   unsigned val = MI->getOperand(OpNum).getImm();
     696          35 :   O << ARM_ISB::InstSyncBOptToString(val);
     697          35 : }
     698             : 
     699         160 : void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
     700             :                                           const MCSubtargetInfo &STI,
     701             :                                           raw_ostream &O) {
     702         160 :   unsigned ShiftOp = MI->getOperand(OpNum).getImm();
     703         160 :   bool isASR = (ShiftOp & (1 << 5)) != 0;
     704         160 :   unsigned Amt = ShiftOp & 0x1f;
     705         160 :   if (isASR) {
     706          57 :     O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt)
     707          19 :       << markup(">");
     708         141 :   } else if (Amt) {
     709          39 :     O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">");
     710             :   }
     711         160 : }
     712             : 
     713          47 : void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
     714             :                                          const MCSubtargetInfo &STI,
     715             :                                          raw_ostream &O) {
     716          47 :   unsigned Imm = MI->getOperand(OpNum).getImm();
     717          47 :   if (Imm == 0)
     718             :     return;
     719             :   assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
     720          81 :   O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">");
     721             : }
     722             : 
     723          26 : void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
     724             :                                          const MCSubtargetInfo &STI,
     725             :                                          raw_ostream &O) {
     726          26 :   unsigned Imm = MI->getOperand(OpNum).getImm();
     727             :   // A shift amount of 32 is encoded as 0.
     728          26 :   if (Imm == 0)
     729             :     Imm = 32;
     730             :   assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
     731          78 :   O << ", asr " << markup("<imm:") << "#" << Imm << markup(">");
     732          26 : }
     733             : 
     734       10040 : void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
     735             :                                        const MCSubtargetInfo &STI,
     736             :                                        raw_ostream &O) {
     737             :   assert(std::is_sorted(MI->begin() + OpNum, MI->end(),
     738             :                         [&](const MCOperand &LHS, const MCOperand &RHS) {
     739             :                           return MRI.getEncodingValue(LHS.getReg()) <
     740             :                                  MRI.getEncodingValue(RHS.getReg());
     741             :                         }));
     742             : 
     743       10040 :   O << "{";
     744       69264 :   for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
     745       29612 :     if (i != OpNum)
     746       19572 :       O << ", ";
     747       59224 :     printRegName(O, MI->getOperand(i).getReg());
     748             :   }
     749       10040 :   O << "}";
     750       10040 : }
     751             : 
     752         170 : void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
     753             :                                          const MCSubtargetInfo &STI,
     754             :                                          raw_ostream &O) {
     755         170 :   unsigned Reg = MI->getOperand(OpNum).getReg();
     756         170 :   printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
     757         170 :   O << ", ";
     758         170 :   printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
     759         170 : }
     760             : 
     761          28 : void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
     762             :                                         const MCSubtargetInfo &STI,
     763             :                                         raw_ostream &O) {
     764             :   const MCOperand &Op = MI->getOperand(OpNum);
     765          28 :   if (Op.getImm())
     766          17 :     O << "be";
     767             :   else
     768          11 :     O << "le";
     769          28 : }
     770             : 
     771          51 : void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
     772             :                                   const MCSubtargetInfo &STI, raw_ostream &O) {
     773             :   const MCOperand &Op = MI->getOperand(OpNum);
     774         102 :   O << ARM_PROC::IModToString(Op.getImm());
     775          51 : }
     776             : 
     777          51 : void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
     778             :                                    const MCSubtargetInfo &STI, raw_ostream &O) {
     779             :   const MCOperand &Op = MI->getOperand(OpNum);
     780          51 :   unsigned IFlags = Op.getImm();
     781         357 :   for (int i = 2; i >= 0; --i)
     782         153 :     if (IFlags & (1 << i))
     783          70 :       O << ARM_PROC::IFlagsToString(1 << i);
     784             : 
     785          51 :   if (IFlags == 0)
     786           3 :     O << "none";
     787          51 : }
     788             : 
     789         516 : void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
     790             :                                          const MCSubtargetInfo &STI,
     791             :                                          raw_ostream &O) {
     792             :   const MCOperand &Op = MI->getOperand(OpNum);
     793             :   const FeatureBitset &FeatureBits = STI.getFeatureBits();
     794         516 :   if (FeatureBits[ARM::FeatureMClass]) {
     795             : 
     796         339 :     unsigned SYSm = Op.getImm() & 0xFFF; // 12-bit SYSm
     797         339 :     unsigned Opcode = MI->getOpcode();
     798             : 
     799             :     // For writes, handle extended mask bits if the DSP extension is present.
     800         534 :     if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) {
     801         106 :       auto TheReg =ARMSysReg::lookupMClassSysRegBy12bitSYSmValue(SYSm);
     802         208 :       if (TheReg && TheReg->isInRequiredFeatures({ARM::FeatureDSP})) {
     803          33 :           O << TheReg->Name;
     804          33 :           return;
     805             :       }
     806             :     }
     807             : 
     808             :     // Handle the basic 8-bit mask.
     809         306 :     SYSm &= 0xff;
     810         468 :     if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
     811             :       // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
     812             :       // alias for MSR APSR_nzcvq.
     813         112 :       auto TheReg = ARMSysReg::lookupMClassSysRegAPSRNonDeprecated(SYSm);
     814         112 :       if (TheReg) {
     815          37 :           O << TheReg->Name;
     816          37 :           return;
     817             :       }
     818             :     }
     819             : 
     820         269 :     auto TheReg = ARMSysReg::lookupMClassSysRegBy8bitSYSmValue(SYSm);
     821         269 :     if (TheReg) {
     822         259 :       O << TheReg->Name;
     823         259 :       return;
     824             :     }
     825             : 
     826             :     O << SYSm; 
     827             : 
     828             :     return;
     829             :   }
     830             : 
     831             :   // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
     832             :   // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
     833         177 :   unsigned SpecRegRBit = Op.getImm() >> 4;
     834         177 :   unsigned Mask = Op.getImm() & 0xf;
     835             : 
     836         177 :   if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
     837          71 :     O << "APSR_";
     838          71 :     switch (Mask) {
     839           0 :     default:
     840           0 :       llvm_unreachable("Unexpected mask value!");
     841          11 :     case 4:
     842          11 :       O << "g";
     843          11 :       return;
     844          46 :     case 8:
     845          46 :       O << "nzcvq";
     846          46 :       return;
     847          14 :     case 12:
     848          14 :       O << "nzcvqg";
     849          14 :       return;
     850             :     }
     851             :   }
     852             : 
     853         106 :   if (SpecRegRBit)
     854          32 :     O << "SPSR";
     855             :   else
     856          74 :     O << "CPSR";
     857             : 
     858         106 :   if (Mask) {
     859             :     O << '_';
     860         106 :     if (Mask & 8)
     861             :       O << 'f';
     862         106 :     if (Mask & 4)
     863             :       O << 's';
     864         106 :     if (Mask & 2)
     865             :       O << 'x';
     866         106 :     if (Mask & 1)
     867             :       O << 'c';
     868             :   }
     869             : }
     870             : 
     871         264 : void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum,
     872             :                                            const MCSubtargetInfo &STI,
     873             :                                            raw_ostream &O) {
     874         264 :   uint32_t Banked = MI->getOperand(OpNum).getImm();
     875         264 :   auto TheReg = ARMBankedReg::lookupBankedRegByEncoding(Banked);
     876             :   assert(TheReg && "invalid banked register operand");
     877         264 :   std::string Name = TheReg->Name;
     878             : 
     879         264 :   uint32_t isSPSR = (Banked & 0x20) >> 5;
     880         264 :   if (isSPSR)
     881          56 :     Name.replace(0, 4, "SPSR"); // convert 'spsr_' to 'SPSR_'
     882             :   O << Name;
     883         264 : }
     884             : 
     885      138824 : void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
     886             :                                            const MCSubtargetInfo &STI,
     887             :                                            raw_ostream &O) {
     888      138824 :   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
     889             :   // Handle the undefined 15 CC value here for printing so we don't abort().
     890      138824 :   if ((unsigned)CC == 15)
     891           1 :     O << "<und>";
     892      138823 :   else if (CC != ARMCC::AL)
     893        8019 :     O << ARMCondCodeToString(CC);
     894      138824 : }
     895             : 
     896        3674 : void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
     897             :                                                     unsigned OpNum,
     898             :                                                     const MCSubtargetInfo &STI,
     899             :                                                     raw_ostream &O) {
     900        3674 :   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
     901        3674 :   O << ARMCondCodeToString(CC);
     902        3674 : }
     903             : 
     904       31030 : void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
     905             :                                               const MCSubtargetInfo &STI,
     906             :                                               raw_ostream &O) {
     907       31030 :   if (MI->getOperand(OpNum).getReg()) {
     908             :     assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
     909             :            "Expect ARM CPSR register!");
     910             :     O << 's';
     911             :   }
     912       31030 : }
     913             : 
     914        1662 : void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
     915             :                                           const MCSubtargetInfo &STI,
     916             :                                           raw_ostream &O) {
     917        1662 :   O << MI->getOperand(OpNum).getImm();
     918        1662 : }
     919             : 
     920        1079 : void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
     921             :                                      const MCSubtargetInfo &STI,
     922             :                                      raw_ostream &O) {
     923        2158 :   O << "p" << MI->getOperand(OpNum).getImm();
     924        1079 : }
     925             : 
     926        1317 : void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
     927             :                                      const MCSubtargetInfo &STI,
     928             :                                      raw_ostream &O) {
     929        2634 :   O << "c" << MI->getOperand(OpNum).getImm();
     930        1317 : }
     931             : 
     932         109 : void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum,
     933             :                                           const MCSubtargetInfo &STI,
     934             :                                           raw_ostream &O) {
     935         218 :   O << "{" << MI->getOperand(OpNum).getImm() << "}";
     936         109 : }
     937             : 
     938           0 : void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
     939             :                                   const MCSubtargetInfo &STI, raw_ostream &O) {
     940           0 :   llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
     941             : }
     942             : 
     943             : template <unsigned scale>
     944         368 : void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
     945             :                                           const MCSubtargetInfo &STI,
     946             :                                           raw_ostream &O) {
     947             :   const MCOperand &MO = MI->getOperand(OpNum);
     948             : 
     949         368 :   if (MO.isExpr()) {
     950         328 :     MO.getExpr()->print(O, &MAI);
     951         328 :     return;
     952             :   }
     953             : 
     954          40 :   int32_t OffImm = (int32_t)MO.getImm() << scale;
     955             : 
     956          80 :   O << markup("<imm:");
     957          40 :   if (OffImm == INT32_MIN)
     958           4 :     O << "#-0";
     959          36 :   else if (OffImm < 0)
     960          11 :     O << "#-" << -OffImm;
     961             :   else
     962          25 :     O << "#" << OffImm;
     963          40 :   O << markup(">");
     964             : }
     965             : 
     966        2648 : void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
     967             :                                             const MCSubtargetInfo &STI,
     968             :                                             raw_ostream &O) {
     969       10592 :   O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
     970        2648 :     << markup(">");
     971        2648 : }
     972             : 
     973         592 : void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
     974             :                                      const MCSubtargetInfo &STI,
     975             :                                      raw_ostream &O) {
     976         592 :   unsigned Imm = MI->getOperand(OpNum).getImm();
     977        1776 :   O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm))
     978         592 :     << markup(">");
     979         592 : }
     980             : 
     981        3674 : void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
     982             :                                       const MCSubtargetInfo &STI,
     983             :                                       raw_ostream &O) {
     984             :   // (3 - the number of trailing zeros) is the number of then / else.
     985        3674 :   unsigned Mask = MI->getOperand(OpNum).getImm();
     986        7348 :   unsigned Firstcond = MI->getOperand(OpNum - 1).getImm();
     987        3674 :   unsigned CondBit0 = Firstcond & 1;
     988        3674 :   unsigned NumTZ = countTrailingZeros(Mask);
     989             :   assert(NumTZ <= 3 && "Invalid IT mask!");
     990        4694 :   for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
     991         510 :     bool T = ((Mask >> Pos) & 1) == CondBit0;
     992         510 :     if (T)
     993             :       O << 't';
     994             :     else
     995             :       O << 'e';
     996             :   }
     997        3674 : }
     998             : 
     999         389 : void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
    1000             :                                                  const MCSubtargetInfo &STI,
    1001             :                                                  raw_ostream &O) {
    1002             :   const MCOperand &MO1 = MI->getOperand(Op);
    1003         389 :   const MCOperand &MO2 = MI->getOperand(Op + 1);
    1004             : 
    1005         389 :   if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
    1006           0 :     printOperand(MI, Op, STI, O);
    1007           0 :     return;
    1008             :   }
    1009             : 
    1010         778 :   O << markup("<mem:") << "[";
    1011         389 :   printRegName(O, MO1.getReg());
    1012         389 :   if (unsigned RegNum = MO2.getReg()) {
    1013         389 :     O << ", ";
    1014         389 :     printRegName(O, RegNum);
    1015             :   }
    1016         778 :   O << "]" << markup(">");
    1017             : }
    1018             : 
    1019        6390 : void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
    1020             :                                                     unsigned Op,
    1021             :                                                     const MCSubtargetInfo &STI,
    1022             :                                                     raw_ostream &O,
    1023             :                                                     unsigned Scale) {
    1024             :   const MCOperand &MO1 = MI->getOperand(Op);
    1025        6390 :   const MCOperand &MO2 = MI->getOperand(Op + 1);
    1026             : 
    1027        6390 :   if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
    1028           0 :     printOperand(MI, Op, STI, O);
    1029           0 :     return;
    1030             :   }
    1031             : 
    1032       12780 :   O << markup("<mem:") << "[";
    1033        6390 :   printRegName(O, MO1.getReg());
    1034        6390 :   if (unsigned ImmOffs = MO2.getImm()) {
    1035        6993 :     O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale)
    1036        2331 :       << markup(">");
    1037             :   }
    1038       12780 :   O << "]" << markup(">");
    1039             : }
    1040             : 
    1041        1339 : void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
    1042             :                                                      unsigned Op,
    1043             :                                                      const MCSubtargetInfo &STI,
    1044             :                                                      raw_ostream &O) {
    1045        1339 :   printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1);
    1046        1339 : }
    1047             : 
    1048         635 : void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
    1049             :                                                      unsigned Op,
    1050             :                                                      const MCSubtargetInfo &STI,
    1051             :                                                      raw_ostream &O) {
    1052         635 :   printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2);
    1053         635 : }
    1054             : 
    1055        2590 : void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
    1056             :                                                      unsigned Op,
    1057             :                                                      const MCSubtargetInfo &STI,
    1058             :                                                      raw_ostream &O) {
    1059        2590 :   printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
    1060        2590 : }
    1061             : 
    1062        1826 : void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
    1063             :                                                  const MCSubtargetInfo &STI,
    1064             :                                                  raw_ostream &O) {
    1065        1826 :   printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
    1066        1826 : }
    1067             : 
    1068             : // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
    1069             : // register with shift forms.
    1070             : // REG 0   0           - e.g. R5
    1071             : // REG IMM, SH_OPC     - e.g. R5, LSL #3
    1072         540 : void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
    1073             :                                       const MCSubtargetInfo &STI,
    1074             :                                       raw_ostream &O) {
    1075             :   const MCOperand &MO1 = MI->getOperand(OpNum);
    1076         540 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
    1077             : 
    1078         540 :   unsigned Reg = MO1.getReg();
    1079         540 :   printRegName(O, Reg);
    1080             : 
    1081             :   // Print the shift opc.
    1082             :   assert(MO2.isImm() && "Not a valid t2_so_reg value!");
    1083        1620 :   printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
    1084        1080 :                    ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
    1085         540 : }
    1086             : 
    1087             : template <bool AlwaysPrintImm0>
    1088        7818 : void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
    1089             :                                                const MCSubtargetInfo &STI,
    1090             :                                                raw_ostream &O) {
    1091             :   const MCOperand &MO1 = MI->getOperand(OpNum);
    1092        7818 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
    1093             : 
    1094        7818 :   if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
    1095         712 :     printOperand(MI, OpNum, STI, O);
    1096         712 :     return;
    1097             :   }
    1098             : 
    1099       14212 :   O << markup("<mem:") << "[";
    1100        7106 :   printRegName(O, MO1.getReg());
    1101             : 
    1102        7106 :   int32_t OffImm = (int32_t)MO2.getImm();
    1103             :   bool isSub = OffImm < 0;
    1104             :   // Special value for #-0. All others are normal.
    1105        7106 :   if (OffImm == INT32_MIN)
    1106             :     OffImm = 0;
    1107        7106 :   if (isSub) {
    1108         627 :     O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
    1109        6824 :   } else if (AlwaysPrintImm0 || OffImm > 0) {
    1110       14550 :     O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
    1111             :   }
    1112       14212 :   O << "]" << markup(">");
    1113             : }
    1114             : 
    1115             : template <bool AlwaysPrintImm0>
    1116         357 : void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
    1117             :                                                 unsigned OpNum,
    1118             :                                                 const MCSubtargetInfo &STI,
    1119             :                                                 raw_ostream &O) {
    1120             :   const MCOperand &MO1 = MI->getOperand(OpNum);
    1121         357 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
    1122             : 
    1123         714 :   O << markup("<mem:") << "[";
    1124         357 :   printRegName(O, MO1.getReg());
    1125             : 
    1126         357 :   int32_t OffImm = (int32_t)MO2.getImm();
    1127             :   bool isSub = OffImm < 0;
    1128             :   // Don't print +0.
    1129         357 :   if (OffImm == INT32_MIN)
    1130             :     OffImm = 0;
    1131         357 :   if (isSub) {
    1132         615 :     O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
    1133          91 :   } else if (AlwaysPrintImm0 || OffImm > 0) {
    1134         324 :     O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
    1135             :   }
    1136         714 :   O << "]" << markup(">");
    1137         357 : }
    1138             : 
    1139             : template <bool AlwaysPrintImm0>
    1140         330 : void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
    1141             :                                                   unsigned OpNum,
    1142             :                                                   const MCSubtargetInfo &STI,
    1143             :                                                   raw_ostream &O) {
    1144             :   const MCOperand &MO1 = MI->getOperand(OpNum);
    1145         330 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
    1146             : 
    1147         330 :   if (!MO1.isReg()) { //  For label symbolic references.
    1148           0 :     printOperand(MI, OpNum, STI, O);
    1149           0 :     return;
    1150             :   }
    1151             : 
    1152         660 :   O << markup("<mem:") << "[";
    1153         330 :   printRegName(O, MO1.getReg());
    1154             : 
    1155         330 :   int32_t OffImm = (int32_t)MO2.getImm();
    1156             :   bool isSub = OffImm < 0;
    1157             : 
    1158             :   assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
    1159             : 
    1160             :   // Don't print +0.
    1161         330 :   if (OffImm == INT32_MIN)
    1162             :     OffImm = 0;
    1163         330 :   if (isSub) {
    1164         165 :     O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
    1165         241 :   } else if (AlwaysPrintImm0 || OffImm > 0) {
    1166         369 :     O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
    1167             :   }
    1168         660 :   O << "]" << markup(">");
    1169             : }
    1170             : 
    1171         128 : void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(
    1172             :     const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    1173             :     raw_ostream &O) {
    1174             :   const MCOperand &MO1 = MI->getOperand(OpNum);
    1175         128 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
    1176             : 
    1177         256 :   O << markup("<mem:") << "[";
    1178         128 :   printRegName(O, MO1.getReg());
    1179         128 :   if (MO2.getImm()) {
    1180          42 :     O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4)
    1181          14 :       << markup(">");
    1182             :   }
    1183         256 :   O << "]" << markup(">");
    1184         128 : }
    1185             : 
    1186        1210 : void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(
    1187             :     const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    1188             :     raw_ostream &O) {
    1189             :   const MCOperand &MO1 = MI->getOperand(OpNum);
    1190        1210 :   int32_t OffImm = (int32_t)MO1.getImm();
    1191        2420 :   O << ", " << markup("<imm:");
    1192        1210 :   if (OffImm == INT32_MIN)
    1193           2 :     O << "#-0";
    1194        1208 :   else if (OffImm < 0)
    1195          29 :     O << "#-" << -OffImm;
    1196             :   else
    1197        1179 :     O << "#" << OffImm;
    1198        1210 :   O << markup(">");
    1199        1210 : }
    1200             : 
    1201          79 : void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(
    1202             :     const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    1203             :     raw_ostream &O) {
    1204             :   const MCOperand &MO1 = MI->getOperand(OpNum);
    1205          79 :   int32_t OffImm = (int32_t)MO1.getImm();
    1206             : 
    1207             :   assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
    1208             : 
    1209         158 :   O << ", " << markup("<imm:");
    1210          79 :   if (OffImm == INT32_MIN)
    1211          22 :     O << "#-0";
    1212          57 :   else if (OffImm < 0)
    1213          17 :     O << "#-" << -OffImm;
    1214             :   else
    1215          40 :     O << "#" << OffImm;
    1216          79 :   O << markup(">");
    1217          79 : }
    1218             : 
    1219         390 : void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
    1220             :                                                  unsigned OpNum,
    1221             :                                                  const MCSubtargetInfo &STI,
    1222             :                                                  raw_ostream &O) {
    1223             :   const MCOperand &MO1 = MI->getOperand(OpNum);
    1224         390 :   const MCOperand &MO2 = MI->getOperand(OpNum + 1);
    1225         390 :   const MCOperand &MO3 = MI->getOperand(OpNum + 2);
    1226             : 
    1227         780 :   O << markup("<mem:") << "[";
    1228         390 :   printRegName(O, MO1.getReg());
    1229             : 
    1230             :   assert(MO2.getReg() && "Invalid so_reg load / store address!");
    1231         390 :   O << ", ";
    1232         390 :   printRegName(O, MO2.getReg());
    1233             : 
    1234         390 :   unsigned ShAmt = MO3.getImm();
    1235         390 :   if (ShAmt) {
    1236             :     assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
    1237         438 :     O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">");
    1238             :   }
    1239         780 :   O << "]" << markup(">");
    1240         390 : }
    1241             : 
    1242         434 : void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
    1243             :                                        const MCSubtargetInfo &STI,
    1244             :                                        raw_ostream &O) {
    1245             :   const MCOperand &MO = MI->getOperand(OpNum);
    1246        1736 :   O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm())
    1247         434 :     << markup(">");
    1248         434 : }
    1249             : 
    1250         452 : void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
    1251             :                                             const MCSubtargetInfo &STI,
    1252             :                                             raw_ostream &O) {
    1253         452 :   unsigned EncodedImm = MI->getOperand(OpNum).getImm();
    1254             :   unsigned EltBits;
    1255         452 :   uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
    1256         904 :   O << markup("<imm:") << "#0x";
    1257         452 :   O.write_hex(Val);
    1258         452 :   O << markup(">");
    1259         452 : }
    1260             : 
    1261         268 : void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
    1262             :                                             const MCSubtargetInfo &STI,
    1263             :                                             raw_ostream &O) {
    1264         268 :   unsigned Imm = MI->getOperand(OpNum).getImm();
    1265         804 :   O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">");
    1266         268 : }
    1267             : 
    1268         867 : void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
    1269             :                                         const MCSubtargetInfo &STI,
    1270             :                                         raw_ostream &O) {
    1271         867 :   unsigned Imm = MI->getOperand(OpNum).getImm();
    1272         867 :   if (Imm == 0)
    1273             :     return;
    1274             :   assert(Imm <= 3 && "illegal ror immediate!");
    1275        1071 :   O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">");
    1276             : }
    1277             : 
    1278        9771 : void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum,
    1279             :                                         const MCSubtargetInfo &STI,
    1280             :                                         raw_ostream &O) {
    1281        9771 :   MCOperand Op = MI->getOperand(OpNum);
    1282             : 
    1283             :   // Support for fixups (MCFixup)
    1284        9771 :   if (Op.isExpr())
    1285           2 :     return printOperand(MI, OpNum, STI, O);
    1286             : 
    1287        9769 :   unsigned Bits = Op.getImm() & 0xFF;
    1288        9769 :   unsigned Rot = (Op.getImm() & 0xF00) >> 7;
    1289             : 
    1290             :   bool PrintUnsigned = false;
    1291        9769 :   switch (MI->getOpcode()) {
    1292        2871 :   case ARM::MOVi:
    1293             :     // Movs to PC should be treated unsigned
    1294        5742 :     PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
    1295        2871 :     break;
    1296          63 :   case ARM::MSRi:
    1297             :     // Movs to special registers should be treated unsigned
    1298             :     PrintUnsigned = true;
    1299          63 :     break;
    1300             :   }
    1301             : 
    1302        9769 :   int32_t Rotated = ARM_AM::rotr32(Bits, Rot);
    1303        9769 :   if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
    1304             :     // #rot has the least possible value
    1305       18870 :     O << "#" << markup("<imm:");
    1306        9435 :     if (PrintUnsigned)
    1307             :       O << static_cast<uint32_t>(Rotated);
    1308             :     else
    1309             :       O << Rotated;
    1310        9435 :     O << markup(">");
    1311        9435 :     return;
    1312             :   }
    1313             : 
    1314             :   // Explicit #bits, #rot implied
    1315        1670 :   O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:")
    1316         334 :     << Rot << markup(">");
    1317             : }
    1318             : 
    1319          24 : void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
    1320             :                                   const MCSubtargetInfo &STI, raw_ostream &O) {
    1321          96 :   O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm()
    1322          24 :     << markup(">");
    1323          24 : }
    1324             : 
    1325          24 : void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
    1326             :                                   const MCSubtargetInfo &STI, raw_ostream &O) {
    1327          96 :   O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm()
    1328          24 :     << markup(">");
    1329          24 : }
    1330             : 
    1331         947 : void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
    1332             :                                       const MCSubtargetInfo &STI,
    1333             :                                       raw_ostream &O) {
    1334        1894 :   O << "[" << MI->getOperand(OpNum).getImm() << "]";
    1335         947 : }
    1336             : 
    1337         396 : void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
    1338             :                                         const MCSubtargetInfo &STI,
    1339             :                                         raw_ostream &O) {
    1340         396 :   O << "{";
    1341         792 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1342         396 :   O << "}";
    1343         396 : }
    1344             : 
    1345        4406 : void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
    1346             :                                         const MCSubtargetInfo &STI,
    1347             :                                         raw_ostream &O) {
    1348        4406 :   unsigned Reg = MI->getOperand(OpNum).getReg();
    1349        4406 :   unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
    1350        4406 :   unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
    1351        4406 :   O << "{";
    1352        4406 :   printRegName(O, Reg0);
    1353        4406 :   O << ", ";
    1354        4406 :   printRegName(O, Reg1);
    1355        4406 :   O << "}";
    1356        4406 : }
    1357             : 
    1358          84 : void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum,
    1359             :                                               const MCSubtargetInfo &STI,
    1360             :                                               raw_ostream &O) {
    1361          84 :   unsigned Reg = MI->getOperand(OpNum).getReg();
    1362          84 :   unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
    1363          84 :   unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
    1364          84 :   O << "{";
    1365          84 :   printRegName(O, Reg0);
    1366          84 :   O << ", ";
    1367          84 :   printRegName(O, Reg1);
    1368          84 :   O << "}";
    1369          84 : }
    1370             : 
    1371         144 : void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum,
    1372             :                                           const MCSubtargetInfo &STI,
    1373             :                                           raw_ostream &O) {
    1374             :   // Normally, it's not safe to use register enum values directly with
    1375             :   // addition to get the next register, but for VFP registers, the
    1376             :   // sort order is guaranteed because they're all of the form D<n>.
    1377         144 :   O << "{";
    1378         288 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1379         144 :   O << ", ";
    1380         288 :   printRegName(O, MI->getOperand(OpNum).getReg() + 1);
    1381         144 :   O << ", ";
    1382         288 :   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
    1383         144 :   O << "}";
    1384         144 : }
    1385             : 
    1386         428 : void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
    1387             :                                          const MCSubtargetInfo &STI,
    1388             :                                          raw_ostream &O) {
    1389             :   // Normally, it's not safe to use register enum values directly with
    1390             :   // addition to get the next register, but for VFP registers, the
    1391             :   // sort order is guaranteed because they're all of the form D<n>.
    1392         428 :   O << "{";
    1393         856 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1394         428 :   O << ", ";
    1395         856 :   printRegName(O, MI->getOperand(OpNum).getReg() + 1);
    1396         428 :   O << ", ";
    1397         856 :   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
    1398         428 :   O << ", ";
    1399         856 :   printRegName(O, MI->getOperand(OpNum).getReg() + 3);
    1400         428 :   O << "}";
    1401         428 : }
    1402             : 
    1403          41 : void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI,
    1404             :                                                 unsigned OpNum,
    1405             :                                                 const MCSubtargetInfo &STI,
    1406             :                                                 raw_ostream &O) {
    1407          41 :   O << "{";
    1408          82 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1409          41 :   O << "[]}";
    1410          41 : }
    1411             : 
    1412          78 : void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
    1413             :                                                 unsigned OpNum,
    1414             :                                                 const MCSubtargetInfo &STI,
    1415             :                                                 raw_ostream &O) {
    1416          78 :   unsigned Reg = MI->getOperand(OpNum).getReg();
    1417          78 :   unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
    1418          78 :   unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
    1419          78 :   O << "{";
    1420          78 :   printRegName(O, Reg0);
    1421          78 :   O << "[], ";
    1422          78 :   printRegName(O, Reg1);
    1423          78 :   O << "[]}";
    1424          78 : }
    1425             : 
    1426           0 : void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI,
    1427             :                                                   unsigned OpNum,
    1428             :                                                   const MCSubtargetInfo &STI,
    1429             :                                                   raw_ostream &O) {
    1430             :   // Normally, it's not safe to use register enum values directly with
    1431             :   // addition to get the next register, but for VFP registers, the
    1432             :   // sort order is guaranteed because they're all of the form D<n>.
    1433           0 :   O << "{";
    1434           0 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1435           0 :   O << "[], ";
    1436           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 1);
    1437           0 :   O << "[], ";
    1438           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
    1439           0 :   O << "[]}";
    1440           0 : }
    1441             : 
    1442           0 : void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
    1443             :                                                  unsigned OpNum,
    1444             :                                                  const MCSubtargetInfo &STI,
    1445             :                                                  raw_ostream &O) {
    1446             :   // Normally, it's not safe to use register enum values directly with
    1447             :   // addition to get the next register, but for VFP registers, the
    1448             :   // sort order is guaranteed because they're all of the form D<n>.
    1449           0 :   O << "{";
    1450           0 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1451           0 :   O << "[], ";
    1452           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 1);
    1453           0 :   O << "[], ";
    1454           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
    1455           0 :   O << "[], ";
    1456           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 3);
    1457           0 :   O << "[]}";
    1458           0 : }
    1459             : 
    1460          45 : void ARMInstPrinter::printVectorListTwoSpacedAllLanes(
    1461             :     const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    1462             :     raw_ostream &O) {
    1463          45 :   unsigned Reg = MI->getOperand(OpNum).getReg();
    1464          45 :   unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
    1465          45 :   unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
    1466          45 :   O << "{";
    1467          45 :   printRegName(O, Reg0);
    1468          45 :   O << "[], ";
    1469          45 :   printRegName(O, Reg1);
    1470          45 :   O << "[]}";
    1471          45 : }
    1472             : 
    1473           0 : void ARMInstPrinter::printVectorListThreeSpacedAllLanes(
    1474             :     const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    1475             :     raw_ostream &O) {
    1476             :   // Normally, it's not safe to use register enum values directly with
    1477             :   // addition to get the next register, but for VFP registers, the
    1478             :   // sort order is guaranteed because they're all of the form D<n>.
    1479           0 :   O << "{";
    1480           0 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1481           0 :   O << "[], ";
    1482           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
    1483           0 :   O << "[], ";
    1484           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 4);
    1485           0 :   O << "[]}";
    1486           0 : }
    1487             : 
    1488           0 : void ARMInstPrinter::printVectorListFourSpacedAllLanes(
    1489             :     const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
    1490             :     raw_ostream &O) {
    1491             :   // Normally, it's not safe to use register enum values directly with
    1492             :   // addition to get the next register, but for VFP registers, the
    1493             :   // sort order is guaranteed because they're all of the form D<n>.
    1494           0 :   O << "{";
    1495           0 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1496           0 :   O << "[], ";
    1497           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
    1498           0 :   O << "[], ";
    1499           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 4);
    1500           0 :   O << "[], ";
    1501           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 6);
    1502           0 :   O << "[]}";
    1503           0 : }
    1504             : 
    1505           0 : void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI,
    1506             :                                                 unsigned OpNum,
    1507             :                                                 const MCSubtargetInfo &STI,
    1508             :                                                 raw_ostream &O) {
    1509             :   // Normally, it's not safe to use register enum values directly with
    1510             :   // addition to get the next register, but for VFP registers, the
    1511             :   // sort order is guaranteed because they're all of the form D<n>.
    1512           0 :   O << "{";
    1513           0 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1514           0 :   O << ", ";
    1515           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
    1516           0 :   O << ", ";
    1517           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 4);
    1518           0 :   O << "}";
    1519           0 : }
    1520             : 
    1521           0 : void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum,
    1522             :                                                const MCSubtargetInfo &STI,
    1523             :                                                raw_ostream &O) {
    1524             :   // Normally, it's not safe to use register enum values directly with
    1525             :   // addition to get the next register, but for VFP registers, the
    1526             :   // sort order is guaranteed because they're all of the form D<n>.
    1527           0 :   O << "{";
    1528           0 :   printRegName(O, MI->getOperand(OpNum).getReg());
    1529           0 :   O << ", ";
    1530           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
    1531           0 :   O << ", ";
    1532           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 4);
    1533           0 :   O << ", ";
    1534           0 :   printRegName(O, MI->getOperand(OpNum).getReg() + 6);
    1535           0 :   O << "}";
    1536           0 : }
    1537             : 
    1538             : template<int64_t Angle, int64_t Remainder>
    1539         132 : void ARMInstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo,
    1540             :                                             const MCSubtargetInfo &STI,
    1541             :                                             raw_ostream &O) {
    1542         132 :   unsigned Val = MI->getOperand(OpNo).getImm();
    1543         132 :   O << "#" << (Val * Angle) + Remainder;
    1544         132 : }
    1545             : 

Generated by: LCOV version 1.13