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

Generated by: LCOV version 1.13