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