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