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