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