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

Generated by: LCOV version 1.13