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