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