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